blob: 4c5febd57f91872ed50e3c7112d4539d0b14f616 [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"
florianffbd84d2012-12-09 02:06:29 +000044#include "host_s390_defs.h" /* S390_BFP_ROUND_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000045
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
floriane38f6412012-12-21 17:32:12 +0000458/* Read a floating point register pair cointaining DFP value
459 and combine their contents into a 128-bit value */
460
461static IRExpr *
462get_dpr_pair(UInt archreg)
463{
464 IRExpr *high = get_dpr_dw0(archreg);
465 IRExpr *low = get_dpr_dw0(archreg + 2);
466
467 return binop(Iop_D64HLtoD128, high, low);
468}
469
470/* Write a 128-bit decimal floating point value into a register pair. */
471static void
472put_dpr_pair(UInt archreg, IRExpr *expr)
473{
474 IRExpr *high = unop(Iop_D128HItoD64, expr);
475 IRExpr *low = unop(Iop_D128LOtoD64, expr);
476
477 put_dpr_dw0(archreg, high);
478 put_dpr_dw0(archreg + 2, low);
479}
480
floriane75dafa2012-09-01 17:54:09 +0000481/* Terminate the current IRSB with an emulation failure. */
482static void
483emulation_failure(VexEmNote fail_kind)
484{
485 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000486 dis_res->whatNext = Dis_StopHere;
487 dis_res->jk_StopHere = Ijk_EmFail;
488}
sewardj2019a972011-03-07 16:04:07 +0000489
florian4b8efad2012-09-02 18:07:08 +0000490/* Terminate the current IRSB with an emulation warning. */
491static void
492emulation_warning(VexEmNote warn_kind)
493{
494 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
495 dis_res->whatNext = Dis_StopHere;
496 dis_res->jk_StopHere = Ijk_EmWarn;
497}
498
sewardj2019a972011-03-07 16:04:07 +0000499/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000500/*--- IR Debugging aids. ---*/
501/*------------------------------------------------------------*/
502#if 0
503
504static ULong
505s390_do_print(HChar *text, ULong value)
506{
507 vex_printf("%s %llu\n", text, value);
508 return 0;
509}
510
511static void
512s390_print(HChar *text, IRExpr *value)
513{
514 IRDirty *d;
515
516 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
517 mkIRExprVec_2(mkU64((ULong)text), value));
518 stmt(IRStmt_Dirty(d));
519}
520#endif
521
522
523/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000524/*--- Build the flags thunk. ---*/
525/*------------------------------------------------------------*/
526
527/* Completely fill the flags thunk. We're always filling all fields.
528 Apparently, that is better for redundant PUT elimination. */
529static void
530s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
531{
532 UInt op_off, dep1_off, dep2_off, ndep_off;
533
florian428dfdd2012-03-27 03:09:49 +0000534 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
535 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
536 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
537 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000538
539 stmt(IRStmt_Put(op_off, op));
540 stmt(IRStmt_Put(dep1_off, dep1));
541 stmt(IRStmt_Put(dep2_off, dep2));
542 stmt(IRStmt_Put(ndep_off, ndep));
543}
544
545
546/* Create an expression for V and widen the result to 64 bit. */
547static IRExpr *
548s390_cc_widen(IRTemp v, Bool sign_extend)
549{
550 IRExpr *expr;
551
552 expr = mkexpr(v);
553
554 switch (typeOfIRTemp(irsb->tyenv, v)) {
555 case Ity_I64:
556 break;
557 case Ity_I32:
558 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
559 break;
560 case Ity_I16:
561 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
562 break;
563 case Ity_I8:
564 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
565 break;
566 default:
567 vpanic("s390_cc_widen");
568 }
569
570 return expr;
571}
572
573static void
574s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
575{
576 IRExpr *op, *dep1, *dep2, *ndep;
577
578 op = mkU64(opc);
579 dep1 = s390_cc_widen(d1, sign_extend);
580 dep2 = mkU64(0);
581 ndep = mkU64(0);
582
583 s390_cc_thunk_fill(op, dep1, dep2, ndep);
584}
585
586
587static void
588s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
589{
590 IRExpr *op, *dep1, *dep2, *ndep;
591
592 op = mkU64(opc);
593 dep1 = s390_cc_widen(d1, sign_extend);
594 dep2 = s390_cc_widen(d2, sign_extend);
595 ndep = mkU64(0);
596
597 s390_cc_thunk_fill(op, dep1, dep2, ndep);
598}
599
600
601/* memcheck believes that the NDEP field in the flags thunk is always
602 defined. But for some flag computations (e.g. add with carry) that is
603 just not true. We therefore need to convey to memcheck that the value
604 of the ndep field does matter and therefore we make the DEP2 field
605 depend on it:
606
607 DEP2 = original_DEP2 ^ NDEP
608
609 In s390_calculate_cc we exploit that (a^b)^b == a
610 I.e. we xor the DEP2 value with the NDEP value to recover the
611 original_DEP2 value. */
612static void
613s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
614{
615 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
616
617 op = mkU64(opc);
618 dep1 = s390_cc_widen(d1, sign_extend);
619 dep2 = s390_cc_widen(d2, sign_extend);
620 ndep = s390_cc_widen(nd, sign_extend);
621
622 dep2x = binop(Iop_Xor64, dep2, ndep);
623
624 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
625}
626
627
628/* Write one floating point value into the flags thunk */
629static void
630s390_cc_thunk_put1f(UInt opc, IRTemp d1)
631{
632 IRExpr *op, *dep1, *dep2, *ndep;
633
634 op = mkU64(opc);
635 dep1 = mkexpr(d1);
636 dep2 = mkU64(0);
637 ndep = mkU64(0);
638
639 s390_cc_thunk_fill(op, dep1, dep2, ndep);
640}
641
642
643/* Write a floating point value and an integer into the flags thunk. The
644 integer value is zero-extended first. */
645static void
646s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
647{
648 IRExpr *op, *dep1, *dep2, *ndep;
649
650 op = mkU64(opc);
651 dep1 = mkexpr(d1);
652 dep2 = s390_cc_widen(d2, False);
653 ndep = mkU64(0);
654
655 s390_cc_thunk_fill(op, dep1, dep2, ndep);
656}
657
658
659/* Write a 128-bit floating point value into the flags thunk. This is
660 done by splitting the value into two 64-bits values. */
661static void
662s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
663{
664 IRExpr *op, *hi, *lo, *ndep;
665
666 op = mkU64(opc);
667 hi = unop(Iop_F128HItoF64, mkexpr(d1));
668 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
669 ndep = mkU64(0);
670
671 s390_cc_thunk_fill(op, hi, lo, ndep);
672}
673
674
675/* Write a 128-bit floating point value and an integer into the flags thunk.
676 The integer value is zero-extended first. */
677static void
678s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
679{
680 IRExpr *op, *hi, *lo, *lox, *ndep;
681
682 op = mkU64(opc);
683 hi = unop(Iop_F128HItoF64, mkexpr(d1));
684 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
685 ndep = s390_cc_widen(nd, False);
686
687 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
688
689 s390_cc_thunk_fill(op, hi, lox, ndep);
690}
691
692
floriane38f6412012-12-21 17:32:12 +0000693/* Write a 128-bit decimal floating point value into the flags thunk.
694 This is done by splitting the value into two 64-bits values. */
695static void
696s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
697{
698 IRExpr *op, *hi, *lo, *ndep;
699
700 op = mkU64(opc);
701 hi = unop(Iop_D128HItoD64, mkexpr(d1));
702 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
703 ndep = mkU64(0);
704
705 s390_cc_thunk_fill(op, hi, lo, ndep);
706}
707
708
sewardj2019a972011-03-07 16:04:07 +0000709static void
710s390_cc_set(UInt val)
711{
712 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
713 mkU64(val), mkU64(0), mkU64(0));
714}
715
716/* Build IR to calculate the condition code from flags thunk.
717 Returns an expression of type Ity_I32 */
718static IRExpr *
719s390_call_calculate_cc(void)
720{
721 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
722
florian428dfdd2012-03-27 03:09:49 +0000723 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
724 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
725 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
726 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000727
728 args = mkIRExprVec_4(op, dep1, dep2, ndep);
729 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
730 "s390_calculate_cc", &s390_calculate_cc, args);
731
732 /* Exclude OP and NDEP from definedness checking. We're only
733 interested in DEP1 and DEP2. */
734 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
735
736 return call;
737}
738
739/* Build IR to calculate the internal condition code for a "compare and branch"
740 insn. Returns an expression of type Ity_I32 */
741static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000742s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000743{
florianff9613f2012-05-12 15:26:44 +0000744 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000745
florianff9613f2012-05-12 15:26:44 +0000746 switch (opc) {
747 case S390_CC_OP_SIGNED_COMPARE:
748 dep1 = s390_cc_widen(op1, True);
749 dep2 = s390_cc_widen(op2, True);
750 break;
751
752 case S390_CC_OP_UNSIGNED_COMPARE:
753 dep1 = s390_cc_widen(op1, False);
754 dep2 = s390_cc_widen(op2, False);
755 break;
756
757 default:
758 vpanic("s390_call_calculate_icc");
759 }
760
761 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000762 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000763
florianff9613f2012-05-12 15:26:44 +0000764 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000765 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000766 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000767
florianff9613f2012-05-12 15:26:44 +0000768 /* Exclude the requested condition, OP and NDEP from definedness
769 checking. We're only interested in DEP1 and DEP2. */
770 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000771
772 return call;
773}
774
775/* Build IR to calculate the condition code from flags thunk.
776 Returns an expression of type Ity_I32 */
777static IRExpr *
778s390_call_calculate_cond(UInt m)
779{
780 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
781
782 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000783 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
784 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
785 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
786 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000787
788 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
789 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
790 "s390_calculate_cond", &s390_calculate_cond, args);
791
792 /* Exclude the requested condition, OP and NDEP from definedness
793 checking. We're only interested in DEP1 and DEP2. */
794 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
795
796 return call;
797}
798
799#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
800#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
801#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
802#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
803#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
804#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
805#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
806 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
807#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
808 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000809
810
sewardj2019a972011-03-07 16:04:07 +0000811
812
813/*------------------------------------------------------------*/
814/*--- Guest register access ---*/
815/*------------------------------------------------------------*/
816
817
818/*------------------------------------------------------------*/
819/*--- ar registers ---*/
820/*------------------------------------------------------------*/
821
822/* Return the guest state offset of a ar register. */
823static UInt
824ar_offset(UInt archreg)
825{
826 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000827 S390X_GUEST_OFFSET(guest_a0),
828 S390X_GUEST_OFFSET(guest_a1),
829 S390X_GUEST_OFFSET(guest_a2),
830 S390X_GUEST_OFFSET(guest_a3),
831 S390X_GUEST_OFFSET(guest_a4),
832 S390X_GUEST_OFFSET(guest_a5),
833 S390X_GUEST_OFFSET(guest_a6),
834 S390X_GUEST_OFFSET(guest_a7),
835 S390X_GUEST_OFFSET(guest_a8),
836 S390X_GUEST_OFFSET(guest_a9),
837 S390X_GUEST_OFFSET(guest_a10),
838 S390X_GUEST_OFFSET(guest_a11),
839 S390X_GUEST_OFFSET(guest_a12),
840 S390X_GUEST_OFFSET(guest_a13),
841 S390X_GUEST_OFFSET(guest_a14),
842 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000843 };
844
845 vassert(archreg < 16);
846
847 return offset[archreg];
848}
849
850
851/* Return the guest state offset of word #0 of a ar register. */
852static __inline__ UInt
853ar_w0_offset(UInt archreg)
854{
855 return ar_offset(archreg) + 0;
856}
857
858/* Write word #0 of a ar to the guest state. */
859static __inline__ void
860put_ar_w0(UInt archreg, IRExpr *expr)
861{
862 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
863
864 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
865}
866
867/* Read word #0 of a ar register. */
868static __inline__ IRExpr *
869get_ar_w0(UInt archreg)
870{
871 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
872}
873
874
875/*------------------------------------------------------------*/
876/*--- fpr registers ---*/
877/*------------------------------------------------------------*/
878
879/* Return the guest state offset of a fpr register. */
880static UInt
881fpr_offset(UInt archreg)
882{
883 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000884 S390X_GUEST_OFFSET(guest_f0),
885 S390X_GUEST_OFFSET(guest_f1),
886 S390X_GUEST_OFFSET(guest_f2),
887 S390X_GUEST_OFFSET(guest_f3),
888 S390X_GUEST_OFFSET(guest_f4),
889 S390X_GUEST_OFFSET(guest_f5),
890 S390X_GUEST_OFFSET(guest_f6),
891 S390X_GUEST_OFFSET(guest_f7),
892 S390X_GUEST_OFFSET(guest_f8),
893 S390X_GUEST_OFFSET(guest_f9),
894 S390X_GUEST_OFFSET(guest_f10),
895 S390X_GUEST_OFFSET(guest_f11),
896 S390X_GUEST_OFFSET(guest_f12),
897 S390X_GUEST_OFFSET(guest_f13),
898 S390X_GUEST_OFFSET(guest_f14),
899 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000900 };
901
902 vassert(archreg < 16);
903
904 return offset[archreg];
905}
906
907
908/* Return the guest state offset of word #0 of a fpr register. */
909static __inline__ UInt
910fpr_w0_offset(UInt archreg)
911{
912 return fpr_offset(archreg) + 0;
913}
914
915/* Write word #0 of a fpr to the guest state. */
916static __inline__ void
917put_fpr_w0(UInt archreg, IRExpr *expr)
918{
919 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
920
921 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
922}
923
924/* Read word #0 of a fpr register. */
925static __inline__ IRExpr *
926get_fpr_w0(UInt archreg)
927{
928 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
929}
930
931/* Return the guest state offset of double word #0 of a fpr register. */
932static __inline__ UInt
933fpr_dw0_offset(UInt archreg)
934{
935 return fpr_offset(archreg) + 0;
936}
937
938/* Write double word #0 of a fpr to the guest state. */
939static __inline__ void
940put_fpr_dw0(UInt archreg, IRExpr *expr)
941{
942 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
943
944 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
945}
946
947/* Read double word #0 of a fpr register. */
948static __inline__ IRExpr *
949get_fpr_dw0(UInt archreg)
950{
951 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
952}
953
floriane38f6412012-12-21 17:32:12 +0000954/* Write word #0 of a dpr to the guest state. */
955static __inline__ void
956put_dpr_w0(UInt archreg, IRExpr *expr)
957{
958 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
959
960 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
961}
962
963/* Read word #0 of a dpr register. */
964static __inline__ IRExpr *
965get_dpr_w0(UInt archreg)
966{
967 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
968}
969
florian12390202012-11-10 22:34:14 +0000970/* Write double word #0 of a fpr containg DFP value to the guest state. */
971static __inline__ void
972put_dpr_dw0(UInt archreg, IRExpr *expr)
973{
974 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
975
976 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
977}
978
979/* Read double word #0 of a fpr register containing DFP value. */
980static __inline__ IRExpr *
981get_dpr_dw0(UInt archreg)
982{
983 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
984}
sewardj2019a972011-03-07 16:04:07 +0000985
986/*------------------------------------------------------------*/
987/*--- gpr registers ---*/
988/*------------------------------------------------------------*/
989
990/* Return the guest state offset of a gpr register. */
991static UInt
992gpr_offset(UInt archreg)
993{
994 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000995 S390X_GUEST_OFFSET(guest_r0),
996 S390X_GUEST_OFFSET(guest_r1),
997 S390X_GUEST_OFFSET(guest_r2),
998 S390X_GUEST_OFFSET(guest_r3),
999 S390X_GUEST_OFFSET(guest_r4),
1000 S390X_GUEST_OFFSET(guest_r5),
1001 S390X_GUEST_OFFSET(guest_r6),
1002 S390X_GUEST_OFFSET(guest_r7),
1003 S390X_GUEST_OFFSET(guest_r8),
1004 S390X_GUEST_OFFSET(guest_r9),
1005 S390X_GUEST_OFFSET(guest_r10),
1006 S390X_GUEST_OFFSET(guest_r11),
1007 S390X_GUEST_OFFSET(guest_r12),
1008 S390X_GUEST_OFFSET(guest_r13),
1009 S390X_GUEST_OFFSET(guest_r14),
1010 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001011 };
1012
1013 vassert(archreg < 16);
1014
1015 return offset[archreg];
1016}
1017
1018
1019/* Return the guest state offset of word #0 of a gpr register. */
1020static __inline__ UInt
1021gpr_w0_offset(UInt archreg)
1022{
1023 return gpr_offset(archreg) + 0;
1024}
1025
1026/* Write word #0 of a gpr to the guest state. */
1027static __inline__ void
1028put_gpr_w0(UInt archreg, IRExpr *expr)
1029{
1030 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1031
1032 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1033}
1034
1035/* Read word #0 of a gpr register. */
1036static __inline__ IRExpr *
1037get_gpr_w0(UInt archreg)
1038{
1039 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1040}
1041
1042/* Return the guest state offset of double word #0 of a gpr register. */
1043static __inline__ UInt
1044gpr_dw0_offset(UInt archreg)
1045{
1046 return gpr_offset(archreg) + 0;
1047}
1048
1049/* Write double word #0 of a gpr to the guest state. */
1050static __inline__ void
1051put_gpr_dw0(UInt archreg, IRExpr *expr)
1052{
1053 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1054
1055 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1056}
1057
1058/* Read double word #0 of a gpr register. */
1059static __inline__ IRExpr *
1060get_gpr_dw0(UInt archreg)
1061{
1062 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1063}
1064
1065/* Return the guest state offset of half word #1 of a gpr register. */
1066static __inline__ UInt
1067gpr_hw1_offset(UInt archreg)
1068{
1069 return gpr_offset(archreg) + 2;
1070}
1071
1072/* Write half word #1 of a gpr to the guest state. */
1073static __inline__ void
1074put_gpr_hw1(UInt archreg, IRExpr *expr)
1075{
1076 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1077
1078 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1079}
1080
1081/* Read half word #1 of a gpr register. */
1082static __inline__ IRExpr *
1083get_gpr_hw1(UInt archreg)
1084{
1085 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1086}
1087
1088/* Return the guest state offset of byte #6 of a gpr register. */
1089static __inline__ UInt
1090gpr_b6_offset(UInt archreg)
1091{
1092 return gpr_offset(archreg) + 6;
1093}
1094
1095/* Write byte #6 of a gpr to the guest state. */
1096static __inline__ void
1097put_gpr_b6(UInt archreg, IRExpr *expr)
1098{
1099 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1100
1101 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1102}
1103
1104/* Read byte #6 of a gpr register. */
1105static __inline__ IRExpr *
1106get_gpr_b6(UInt archreg)
1107{
1108 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1109}
1110
1111/* Return the guest state offset of byte #3 of a gpr register. */
1112static __inline__ UInt
1113gpr_b3_offset(UInt archreg)
1114{
1115 return gpr_offset(archreg) + 3;
1116}
1117
1118/* Write byte #3 of a gpr to the guest state. */
1119static __inline__ void
1120put_gpr_b3(UInt archreg, IRExpr *expr)
1121{
1122 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1123
1124 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1125}
1126
1127/* Read byte #3 of a gpr register. */
1128static __inline__ IRExpr *
1129get_gpr_b3(UInt archreg)
1130{
1131 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1132}
1133
1134/* Return the guest state offset of byte #0 of a gpr register. */
1135static __inline__ UInt
1136gpr_b0_offset(UInt archreg)
1137{
1138 return gpr_offset(archreg) + 0;
1139}
1140
1141/* Write byte #0 of a gpr to the guest state. */
1142static __inline__ void
1143put_gpr_b0(UInt archreg, IRExpr *expr)
1144{
1145 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1146
1147 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1148}
1149
1150/* Read byte #0 of a gpr register. */
1151static __inline__ IRExpr *
1152get_gpr_b0(UInt archreg)
1153{
1154 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1155}
1156
1157/* Return the guest state offset of word #1 of a gpr register. */
1158static __inline__ UInt
1159gpr_w1_offset(UInt archreg)
1160{
1161 return gpr_offset(archreg) + 4;
1162}
1163
1164/* Write word #1 of a gpr to the guest state. */
1165static __inline__ void
1166put_gpr_w1(UInt archreg, IRExpr *expr)
1167{
1168 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1169
1170 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1171}
1172
1173/* Read word #1 of a gpr register. */
1174static __inline__ IRExpr *
1175get_gpr_w1(UInt archreg)
1176{
1177 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1178}
1179
1180/* Return the guest state offset of half word #3 of a gpr register. */
1181static __inline__ UInt
1182gpr_hw3_offset(UInt archreg)
1183{
1184 return gpr_offset(archreg) + 6;
1185}
1186
1187/* Write half word #3 of a gpr to the guest state. */
1188static __inline__ void
1189put_gpr_hw3(UInt archreg, IRExpr *expr)
1190{
1191 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1192
1193 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1194}
1195
1196/* Read half word #3 of a gpr register. */
1197static __inline__ IRExpr *
1198get_gpr_hw3(UInt archreg)
1199{
1200 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1201}
1202
1203/* Return the guest state offset of byte #7 of a gpr register. */
1204static __inline__ UInt
1205gpr_b7_offset(UInt archreg)
1206{
1207 return gpr_offset(archreg) + 7;
1208}
1209
1210/* Write byte #7 of a gpr to the guest state. */
1211static __inline__ void
1212put_gpr_b7(UInt archreg, IRExpr *expr)
1213{
1214 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1215
1216 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1217}
1218
1219/* Read byte #7 of a gpr register. */
1220static __inline__ IRExpr *
1221get_gpr_b7(UInt archreg)
1222{
1223 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1224}
1225
1226/* Return the guest state offset of half word #0 of a gpr register. */
1227static __inline__ UInt
1228gpr_hw0_offset(UInt archreg)
1229{
1230 return gpr_offset(archreg) + 0;
1231}
1232
1233/* Write half word #0 of a gpr to the guest state. */
1234static __inline__ void
1235put_gpr_hw0(UInt archreg, IRExpr *expr)
1236{
1237 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1238
1239 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1240}
1241
1242/* Read half word #0 of a gpr register. */
1243static __inline__ IRExpr *
1244get_gpr_hw0(UInt archreg)
1245{
1246 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1247}
1248
1249/* Return the guest state offset of byte #4 of a gpr register. */
1250static __inline__ UInt
1251gpr_b4_offset(UInt archreg)
1252{
1253 return gpr_offset(archreg) + 4;
1254}
1255
1256/* Write byte #4 of a gpr to the guest state. */
1257static __inline__ void
1258put_gpr_b4(UInt archreg, IRExpr *expr)
1259{
1260 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1261
1262 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1263}
1264
1265/* Read byte #4 of a gpr register. */
1266static __inline__ IRExpr *
1267get_gpr_b4(UInt archreg)
1268{
1269 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1270}
1271
1272/* Return the guest state offset of byte #1 of a gpr register. */
1273static __inline__ UInt
1274gpr_b1_offset(UInt archreg)
1275{
1276 return gpr_offset(archreg) + 1;
1277}
1278
1279/* Write byte #1 of a gpr to the guest state. */
1280static __inline__ void
1281put_gpr_b1(UInt archreg, IRExpr *expr)
1282{
1283 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1284
1285 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1286}
1287
1288/* Read byte #1 of a gpr register. */
1289static __inline__ IRExpr *
1290get_gpr_b1(UInt archreg)
1291{
1292 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1293}
1294
1295/* Return the guest state offset of half word #2 of a gpr register. */
1296static __inline__ UInt
1297gpr_hw2_offset(UInt archreg)
1298{
1299 return gpr_offset(archreg) + 4;
1300}
1301
1302/* Write half word #2 of a gpr to the guest state. */
1303static __inline__ void
1304put_gpr_hw2(UInt archreg, IRExpr *expr)
1305{
1306 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1307
1308 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1309}
1310
1311/* Read half word #2 of a gpr register. */
1312static __inline__ IRExpr *
1313get_gpr_hw2(UInt archreg)
1314{
1315 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1316}
1317
1318/* Return the guest state offset of byte #5 of a gpr register. */
1319static __inline__ UInt
1320gpr_b5_offset(UInt archreg)
1321{
1322 return gpr_offset(archreg) + 5;
1323}
1324
1325/* Write byte #5 of a gpr to the guest state. */
1326static __inline__ void
1327put_gpr_b5(UInt archreg, IRExpr *expr)
1328{
1329 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1330
1331 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1332}
1333
1334/* Read byte #5 of a gpr register. */
1335static __inline__ IRExpr *
1336get_gpr_b5(UInt archreg)
1337{
1338 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1339}
1340
1341/* Return the guest state offset of byte #2 of a gpr register. */
1342static __inline__ UInt
1343gpr_b2_offset(UInt archreg)
1344{
1345 return gpr_offset(archreg) + 2;
1346}
1347
1348/* Write byte #2 of a gpr to the guest state. */
1349static __inline__ void
1350put_gpr_b2(UInt archreg, IRExpr *expr)
1351{
1352 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1353
1354 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1355}
1356
1357/* Read byte #2 of a gpr register. */
1358static __inline__ IRExpr *
1359get_gpr_b2(UInt archreg)
1360{
1361 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1362}
1363
1364/* Return the guest state offset of the counter register. */
1365static UInt
1366counter_offset(void)
1367{
floriane88b3c92011-07-05 02:48:39 +00001368 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001369}
1370
1371/* Return the guest state offset of double word #0 of the counter register. */
1372static __inline__ UInt
1373counter_dw0_offset(void)
1374{
1375 return counter_offset() + 0;
1376}
1377
1378/* Write double word #0 of the counter to the guest state. */
1379static __inline__ void
1380put_counter_dw0(IRExpr *expr)
1381{
1382 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1383
1384 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1385}
1386
1387/* Read double word #0 of the counter register. */
1388static __inline__ IRExpr *
1389get_counter_dw0(void)
1390{
1391 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1392}
1393
1394/* Return the guest state offset of word #0 of the counter register. */
1395static __inline__ UInt
1396counter_w0_offset(void)
1397{
1398 return counter_offset() + 0;
1399}
1400
1401/* Return the guest state offset of word #1 of the counter register. */
1402static __inline__ UInt
1403counter_w1_offset(void)
1404{
1405 return counter_offset() + 4;
1406}
1407
1408/* Write word #0 of the counter to the guest state. */
1409static __inline__ void
1410put_counter_w0(IRExpr *expr)
1411{
1412 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1413
1414 stmt(IRStmt_Put(counter_w0_offset(), expr));
1415}
1416
1417/* Read word #0 of the counter register. */
1418static __inline__ IRExpr *
1419get_counter_w0(void)
1420{
1421 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1422}
1423
1424/* Write word #1 of the counter to the guest state. */
1425static __inline__ void
1426put_counter_w1(IRExpr *expr)
1427{
1428 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1429
1430 stmt(IRStmt_Put(counter_w1_offset(), expr));
1431}
1432
1433/* Read word #1 of the counter register. */
1434static __inline__ IRExpr *
1435get_counter_w1(void)
1436{
1437 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1438}
1439
1440/* Return the guest state offset of the fpc register. */
1441static UInt
1442fpc_offset(void)
1443{
floriane88b3c92011-07-05 02:48:39 +00001444 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001445}
1446
1447/* Return the guest state offset of word #0 of the fpc register. */
1448static __inline__ UInt
1449fpc_w0_offset(void)
1450{
1451 return fpc_offset() + 0;
1452}
1453
1454/* Write word #0 of the fpc to the guest state. */
1455static __inline__ void
1456put_fpc_w0(IRExpr *expr)
1457{
1458 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1459
1460 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1461}
1462
1463/* Read word #0 of the fpc register. */
1464static __inline__ IRExpr *
1465get_fpc_w0(void)
1466{
1467 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1468}
1469
1470
1471/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001472/*--- Rounding modes ---*/
1473/*------------------------------------------------------------*/
1474
florian125e20d2012-10-07 15:42:37 +00001475/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001476 IRRoundingMode:
1477
1478 rounding mode | s390 | IR
1479 -------------------------
1480 to nearest | 00 | 00
1481 to zero | 01 | 11
1482 to +infinity | 10 | 10
1483 to -infinity | 11 | 01
1484
1485 So: IR = (4 - s390) & 3
1486*/
1487static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001488get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001489{
1490 IRTemp fpc_bits = newTemp(Ity_I32);
1491
1492 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1493 Prior to that bits [30:31] contained the bfp rounding mode with
1494 bit 29 being unused and having a value of 0. So we can always
1495 extract the least significant 3 bits. */
1496 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1497
1498 /* fixs390:
1499
1500
1501 if (! s390_host_has_fpext && rounding_mode > 3) {
1502 emulation warning @ runtime and
1503 set fpc to round nearest
1504 }
1505 */
1506
1507 /* For now silently adjust an unsupported rounding mode to "nearest" */
1508 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1509 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001510 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001511
1512 // rm_IR = (4 - rm_s390) & 3;
1513 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1514}
1515
1516/* Encode the s390 rounding mode as it appears in the m3 field of certain
1517 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1518 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1519 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1520 considers the default rounding mode (4.3.3). */
1521static IRTemp
1522encode_bfp_rounding_mode(UChar mode)
1523{
1524 IRExpr *rm;
1525
1526 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001527 case S390_BFP_ROUND_PER_FPC:
1528 rm = get_bfp_rounding_mode_from_fpc();
1529 break;
1530 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1531 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1532 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1533 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1534 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1535 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001536 default:
1537 vpanic("encode_bfp_rounding_mode");
1538 }
1539
1540 return mktemp(Ity_I32, rm);
1541}
1542
florianc8e4f562012-10-27 16:19:31 +00001543/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1544 IRRoundingMode:
1545
1546 rounding mode | s390 | IR
1547 ------------------------------------------------
1548 to nearest, ties to even | 000 | 000
1549 to zero | 001 | 011
1550 to +infinity | 010 | 010
1551 to -infinity | 011 | 001
1552 to nearest, ties away from 0 | 100 | 100
1553 to nearest, ties toward 0 | 101 | 111
1554 to away from 0 | 110 | 110
1555 to prepare for shorter precision | 111 | 101
1556
1557 So: IR = (s390 ^ ((s390 << 1) & 2))
1558*/
florianc8e4f562012-10-27 16:19:31 +00001559static IRExpr *
1560get_dfp_rounding_mode_from_fpc(void)
1561{
1562 IRTemp fpc_bits = newTemp(Ity_I32);
1563
1564 /* The dfp rounding mode is stored in bits [25:27].
1565 extract the bits at 25:27 and right shift 4 times. */
1566 assign(fpc_bits, binop(Iop_Shr32,
1567 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1568 mkU8(4)));
1569
1570 IRExpr *rm_s390 = mkexpr(fpc_bits);
1571 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1572
1573 return binop(Iop_Xor32, rm_s390,
1574 binop( Iop_And32,
1575 binop(Iop_Shl32, rm_s390, mkU8(1)),
1576 mkU32(2)));
1577}
1578
1579/* Encode the s390 rounding mode as it appears in the m3 field of certain
1580 instructions to VEX's IRRoundingMode. */
1581static IRTemp
1582encode_dfp_rounding_mode(UChar mode)
1583{
1584 IRExpr *rm;
1585
1586 switch (mode) {
1587 case S390_DFP_ROUND_PER_FPC_0:
1588 case S390_DFP_ROUND_PER_FPC_2:
1589 rm = get_dfp_rounding_mode_from_fpc(); break;
1590 case S390_DFP_ROUND_NEAREST_EVEN_4:
1591 case S390_DFP_ROUND_NEAREST_EVEN_8:
1592 rm = mkU32(Irrm_DFP_NEAREST); break;
1593 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1594 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1595 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1596 case S390_DFP_ROUND_PREPARE_SHORT_3:
1597 case S390_DFP_ROUND_PREPARE_SHORT_15:
1598 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1599 case S390_DFP_ROUND_ZERO_5:
1600 case S390_DFP_ROUND_ZERO_9:
1601 rm = mkU32(Irrm_DFP_ZERO ); break;
1602 case S390_DFP_ROUND_POSINF_6:
1603 case S390_DFP_ROUND_POSINF_10:
1604 rm = mkU32(Irrm_DFP_PosINF); break;
1605 case S390_DFP_ROUND_NEGINF_7:
1606 case S390_DFP_ROUND_NEGINF_11:
1607 rm = mkU32(Irrm_DFP_NegINF); break;
1608 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1609 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1610 case S390_DFP_ROUND_AWAY_0:
1611 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1612 default:
1613 vpanic("encode_dfp_rounding_mode");
1614 }
1615
1616 return mktemp(Ity_I32, rm);
1617}
florian12390202012-11-10 22:34:14 +00001618
florianc8e4f562012-10-27 16:19:31 +00001619
florian2c74d242012-09-12 19:38:42 +00001620/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001621/*--- Condition code helpers ---*/
1622/*------------------------------------------------------------*/
1623
1624/* The result of a Iop_CmpFxx operation is a condition code. It is
1625 encoded using the values defined in type IRCmpFxxResult.
1626 Before we can store the condition code into the guest state (or do
1627 anything else with it for that matter) we need to convert it to
1628 the encoding that s390 uses. This is what this function does.
1629
1630 s390 VEX b6 b2 b0 cc.1 cc.0
1631 0 0x40 EQ 1 0 0 0 0
1632 1 0x01 LT 0 0 1 0 1
1633 2 0x00 GT 0 0 0 1 0
1634 3 0x45 Unordered 1 1 1 1 1
1635
1636 The following bits from the VEX encoding are interesting:
1637 b0, b2, b6 with b0 being the LSB. We observe:
1638
1639 cc.0 = b0;
1640 cc.1 = b2 | (~b0 & ~b6)
1641
1642 with cc being the s390 condition code.
1643*/
1644static IRExpr *
1645convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1646{
1647 IRTemp cc0 = newTemp(Ity_I32);
1648 IRTemp cc1 = newTemp(Ity_I32);
1649 IRTemp b0 = newTemp(Ity_I32);
1650 IRTemp b2 = newTemp(Ity_I32);
1651 IRTemp b6 = newTemp(Ity_I32);
1652
1653 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1654 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1655 mkU32(1)));
1656 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1657 mkU32(1)));
1658
1659 assign(cc0, mkexpr(b0));
1660 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1661 binop(Iop_And32,
1662 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1663 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1664 )));
1665
1666 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1667}
1668
1669
1670/* The result of a Iop_CmpDxx operation is a condition code. It is
1671 encoded using the values defined in type IRCmpDxxResult.
1672 Before we can store the condition code into the guest state (or do
1673 anything else with it for that matter) we need to convert it to
1674 the encoding that s390 uses. This is what this function does. */
1675static IRExpr *
1676convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1677{
1678 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1679 same. currently. */
1680 return convert_vex_dfpcc_to_s390(vex_cc);
1681}
1682
1683
1684/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001685/*--- Build IR for formats ---*/
1686/*------------------------------------------------------------*/
1687static void
florian55085f82012-11-21 00:36:55 +00001688s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001689 UChar i)
1690{
florian55085f82012-11-21 00:36:55 +00001691 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001692
sewardj7ee97522011-05-09 21:45:04 +00001693 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001694 s390_disasm(ENC2(MNM, UINT), mnm, i);
1695}
1696
1697static void
florian55085f82012-11-21 00:36:55 +00001698s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001699 UChar r1, UShort i2)
1700{
1701 irgen(r1, i2);
1702}
1703
1704static void
florian55085f82012-11-21 00:36:55 +00001705s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001706 UChar r1, UShort i2)
1707{
florian55085f82012-11-21 00:36:55 +00001708 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001709
sewardj7ee97522011-05-09 21:45:04 +00001710 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001711 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1712}
1713
1714static void
florian55085f82012-11-21 00:36:55 +00001715s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001716 UChar r1, UShort i2)
1717{
florian55085f82012-11-21 00:36:55 +00001718 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001719
sewardj7ee97522011-05-09 21:45:04 +00001720 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001721 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1722}
1723
1724static void
florian55085f82012-11-21 00:36:55 +00001725s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001726 UChar r1, UShort i2)
1727{
florian55085f82012-11-21 00:36:55 +00001728 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001729
sewardj7ee97522011-05-09 21:45:04 +00001730 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001731 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1732}
1733
1734static void
florian55085f82012-11-21 00:36:55 +00001735s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001736 UChar r1, UChar r3, UShort i2)
1737{
florian55085f82012-11-21 00:36:55 +00001738 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001739
sewardj7ee97522011-05-09 21:45:04 +00001740 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001741 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1742}
1743
1744static void
florian55085f82012-11-21 00:36:55 +00001745s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001746 UChar r1, UChar r3, UShort i2)
1747{
florian55085f82012-11-21 00:36:55 +00001748 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001749
sewardj7ee97522011-05-09 21:45:04 +00001750 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001751 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1752}
1753
1754static void
florian55085f82012-11-21 00:36:55 +00001755s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1756 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001757 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1758{
florian55085f82012-11-21 00:36:55 +00001759 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001760
sewardj7ee97522011-05-09 21:45:04 +00001761 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001762 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1763 i5);
1764}
1765
1766static void
florian55085f82012-11-21 00:36:55 +00001767s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1768 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001769 UChar r1, UChar r2, UShort i4, UChar m3)
1770{
florian55085f82012-11-21 00:36:55 +00001771 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001772
sewardj7ee97522011-05-09 21:45:04 +00001773 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001774 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1775 r2, m3, (Int)(Short)i4);
1776}
1777
1778static void
florian55085f82012-11-21 00:36:55 +00001779s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1780 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001781 UChar r1, UChar m3, UShort i4, UChar i2)
1782{
florian55085f82012-11-21 00:36:55 +00001783 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001784
sewardj7ee97522011-05-09 21:45:04 +00001785 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001786 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1787 r1, i2, m3, (Int)(Short)i4);
1788}
1789
1790static void
florian55085f82012-11-21 00:36:55 +00001791s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1792 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001793 UChar r1, UChar m3, UShort i4, UChar i2)
1794{
florian55085f82012-11-21 00:36:55 +00001795 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001796
sewardj7ee97522011-05-09 21:45:04 +00001797 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001798 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1799 (Int)(Char)i2, m3, (Int)(Short)i4);
1800}
1801
1802static void
florian55085f82012-11-21 00:36:55 +00001803s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001804 UChar r1, UInt i2)
1805{
1806 irgen(r1, i2);
1807}
1808
1809static void
florian55085f82012-11-21 00:36:55 +00001810s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001811 UChar r1, UInt i2)
1812{
florian55085f82012-11-21 00:36:55 +00001813 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001814
sewardj7ee97522011-05-09 21:45:04 +00001815 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001816 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1817}
1818
1819static void
florian55085f82012-11-21 00:36:55 +00001820s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001821 UChar r1, UInt i2)
1822{
florian55085f82012-11-21 00:36:55 +00001823 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001824
sewardj7ee97522011-05-09 21:45:04 +00001825 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001826 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1827}
1828
1829static void
florian55085f82012-11-21 00:36:55 +00001830s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001831 UChar r1, UInt i2)
1832{
florian55085f82012-11-21 00:36:55 +00001833 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001834
sewardj7ee97522011-05-09 21:45:04 +00001835 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001836 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1837}
1838
1839static void
florian55085f82012-11-21 00:36:55 +00001840s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001841 UChar r1, UInt i2)
1842{
florian55085f82012-11-21 00:36:55 +00001843 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001844
sewardj7ee97522011-05-09 21:45:04 +00001845 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001846 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1847}
1848
1849static void
florian55085f82012-11-21 00:36:55 +00001850s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001851 IRTemp op4addr),
1852 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1853{
florian55085f82012-11-21 00:36:55 +00001854 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001855 IRTemp op4addr = newTemp(Ity_I64);
1856
1857 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1858 mkU64(0)));
1859
1860 mnm = irgen(r1, m3, i2, op4addr);
1861
sewardj7ee97522011-05-09 21:45:04 +00001862 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001863 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1864 (Int)(Char)i2, m3, d4, 0, b4);
1865}
1866
1867static void
florian55085f82012-11-21 00:36:55 +00001868s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001869 IRTemp op4addr),
1870 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1871{
florian55085f82012-11-21 00:36:55 +00001872 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001873 IRTemp op4addr = newTemp(Ity_I64);
1874
1875 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1876 mkU64(0)));
1877
1878 mnm = irgen(r1, m3, i2, op4addr);
1879
sewardj7ee97522011-05-09 21:45:04 +00001880 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001881 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1882 i2, m3, d4, 0, b4);
1883}
1884
1885static void
florian55085f82012-11-21 00:36:55 +00001886s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001887 UChar r1, UChar r2)
1888{
1889 irgen(r1, r2);
1890}
1891
1892static void
florian55085f82012-11-21 00:36:55 +00001893s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001894 UChar r1, UChar r2)
1895{
florian55085f82012-11-21 00:36:55 +00001896 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001897
sewardj7ee97522011-05-09 21:45:04 +00001898 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001899 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1900}
1901
1902static void
florian55085f82012-11-21 00:36:55 +00001903s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001904 UChar r1, UChar r2)
1905{
florian55085f82012-11-21 00:36:55 +00001906 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001907
sewardj7ee97522011-05-09 21:45:04 +00001908 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001909 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1910}
1911
1912static void
florian55085f82012-11-21 00:36:55 +00001913s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001914 UChar r1, UChar r2)
1915{
1916 irgen(r1, r2);
1917}
1918
1919static void
florian55085f82012-11-21 00:36:55 +00001920s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001921 UChar r1, UChar r2)
1922{
florian55085f82012-11-21 00:36:55 +00001923 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001924
sewardj7ee97522011-05-09 21:45:04 +00001925 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001926 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1927}
1928
1929static void
florian55085f82012-11-21 00:36:55 +00001930s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001931 UChar r1, UChar r2)
1932{
florian55085f82012-11-21 00:36:55 +00001933 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001934
sewardj7ee97522011-05-09 21:45:04 +00001935 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001936 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1937}
1938
1939static void
florian55085f82012-11-21 00:36:55 +00001940s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001941 UChar r1, UChar r2)
1942{
florian55085f82012-11-21 00:36:55 +00001943 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001944
sewardj7ee97522011-05-09 21:45:04 +00001945 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001946 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1947}
1948
1949static void
florian55085f82012-11-21 00:36:55 +00001950s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001951 UChar r1, UChar r2)
1952{
florian55085f82012-11-21 00:36:55 +00001953 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001954
sewardj7ee97522011-05-09 21:45:04 +00001955 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001956 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1957}
1958
1959static void
florian55085f82012-11-21 00:36:55 +00001960s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001961 UChar r1)
1962{
florian55085f82012-11-21 00:36:55 +00001963 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001964
sewardj7ee97522011-05-09 21:45:04 +00001965 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001966 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1967}
1968
1969static void
florian55085f82012-11-21 00:36:55 +00001970s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001971 UChar r1)
1972{
florian55085f82012-11-21 00:36:55 +00001973 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001974
sewardj7ee97522011-05-09 21:45:04 +00001975 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001976 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1977}
1978
1979static void
florian55085f82012-11-21 00:36:55 +00001980s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00001981 UChar m3, UChar r1, UChar r2)
1982{
florian55085f82012-11-21 00:36:55 +00001983 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001984
1985 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001986 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001987}
1988
1989static void
florian55085f82012-11-21 00:36:55 +00001990s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001991 UChar r1, UChar r3, UChar r2)
1992{
florian55085f82012-11-21 00:36:55 +00001993 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00001994
sewardj7ee97522011-05-09 21:45:04 +00001995 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001996 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1997}
1998
1999static void
florian55085f82012-11-21 00:36:55 +00002000s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2001 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002002 UChar m3, UChar m4, UChar r1, UChar r2)
2003{
florian55085f82012-11-21 00:36:55 +00002004 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002005
2006 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2007 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2008}
2009
2010static void
floriane38f6412012-12-21 17:32:12 +00002011s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2012 UChar m4, UChar r1, UChar r2)
2013{
2014 const HChar *mnm = irgen(m4, r1, r2);
2015
2016 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2017 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2018}
2019
2020static void
florian55085f82012-11-21 00:36:55 +00002021s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2022 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002023 UChar m3, UChar m4, UChar r1, UChar r2)
2024{
florian55085f82012-11-21 00:36:55 +00002025 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002026
2027 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2028 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2029}
2030
2031static void
florian55085f82012-11-21 00:36:55 +00002032s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2033 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002034 UChar m3, UChar m4, UChar r1, UChar r2)
2035{
florian55085f82012-11-21 00:36:55 +00002036 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002037
2038 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2039 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2040}
2041
2042
2043static void
florian55085f82012-11-21 00:36:55 +00002044s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002045 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2046{
2047 irgen(m3, r1, r2);
2048
sewardj7ee97522011-05-09 21:45:04 +00002049 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002050 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2051}
2052
2053static void
florian55085f82012-11-21 00:36:55 +00002054s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002055 UChar r3, UChar r1, UChar r2)
2056{
florian55085f82012-11-21 00:36:55 +00002057 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002058
sewardj7ee97522011-05-09 21:45:04 +00002059 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002060 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2061}
2062
2063static void
florian55085f82012-11-21 00:36:55 +00002064s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002065 UChar r3, UChar m4, UChar r1, UChar r2)
2066{
florian55085f82012-11-21 00:36:55 +00002067 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002068
2069 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2070 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2071}
2072
2073static void
florian55085f82012-11-21 00:36:55 +00002074s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002075 UChar r3, UChar r1, UChar r2)
2076{
florian55085f82012-11-21 00:36:55 +00002077 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002078
sewardj7ee97522011-05-09 21:45:04 +00002079 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002080 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2081}
2082
2083static void
florian55085f82012-11-21 00:36:55 +00002084s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2085 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002086 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2087{
florian55085f82012-11-21 00:36:55 +00002088 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002089 IRTemp op4addr = newTemp(Ity_I64);
2090
2091 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2092 mkU64(0)));
2093
2094 mnm = irgen(r1, r2, m3, op4addr);
2095
sewardj7ee97522011-05-09 21:45:04 +00002096 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002097 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2098 r2, m3, d4, 0, b4);
2099}
2100
2101static void
florian55085f82012-11-21 00:36:55 +00002102s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002103 UChar r1, UChar b2, UShort d2)
2104{
florian55085f82012-11-21 00:36:55 +00002105 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002106 IRTemp op2addr = newTemp(Ity_I64);
2107
2108 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2109 mkU64(0)));
2110
2111 mnm = irgen(r1, op2addr);
2112
sewardj7ee97522011-05-09 21:45:04 +00002113 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002114 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2115}
2116
2117static void
florian55085f82012-11-21 00:36:55 +00002118s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002119 UChar r1, UChar r3, UChar b2, UShort d2)
2120{
florian55085f82012-11-21 00:36:55 +00002121 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002122 IRTemp op2addr = newTemp(Ity_I64);
2123
2124 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2125 mkU64(0)));
2126
2127 mnm = irgen(r1, r3, op2addr);
2128
sewardj7ee97522011-05-09 21:45:04 +00002129 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002130 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2131}
2132
2133static void
florian55085f82012-11-21 00:36:55 +00002134s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002135 UChar r1, UChar r3, UChar b2, UShort d2)
2136{
florian55085f82012-11-21 00:36:55 +00002137 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002138 IRTemp op2addr = newTemp(Ity_I64);
2139
2140 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2141 mkU64(0)));
2142
2143 mnm = irgen(r1, r3, op2addr);
2144
sewardj7ee97522011-05-09 21:45:04 +00002145 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002146 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2147}
2148
2149static void
florian55085f82012-11-21 00:36:55 +00002150s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002151 UChar r1, UChar r3, UChar b2, UShort d2)
2152{
florian55085f82012-11-21 00:36:55 +00002153 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002154 IRTemp op2addr = newTemp(Ity_I64);
2155
2156 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2157 mkU64(0)));
2158
2159 mnm = irgen(r1, r3, op2addr);
2160
sewardj7ee97522011-05-09 21:45:04 +00002161 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002162 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2163}
2164
2165static void
florian55085f82012-11-21 00:36:55 +00002166s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002167 UChar r1, UChar r3, UShort i2)
2168{
florian55085f82012-11-21 00:36:55 +00002169 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002170
sewardj7ee97522011-05-09 21:45:04 +00002171 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002172 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2173}
2174
2175static void
florian55085f82012-11-21 00:36:55 +00002176s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002177 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2178{
florian55085f82012-11-21 00:36:55 +00002179 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002180 IRTemp op2addr = newTemp(Ity_I64);
2181 IRTemp d2 = newTemp(Ity_I64);
2182
2183 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2184 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2185 mkU64(0)));
2186
2187 mnm = irgen(r1, r3, op2addr);
2188
sewardj7ee97522011-05-09 21:45:04 +00002189 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002190 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2191}
2192
2193static void
florian55085f82012-11-21 00:36:55 +00002194s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002195 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2196{
florian55085f82012-11-21 00:36:55 +00002197 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002198 IRTemp op2addr = newTemp(Ity_I64);
2199 IRTemp d2 = newTemp(Ity_I64);
2200
2201 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2202 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2203 mkU64(0)));
2204
2205 mnm = irgen(r1, r3, op2addr);
2206
sewardj7ee97522011-05-09 21:45:04 +00002207 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002208 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2209}
2210
2211static void
florian55085f82012-11-21 00:36:55 +00002212s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002213 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2214{
florian55085f82012-11-21 00:36:55 +00002215 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002216 IRTemp op2addr = newTemp(Ity_I64);
2217 IRTemp d2 = newTemp(Ity_I64);
2218
2219 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2220 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2221 mkU64(0)));
2222
2223 mnm = irgen(r1, r3, op2addr);
2224
sewardj7ee97522011-05-09 21:45:04 +00002225 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002226 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2227}
2228
2229static void
florian55085f82012-11-21 00:36:55 +00002230s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002231 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2232 Int xmnm_kind)
2233{
2234 IRTemp op2addr = newTemp(Ity_I64);
2235 IRTemp d2 = newTemp(Ity_I64);
2236
florian6820ba52012-07-26 02:01:50 +00002237 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2238
sewardjd7bde722011-04-05 13:19:33 +00002239 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2240 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2241 mkU64(0)));
2242
2243 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002244
2245 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002246
sewardj7ee97522011-05-09 21:45:04 +00002247 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002248 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2249}
2250
2251static void
florian55085f82012-11-21 00:36:55 +00002252s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002253 IRTemp op2addr),
2254 UChar r1, UChar x2, UChar b2, UShort d2)
2255{
2256 IRTemp op2addr = newTemp(Ity_I64);
2257
2258 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2259 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2260 mkU64(0)));
2261
2262 irgen(r1, x2, b2, d2, op2addr);
2263}
2264
2265static void
florian55085f82012-11-21 00:36:55 +00002266s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002267 UChar r1, UChar x2, UChar b2, UShort d2)
2268{
florian55085f82012-11-21 00:36:55 +00002269 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002270 IRTemp op2addr = newTemp(Ity_I64);
2271
2272 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2273 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2274 mkU64(0)));
2275
2276 mnm = irgen(r1, op2addr);
2277
sewardj7ee97522011-05-09 21:45:04 +00002278 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002279 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2280}
2281
2282static void
florian55085f82012-11-21 00:36:55 +00002283s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002284 UChar r1, UChar x2, UChar b2, UShort d2)
2285{
florian55085f82012-11-21 00:36:55 +00002286 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002287 IRTemp op2addr = newTemp(Ity_I64);
2288
2289 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2290 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2291 mkU64(0)));
2292
2293 mnm = irgen(r1, op2addr);
2294
sewardj7ee97522011-05-09 21:45:04 +00002295 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002296 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2297}
2298
2299static void
florian55085f82012-11-21 00:36:55 +00002300s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002301 UChar r1, UChar x2, UChar b2, UShort d2)
2302{
florian55085f82012-11-21 00:36:55 +00002303 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002304 IRTemp op2addr = newTemp(Ity_I64);
2305
2306 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2307 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2308 mkU64(0)));
2309
2310 mnm = irgen(r1, op2addr);
2311
sewardj7ee97522011-05-09 21:45:04 +00002312 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002313 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2314}
2315
2316static void
florian55085f82012-11-21 00:36:55 +00002317s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002318 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2319{
florian55085f82012-11-21 00:36:55 +00002320 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002321 IRTemp op2addr = newTemp(Ity_I64);
2322
2323 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2324 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2325 mkU64(0)));
2326
2327 mnm = irgen(r3, op2addr, r1);
2328
sewardj7ee97522011-05-09 21:45:04 +00002329 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002330 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2331}
2332
2333static void
florian55085f82012-11-21 00:36:55 +00002334s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002335 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2336{
florian55085f82012-11-21 00:36:55 +00002337 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002338 IRTemp op2addr = newTemp(Ity_I64);
2339 IRTemp d2 = newTemp(Ity_I64);
2340
2341 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2342 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2343 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2344 mkU64(0)));
2345
2346 mnm = irgen(r1, op2addr);
2347
sewardj7ee97522011-05-09 21:45:04 +00002348 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002349 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2350}
2351
2352static void
florian55085f82012-11-21 00:36:55 +00002353s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002354 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2355{
florian55085f82012-11-21 00:36:55 +00002356 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002357 IRTemp op2addr = newTemp(Ity_I64);
2358 IRTemp d2 = newTemp(Ity_I64);
2359
2360 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2361 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2362 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2363 mkU64(0)));
2364
2365 mnm = irgen(r1, op2addr);
2366
sewardj7ee97522011-05-09 21:45:04 +00002367 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002368 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2369}
2370
2371static void
florian55085f82012-11-21 00:36:55 +00002372s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002373 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2374{
florian55085f82012-11-21 00:36:55 +00002375 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002376 IRTemp op2addr = newTemp(Ity_I64);
2377 IRTemp d2 = newTemp(Ity_I64);
2378
2379 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2380 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2381 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2382 mkU64(0)));
2383
2384 mnm = irgen();
2385
sewardj7ee97522011-05-09 21:45:04 +00002386 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002387 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2388}
2389
2390static void
florian55085f82012-11-21 00:36:55 +00002391s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar b2, UShort d2)
2393{
florian55085f82012-11-21 00:36:55 +00002394 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002395 IRTemp op2addr = newTemp(Ity_I64);
2396
2397 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2398 mkU64(0)));
2399
2400 mnm = irgen(op2addr);
2401
sewardj7ee97522011-05-09 21:45:04 +00002402 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002403 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2404}
2405
2406static void
florian55085f82012-11-21 00:36:55 +00002407s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002408 UChar i2, UChar b1, UShort d1)
2409{
florian55085f82012-11-21 00:36:55 +00002410 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002411 IRTemp op1addr = newTemp(Ity_I64);
2412
2413 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2414 mkU64(0)));
2415
2416 mnm = irgen(i2, op1addr);
2417
sewardj7ee97522011-05-09 21:45:04 +00002418 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002419 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2420}
2421
2422static void
florian55085f82012-11-21 00:36:55 +00002423s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002424 UChar i2, UChar b1, UShort dl1, UChar dh1)
2425{
florian55085f82012-11-21 00:36:55 +00002426 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002427 IRTemp op1addr = newTemp(Ity_I64);
2428 IRTemp d1 = newTemp(Ity_I64);
2429
2430 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2431 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2432 mkU64(0)));
2433
2434 mnm = irgen(i2, op1addr);
2435
sewardj7ee97522011-05-09 21:45:04 +00002436 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002437 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2438}
2439
2440static void
florian55085f82012-11-21 00:36:55 +00002441s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002442 UChar i2, UChar b1, UShort dl1, UChar dh1)
2443{
florian55085f82012-11-21 00:36:55 +00002444 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002445 IRTemp op1addr = newTemp(Ity_I64);
2446 IRTemp d1 = newTemp(Ity_I64);
2447
2448 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2449 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2450 mkU64(0)));
2451
2452 mnm = irgen(i2, op1addr);
2453
sewardj7ee97522011-05-09 21:45:04 +00002454 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002455 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2456}
2457
2458static void
florian55085f82012-11-21 00:36:55 +00002459s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002460 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2461{
florian55085f82012-11-21 00:36:55 +00002462 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002463 IRTemp op1addr = newTemp(Ity_I64);
2464 IRTemp op2addr = newTemp(Ity_I64);
2465
2466 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2467 mkU64(0)));
2468 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2469 mkU64(0)));
2470
2471 mnm = irgen(l, op1addr, op2addr);
2472
sewardj7ee97522011-05-09 21:45:04 +00002473 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002474 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2475}
2476
2477static void
florian55085f82012-11-21 00:36:55 +00002478s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002479 UChar b1, UShort d1, UShort i2)
2480{
florian55085f82012-11-21 00:36:55 +00002481 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002482 IRTemp op1addr = newTemp(Ity_I64);
2483
2484 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2485 mkU64(0)));
2486
2487 mnm = irgen(i2, op1addr);
2488
sewardj7ee97522011-05-09 21:45:04 +00002489 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002490 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2491}
2492
2493static void
florian55085f82012-11-21 00:36:55 +00002494s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002495 UChar b1, UShort d1, UShort i2)
2496{
florian55085f82012-11-21 00:36:55 +00002497 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002498 IRTemp op1addr = newTemp(Ity_I64);
2499
2500 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2501 mkU64(0)));
2502
2503 mnm = irgen(i2, op1addr);
2504
sewardj7ee97522011-05-09 21:45:04 +00002505 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002506 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2507}
2508
2509
2510
2511/*------------------------------------------------------------*/
2512/*--- Build IR for opcodes ---*/
2513/*------------------------------------------------------------*/
2514
florian55085f82012-11-21 00:36:55 +00002515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002516s390_irgen_AR(UChar r1, UChar r2)
2517{
2518 IRTemp op1 = newTemp(Ity_I32);
2519 IRTemp op2 = newTemp(Ity_I32);
2520 IRTemp result = newTemp(Ity_I32);
2521
2522 assign(op1, get_gpr_w1(r1));
2523 assign(op2, get_gpr_w1(r2));
2524 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2525 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2526 put_gpr_w1(r1, mkexpr(result));
2527
2528 return "ar";
2529}
2530
florian55085f82012-11-21 00:36:55 +00002531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002532s390_irgen_AGR(UChar r1, UChar r2)
2533{
2534 IRTemp op1 = newTemp(Ity_I64);
2535 IRTemp op2 = newTemp(Ity_I64);
2536 IRTemp result = newTemp(Ity_I64);
2537
2538 assign(op1, get_gpr_dw0(r1));
2539 assign(op2, get_gpr_dw0(r2));
2540 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2541 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2542 put_gpr_dw0(r1, mkexpr(result));
2543
2544 return "agr";
2545}
2546
florian55085f82012-11-21 00:36:55 +00002547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002548s390_irgen_AGFR(UChar r1, UChar r2)
2549{
2550 IRTemp op1 = newTemp(Ity_I64);
2551 IRTemp op2 = newTemp(Ity_I64);
2552 IRTemp result = newTemp(Ity_I64);
2553
2554 assign(op1, get_gpr_dw0(r1));
2555 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2556 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2557 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2558 put_gpr_dw0(r1, mkexpr(result));
2559
2560 return "agfr";
2561}
2562
florian55085f82012-11-21 00:36:55 +00002563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002564s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2565{
2566 IRTemp op2 = newTemp(Ity_I32);
2567 IRTemp op3 = newTemp(Ity_I32);
2568 IRTemp result = newTemp(Ity_I32);
2569
2570 assign(op2, get_gpr_w1(r2));
2571 assign(op3, get_gpr_w1(r3));
2572 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2573 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2574 put_gpr_w1(r1, mkexpr(result));
2575
2576 return "ark";
2577}
2578
florian55085f82012-11-21 00:36:55 +00002579static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002580s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2581{
2582 IRTemp op2 = newTemp(Ity_I64);
2583 IRTemp op3 = newTemp(Ity_I64);
2584 IRTemp result = newTemp(Ity_I64);
2585
2586 assign(op2, get_gpr_dw0(r2));
2587 assign(op3, get_gpr_dw0(r3));
2588 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2589 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2590 put_gpr_dw0(r1, mkexpr(result));
2591
2592 return "agrk";
2593}
2594
florian55085f82012-11-21 00:36:55 +00002595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002596s390_irgen_A(UChar r1, IRTemp op2addr)
2597{
2598 IRTemp op1 = newTemp(Ity_I32);
2599 IRTemp op2 = newTemp(Ity_I32);
2600 IRTemp result = newTemp(Ity_I32);
2601
2602 assign(op1, get_gpr_w1(r1));
2603 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2604 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2605 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2606 put_gpr_w1(r1, mkexpr(result));
2607
2608 return "a";
2609}
2610
florian55085f82012-11-21 00:36:55 +00002611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002612s390_irgen_AY(UChar r1, IRTemp op2addr)
2613{
2614 IRTemp op1 = newTemp(Ity_I32);
2615 IRTemp op2 = newTemp(Ity_I32);
2616 IRTemp result = newTemp(Ity_I32);
2617
2618 assign(op1, get_gpr_w1(r1));
2619 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2620 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2621 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2622 put_gpr_w1(r1, mkexpr(result));
2623
2624 return "ay";
2625}
2626
florian55085f82012-11-21 00:36:55 +00002627static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002628s390_irgen_AG(UChar r1, IRTemp op2addr)
2629{
2630 IRTemp op1 = newTemp(Ity_I64);
2631 IRTemp op2 = newTemp(Ity_I64);
2632 IRTemp result = newTemp(Ity_I64);
2633
2634 assign(op1, get_gpr_dw0(r1));
2635 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2636 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2637 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2638 put_gpr_dw0(r1, mkexpr(result));
2639
2640 return "ag";
2641}
2642
florian55085f82012-11-21 00:36:55 +00002643static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002644s390_irgen_AGF(UChar r1, IRTemp op2addr)
2645{
2646 IRTemp op1 = newTemp(Ity_I64);
2647 IRTemp op2 = newTemp(Ity_I64);
2648 IRTemp result = newTemp(Ity_I64);
2649
2650 assign(op1, get_gpr_dw0(r1));
2651 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2652 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2653 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2654 put_gpr_dw0(r1, mkexpr(result));
2655
2656 return "agf";
2657}
2658
florian55085f82012-11-21 00:36:55 +00002659static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002660s390_irgen_AFI(UChar r1, UInt i2)
2661{
2662 IRTemp op1 = newTemp(Ity_I32);
2663 Int op2;
2664 IRTemp result = newTemp(Ity_I32);
2665
2666 assign(op1, get_gpr_w1(r1));
2667 op2 = (Int)i2;
2668 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2669 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2670 mkU32((UInt)op2)));
2671 put_gpr_w1(r1, mkexpr(result));
2672
2673 return "afi";
2674}
2675
florian55085f82012-11-21 00:36:55 +00002676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002677s390_irgen_AGFI(UChar r1, UInt i2)
2678{
2679 IRTemp op1 = newTemp(Ity_I64);
2680 Long op2;
2681 IRTemp result = newTemp(Ity_I64);
2682
2683 assign(op1, get_gpr_dw0(r1));
2684 op2 = (Long)(Int)i2;
2685 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2686 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2687 mkU64((ULong)op2)));
2688 put_gpr_dw0(r1, mkexpr(result));
2689
2690 return "agfi";
2691}
2692
florian55085f82012-11-21 00:36:55 +00002693static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002694s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2695{
2696 Int op2;
2697 IRTemp op3 = newTemp(Ity_I32);
2698 IRTemp result = newTemp(Ity_I32);
2699
2700 op2 = (Int)(Short)i2;
2701 assign(op3, get_gpr_w1(r3));
2702 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2703 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2704 op2)), op3);
2705 put_gpr_w1(r1, mkexpr(result));
2706
2707 return "ahik";
2708}
2709
florian55085f82012-11-21 00:36:55 +00002710static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002711s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2712{
2713 Long op2;
2714 IRTemp op3 = newTemp(Ity_I64);
2715 IRTemp result = newTemp(Ity_I64);
2716
2717 op2 = (Long)(Short)i2;
2718 assign(op3, get_gpr_dw0(r3));
2719 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2720 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2721 op2)), op3);
2722 put_gpr_dw0(r1, mkexpr(result));
2723
2724 return "aghik";
2725}
2726
florian55085f82012-11-21 00:36:55 +00002727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002728s390_irgen_ASI(UChar i2, IRTemp op1addr)
2729{
2730 IRTemp op1 = newTemp(Ity_I32);
2731 Int op2;
2732 IRTemp result = newTemp(Ity_I32);
2733
2734 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2735 op2 = (Int)(Char)i2;
2736 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2737 store(mkexpr(op1addr), mkexpr(result));
2738 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2739 mkU32((UInt)op2)));
2740
2741 return "asi";
2742}
2743
florian55085f82012-11-21 00:36:55 +00002744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002745s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2746{
2747 IRTemp op1 = newTemp(Ity_I64);
2748 Long op2;
2749 IRTemp result = newTemp(Ity_I64);
2750
2751 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2752 op2 = (Long)(Char)i2;
2753 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2754 store(mkexpr(op1addr), mkexpr(result));
2755 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2756 mkU64((ULong)op2)));
2757
2758 return "agsi";
2759}
2760
florian55085f82012-11-21 00:36:55 +00002761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002762s390_irgen_AH(UChar r1, IRTemp op2addr)
2763{
2764 IRTemp op1 = newTemp(Ity_I32);
2765 IRTemp op2 = newTemp(Ity_I32);
2766 IRTemp result = newTemp(Ity_I32);
2767
2768 assign(op1, get_gpr_w1(r1));
2769 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2770 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2771 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2772 put_gpr_w1(r1, mkexpr(result));
2773
2774 return "ah";
2775}
2776
florian55085f82012-11-21 00:36:55 +00002777static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002778s390_irgen_AHY(UChar r1, IRTemp op2addr)
2779{
2780 IRTemp op1 = newTemp(Ity_I32);
2781 IRTemp op2 = newTemp(Ity_I32);
2782 IRTemp result = newTemp(Ity_I32);
2783
2784 assign(op1, get_gpr_w1(r1));
2785 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2786 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2787 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2788 put_gpr_w1(r1, mkexpr(result));
2789
2790 return "ahy";
2791}
2792
florian55085f82012-11-21 00:36:55 +00002793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002794s390_irgen_AHI(UChar r1, UShort i2)
2795{
2796 IRTemp op1 = newTemp(Ity_I32);
2797 Int op2;
2798 IRTemp result = newTemp(Ity_I32);
2799
2800 assign(op1, get_gpr_w1(r1));
2801 op2 = (Int)(Short)i2;
2802 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2803 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2804 mkU32((UInt)op2)));
2805 put_gpr_w1(r1, mkexpr(result));
2806
2807 return "ahi";
2808}
2809
florian55085f82012-11-21 00:36:55 +00002810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002811s390_irgen_AGHI(UChar r1, UShort i2)
2812{
2813 IRTemp op1 = newTemp(Ity_I64);
2814 Long op2;
2815 IRTemp result = newTemp(Ity_I64);
2816
2817 assign(op1, get_gpr_dw0(r1));
2818 op2 = (Long)(Short)i2;
2819 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2820 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2821 mkU64((ULong)op2)));
2822 put_gpr_dw0(r1, mkexpr(result));
2823
2824 return "aghi";
2825}
2826
florian55085f82012-11-21 00:36:55 +00002827static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002828s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2829{
2830 IRTemp op2 = newTemp(Ity_I32);
2831 IRTemp op3 = newTemp(Ity_I32);
2832 IRTemp result = newTemp(Ity_I32);
2833
2834 assign(op2, get_gpr_w0(r2));
2835 assign(op3, get_gpr_w0(r3));
2836 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2837 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2838 put_gpr_w0(r1, mkexpr(result));
2839
2840 return "ahhhr";
2841}
2842
florian55085f82012-11-21 00:36:55 +00002843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002844s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2845{
2846 IRTemp op2 = newTemp(Ity_I32);
2847 IRTemp op3 = newTemp(Ity_I32);
2848 IRTemp result = newTemp(Ity_I32);
2849
2850 assign(op2, get_gpr_w0(r2));
2851 assign(op3, get_gpr_w1(r3));
2852 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2853 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2854 put_gpr_w0(r1, mkexpr(result));
2855
2856 return "ahhlr";
2857}
2858
florian55085f82012-11-21 00:36:55 +00002859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002860s390_irgen_AIH(UChar r1, UInt i2)
2861{
2862 IRTemp op1 = newTemp(Ity_I32);
2863 Int op2;
2864 IRTemp result = newTemp(Ity_I32);
2865
2866 assign(op1, get_gpr_w0(r1));
2867 op2 = (Int)i2;
2868 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2869 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2870 mkU32((UInt)op2)));
2871 put_gpr_w0(r1, mkexpr(result));
2872
2873 return "aih";
2874}
2875
florian55085f82012-11-21 00:36:55 +00002876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002877s390_irgen_ALR(UChar r1, UChar r2)
2878{
2879 IRTemp op1 = newTemp(Ity_I32);
2880 IRTemp op2 = newTemp(Ity_I32);
2881 IRTemp result = newTemp(Ity_I32);
2882
2883 assign(op1, get_gpr_w1(r1));
2884 assign(op2, get_gpr_w1(r2));
2885 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2886 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2887 put_gpr_w1(r1, mkexpr(result));
2888
2889 return "alr";
2890}
2891
florian55085f82012-11-21 00:36:55 +00002892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002893s390_irgen_ALGR(UChar r1, UChar r2)
2894{
2895 IRTemp op1 = newTemp(Ity_I64);
2896 IRTemp op2 = newTemp(Ity_I64);
2897 IRTemp result = newTemp(Ity_I64);
2898
2899 assign(op1, get_gpr_dw0(r1));
2900 assign(op2, get_gpr_dw0(r2));
2901 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2902 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2903 put_gpr_dw0(r1, mkexpr(result));
2904
2905 return "algr";
2906}
2907
florian55085f82012-11-21 00:36:55 +00002908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002909s390_irgen_ALGFR(UChar r1, UChar r2)
2910{
2911 IRTemp op1 = newTemp(Ity_I64);
2912 IRTemp op2 = newTemp(Ity_I64);
2913 IRTemp result = newTemp(Ity_I64);
2914
2915 assign(op1, get_gpr_dw0(r1));
2916 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2917 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2918 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2919 put_gpr_dw0(r1, mkexpr(result));
2920
2921 return "algfr";
2922}
2923
florian55085f82012-11-21 00:36:55 +00002924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002925s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2926{
2927 IRTemp op2 = newTemp(Ity_I32);
2928 IRTemp op3 = newTemp(Ity_I32);
2929 IRTemp result = newTemp(Ity_I32);
2930
2931 assign(op2, get_gpr_w1(r2));
2932 assign(op3, get_gpr_w1(r3));
2933 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2934 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2935 put_gpr_w1(r1, mkexpr(result));
2936
2937 return "alrk";
2938}
2939
florian55085f82012-11-21 00:36:55 +00002940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002941s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2942{
2943 IRTemp op2 = newTemp(Ity_I64);
2944 IRTemp op3 = newTemp(Ity_I64);
2945 IRTemp result = newTemp(Ity_I64);
2946
2947 assign(op2, get_gpr_dw0(r2));
2948 assign(op3, get_gpr_dw0(r3));
2949 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2950 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2951 put_gpr_dw0(r1, mkexpr(result));
2952
2953 return "algrk";
2954}
2955
florian55085f82012-11-21 00:36:55 +00002956static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002957s390_irgen_AL(UChar r1, IRTemp op2addr)
2958{
2959 IRTemp op1 = newTemp(Ity_I32);
2960 IRTemp op2 = newTemp(Ity_I32);
2961 IRTemp result = newTemp(Ity_I32);
2962
2963 assign(op1, get_gpr_w1(r1));
2964 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2965 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2966 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2967 put_gpr_w1(r1, mkexpr(result));
2968
2969 return "al";
2970}
2971
florian55085f82012-11-21 00:36:55 +00002972static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002973s390_irgen_ALY(UChar r1, IRTemp op2addr)
2974{
2975 IRTemp op1 = newTemp(Ity_I32);
2976 IRTemp op2 = newTemp(Ity_I32);
2977 IRTemp result = newTemp(Ity_I32);
2978
2979 assign(op1, get_gpr_w1(r1));
2980 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2981 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2982 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2983 put_gpr_w1(r1, mkexpr(result));
2984
2985 return "aly";
2986}
2987
florian55085f82012-11-21 00:36:55 +00002988static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002989s390_irgen_ALG(UChar r1, IRTemp op2addr)
2990{
2991 IRTemp op1 = newTemp(Ity_I64);
2992 IRTemp op2 = newTemp(Ity_I64);
2993 IRTemp result = newTemp(Ity_I64);
2994
2995 assign(op1, get_gpr_dw0(r1));
2996 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2997 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2998 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2999 put_gpr_dw0(r1, mkexpr(result));
3000
3001 return "alg";
3002}
3003
florian55085f82012-11-21 00:36:55 +00003004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003005s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3006{
3007 IRTemp op1 = newTemp(Ity_I64);
3008 IRTemp op2 = newTemp(Ity_I64);
3009 IRTemp result = newTemp(Ity_I64);
3010
3011 assign(op1, get_gpr_dw0(r1));
3012 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3013 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3014 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3015 put_gpr_dw0(r1, mkexpr(result));
3016
3017 return "algf";
3018}
3019
florian55085f82012-11-21 00:36:55 +00003020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003021s390_irgen_ALFI(UChar r1, UInt i2)
3022{
3023 IRTemp op1 = newTemp(Ity_I32);
3024 UInt op2;
3025 IRTemp result = newTemp(Ity_I32);
3026
3027 assign(op1, get_gpr_w1(r1));
3028 op2 = i2;
3029 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3030 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3031 mkU32(op2)));
3032 put_gpr_w1(r1, mkexpr(result));
3033
3034 return "alfi";
3035}
3036
florian55085f82012-11-21 00:36:55 +00003037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003038s390_irgen_ALGFI(UChar r1, UInt i2)
3039{
3040 IRTemp op1 = newTemp(Ity_I64);
3041 ULong op2;
3042 IRTemp result = newTemp(Ity_I64);
3043
3044 assign(op1, get_gpr_dw0(r1));
3045 op2 = (ULong)i2;
3046 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3047 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3048 mkU64(op2)));
3049 put_gpr_dw0(r1, mkexpr(result));
3050
3051 return "algfi";
3052}
3053
florian55085f82012-11-21 00:36:55 +00003054static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003055s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3056{
3057 IRTemp op2 = newTemp(Ity_I32);
3058 IRTemp op3 = newTemp(Ity_I32);
3059 IRTemp result = newTemp(Ity_I32);
3060
3061 assign(op2, get_gpr_w0(r2));
3062 assign(op3, get_gpr_w0(r3));
3063 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3064 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3065 put_gpr_w0(r1, mkexpr(result));
3066
3067 return "alhhhr";
3068}
3069
florian55085f82012-11-21 00:36:55 +00003070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003071s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3072{
3073 IRTemp op2 = newTemp(Ity_I32);
3074 IRTemp op3 = newTemp(Ity_I32);
3075 IRTemp result = newTemp(Ity_I32);
3076
3077 assign(op2, get_gpr_w0(r2));
3078 assign(op3, get_gpr_w1(r3));
3079 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3080 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3081 put_gpr_w0(r1, mkexpr(result));
3082
3083 return "alhhlr";
3084}
3085
florian55085f82012-11-21 00:36:55 +00003086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003087s390_irgen_ALCR(UChar r1, UChar r2)
3088{
3089 IRTemp op1 = newTemp(Ity_I32);
3090 IRTemp op2 = newTemp(Ity_I32);
3091 IRTemp result = newTemp(Ity_I32);
3092 IRTemp carry_in = newTemp(Ity_I32);
3093
3094 assign(op1, get_gpr_w1(r1));
3095 assign(op2, get_gpr_w1(r2));
3096 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3097 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3098 mkexpr(carry_in)));
3099 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3100 put_gpr_w1(r1, mkexpr(result));
3101
3102 return "alcr";
3103}
3104
florian55085f82012-11-21 00:36:55 +00003105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003106s390_irgen_ALCGR(UChar r1, UChar r2)
3107{
3108 IRTemp op1 = newTemp(Ity_I64);
3109 IRTemp op2 = newTemp(Ity_I64);
3110 IRTemp result = newTemp(Ity_I64);
3111 IRTemp carry_in = newTemp(Ity_I64);
3112
3113 assign(op1, get_gpr_dw0(r1));
3114 assign(op2, get_gpr_dw0(r2));
3115 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3116 mkU8(1))));
3117 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3118 mkexpr(carry_in)));
3119 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3120 put_gpr_dw0(r1, mkexpr(result));
3121
3122 return "alcgr";
3123}
3124
florian55085f82012-11-21 00:36:55 +00003125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003126s390_irgen_ALC(UChar r1, IRTemp op2addr)
3127{
3128 IRTemp op1 = newTemp(Ity_I32);
3129 IRTemp op2 = newTemp(Ity_I32);
3130 IRTemp result = newTemp(Ity_I32);
3131 IRTemp carry_in = newTemp(Ity_I32);
3132
3133 assign(op1, get_gpr_w1(r1));
3134 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3135 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3136 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3137 mkexpr(carry_in)));
3138 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3139 put_gpr_w1(r1, mkexpr(result));
3140
3141 return "alc";
3142}
3143
florian55085f82012-11-21 00:36:55 +00003144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003145s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3146{
3147 IRTemp op1 = newTemp(Ity_I64);
3148 IRTemp op2 = newTemp(Ity_I64);
3149 IRTemp result = newTemp(Ity_I64);
3150 IRTemp carry_in = newTemp(Ity_I64);
3151
3152 assign(op1, get_gpr_dw0(r1));
3153 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3154 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3155 mkU8(1))));
3156 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3157 mkexpr(carry_in)));
3158 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3159 put_gpr_dw0(r1, mkexpr(result));
3160
3161 return "alcg";
3162}
3163
florian55085f82012-11-21 00:36:55 +00003164static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003165s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3166{
3167 IRTemp op1 = newTemp(Ity_I32);
3168 UInt op2;
3169 IRTemp result = newTemp(Ity_I32);
3170
3171 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3172 op2 = (UInt)(Int)(Char)i2;
3173 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3174 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3175 mkU32(op2)));
3176 store(mkexpr(op1addr), mkexpr(result));
3177
3178 return "alsi";
3179}
3180
florian55085f82012-11-21 00:36:55 +00003181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003182s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3183{
3184 IRTemp op1 = newTemp(Ity_I64);
3185 ULong op2;
3186 IRTemp result = newTemp(Ity_I64);
3187
3188 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3189 op2 = (ULong)(Long)(Char)i2;
3190 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3191 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3192 mkU64(op2)));
3193 store(mkexpr(op1addr), mkexpr(result));
3194
3195 return "algsi";
3196}
3197
florian55085f82012-11-21 00:36:55 +00003198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003199s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3200{
3201 UInt op2;
3202 IRTemp op3 = newTemp(Ity_I32);
3203 IRTemp result = newTemp(Ity_I32);
3204
3205 op2 = (UInt)(Int)(Short)i2;
3206 assign(op3, get_gpr_w1(r3));
3207 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3208 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3209 op3);
3210 put_gpr_w1(r1, mkexpr(result));
3211
3212 return "alhsik";
3213}
3214
florian55085f82012-11-21 00:36:55 +00003215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003216s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3217{
3218 ULong op2;
3219 IRTemp op3 = newTemp(Ity_I64);
3220 IRTemp result = newTemp(Ity_I64);
3221
3222 op2 = (ULong)(Long)(Short)i2;
3223 assign(op3, get_gpr_dw0(r3));
3224 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3225 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3226 op3);
3227 put_gpr_dw0(r1, mkexpr(result));
3228
3229 return "alghsik";
3230}
3231
florian55085f82012-11-21 00:36:55 +00003232static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003233s390_irgen_ALSIH(UChar r1, UInt i2)
3234{
3235 IRTemp op1 = newTemp(Ity_I32);
3236 UInt op2;
3237 IRTemp result = newTemp(Ity_I32);
3238
3239 assign(op1, get_gpr_w0(r1));
3240 op2 = i2;
3241 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3242 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3243 mkU32(op2)));
3244 put_gpr_w0(r1, mkexpr(result));
3245
3246 return "alsih";
3247}
3248
florian55085f82012-11-21 00:36:55 +00003249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003250s390_irgen_ALSIHN(UChar r1, UInt i2)
3251{
3252 IRTemp op1 = newTemp(Ity_I32);
3253 UInt op2;
3254 IRTemp result = newTemp(Ity_I32);
3255
3256 assign(op1, get_gpr_w0(r1));
3257 op2 = i2;
3258 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3259 put_gpr_w0(r1, mkexpr(result));
3260
3261 return "alsihn";
3262}
3263
florian55085f82012-11-21 00:36:55 +00003264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003265s390_irgen_NR(UChar r1, UChar r2)
3266{
3267 IRTemp op1 = newTemp(Ity_I32);
3268 IRTemp op2 = newTemp(Ity_I32);
3269 IRTemp result = newTemp(Ity_I32);
3270
3271 assign(op1, get_gpr_w1(r1));
3272 assign(op2, get_gpr_w1(r2));
3273 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3274 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3275 put_gpr_w1(r1, mkexpr(result));
3276
3277 return "nr";
3278}
3279
florian55085f82012-11-21 00:36:55 +00003280static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003281s390_irgen_NGR(UChar r1, UChar r2)
3282{
3283 IRTemp op1 = newTemp(Ity_I64);
3284 IRTemp op2 = newTemp(Ity_I64);
3285 IRTemp result = newTemp(Ity_I64);
3286
3287 assign(op1, get_gpr_dw0(r1));
3288 assign(op2, get_gpr_dw0(r2));
3289 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3290 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3291 put_gpr_dw0(r1, mkexpr(result));
3292
3293 return "ngr";
3294}
3295
florian55085f82012-11-21 00:36:55 +00003296static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003297s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3298{
3299 IRTemp op2 = newTemp(Ity_I32);
3300 IRTemp op3 = newTemp(Ity_I32);
3301 IRTemp result = newTemp(Ity_I32);
3302
3303 assign(op2, get_gpr_w1(r2));
3304 assign(op3, get_gpr_w1(r3));
3305 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3306 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3307 put_gpr_w1(r1, mkexpr(result));
3308
3309 return "nrk";
3310}
3311
florian55085f82012-11-21 00:36:55 +00003312static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003313s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3314{
3315 IRTemp op2 = newTemp(Ity_I64);
3316 IRTemp op3 = newTemp(Ity_I64);
3317 IRTemp result = newTemp(Ity_I64);
3318
3319 assign(op2, get_gpr_dw0(r2));
3320 assign(op3, get_gpr_dw0(r3));
3321 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3322 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3323 put_gpr_dw0(r1, mkexpr(result));
3324
3325 return "ngrk";
3326}
3327
florian55085f82012-11-21 00:36:55 +00003328static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003329s390_irgen_N(UChar r1, IRTemp op2addr)
3330{
3331 IRTemp op1 = newTemp(Ity_I32);
3332 IRTemp op2 = newTemp(Ity_I32);
3333 IRTemp result = newTemp(Ity_I32);
3334
3335 assign(op1, get_gpr_w1(r1));
3336 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3337 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3338 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3339 put_gpr_w1(r1, mkexpr(result));
3340
3341 return "n";
3342}
3343
florian55085f82012-11-21 00:36:55 +00003344static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003345s390_irgen_NY(UChar r1, IRTemp op2addr)
3346{
3347 IRTemp op1 = newTemp(Ity_I32);
3348 IRTemp op2 = newTemp(Ity_I32);
3349 IRTemp result = newTemp(Ity_I32);
3350
3351 assign(op1, get_gpr_w1(r1));
3352 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3353 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3354 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3355 put_gpr_w1(r1, mkexpr(result));
3356
3357 return "ny";
3358}
3359
florian55085f82012-11-21 00:36:55 +00003360static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003361s390_irgen_NG(UChar r1, IRTemp op2addr)
3362{
3363 IRTemp op1 = newTemp(Ity_I64);
3364 IRTemp op2 = newTemp(Ity_I64);
3365 IRTemp result = newTemp(Ity_I64);
3366
3367 assign(op1, get_gpr_dw0(r1));
3368 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3369 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3370 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3371 put_gpr_dw0(r1, mkexpr(result));
3372
3373 return "ng";
3374}
3375
florian55085f82012-11-21 00:36:55 +00003376static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003377s390_irgen_NI(UChar i2, IRTemp op1addr)
3378{
3379 IRTemp op1 = newTemp(Ity_I8);
3380 UChar op2;
3381 IRTemp result = newTemp(Ity_I8);
3382
3383 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3384 op2 = i2;
3385 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3386 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3387 store(mkexpr(op1addr), mkexpr(result));
3388
3389 return "ni";
3390}
3391
florian55085f82012-11-21 00:36:55 +00003392static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003393s390_irgen_NIY(UChar i2, IRTemp op1addr)
3394{
3395 IRTemp op1 = newTemp(Ity_I8);
3396 UChar op2;
3397 IRTemp result = newTemp(Ity_I8);
3398
3399 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3400 op2 = i2;
3401 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3402 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3403 store(mkexpr(op1addr), mkexpr(result));
3404
3405 return "niy";
3406}
3407
florian55085f82012-11-21 00:36:55 +00003408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003409s390_irgen_NIHF(UChar r1, UInt i2)
3410{
3411 IRTemp op1 = newTemp(Ity_I32);
3412 UInt op2;
3413 IRTemp result = newTemp(Ity_I32);
3414
3415 assign(op1, get_gpr_w0(r1));
3416 op2 = i2;
3417 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3418 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3419 put_gpr_w0(r1, mkexpr(result));
3420
3421 return "nihf";
3422}
3423
florian55085f82012-11-21 00:36:55 +00003424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003425s390_irgen_NIHH(UChar r1, UShort i2)
3426{
3427 IRTemp op1 = newTemp(Ity_I16);
3428 UShort op2;
3429 IRTemp result = newTemp(Ity_I16);
3430
3431 assign(op1, get_gpr_hw0(r1));
3432 op2 = i2;
3433 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3434 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3435 put_gpr_hw0(r1, mkexpr(result));
3436
3437 return "nihh";
3438}
3439
florian55085f82012-11-21 00:36:55 +00003440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003441s390_irgen_NIHL(UChar r1, UShort i2)
3442{
3443 IRTemp op1 = newTemp(Ity_I16);
3444 UShort op2;
3445 IRTemp result = newTemp(Ity_I16);
3446
3447 assign(op1, get_gpr_hw1(r1));
3448 op2 = i2;
3449 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3450 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3451 put_gpr_hw1(r1, mkexpr(result));
3452
3453 return "nihl";
3454}
3455
florian55085f82012-11-21 00:36:55 +00003456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003457s390_irgen_NILF(UChar r1, UInt i2)
3458{
3459 IRTemp op1 = newTemp(Ity_I32);
3460 UInt op2;
3461 IRTemp result = newTemp(Ity_I32);
3462
3463 assign(op1, get_gpr_w1(r1));
3464 op2 = i2;
3465 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3466 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3467 put_gpr_w1(r1, mkexpr(result));
3468
3469 return "nilf";
3470}
3471
florian55085f82012-11-21 00:36:55 +00003472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003473s390_irgen_NILH(UChar r1, UShort i2)
3474{
3475 IRTemp op1 = newTemp(Ity_I16);
3476 UShort op2;
3477 IRTemp result = newTemp(Ity_I16);
3478
3479 assign(op1, get_gpr_hw2(r1));
3480 op2 = i2;
3481 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3482 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3483 put_gpr_hw2(r1, mkexpr(result));
3484
3485 return "nilh";
3486}
3487
florian55085f82012-11-21 00:36:55 +00003488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003489s390_irgen_NILL(UChar r1, UShort i2)
3490{
3491 IRTemp op1 = newTemp(Ity_I16);
3492 UShort op2;
3493 IRTemp result = newTemp(Ity_I16);
3494
3495 assign(op1, get_gpr_hw3(r1));
3496 op2 = i2;
3497 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3498 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3499 put_gpr_hw3(r1, mkexpr(result));
3500
3501 return "nill";
3502}
3503
florian55085f82012-11-21 00:36:55 +00003504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003505s390_irgen_BASR(UChar r1, UChar r2)
3506{
3507 IRTemp target = newTemp(Ity_I64);
3508
3509 if (r2 == 0) {
3510 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3511 } else {
3512 if (r1 != r2) {
3513 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3514 call_function(get_gpr_dw0(r2));
3515 } else {
3516 assign(target, get_gpr_dw0(r2));
3517 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3518 call_function(mkexpr(target));
3519 }
3520 }
3521
3522 return "basr";
3523}
3524
florian55085f82012-11-21 00:36:55 +00003525static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003526s390_irgen_BAS(UChar r1, IRTemp op2addr)
3527{
3528 IRTemp target = newTemp(Ity_I64);
3529
3530 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3531 assign(target, mkexpr(op2addr));
3532 call_function(mkexpr(target));
3533
3534 return "bas";
3535}
3536
florian55085f82012-11-21 00:36:55 +00003537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003538s390_irgen_BCR(UChar r1, UChar r2)
3539{
3540 IRTemp cond = newTemp(Ity_I32);
3541
sewardja52e37e2011-04-28 18:48:06 +00003542 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3543 stmt(IRStmt_MBE(Imbe_Fence));
3544 }
3545
sewardj2019a972011-03-07 16:04:07 +00003546 if ((r2 == 0) || (r1 == 0)) {
3547 } else {
3548 if (r1 == 15) {
3549 return_from_function(get_gpr_dw0(r2));
3550 } else {
3551 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003552 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3553 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003554 }
3555 }
sewardj7ee97522011-05-09 21:45:04 +00003556 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003557 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3558
3559 return "bcr";
3560}
3561
florian55085f82012-11-21 00:36:55 +00003562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003563s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3564{
3565 IRTemp cond = newTemp(Ity_I32);
3566
3567 if (r1 == 0) {
3568 } else {
3569 if (r1 == 15) {
3570 always_goto(mkexpr(op2addr));
3571 } else {
3572 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003573 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3574 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003575 }
3576 }
sewardj7ee97522011-05-09 21:45:04 +00003577 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003578 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3579
3580 return "bc";
3581}
3582
florian55085f82012-11-21 00:36:55 +00003583static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003584s390_irgen_BCTR(UChar r1, UChar r2)
3585{
3586 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3587 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003588 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3589 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003590 }
3591
3592 return "bctr";
3593}
3594
florian55085f82012-11-21 00:36:55 +00003595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003596s390_irgen_BCTGR(UChar r1, UChar r2)
3597{
3598 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3599 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003600 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3601 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003602 }
3603
3604 return "bctgr";
3605}
3606
florian55085f82012-11-21 00:36:55 +00003607static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003608s390_irgen_BCT(UChar r1, IRTemp op2addr)
3609{
3610 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003611 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3612 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003613
3614 return "bct";
3615}
3616
florian55085f82012-11-21 00:36:55 +00003617static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003618s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3619{
3620 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003621 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3622 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003623
3624 return "bctg";
3625}
3626
florian55085f82012-11-21 00:36:55 +00003627static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003628s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3629{
3630 IRTemp value = newTemp(Ity_I32);
3631
3632 assign(value, get_gpr_w1(r3 | 1));
3633 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003634 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3635 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003636
3637 return "bxh";
3638}
3639
florian55085f82012-11-21 00:36:55 +00003640static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003641s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3642{
3643 IRTemp value = newTemp(Ity_I64);
3644
3645 assign(value, get_gpr_dw0(r3 | 1));
3646 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003647 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3648 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003649
3650 return "bxhg";
3651}
3652
florian55085f82012-11-21 00:36:55 +00003653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003654s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3655{
3656 IRTemp value = newTemp(Ity_I32);
3657
3658 assign(value, get_gpr_w1(r3 | 1));
3659 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003660 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3661 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003662
3663 return "bxle";
3664}
3665
florian55085f82012-11-21 00:36:55 +00003666static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003667s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3668{
3669 IRTemp value = newTemp(Ity_I64);
3670
3671 assign(value, get_gpr_dw0(r3 | 1));
3672 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003673 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3674 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003675
3676 return "bxleg";
3677}
3678
florian55085f82012-11-21 00:36:55 +00003679static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003680s390_irgen_BRAS(UChar r1, UShort i2)
3681{
3682 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003683 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003684
3685 return "bras";
3686}
3687
florian55085f82012-11-21 00:36:55 +00003688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003689s390_irgen_BRASL(UChar r1, UInt i2)
3690{
3691 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003692 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003693
3694 return "brasl";
3695}
3696
florian55085f82012-11-21 00:36:55 +00003697static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003698s390_irgen_BRC(UChar r1, UShort i2)
3699{
3700 IRTemp cond = newTemp(Ity_I32);
3701
3702 if (r1 == 0) {
3703 } else {
3704 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003705 always_goto_and_chase(
3706 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003707 } else {
3708 assign(cond, s390_call_calculate_cond(r1));
3709 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3710 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3711
3712 }
3713 }
sewardj7ee97522011-05-09 21:45:04 +00003714 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003715 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3716
3717 return "brc";
3718}
3719
florian55085f82012-11-21 00:36:55 +00003720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003721s390_irgen_BRCL(UChar r1, UInt i2)
3722{
3723 IRTemp cond = newTemp(Ity_I32);
3724
3725 if (r1 == 0) {
3726 } else {
3727 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003728 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003729 } else {
3730 assign(cond, s390_call_calculate_cond(r1));
3731 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3732 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3733 }
3734 }
sewardj7ee97522011-05-09 21:45:04 +00003735 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003736 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3737
3738 return "brcl";
3739}
3740
florian55085f82012-11-21 00:36:55 +00003741static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003742s390_irgen_BRCT(UChar r1, UShort i2)
3743{
3744 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3745 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3746 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3747
3748 return "brct";
3749}
3750
florian55085f82012-11-21 00:36:55 +00003751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003752s390_irgen_BRCTG(UChar r1, UShort i2)
3753{
3754 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3755 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3756 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3757
3758 return "brctg";
3759}
3760
florian55085f82012-11-21 00:36:55 +00003761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003762s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3763{
3764 IRTemp value = newTemp(Ity_I32);
3765
3766 assign(value, get_gpr_w1(r3 | 1));
3767 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3768 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3769 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3770
3771 return "brxh";
3772}
3773
florian55085f82012-11-21 00:36:55 +00003774static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003775s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3776{
3777 IRTemp value = newTemp(Ity_I64);
3778
3779 assign(value, get_gpr_dw0(r3 | 1));
3780 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3781 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3782 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3783
3784 return "brxhg";
3785}
3786
florian55085f82012-11-21 00:36:55 +00003787static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003788s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3789{
3790 IRTemp value = newTemp(Ity_I32);
3791
3792 assign(value, get_gpr_w1(r3 | 1));
3793 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3794 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3795 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3796
3797 return "brxle";
3798}
3799
florian55085f82012-11-21 00:36:55 +00003800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003801s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3802{
3803 IRTemp value = newTemp(Ity_I64);
3804
3805 assign(value, get_gpr_dw0(r3 | 1));
3806 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3807 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3808 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3809
3810 return "brxlg";
3811}
3812
florian55085f82012-11-21 00:36:55 +00003813static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003814s390_irgen_CR(UChar r1, UChar r2)
3815{
3816 IRTemp op1 = newTemp(Ity_I32);
3817 IRTemp op2 = newTemp(Ity_I32);
3818
3819 assign(op1, get_gpr_w1(r1));
3820 assign(op2, get_gpr_w1(r2));
3821 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3822
3823 return "cr";
3824}
3825
florian55085f82012-11-21 00:36:55 +00003826static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003827s390_irgen_CGR(UChar r1, UChar r2)
3828{
3829 IRTemp op1 = newTemp(Ity_I64);
3830 IRTemp op2 = newTemp(Ity_I64);
3831
3832 assign(op1, get_gpr_dw0(r1));
3833 assign(op2, get_gpr_dw0(r2));
3834 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3835
3836 return "cgr";
3837}
3838
florian55085f82012-11-21 00:36:55 +00003839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003840s390_irgen_CGFR(UChar r1, UChar r2)
3841{
3842 IRTemp op1 = newTemp(Ity_I64);
3843 IRTemp op2 = newTemp(Ity_I64);
3844
3845 assign(op1, get_gpr_dw0(r1));
3846 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3847 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3848
3849 return "cgfr";
3850}
3851
florian55085f82012-11-21 00:36:55 +00003852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003853s390_irgen_C(UChar r1, IRTemp op2addr)
3854{
3855 IRTemp op1 = newTemp(Ity_I32);
3856 IRTemp op2 = newTemp(Ity_I32);
3857
3858 assign(op1, get_gpr_w1(r1));
3859 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3860 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3861
3862 return "c";
3863}
3864
florian55085f82012-11-21 00:36:55 +00003865static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003866s390_irgen_CY(UChar r1, IRTemp op2addr)
3867{
3868 IRTemp op1 = newTemp(Ity_I32);
3869 IRTemp op2 = newTemp(Ity_I32);
3870
3871 assign(op1, get_gpr_w1(r1));
3872 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3873 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3874
3875 return "cy";
3876}
3877
florian55085f82012-11-21 00:36:55 +00003878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003879s390_irgen_CG(UChar r1, IRTemp op2addr)
3880{
3881 IRTemp op1 = newTemp(Ity_I64);
3882 IRTemp op2 = newTemp(Ity_I64);
3883
3884 assign(op1, get_gpr_dw0(r1));
3885 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3886 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3887
3888 return "cg";
3889}
3890
florian55085f82012-11-21 00:36:55 +00003891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003892s390_irgen_CGF(UChar r1, IRTemp op2addr)
3893{
3894 IRTemp op1 = newTemp(Ity_I64);
3895 IRTemp op2 = newTemp(Ity_I64);
3896
3897 assign(op1, get_gpr_dw0(r1));
3898 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3899 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3900
3901 return "cgf";
3902}
3903
florian55085f82012-11-21 00:36:55 +00003904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003905s390_irgen_CFI(UChar r1, UInt i2)
3906{
3907 IRTemp op1 = newTemp(Ity_I32);
3908 Int op2;
3909
3910 assign(op1, get_gpr_w1(r1));
3911 op2 = (Int)i2;
3912 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3913 mkU32((UInt)op2)));
3914
3915 return "cfi";
3916}
3917
florian55085f82012-11-21 00:36:55 +00003918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003919s390_irgen_CGFI(UChar r1, UInt i2)
3920{
3921 IRTemp op1 = newTemp(Ity_I64);
3922 Long op2;
3923
3924 assign(op1, get_gpr_dw0(r1));
3925 op2 = (Long)(Int)i2;
3926 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3927 mkU64((ULong)op2)));
3928
3929 return "cgfi";
3930}
3931
florian55085f82012-11-21 00:36:55 +00003932static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003933s390_irgen_CRL(UChar r1, UInt i2)
3934{
3935 IRTemp op1 = newTemp(Ity_I32);
3936 IRTemp op2 = newTemp(Ity_I32);
3937
3938 assign(op1, get_gpr_w1(r1));
3939 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3940 i2 << 1))));
3941 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3942
3943 return "crl";
3944}
3945
florian55085f82012-11-21 00:36:55 +00003946static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003947s390_irgen_CGRL(UChar r1, UInt i2)
3948{
3949 IRTemp op1 = newTemp(Ity_I64);
3950 IRTemp op2 = newTemp(Ity_I64);
3951
3952 assign(op1, get_gpr_dw0(r1));
3953 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3954 i2 << 1))));
3955 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3956
3957 return "cgrl";
3958}
3959
florian55085f82012-11-21 00:36:55 +00003960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003961s390_irgen_CGFRL(UChar r1, UInt i2)
3962{
3963 IRTemp op1 = newTemp(Ity_I64);
3964 IRTemp op2 = newTemp(Ity_I64);
3965
3966 assign(op1, get_gpr_dw0(r1));
3967 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3968 ((ULong)(Long)(Int)i2 << 1)))));
3969 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3970
3971 return "cgfrl";
3972}
3973
florian55085f82012-11-21 00:36:55 +00003974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003975s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3976{
3977 IRTemp op1 = newTemp(Ity_I32);
3978 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003979 IRTemp cond = newTemp(Ity_I32);
3980
3981 if (m3 == 0) {
3982 } else {
3983 if (m3 == 14) {
3984 always_goto(mkexpr(op4addr));
3985 } else {
3986 assign(op1, get_gpr_w1(r1));
3987 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003988 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3989 op1, op2));
florianf321da72012-07-21 20:32:57 +00003990 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3991 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003992 }
3993 }
3994
3995 return "crb";
3996}
3997
florian55085f82012-11-21 00:36:55 +00003998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003999s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4000{
4001 IRTemp op1 = newTemp(Ity_I64);
4002 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004003 IRTemp cond = newTemp(Ity_I32);
4004
4005 if (m3 == 0) {
4006 } else {
4007 if (m3 == 14) {
4008 always_goto(mkexpr(op4addr));
4009 } else {
4010 assign(op1, get_gpr_dw0(r1));
4011 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004012 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4013 op1, op2));
florianf321da72012-07-21 20:32:57 +00004014 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4015 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004016 }
4017 }
4018
4019 return "cgrb";
4020}
4021
florian55085f82012-11-21 00:36:55 +00004022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004023s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4024{
4025 IRTemp op1 = newTemp(Ity_I32);
4026 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004027 IRTemp cond = newTemp(Ity_I32);
4028
4029 if (m3 == 0) {
4030 } else {
4031 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004032 always_goto_and_chase(
4033 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004034 } else {
4035 assign(op1, get_gpr_w1(r1));
4036 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004037 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4038 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004039 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4040 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4041
4042 }
4043 }
4044
4045 return "crj";
4046}
4047
florian55085f82012-11-21 00:36:55 +00004048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004049s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4050{
4051 IRTemp op1 = newTemp(Ity_I64);
4052 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004053 IRTemp cond = newTemp(Ity_I32);
4054
4055 if (m3 == 0) {
4056 } else {
4057 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004058 always_goto_and_chase(
4059 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004060 } else {
4061 assign(op1, get_gpr_dw0(r1));
4062 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004063 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4064 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004065 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4066 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4067
4068 }
4069 }
4070
4071 return "cgrj";
4072}
4073
florian55085f82012-11-21 00:36:55 +00004074static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004075s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4076{
4077 IRTemp op1 = newTemp(Ity_I32);
4078 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004079 IRTemp cond = newTemp(Ity_I32);
4080
4081 if (m3 == 0) {
4082 } else {
4083 if (m3 == 14) {
4084 always_goto(mkexpr(op4addr));
4085 } else {
4086 assign(op1, get_gpr_w1(r1));
4087 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004088 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4089 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004090 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4091 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004092 }
4093 }
4094
4095 return "cib";
4096}
4097
florian55085f82012-11-21 00:36:55 +00004098static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004099s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4100{
4101 IRTemp op1 = newTemp(Ity_I64);
4102 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004103 IRTemp cond = newTemp(Ity_I32);
4104
4105 if (m3 == 0) {
4106 } else {
4107 if (m3 == 14) {
4108 always_goto(mkexpr(op4addr));
4109 } else {
4110 assign(op1, get_gpr_dw0(r1));
4111 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004112 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4113 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004114 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4115 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004116 }
4117 }
4118
4119 return "cgib";
4120}
4121
florian55085f82012-11-21 00:36:55 +00004122static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004123s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4124{
4125 IRTemp op1 = newTemp(Ity_I32);
4126 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004127 IRTemp cond = newTemp(Ity_I32);
4128
4129 if (m3 == 0) {
4130 } else {
4131 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004132 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004133 } else {
4134 assign(op1, get_gpr_w1(r1));
4135 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004136 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4137 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004138 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4139 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4140
4141 }
4142 }
4143
4144 return "cij";
4145}
4146
florian55085f82012-11-21 00:36:55 +00004147static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004148s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4149{
4150 IRTemp op1 = newTemp(Ity_I64);
4151 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004152 IRTemp cond = newTemp(Ity_I32);
4153
4154 if (m3 == 0) {
4155 } else {
4156 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004157 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004158 } else {
4159 assign(op1, get_gpr_dw0(r1));
4160 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004161 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4162 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004163 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4164 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4165
4166 }
4167 }
4168
4169 return "cgij";
4170}
4171
florian55085f82012-11-21 00:36:55 +00004172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004173s390_irgen_CH(UChar r1, IRTemp op2addr)
4174{
4175 IRTemp op1 = newTemp(Ity_I32);
4176 IRTemp op2 = newTemp(Ity_I32);
4177
4178 assign(op1, get_gpr_w1(r1));
4179 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4180 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4181
4182 return "ch";
4183}
4184
florian55085f82012-11-21 00:36:55 +00004185static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004186s390_irgen_CHY(UChar r1, IRTemp op2addr)
4187{
4188 IRTemp op1 = newTemp(Ity_I32);
4189 IRTemp op2 = newTemp(Ity_I32);
4190
4191 assign(op1, get_gpr_w1(r1));
4192 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4193 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4194
4195 return "chy";
4196}
4197
florian55085f82012-11-21 00:36:55 +00004198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004199s390_irgen_CGH(UChar r1, IRTemp op2addr)
4200{
4201 IRTemp op1 = newTemp(Ity_I64);
4202 IRTemp op2 = newTemp(Ity_I64);
4203
4204 assign(op1, get_gpr_dw0(r1));
4205 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4206 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4207
4208 return "cgh";
4209}
4210
florian55085f82012-11-21 00:36:55 +00004211static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004212s390_irgen_CHI(UChar r1, UShort i2)
4213{
4214 IRTemp op1 = newTemp(Ity_I32);
4215 Int op2;
4216
4217 assign(op1, get_gpr_w1(r1));
4218 op2 = (Int)(Short)i2;
4219 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4220 mkU32((UInt)op2)));
4221
4222 return "chi";
4223}
4224
florian55085f82012-11-21 00:36:55 +00004225static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004226s390_irgen_CGHI(UChar r1, UShort i2)
4227{
4228 IRTemp op1 = newTemp(Ity_I64);
4229 Long op2;
4230
4231 assign(op1, get_gpr_dw0(r1));
4232 op2 = (Long)(Short)i2;
4233 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4234 mkU64((ULong)op2)));
4235
4236 return "cghi";
4237}
4238
florian55085f82012-11-21 00:36:55 +00004239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004240s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4241{
4242 IRTemp op1 = newTemp(Ity_I16);
4243 Short op2;
4244
4245 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4246 op2 = (Short)i2;
4247 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4248 mkU16((UShort)op2)));
4249
4250 return "chhsi";
4251}
4252
florian55085f82012-11-21 00:36:55 +00004253static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004254s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4255{
4256 IRTemp op1 = newTemp(Ity_I32);
4257 Int op2;
4258
4259 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4260 op2 = (Int)(Short)i2;
4261 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4262 mkU32((UInt)op2)));
4263
4264 return "chsi";
4265}
4266
florian55085f82012-11-21 00:36:55 +00004267static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004268s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4269{
4270 IRTemp op1 = newTemp(Ity_I64);
4271 Long op2;
4272
4273 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4274 op2 = (Long)(Short)i2;
4275 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4276 mkU64((ULong)op2)));
4277
4278 return "cghsi";
4279}
4280
florian55085f82012-11-21 00:36:55 +00004281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004282s390_irgen_CHRL(UChar r1, UInt i2)
4283{
4284 IRTemp op1 = newTemp(Ity_I32);
4285 IRTemp op2 = newTemp(Ity_I32);
4286
4287 assign(op1, get_gpr_w1(r1));
4288 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4289 ((ULong)(Long)(Int)i2 << 1)))));
4290 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4291
4292 return "chrl";
4293}
4294
florian55085f82012-11-21 00:36:55 +00004295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004296s390_irgen_CGHRL(UChar r1, UInt i2)
4297{
4298 IRTemp op1 = newTemp(Ity_I64);
4299 IRTemp op2 = newTemp(Ity_I64);
4300
4301 assign(op1, get_gpr_dw0(r1));
4302 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4303 ((ULong)(Long)(Int)i2 << 1)))));
4304 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4305
4306 return "cghrl";
4307}
4308
florian55085f82012-11-21 00:36:55 +00004309static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004310s390_irgen_CHHR(UChar r1, UChar r2)
4311{
4312 IRTemp op1 = newTemp(Ity_I32);
4313 IRTemp op2 = newTemp(Ity_I32);
4314
4315 assign(op1, get_gpr_w0(r1));
4316 assign(op2, get_gpr_w0(r2));
4317 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4318
4319 return "chhr";
4320}
4321
florian55085f82012-11-21 00:36:55 +00004322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004323s390_irgen_CHLR(UChar r1, UChar r2)
4324{
4325 IRTemp op1 = newTemp(Ity_I32);
4326 IRTemp op2 = newTemp(Ity_I32);
4327
4328 assign(op1, get_gpr_w0(r1));
4329 assign(op2, get_gpr_w1(r2));
4330 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4331
4332 return "chlr";
4333}
4334
florian55085f82012-11-21 00:36:55 +00004335static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004336s390_irgen_CHF(UChar r1, IRTemp op2addr)
4337{
4338 IRTemp op1 = newTemp(Ity_I32);
4339 IRTemp op2 = newTemp(Ity_I32);
4340
4341 assign(op1, get_gpr_w0(r1));
4342 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4343 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4344
4345 return "chf";
4346}
4347
florian55085f82012-11-21 00:36:55 +00004348static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004349s390_irgen_CIH(UChar r1, UInt i2)
4350{
4351 IRTemp op1 = newTemp(Ity_I32);
4352 Int op2;
4353
4354 assign(op1, get_gpr_w0(r1));
4355 op2 = (Int)i2;
4356 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4357 mkU32((UInt)op2)));
4358
4359 return "cih";
4360}
4361
florian55085f82012-11-21 00:36:55 +00004362static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004363s390_irgen_CLR(UChar r1, UChar r2)
4364{
4365 IRTemp op1 = newTemp(Ity_I32);
4366 IRTemp op2 = newTemp(Ity_I32);
4367
4368 assign(op1, get_gpr_w1(r1));
4369 assign(op2, get_gpr_w1(r2));
4370 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4371
4372 return "clr";
4373}
4374
florian55085f82012-11-21 00:36:55 +00004375static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004376s390_irgen_CLGR(UChar r1, UChar r2)
4377{
4378 IRTemp op1 = newTemp(Ity_I64);
4379 IRTemp op2 = newTemp(Ity_I64);
4380
4381 assign(op1, get_gpr_dw0(r1));
4382 assign(op2, get_gpr_dw0(r2));
4383 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4384
4385 return "clgr";
4386}
4387
florian55085f82012-11-21 00:36:55 +00004388static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004389s390_irgen_CLGFR(UChar r1, UChar r2)
4390{
4391 IRTemp op1 = newTemp(Ity_I64);
4392 IRTemp op2 = newTemp(Ity_I64);
4393
4394 assign(op1, get_gpr_dw0(r1));
4395 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4396 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4397
4398 return "clgfr";
4399}
4400
florian55085f82012-11-21 00:36:55 +00004401static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004402s390_irgen_CL(UChar r1, IRTemp op2addr)
4403{
4404 IRTemp op1 = newTemp(Ity_I32);
4405 IRTemp op2 = newTemp(Ity_I32);
4406
4407 assign(op1, get_gpr_w1(r1));
4408 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4409 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4410
4411 return "cl";
4412}
4413
florian55085f82012-11-21 00:36:55 +00004414static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004415s390_irgen_CLY(UChar r1, IRTemp op2addr)
4416{
4417 IRTemp op1 = newTemp(Ity_I32);
4418 IRTemp op2 = newTemp(Ity_I32);
4419
4420 assign(op1, get_gpr_w1(r1));
4421 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4422 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4423
4424 return "cly";
4425}
4426
florian55085f82012-11-21 00:36:55 +00004427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004428s390_irgen_CLG(UChar r1, IRTemp op2addr)
4429{
4430 IRTemp op1 = newTemp(Ity_I64);
4431 IRTemp op2 = newTemp(Ity_I64);
4432
4433 assign(op1, get_gpr_dw0(r1));
4434 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4435 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4436
4437 return "clg";
4438}
4439
florian55085f82012-11-21 00:36:55 +00004440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004441s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4442{
4443 IRTemp op1 = newTemp(Ity_I64);
4444 IRTemp op2 = newTemp(Ity_I64);
4445
4446 assign(op1, get_gpr_dw0(r1));
4447 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4448 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4449
4450 return "clgf";
4451}
4452
florian55085f82012-11-21 00:36:55 +00004453static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004454s390_irgen_CLFI(UChar r1, UInt i2)
4455{
4456 IRTemp op1 = newTemp(Ity_I32);
4457 UInt op2;
4458
4459 assign(op1, get_gpr_w1(r1));
4460 op2 = i2;
4461 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4462 mkU32(op2)));
4463
4464 return "clfi";
4465}
4466
florian55085f82012-11-21 00:36:55 +00004467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004468s390_irgen_CLGFI(UChar r1, UInt i2)
4469{
4470 IRTemp op1 = newTemp(Ity_I64);
4471 ULong op2;
4472
4473 assign(op1, get_gpr_dw0(r1));
4474 op2 = (ULong)i2;
4475 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4476 mkU64(op2)));
4477
4478 return "clgfi";
4479}
4480
florian55085f82012-11-21 00:36:55 +00004481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004482s390_irgen_CLI(UChar i2, IRTemp op1addr)
4483{
4484 IRTemp op1 = newTemp(Ity_I8);
4485 UChar op2;
4486
4487 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4488 op2 = i2;
4489 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4490 mkU8(op2)));
4491
4492 return "cli";
4493}
4494
florian55085f82012-11-21 00:36:55 +00004495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004496s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4497{
4498 IRTemp op1 = newTemp(Ity_I8);
4499 UChar op2;
4500
4501 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4502 op2 = i2;
4503 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4504 mkU8(op2)));
4505
4506 return "cliy";
4507}
4508
florian55085f82012-11-21 00:36:55 +00004509static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004510s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4511{
4512 IRTemp op1 = newTemp(Ity_I32);
4513 UInt op2;
4514
4515 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4516 op2 = (UInt)i2;
4517 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4518 mkU32(op2)));
4519
4520 return "clfhsi";
4521}
4522
florian55085f82012-11-21 00:36:55 +00004523static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004524s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4525{
4526 IRTemp op1 = newTemp(Ity_I64);
4527 ULong op2;
4528
4529 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4530 op2 = (ULong)i2;
4531 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4532 mkU64(op2)));
4533
4534 return "clghsi";
4535}
4536
florian55085f82012-11-21 00:36:55 +00004537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004538s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4539{
4540 IRTemp op1 = newTemp(Ity_I16);
4541 UShort op2;
4542
4543 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4544 op2 = i2;
4545 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4546 mkU16(op2)));
4547
4548 return "clhhsi";
4549}
4550
florian55085f82012-11-21 00:36:55 +00004551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004552s390_irgen_CLRL(UChar r1, UInt i2)
4553{
4554 IRTemp op1 = newTemp(Ity_I32);
4555 IRTemp op2 = newTemp(Ity_I32);
4556
4557 assign(op1, get_gpr_w1(r1));
4558 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4559 i2 << 1))));
4560 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4561
4562 return "clrl";
4563}
4564
florian55085f82012-11-21 00:36:55 +00004565static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004566s390_irgen_CLGRL(UChar r1, UInt i2)
4567{
4568 IRTemp op1 = newTemp(Ity_I64);
4569 IRTemp op2 = newTemp(Ity_I64);
4570
4571 assign(op1, get_gpr_dw0(r1));
4572 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4573 i2 << 1))));
4574 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4575
4576 return "clgrl";
4577}
4578
florian55085f82012-11-21 00:36:55 +00004579static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004580s390_irgen_CLGFRL(UChar r1, UInt i2)
4581{
4582 IRTemp op1 = newTemp(Ity_I64);
4583 IRTemp op2 = newTemp(Ity_I64);
4584
4585 assign(op1, get_gpr_dw0(r1));
4586 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4587 ((ULong)(Long)(Int)i2 << 1)))));
4588 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4589
4590 return "clgfrl";
4591}
4592
florian55085f82012-11-21 00:36:55 +00004593static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004594s390_irgen_CLHRL(UChar r1, UInt i2)
4595{
4596 IRTemp op1 = newTemp(Ity_I32);
4597 IRTemp op2 = newTemp(Ity_I32);
4598
4599 assign(op1, get_gpr_w1(r1));
4600 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4601 ((ULong)(Long)(Int)i2 << 1)))));
4602 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4603
4604 return "clhrl";
4605}
4606
florian55085f82012-11-21 00:36:55 +00004607static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004608s390_irgen_CLGHRL(UChar r1, UInt i2)
4609{
4610 IRTemp op1 = newTemp(Ity_I64);
4611 IRTemp op2 = newTemp(Ity_I64);
4612
4613 assign(op1, get_gpr_dw0(r1));
4614 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4615 ((ULong)(Long)(Int)i2 << 1)))));
4616 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4617
4618 return "clghrl";
4619}
4620
florian55085f82012-11-21 00:36:55 +00004621static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004622s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4623{
4624 IRTemp op1 = newTemp(Ity_I32);
4625 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004626 IRTemp cond = newTemp(Ity_I32);
4627
4628 if (m3 == 0) {
4629 } else {
4630 if (m3 == 14) {
4631 always_goto(mkexpr(op4addr));
4632 } else {
4633 assign(op1, get_gpr_w1(r1));
4634 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004635 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4636 op1, op2));
florianf321da72012-07-21 20:32:57 +00004637 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4638 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004639 }
4640 }
4641
4642 return "clrb";
4643}
4644
florian55085f82012-11-21 00:36:55 +00004645static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004646s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4647{
4648 IRTemp op1 = newTemp(Ity_I64);
4649 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004650 IRTemp cond = newTemp(Ity_I32);
4651
4652 if (m3 == 0) {
4653 } else {
4654 if (m3 == 14) {
4655 always_goto(mkexpr(op4addr));
4656 } else {
4657 assign(op1, get_gpr_dw0(r1));
4658 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004659 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4660 op1, op2));
florianf321da72012-07-21 20:32:57 +00004661 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4662 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004663 }
4664 }
4665
4666 return "clgrb";
4667}
4668
florian55085f82012-11-21 00:36:55 +00004669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004670s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4671{
4672 IRTemp op1 = newTemp(Ity_I32);
4673 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004674 IRTemp cond = newTemp(Ity_I32);
4675
4676 if (m3 == 0) {
4677 } else {
4678 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004679 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004680 } else {
4681 assign(op1, get_gpr_w1(r1));
4682 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004683 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4684 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004685 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4686 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4687
4688 }
4689 }
4690
4691 return "clrj";
4692}
4693
florian55085f82012-11-21 00:36:55 +00004694static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004695s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4696{
4697 IRTemp op1 = newTemp(Ity_I64);
4698 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004699 IRTemp cond = newTemp(Ity_I32);
4700
4701 if (m3 == 0) {
4702 } else {
4703 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004704 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004705 } else {
4706 assign(op1, get_gpr_dw0(r1));
4707 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004708 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4709 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004710 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4711 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4712
4713 }
4714 }
4715
4716 return "clgrj";
4717}
4718
florian55085f82012-11-21 00:36:55 +00004719static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004720s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4721{
4722 IRTemp op1 = newTemp(Ity_I32);
4723 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004724 IRTemp cond = newTemp(Ity_I32);
4725
4726 if (m3 == 0) {
4727 } else {
4728 if (m3 == 14) {
4729 always_goto(mkexpr(op4addr));
4730 } else {
4731 assign(op1, get_gpr_w1(r1));
4732 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004733 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4734 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004735 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4736 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004737 }
4738 }
4739
4740 return "clib";
4741}
4742
florian55085f82012-11-21 00:36:55 +00004743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004744s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4745{
4746 IRTemp op1 = newTemp(Ity_I64);
4747 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004748 IRTemp cond = newTemp(Ity_I32);
4749
4750 if (m3 == 0) {
4751 } else {
4752 if (m3 == 14) {
4753 always_goto(mkexpr(op4addr));
4754 } else {
4755 assign(op1, get_gpr_dw0(r1));
4756 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004757 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4758 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004759 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4760 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004761 }
4762 }
4763
4764 return "clgib";
4765}
4766
florian55085f82012-11-21 00:36:55 +00004767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004768s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4769{
4770 IRTemp op1 = newTemp(Ity_I32);
4771 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004772 IRTemp cond = newTemp(Ity_I32);
4773
4774 if (m3 == 0) {
4775 } else {
4776 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004777 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004778 } else {
4779 assign(op1, get_gpr_w1(r1));
4780 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004781 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4782 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004783 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4784 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4785
4786 }
4787 }
4788
4789 return "clij";
4790}
4791
florian55085f82012-11-21 00:36:55 +00004792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004793s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4794{
4795 IRTemp op1 = newTemp(Ity_I64);
4796 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004797 IRTemp cond = newTemp(Ity_I32);
4798
4799 if (m3 == 0) {
4800 } else {
4801 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004802 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004803 } else {
4804 assign(op1, get_gpr_dw0(r1));
4805 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004806 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4807 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004808 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4809 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4810
4811 }
4812 }
4813
4814 return "clgij";
4815}
4816
florian55085f82012-11-21 00:36:55 +00004817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004818s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4819{
4820 IRTemp op1 = newTemp(Ity_I32);
4821 IRTemp op2 = newTemp(Ity_I32);
4822 IRTemp b0 = newTemp(Ity_I32);
4823 IRTemp b1 = newTemp(Ity_I32);
4824 IRTemp b2 = newTemp(Ity_I32);
4825 IRTemp b3 = newTemp(Ity_I32);
4826 IRTemp c0 = newTemp(Ity_I32);
4827 IRTemp c1 = newTemp(Ity_I32);
4828 IRTemp c2 = newTemp(Ity_I32);
4829 IRTemp c3 = newTemp(Ity_I32);
4830 UChar n;
4831
4832 n = 0;
4833 if ((r3 & 8) != 0) {
4834 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4835 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4836 n = n + 1;
4837 } else {
4838 assign(b0, mkU32(0));
4839 assign(c0, mkU32(0));
4840 }
4841 if ((r3 & 4) != 0) {
4842 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4843 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4844 mkU64(n)))));
4845 n = n + 1;
4846 } else {
4847 assign(b1, mkU32(0));
4848 assign(c1, mkU32(0));
4849 }
4850 if ((r3 & 2) != 0) {
4851 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4852 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4853 mkU64(n)))));
4854 n = n + 1;
4855 } else {
4856 assign(b2, mkU32(0));
4857 assign(c2, mkU32(0));
4858 }
4859 if ((r3 & 1) != 0) {
4860 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4861 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4862 mkU64(n)))));
4863 n = n + 1;
4864 } else {
4865 assign(b3, mkU32(0));
4866 assign(c3, mkU32(0));
4867 }
4868 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4869 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4870 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4871 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4872 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4873 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4874 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4875
4876 return "clm";
4877}
4878
florian55085f82012-11-21 00:36:55 +00004879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004880s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4881{
4882 IRTemp op1 = newTemp(Ity_I32);
4883 IRTemp op2 = newTemp(Ity_I32);
4884 IRTemp b0 = newTemp(Ity_I32);
4885 IRTemp b1 = newTemp(Ity_I32);
4886 IRTemp b2 = newTemp(Ity_I32);
4887 IRTemp b3 = newTemp(Ity_I32);
4888 IRTemp c0 = newTemp(Ity_I32);
4889 IRTemp c1 = newTemp(Ity_I32);
4890 IRTemp c2 = newTemp(Ity_I32);
4891 IRTemp c3 = newTemp(Ity_I32);
4892 UChar n;
4893
4894 n = 0;
4895 if ((r3 & 8) != 0) {
4896 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4897 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4898 n = n + 1;
4899 } else {
4900 assign(b0, mkU32(0));
4901 assign(c0, mkU32(0));
4902 }
4903 if ((r3 & 4) != 0) {
4904 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4905 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4906 mkU64(n)))));
4907 n = n + 1;
4908 } else {
4909 assign(b1, mkU32(0));
4910 assign(c1, mkU32(0));
4911 }
4912 if ((r3 & 2) != 0) {
4913 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4914 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4915 mkU64(n)))));
4916 n = n + 1;
4917 } else {
4918 assign(b2, mkU32(0));
4919 assign(c2, mkU32(0));
4920 }
4921 if ((r3 & 1) != 0) {
4922 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4923 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4924 mkU64(n)))));
4925 n = n + 1;
4926 } else {
4927 assign(b3, mkU32(0));
4928 assign(c3, mkU32(0));
4929 }
4930 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4931 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4932 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4933 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4934 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4935 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4936 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4937
4938 return "clmy";
4939}
4940
florian55085f82012-11-21 00:36:55 +00004941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004942s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4943{
4944 IRTemp op1 = newTemp(Ity_I32);
4945 IRTemp op2 = newTemp(Ity_I32);
4946 IRTemp b0 = newTemp(Ity_I32);
4947 IRTemp b1 = newTemp(Ity_I32);
4948 IRTemp b2 = newTemp(Ity_I32);
4949 IRTemp b3 = newTemp(Ity_I32);
4950 IRTemp c0 = newTemp(Ity_I32);
4951 IRTemp c1 = newTemp(Ity_I32);
4952 IRTemp c2 = newTemp(Ity_I32);
4953 IRTemp c3 = newTemp(Ity_I32);
4954 UChar n;
4955
4956 n = 0;
4957 if ((r3 & 8) != 0) {
4958 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4959 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4960 n = n + 1;
4961 } else {
4962 assign(b0, mkU32(0));
4963 assign(c0, mkU32(0));
4964 }
4965 if ((r3 & 4) != 0) {
4966 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4967 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4968 mkU64(n)))));
4969 n = n + 1;
4970 } else {
4971 assign(b1, mkU32(0));
4972 assign(c1, mkU32(0));
4973 }
4974 if ((r3 & 2) != 0) {
4975 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4976 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4977 mkU64(n)))));
4978 n = n + 1;
4979 } else {
4980 assign(b2, mkU32(0));
4981 assign(c2, mkU32(0));
4982 }
4983 if ((r3 & 1) != 0) {
4984 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4985 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4986 mkU64(n)))));
4987 n = n + 1;
4988 } else {
4989 assign(b3, mkU32(0));
4990 assign(c3, mkU32(0));
4991 }
4992 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4993 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4994 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4995 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4996 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4997 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4998 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4999
5000 return "clmh";
5001}
5002
florian55085f82012-11-21 00:36:55 +00005003static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005004s390_irgen_CLHHR(UChar r1, UChar r2)
5005{
5006 IRTemp op1 = newTemp(Ity_I32);
5007 IRTemp op2 = newTemp(Ity_I32);
5008
5009 assign(op1, get_gpr_w0(r1));
5010 assign(op2, get_gpr_w0(r2));
5011 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5012
5013 return "clhhr";
5014}
5015
florian55085f82012-11-21 00:36:55 +00005016static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005017s390_irgen_CLHLR(UChar r1, UChar r2)
5018{
5019 IRTemp op1 = newTemp(Ity_I32);
5020 IRTemp op2 = newTemp(Ity_I32);
5021
5022 assign(op1, get_gpr_w0(r1));
5023 assign(op2, get_gpr_w1(r2));
5024 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5025
5026 return "clhlr";
5027}
5028
florian55085f82012-11-21 00:36:55 +00005029static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005030s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5031{
5032 IRTemp op1 = newTemp(Ity_I32);
5033 IRTemp op2 = newTemp(Ity_I32);
5034
5035 assign(op1, get_gpr_w0(r1));
5036 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5037 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5038
5039 return "clhf";
5040}
5041
florian55085f82012-11-21 00:36:55 +00005042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005043s390_irgen_CLIH(UChar r1, UInt i2)
5044{
5045 IRTemp op1 = newTemp(Ity_I32);
5046 UInt op2;
5047
5048 assign(op1, get_gpr_w0(r1));
5049 op2 = i2;
5050 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5051 mkU32(op2)));
5052
5053 return "clih";
5054}
5055
florian55085f82012-11-21 00:36:55 +00005056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005057s390_irgen_CPYA(UChar r1, UChar r2)
5058{
5059 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005060 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005061 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5062
5063 return "cpya";
5064}
5065
florian55085f82012-11-21 00:36:55 +00005066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005067s390_irgen_XR(UChar r1, UChar r2)
5068{
5069 IRTemp op1 = newTemp(Ity_I32);
5070 IRTemp op2 = newTemp(Ity_I32);
5071 IRTemp result = newTemp(Ity_I32);
5072
5073 if (r1 == r2) {
5074 assign(result, mkU32(0));
5075 } else {
5076 assign(op1, get_gpr_w1(r1));
5077 assign(op2, get_gpr_w1(r2));
5078 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5079 }
5080 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5081 put_gpr_w1(r1, mkexpr(result));
5082
5083 return "xr";
5084}
5085
florian55085f82012-11-21 00:36:55 +00005086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005087s390_irgen_XGR(UChar r1, UChar r2)
5088{
5089 IRTemp op1 = newTemp(Ity_I64);
5090 IRTemp op2 = newTemp(Ity_I64);
5091 IRTemp result = newTemp(Ity_I64);
5092
5093 if (r1 == r2) {
5094 assign(result, mkU64(0));
5095 } else {
5096 assign(op1, get_gpr_dw0(r1));
5097 assign(op2, get_gpr_dw0(r2));
5098 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5099 }
5100 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5101 put_gpr_dw0(r1, mkexpr(result));
5102
5103 return "xgr";
5104}
5105
florian55085f82012-11-21 00:36:55 +00005106static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005107s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5108{
5109 IRTemp op2 = newTemp(Ity_I32);
5110 IRTemp op3 = newTemp(Ity_I32);
5111 IRTemp result = newTemp(Ity_I32);
5112
5113 assign(op2, get_gpr_w1(r2));
5114 assign(op3, get_gpr_w1(r3));
5115 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5116 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5117 put_gpr_w1(r1, mkexpr(result));
5118
5119 return "xrk";
5120}
5121
florian55085f82012-11-21 00:36:55 +00005122static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005123s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5124{
5125 IRTemp op2 = newTemp(Ity_I64);
5126 IRTemp op3 = newTemp(Ity_I64);
5127 IRTemp result = newTemp(Ity_I64);
5128
5129 assign(op2, get_gpr_dw0(r2));
5130 assign(op3, get_gpr_dw0(r3));
5131 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5132 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5133 put_gpr_dw0(r1, mkexpr(result));
5134
5135 return "xgrk";
5136}
5137
florian55085f82012-11-21 00:36:55 +00005138static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005139s390_irgen_X(UChar r1, IRTemp op2addr)
5140{
5141 IRTemp op1 = newTemp(Ity_I32);
5142 IRTemp op2 = newTemp(Ity_I32);
5143 IRTemp result = newTemp(Ity_I32);
5144
5145 assign(op1, get_gpr_w1(r1));
5146 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5147 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5148 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5149 put_gpr_w1(r1, mkexpr(result));
5150
5151 return "x";
5152}
5153
florian55085f82012-11-21 00:36:55 +00005154static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005155s390_irgen_XY(UChar r1, IRTemp op2addr)
5156{
5157 IRTemp op1 = newTemp(Ity_I32);
5158 IRTemp op2 = newTemp(Ity_I32);
5159 IRTemp result = newTemp(Ity_I32);
5160
5161 assign(op1, get_gpr_w1(r1));
5162 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5163 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5164 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5165 put_gpr_w1(r1, mkexpr(result));
5166
5167 return "xy";
5168}
5169
florian55085f82012-11-21 00:36:55 +00005170static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005171s390_irgen_XG(UChar r1, IRTemp op2addr)
5172{
5173 IRTemp op1 = newTemp(Ity_I64);
5174 IRTemp op2 = newTemp(Ity_I64);
5175 IRTemp result = newTemp(Ity_I64);
5176
5177 assign(op1, get_gpr_dw0(r1));
5178 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5179 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5180 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5181 put_gpr_dw0(r1, mkexpr(result));
5182
5183 return "xg";
5184}
5185
florian55085f82012-11-21 00:36:55 +00005186static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005187s390_irgen_XI(UChar i2, IRTemp op1addr)
5188{
5189 IRTemp op1 = newTemp(Ity_I8);
5190 UChar op2;
5191 IRTemp result = newTemp(Ity_I8);
5192
5193 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5194 op2 = i2;
5195 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5196 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5197 store(mkexpr(op1addr), mkexpr(result));
5198
5199 return "xi";
5200}
5201
florian55085f82012-11-21 00:36:55 +00005202static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005203s390_irgen_XIY(UChar i2, IRTemp op1addr)
5204{
5205 IRTemp op1 = newTemp(Ity_I8);
5206 UChar op2;
5207 IRTemp result = newTemp(Ity_I8);
5208
5209 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5210 op2 = i2;
5211 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5212 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5213 store(mkexpr(op1addr), mkexpr(result));
5214
5215 return "xiy";
5216}
5217
florian55085f82012-11-21 00:36:55 +00005218static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005219s390_irgen_XIHF(UChar r1, UInt i2)
5220{
5221 IRTemp op1 = newTemp(Ity_I32);
5222 UInt op2;
5223 IRTemp result = newTemp(Ity_I32);
5224
5225 assign(op1, get_gpr_w0(r1));
5226 op2 = i2;
5227 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5228 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5229 put_gpr_w0(r1, mkexpr(result));
5230
5231 return "xihf";
5232}
5233
florian55085f82012-11-21 00:36:55 +00005234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005235s390_irgen_XILF(UChar r1, UInt i2)
5236{
5237 IRTemp op1 = newTemp(Ity_I32);
5238 UInt op2;
5239 IRTemp result = newTemp(Ity_I32);
5240
5241 assign(op1, get_gpr_w1(r1));
5242 op2 = i2;
5243 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5244 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5245 put_gpr_w1(r1, mkexpr(result));
5246
5247 return "xilf";
5248}
5249
florian55085f82012-11-21 00:36:55 +00005250static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005251s390_irgen_EAR(UChar r1, UChar r2)
5252{
5253 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005254 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005255 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5256
5257 return "ear";
5258}
5259
florian55085f82012-11-21 00:36:55 +00005260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005261s390_irgen_IC(UChar r1, IRTemp op2addr)
5262{
5263 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5264
5265 return "ic";
5266}
5267
florian55085f82012-11-21 00:36:55 +00005268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005269s390_irgen_ICY(UChar r1, IRTemp op2addr)
5270{
5271 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5272
5273 return "icy";
5274}
5275
florian55085f82012-11-21 00:36:55 +00005276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005277s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5278{
5279 UChar n;
5280 IRTemp result = newTemp(Ity_I32);
5281 UInt mask;
5282
5283 n = 0;
5284 mask = (UInt)r3;
5285 if ((mask & 8) != 0) {
5286 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5287 n = n + 1;
5288 }
5289 if ((mask & 4) != 0) {
5290 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5291
5292 n = n + 1;
5293 }
5294 if ((mask & 2) != 0) {
5295 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5296
5297 n = n + 1;
5298 }
5299 if ((mask & 1) != 0) {
5300 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5301
5302 n = n + 1;
5303 }
5304 assign(result, get_gpr_w1(r1));
5305 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5306 mkU32(mask)));
5307
5308 return "icm";
5309}
5310
florian55085f82012-11-21 00:36:55 +00005311static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005312s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5313{
5314 UChar n;
5315 IRTemp result = newTemp(Ity_I32);
5316 UInt mask;
5317
5318 n = 0;
5319 mask = (UInt)r3;
5320 if ((mask & 8) != 0) {
5321 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5322 n = n + 1;
5323 }
5324 if ((mask & 4) != 0) {
5325 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5326
5327 n = n + 1;
5328 }
5329 if ((mask & 2) != 0) {
5330 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5331
5332 n = n + 1;
5333 }
5334 if ((mask & 1) != 0) {
5335 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5336
5337 n = n + 1;
5338 }
5339 assign(result, get_gpr_w1(r1));
5340 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5341 mkU32(mask)));
5342
5343 return "icmy";
5344}
5345
florian55085f82012-11-21 00:36:55 +00005346static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005347s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5348{
5349 UChar n;
5350 IRTemp result = newTemp(Ity_I32);
5351 UInt mask;
5352
5353 n = 0;
5354 mask = (UInt)r3;
5355 if ((mask & 8) != 0) {
5356 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5357 n = n + 1;
5358 }
5359 if ((mask & 4) != 0) {
5360 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5361
5362 n = n + 1;
5363 }
5364 if ((mask & 2) != 0) {
5365 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5366
5367 n = n + 1;
5368 }
5369 if ((mask & 1) != 0) {
5370 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5371
5372 n = n + 1;
5373 }
5374 assign(result, get_gpr_w0(r1));
5375 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5376 mkU32(mask)));
5377
5378 return "icmh";
5379}
5380
florian55085f82012-11-21 00:36:55 +00005381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005382s390_irgen_IIHF(UChar r1, UInt i2)
5383{
5384 put_gpr_w0(r1, mkU32(i2));
5385
5386 return "iihf";
5387}
5388
florian55085f82012-11-21 00:36:55 +00005389static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005390s390_irgen_IIHH(UChar r1, UShort i2)
5391{
5392 put_gpr_hw0(r1, mkU16(i2));
5393
5394 return "iihh";
5395}
5396
florian55085f82012-11-21 00:36:55 +00005397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005398s390_irgen_IIHL(UChar r1, UShort i2)
5399{
5400 put_gpr_hw1(r1, mkU16(i2));
5401
5402 return "iihl";
5403}
5404
florian55085f82012-11-21 00:36:55 +00005405static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005406s390_irgen_IILF(UChar r1, UInt i2)
5407{
5408 put_gpr_w1(r1, mkU32(i2));
5409
5410 return "iilf";
5411}
5412
florian55085f82012-11-21 00:36:55 +00005413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005414s390_irgen_IILH(UChar r1, UShort i2)
5415{
5416 put_gpr_hw2(r1, mkU16(i2));
5417
5418 return "iilh";
5419}
5420
florian55085f82012-11-21 00:36:55 +00005421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005422s390_irgen_IILL(UChar r1, UShort i2)
5423{
5424 put_gpr_hw3(r1, mkU16(i2));
5425
5426 return "iill";
5427}
5428
florian55085f82012-11-21 00:36:55 +00005429static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005430s390_irgen_LR(UChar r1, UChar r2)
5431{
5432 put_gpr_w1(r1, get_gpr_w1(r2));
5433
5434 return "lr";
5435}
5436
florian55085f82012-11-21 00:36:55 +00005437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005438s390_irgen_LGR(UChar r1, UChar r2)
5439{
5440 put_gpr_dw0(r1, get_gpr_dw0(r2));
5441
5442 return "lgr";
5443}
5444
florian55085f82012-11-21 00:36:55 +00005445static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005446s390_irgen_LGFR(UChar r1, UChar r2)
5447{
5448 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5449
5450 return "lgfr";
5451}
5452
florian55085f82012-11-21 00:36:55 +00005453static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005454s390_irgen_L(UChar r1, IRTemp op2addr)
5455{
5456 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5457
5458 return "l";
5459}
5460
florian55085f82012-11-21 00:36:55 +00005461static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005462s390_irgen_LY(UChar r1, IRTemp op2addr)
5463{
5464 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5465
5466 return "ly";
5467}
5468
florian55085f82012-11-21 00:36:55 +00005469static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005470s390_irgen_LG(UChar r1, IRTemp op2addr)
5471{
5472 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5473
5474 return "lg";
5475}
5476
florian55085f82012-11-21 00:36:55 +00005477static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005478s390_irgen_LGF(UChar r1, IRTemp op2addr)
5479{
5480 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5481
5482 return "lgf";
5483}
5484
florian55085f82012-11-21 00:36:55 +00005485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005486s390_irgen_LGFI(UChar r1, UInt i2)
5487{
5488 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5489
5490 return "lgfi";
5491}
5492
florian55085f82012-11-21 00:36:55 +00005493static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005494s390_irgen_LRL(UChar r1, UInt i2)
5495{
5496 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5497 i2 << 1))));
5498
5499 return "lrl";
5500}
5501
florian55085f82012-11-21 00:36:55 +00005502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005503s390_irgen_LGRL(UChar r1, UInt i2)
5504{
5505 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5506 i2 << 1))));
5507
5508 return "lgrl";
5509}
5510
florian55085f82012-11-21 00:36:55 +00005511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005512s390_irgen_LGFRL(UChar r1, UInt i2)
5513{
5514 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5515 ((ULong)(Long)(Int)i2 << 1)))));
5516
5517 return "lgfrl";
5518}
5519
florian55085f82012-11-21 00:36:55 +00005520static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005521s390_irgen_LA(UChar r1, IRTemp op2addr)
5522{
5523 put_gpr_dw0(r1, mkexpr(op2addr));
5524
5525 return "la";
5526}
5527
florian55085f82012-11-21 00:36:55 +00005528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005529s390_irgen_LAY(UChar r1, IRTemp op2addr)
5530{
5531 put_gpr_dw0(r1, mkexpr(op2addr));
5532
5533 return "lay";
5534}
5535
florian55085f82012-11-21 00:36:55 +00005536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005537s390_irgen_LAE(UChar r1, IRTemp op2addr)
5538{
5539 put_gpr_dw0(r1, mkexpr(op2addr));
5540
5541 return "lae";
5542}
5543
florian55085f82012-11-21 00:36:55 +00005544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005545s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5546{
5547 put_gpr_dw0(r1, mkexpr(op2addr));
5548
5549 return "laey";
5550}
5551
florian55085f82012-11-21 00:36:55 +00005552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005553s390_irgen_LARL(UChar r1, UInt i2)
5554{
5555 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5556
5557 return "larl";
5558}
5559
floriana265ee72012-12-02 20:58:17 +00005560/* The IR representation of LAA and friends is an approximation of what
5561 happens natively. Essentially a loop containing a compare-and-swap is
5562 constructed which will iterate until the CAS succeeds. As a consequence,
5563 instrumenters may see more memory accesses than happen natively. See also
5564 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005565static void
5566s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005567{
floriana265ee72012-12-02 20:58:17 +00005568 IRCAS *cas;
5569 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005570 IRTemp op2 = newTemp(Ity_I32);
5571 IRTemp op3 = newTemp(Ity_I32);
5572 IRTemp result = newTemp(Ity_I32);
5573
5574 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5575 assign(op3, get_gpr_w1(r3));
5576 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005577
5578 /* Place the addition of second operand and third operand at the
5579 second-operand location everytime */
5580 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5581 Iend_BE, mkexpr(op2addr),
5582 NULL, mkexpr(op2), /* expected value */
5583 NULL, mkexpr(result) /* new value */);
5584 stmt(IRStmt_CAS(cas));
5585
florianffc94012012-12-02 21:31:15 +00005586 /* Set CC according to 32-bit addition */
5587 if (is_signed) {
5588 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5589 } else {
5590 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5591 }
floriana265ee72012-12-02 20:58:17 +00005592
5593 /* If old_mem contains the expected value, then the CAS succeeded.
5594 Otherwise, it did not */
5595 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5596 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005597}
5598
5599static void
5600s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5601{
5602 IRCAS *cas;
5603 IRTemp old_mem = newTemp(Ity_I64);
5604 IRTemp op2 = newTemp(Ity_I64);
5605 IRTemp op3 = newTemp(Ity_I64);
5606 IRTemp result = newTemp(Ity_I64);
5607
5608 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5609 assign(op3, get_gpr_dw0(r3));
5610 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5611
5612 /* Place the addition of second operand and third operand at the
5613 second-operand location everytime */
5614 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5615 Iend_BE, mkexpr(op2addr),
5616 NULL, mkexpr(op2), /* expected value */
5617 NULL, mkexpr(result) /* new value */);
5618 stmt(IRStmt_CAS(cas));
5619
5620 /* Set CC according to 64-bit addition */
5621 if (is_signed) {
5622 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5623 } else {
5624 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5625 }
5626
5627 /* If old_mem contains the expected value, then the CAS succeeded.
5628 Otherwise, it did not */
5629 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5630 put_gpr_dw0(r1, mkexpr(old_mem));
5631}
5632
5633static void
5634s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5635{
5636 IRCAS *cas;
5637 IRTemp old_mem = newTemp(Ity_I32);
5638 IRTemp op2 = newTemp(Ity_I32);
5639 IRTemp op3 = newTemp(Ity_I32);
5640 IRTemp result = newTemp(Ity_I32);
5641
5642 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5643 assign(op3, get_gpr_w1(r3));
5644 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5645
5646 /* Place the addition of second operand and third operand at the
5647 second-operand location everytime */
5648 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5649 Iend_BE, mkexpr(op2addr),
5650 NULL, mkexpr(op2), /* expected value */
5651 NULL, mkexpr(result) /* new value */);
5652 stmt(IRStmt_CAS(cas));
5653
5654 /* Set CC according to bitwise operation */
5655 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5656
5657 /* If old_mem contains the expected value, then the CAS succeeded.
5658 Otherwise, it did not */
5659 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5660 put_gpr_w1(r1, mkexpr(old_mem));
5661}
5662
5663static void
5664s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5665{
5666 IRCAS *cas;
5667 IRTemp old_mem = newTemp(Ity_I64);
5668 IRTemp op2 = newTemp(Ity_I64);
5669 IRTemp op3 = newTemp(Ity_I64);
5670 IRTemp result = newTemp(Ity_I64);
5671
5672 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5673 assign(op3, get_gpr_dw0(r3));
5674 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5675
5676 /* Place the addition of second operand and third operand at the
5677 second-operand location everytime */
5678 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5679 Iend_BE, mkexpr(op2addr),
5680 NULL, mkexpr(op2), /* expected value */
5681 NULL, mkexpr(result) /* new value */);
5682 stmt(IRStmt_CAS(cas));
5683
5684 /* Set CC according to bitwise operation */
5685 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5686
5687 /* If old_mem contains the expected value, then the CAS succeeded.
5688 Otherwise, it did not */
5689 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5690 put_gpr_dw0(r1, mkexpr(old_mem));
5691}
5692
5693static const HChar *
5694s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5695{
5696 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005697
5698 return "laa";
5699}
5700
florian55085f82012-11-21 00:36:55 +00005701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005702s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5703{
florianffc94012012-12-02 21:31:15 +00005704 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005705
5706 return "laag";
5707}
5708
florian55085f82012-11-21 00:36:55 +00005709static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005710s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5711{
florianffc94012012-12-02 21:31:15 +00005712 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005713
5714 return "laal";
5715}
5716
florian55085f82012-11-21 00:36:55 +00005717static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005718s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5719{
florianffc94012012-12-02 21:31:15 +00005720 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005721
5722 return "laalg";
5723}
5724
florian55085f82012-11-21 00:36:55 +00005725static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005726s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5727{
florianffc94012012-12-02 21:31:15 +00005728 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005729
5730 return "lan";
5731}
5732
florian55085f82012-11-21 00:36:55 +00005733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005734s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5735{
florianffc94012012-12-02 21:31:15 +00005736 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005737
5738 return "lang";
5739}
5740
florian55085f82012-11-21 00:36:55 +00005741static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005742s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5743{
florianffc94012012-12-02 21:31:15 +00005744 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005745
5746 return "lax";
5747}
5748
florian55085f82012-11-21 00:36:55 +00005749static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005750s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5751{
florianffc94012012-12-02 21:31:15 +00005752 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005753
5754 return "laxg";
5755}
5756
florian55085f82012-11-21 00:36:55 +00005757static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005758s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5759{
florianffc94012012-12-02 21:31:15 +00005760 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005761
5762 return "lao";
5763}
5764
florian55085f82012-11-21 00:36:55 +00005765static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005766s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5767{
florianffc94012012-12-02 21:31:15 +00005768 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005769
5770 return "laog";
5771}
5772
florian55085f82012-11-21 00:36:55 +00005773static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005774s390_irgen_LTR(UChar r1, UChar r2)
5775{
5776 IRTemp op2 = newTemp(Ity_I32);
5777
5778 assign(op2, get_gpr_w1(r2));
5779 put_gpr_w1(r1, mkexpr(op2));
5780 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5781
5782 return "ltr";
5783}
5784
florian55085f82012-11-21 00:36:55 +00005785static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005786s390_irgen_LTGR(UChar r1, UChar r2)
5787{
5788 IRTemp op2 = newTemp(Ity_I64);
5789
5790 assign(op2, get_gpr_dw0(r2));
5791 put_gpr_dw0(r1, mkexpr(op2));
5792 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5793
5794 return "ltgr";
5795}
5796
florian55085f82012-11-21 00:36:55 +00005797static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005798s390_irgen_LTGFR(UChar r1, UChar r2)
5799{
5800 IRTemp op2 = newTemp(Ity_I64);
5801
5802 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5803 put_gpr_dw0(r1, mkexpr(op2));
5804 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5805
5806 return "ltgfr";
5807}
5808
florian55085f82012-11-21 00:36:55 +00005809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005810s390_irgen_LT(UChar r1, IRTemp op2addr)
5811{
5812 IRTemp op2 = newTemp(Ity_I32);
5813
5814 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5815 put_gpr_w1(r1, mkexpr(op2));
5816 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5817
5818 return "lt";
5819}
5820
florian55085f82012-11-21 00:36:55 +00005821static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005822s390_irgen_LTG(UChar r1, IRTemp op2addr)
5823{
5824 IRTemp op2 = newTemp(Ity_I64);
5825
5826 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5827 put_gpr_dw0(r1, mkexpr(op2));
5828 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5829
5830 return "ltg";
5831}
5832
florian55085f82012-11-21 00:36:55 +00005833static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005834s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5835{
5836 IRTemp op2 = newTemp(Ity_I64);
5837
5838 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5839 put_gpr_dw0(r1, mkexpr(op2));
5840 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5841
5842 return "ltgf";
5843}
5844
florian55085f82012-11-21 00:36:55 +00005845static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005846s390_irgen_LBR(UChar r1, UChar r2)
5847{
5848 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5849
5850 return "lbr";
5851}
5852
florian55085f82012-11-21 00:36:55 +00005853static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005854s390_irgen_LGBR(UChar r1, UChar r2)
5855{
5856 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5857
5858 return "lgbr";
5859}
5860
florian55085f82012-11-21 00:36:55 +00005861static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005862s390_irgen_LB(UChar r1, IRTemp op2addr)
5863{
5864 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5865
5866 return "lb";
5867}
5868
florian55085f82012-11-21 00:36:55 +00005869static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005870s390_irgen_LGB(UChar r1, IRTemp op2addr)
5871{
5872 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5873
5874 return "lgb";
5875}
5876
florian55085f82012-11-21 00:36:55 +00005877static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005878s390_irgen_LBH(UChar r1, IRTemp op2addr)
5879{
5880 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5881
5882 return "lbh";
5883}
5884
florian55085f82012-11-21 00:36:55 +00005885static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005886s390_irgen_LCR(UChar r1, UChar r2)
5887{
5888 Int op1;
5889 IRTemp op2 = newTemp(Ity_I32);
5890 IRTemp result = newTemp(Ity_I32);
5891
5892 op1 = 0;
5893 assign(op2, get_gpr_w1(r2));
5894 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5895 put_gpr_w1(r1, mkexpr(result));
5896 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5897 op1)), op2);
5898
5899 return "lcr";
5900}
5901
florian55085f82012-11-21 00:36:55 +00005902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005903s390_irgen_LCGR(UChar r1, UChar r2)
5904{
5905 Long op1;
5906 IRTemp op2 = newTemp(Ity_I64);
5907 IRTemp result = newTemp(Ity_I64);
5908
5909 op1 = 0ULL;
5910 assign(op2, get_gpr_dw0(r2));
5911 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5912 put_gpr_dw0(r1, mkexpr(result));
5913 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5914 op1)), op2);
5915
5916 return "lcgr";
5917}
5918
florian55085f82012-11-21 00:36:55 +00005919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005920s390_irgen_LCGFR(UChar r1, UChar r2)
5921{
5922 Long op1;
5923 IRTemp op2 = newTemp(Ity_I64);
5924 IRTemp result = newTemp(Ity_I64);
5925
5926 op1 = 0ULL;
5927 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5928 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5929 put_gpr_dw0(r1, mkexpr(result));
5930 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5931 op1)), op2);
5932
5933 return "lcgfr";
5934}
5935
florian55085f82012-11-21 00:36:55 +00005936static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005937s390_irgen_LHR(UChar r1, UChar r2)
5938{
5939 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5940
5941 return "lhr";
5942}
5943
florian55085f82012-11-21 00:36:55 +00005944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005945s390_irgen_LGHR(UChar r1, UChar r2)
5946{
5947 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5948
5949 return "lghr";
5950}
5951
florian55085f82012-11-21 00:36:55 +00005952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005953s390_irgen_LH(UChar r1, IRTemp op2addr)
5954{
5955 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5956
5957 return "lh";
5958}
5959
florian55085f82012-11-21 00:36:55 +00005960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005961s390_irgen_LHY(UChar r1, IRTemp op2addr)
5962{
5963 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5964
5965 return "lhy";
5966}
5967
florian55085f82012-11-21 00:36:55 +00005968static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005969s390_irgen_LGH(UChar r1, IRTemp op2addr)
5970{
5971 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5972
5973 return "lgh";
5974}
5975
florian55085f82012-11-21 00:36:55 +00005976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005977s390_irgen_LHI(UChar r1, UShort i2)
5978{
5979 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5980
5981 return "lhi";
5982}
5983
florian55085f82012-11-21 00:36:55 +00005984static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005985s390_irgen_LGHI(UChar r1, UShort i2)
5986{
5987 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5988
5989 return "lghi";
5990}
5991
florian55085f82012-11-21 00:36:55 +00005992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005993s390_irgen_LHRL(UChar r1, UInt i2)
5994{
5995 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5996 ((ULong)(Long)(Int)i2 << 1)))));
5997
5998 return "lhrl";
5999}
6000
florian55085f82012-11-21 00:36:55 +00006001static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006002s390_irgen_LGHRL(UChar r1, UInt i2)
6003{
6004 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6005 ((ULong)(Long)(Int)i2 << 1)))));
6006
6007 return "lghrl";
6008}
6009
florian55085f82012-11-21 00:36:55 +00006010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006011s390_irgen_LHH(UChar r1, IRTemp op2addr)
6012{
6013 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6014
6015 return "lhh";
6016}
6017
florian55085f82012-11-21 00:36:55 +00006018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006019s390_irgen_LFH(UChar r1, IRTemp op2addr)
6020{
6021 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6022
6023 return "lfh";
6024}
6025
florian55085f82012-11-21 00:36:55 +00006026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006027s390_irgen_LLGFR(UChar r1, UChar r2)
6028{
6029 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6030
6031 return "llgfr";
6032}
6033
florian55085f82012-11-21 00:36:55 +00006034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006035s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6036{
6037 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6038
6039 return "llgf";
6040}
6041
florian55085f82012-11-21 00:36:55 +00006042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006043s390_irgen_LLGFRL(UChar r1, UInt i2)
6044{
6045 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6046 ((ULong)(Long)(Int)i2 << 1)))));
6047
6048 return "llgfrl";
6049}
6050
florian55085f82012-11-21 00:36:55 +00006051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006052s390_irgen_LLCR(UChar r1, UChar r2)
6053{
6054 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6055
6056 return "llcr";
6057}
6058
florian55085f82012-11-21 00:36:55 +00006059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006060s390_irgen_LLGCR(UChar r1, UChar r2)
6061{
6062 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6063
6064 return "llgcr";
6065}
6066
florian55085f82012-11-21 00:36:55 +00006067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006068s390_irgen_LLC(UChar r1, IRTemp op2addr)
6069{
6070 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6071
6072 return "llc";
6073}
6074
florian55085f82012-11-21 00:36:55 +00006075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006076s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6077{
6078 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6079
6080 return "llgc";
6081}
6082
florian55085f82012-11-21 00:36:55 +00006083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006084s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6085{
6086 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6087
6088 return "llch";
6089}
6090
florian55085f82012-11-21 00:36:55 +00006091static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006092s390_irgen_LLHR(UChar r1, UChar r2)
6093{
6094 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6095
6096 return "llhr";
6097}
6098
florian55085f82012-11-21 00:36:55 +00006099static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006100s390_irgen_LLGHR(UChar r1, UChar r2)
6101{
6102 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6103
6104 return "llghr";
6105}
6106
florian55085f82012-11-21 00:36:55 +00006107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006108s390_irgen_LLH(UChar r1, IRTemp op2addr)
6109{
6110 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6111
6112 return "llh";
6113}
6114
florian55085f82012-11-21 00:36:55 +00006115static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006116s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6117{
6118 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6119
6120 return "llgh";
6121}
6122
florian55085f82012-11-21 00:36:55 +00006123static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006124s390_irgen_LLHRL(UChar r1, UInt i2)
6125{
6126 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6127 ((ULong)(Long)(Int)i2 << 1)))));
6128
6129 return "llhrl";
6130}
6131
florian55085f82012-11-21 00:36:55 +00006132static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006133s390_irgen_LLGHRL(UChar r1, UInt i2)
6134{
6135 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6136 ((ULong)(Long)(Int)i2 << 1)))));
6137
6138 return "llghrl";
6139}
6140
florian55085f82012-11-21 00:36:55 +00006141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006142s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6143{
6144 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6145
6146 return "llhh";
6147}
6148
florian55085f82012-11-21 00:36:55 +00006149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006150s390_irgen_LLIHF(UChar r1, UInt i2)
6151{
6152 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6153
6154 return "llihf";
6155}
6156
florian55085f82012-11-21 00:36:55 +00006157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006158s390_irgen_LLIHH(UChar r1, UShort i2)
6159{
6160 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6161
6162 return "llihh";
6163}
6164
florian55085f82012-11-21 00:36:55 +00006165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006166s390_irgen_LLIHL(UChar r1, UShort i2)
6167{
6168 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6169
6170 return "llihl";
6171}
6172
florian55085f82012-11-21 00:36:55 +00006173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006174s390_irgen_LLILF(UChar r1, UInt i2)
6175{
6176 put_gpr_dw0(r1, mkU64(i2));
6177
6178 return "llilf";
6179}
6180
florian55085f82012-11-21 00:36:55 +00006181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006182s390_irgen_LLILH(UChar r1, UShort i2)
6183{
6184 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6185
6186 return "llilh";
6187}
6188
florian55085f82012-11-21 00:36:55 +00006189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006190s390_irgen_LLILL(UChar r1, UShort i2)
6191{
6192 put_gpr_dw0(r1, mkU64(i2));
6193
6194 return "llill";
6195}
6196
florian55085f82012-11-21 00:36:55 +00006197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006198s390_irgen_LLGTR(UChar r1, UChar r2)
6199{
6200 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6201 mkU32(2147483647))));
6202
6203 return "llgtr";
6204}
6205
florian55085f82012-11-21 00:36:55 +00006206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006207s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6208{
6209 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6210 mkexpr(op2addr)), mkU32(2147483647))));
6211
6212 return "llgt";
6213}
6214
florian55085f82012-11-21 00:36:55 +00006215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006216s390_irgen_LNR(UChar r1, UChar r2)
6217{
6218 IRTemp op2 = newTemp(Ity_I32);
6219 IRTemp result = newTemp(Ity_I32);
6220
6221 assign(op2, get_gpr_w1(r2));
6222 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6223 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6224 put_gpr_w1(r1, mkexpr(result));
6225 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6226
6227 return "lnr";
6228}
6229
florian55085f82012-11-21 00:36:55 +00006230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006231s390_irgen_LNGR(UChar r1, UChar r2)
6232{
6233 IRTemp op2 = newTemp(Ity_I64);
6234 IRTemp result = newTemp(Ity_I64);
6235
6236 assign(op2, get_gpr_dw0(r2));
6237 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6238 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6239 put_gpr_dw0(r1, mkexpr(result));
6240 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6241
6242 return "lngr";
6243}
6244
florian55085f82012-11-21 00:36:55 +00006245static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006246s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6247{
6248 IRTemp op2 = newTemp(Ity_I64);
6249 IRTemp result = newTemp(Ity_I64);
6250
6251 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6252 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6253 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6254 put_gpr_dw0(r1, mkexpr(result));
6255 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6256
6257 return "lngfr";
6258}
6259
florian55085f82012-11-21 00:36:55 +00006260static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006261s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6262{
florian6820ba52012-07-26 02:01:50 +00006263 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006264 put_gpr_w1(r1, get_gpr_w1(r2));
6265
6266 return "locr";
6267}
6268
florian55085f82012-11-21 00:36:55 +00006269static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006270s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6271{
florian6820ba52012-07-26 02:01:50 +00006272 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006273 put_gpr_dw0(r1, get_gpr_dw0(r2));
6274
6275 return "locgr";
6276}
6277
florian55085f82012-11-21 00:36:55 +00006278static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006279s390_irgen_LOC(UChar r1, IRTemp op2addr)
6280{
6281 /* condition is checked in format handler */
6282 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6283
6284 return "loc";
6285}
6286
florian55085f82012-11-21 00:36:55 +00006287static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006288s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6289{
6290 /* condition is checked in format handler */
6291 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6292
6293 return "locg";
6294}
6295
florian55085f82012-11-21 00:36:55 +00006296static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006297s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6298{
6299 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6300 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6301 ));
6302
6303 return "lpq";
6304}
6305
florian55085f82012-11-21 00:36:55 +00006306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006307s390_irgen_LPR(UChar r1, UChar r2)
6308{
6309 IRTemp op2 = newTemp(Ity_I32);
6310 IRTemp result = newTemp(Ity_I32);
6311
6312 assign(op2, get_gpr_w1(r2));
6313 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6314 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6315 put_gpr_w1(r1, mkexpr(result));
6316 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6317
6318 return "lpr";
6319}
6320
florian55085f82012-11-21 00:36:55 +00006321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006322s390_irgen_LPGR(UChar r1, UChar r2)
6323{
6324 IRTemp op2 = newTemp(Ity_I64);
6325 IRTemp result = newTemp(Ity_I64);
6326
6327 assign(op2, get_gpr_dw0(r2));
6328 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6329 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6330 put_gpr_dw0(r1, mkexpr(result));
6331 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6332
6333 return "lpgr";
6334}
6335
florian55085f82012-11-21 00:36:55 +00006336static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006337s390_irgen_LPGFR(UChar r1, UChar r2)
6338{
6339 IRTemp op2 = newTemp(Ity_I64);
6340 IRTemp result = newTemp(Ity_I64);
6341
6342 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6343 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6344 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6345 put_gpr_dw0(r1, mkexpr(result));
6346 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6347
6348 return "lpgfr";
6349}
6350
florian55085f82012-11-21 00:36:55 +00006351static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006352s390_irgen_LRVR(UChar r1, UChar r2)
6353{
6354 IRTemp b0 = newTemp(Ity_I8);
6355 IRTemp b1 = newTemp(Ity_I8);
6356 IRTemp b2 = newTemp(Ity_I8);
6357 IRTemp b3 = newTemp(Ity_I8);
6358
6359 assign(b3, get_gpr_b7(r2));
6360 assign(b2, get_gpr_b6(r2));
6361 assign(b1, get_gpr_b5(r2));
6362 assign(b0, get_gpr_b4(r2));
6363 put_gpr_b4(r1, mkexpr(b3));
6364 put_gpr_b5(r1, mkexpr(b2));
6365 put_gpr_b6(r1, mkexpr(b1));
6366 put_gpr_b7(r1, mkexpr(b0));
6367
6368 return "lrvr";
6369}
6370
florian55085f82012-11-21 00:36:55 +00006371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006372s390_irgen_LRVGR(UChar r1, UChar r2)
6373{
6374 IRTemp b0 = newTemp(Ity_I8);
6375 IRTemp b1 = newTemp(Ity_I8);
6376 IRTemp b2 = newTemp(Ity_I8);
6377 IRTemp b3 = newTemp(Ity_I8);
6378 IRTemp b4 = newTemp(Ity_I8);
6379 IRTemp b5 = newTemp(Ity_I8);
6380 IRTemp b6 = newTemp(Ity_I8);
6381 IRTemp b7 = newTemp(Ity_I8);
6382
6383 assign(b7, get_gpr_b7(r2));
6384 assign(b6, get_gpr_b6(r2));
6385 assign(b5, get_gpr_b5(r2));
6386 assign(b4, get_gpr_b4(r2));
6387 assign(b3, get_gpr_b3(r2));
6388 assign(b2, get_gpr_b2(r2));
6389 assign(b1, get_gpr_b1(r2));
6390 assign(b0, get_gpr_b0(r2));
6391 put_gpr_b0(r1, mkexpr(b7));
6392 put_gpr_b1(r1, mkexpr(b6));
6393 put_gpr_b2(r1, mkexpr(b5));
6394 put_gpr_b3(r1, mkexpr(b4));
6395 put_gpr_b4(r1, mkexpr(b3));
6396 put_gpr_b5(r1, mkexpr(b2));
6397 put_gpr_b6(r1, mkexpr(b1));
6398 put_gpr_b7(r1, mkexpr(b0));
6399
6400 return "lrvgr";
6401}
6402
florian55085f82012-11-21 00:36:55 +00006403static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006404s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6405{
6406 IRTemp op2 = newTemp(Ity_I16);
6407
6408 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6409 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6410 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6411
6412 return "lrvh";
6413}
6414
florian55085f82012-11-21 00:36:55 +00006415static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006416s390_irgen_LRV(UChar r1, IRTemp op2addr)
6417{
6418 IRTemp op2 = newTemp(Ity_I32);
6419
6420 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6421 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6422 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6423 mkU8(8)), mkU32(255))));
6424 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6425 mkU8(16)), mkU32(255))));
6426 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6427 mkU8(24)), mkU32(255))));
6428
6429 return "lrv";
6430}
6431
florian55085f82012-11-21 00:36:55 +00006432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006433s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6434{
6435 IRTemp op2 = newTemp(Ity_I64);
6436
6437 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6438 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6439 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6440 mkU8(8)), mkU64(255))));
6441 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6442 mkU8(16)), mkU64(255))));
6443 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6444 mkU8(24)), mkU64(255))));
6445 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6446 mkU8(32)), mkU64(255))));
6447 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6448 mkU8(40)), mkU64(255))));
6449 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6450 mkU8(48)), mkU64(255))));
6451 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6452 mkU8(56)), mkU64(255))));
6453
6454 return "lrvg";
6455}
6456
florian55085f82012-11-21 00:36:55 +00006457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006458s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6459{
6460 store(mkexpr(op1addr), mkU16(i2));
6461
6462 return "mvhhi";
6463}
6464
florian55085f82012-11-21 00:36:55 +00006465static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006466s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6467{
6468 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6469
6470 return "mvhi";
6471}
6472
florian55085f82012-11-21 00:36:55 +00006473static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006474s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6475{
6476 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6477
6478 return "mvghi";
6479}
6480
florian55085f82012-11-21 00:36:55 +00006481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006482s390_irgen_MVI(UChar i2, IRTemp op1addr)
6483{
6484 store(mkexpr(op1addr), mkU8(i2));
6485
6486 return "mvi";
6487}
6488
florian55085f82012-11-21 00:36:55 +00006489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006490s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6491{
6492 store(mkexpr(op1addr), mkU8(i2));
6493
6494 return "mviy";
6495}
6496
florian55085f82012-11-21 00:36:55 +00006497static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006498s390_irgen_MR(UChar r1, UChar r2)
6499{
6500 IRTemp op1 = newTemp(Ity_I32);
6501 IRTemp op2 = newTemp(Ity_I32);
6502 IRTemp result = newTemp(Ity_I64);
6503
6504 assign(op1, get_gpr_w1(r1 + 1));
6505 assign(op2, get_gpr_w1(r2));
6506 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6507 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6508 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6509
6510 return "mr";
6511}
6512
florian55085f82012-11-21 00:36:55 +00006513static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006514s390_irgen_M(UChar r1, IRTemp op2addr)
6515{
6516 IRTemp op1 = newTemp(Ity_I32);
6517 IRTemp op2 = newTemp(Ity_I32);
6518 IRTemp result = newTemp(Ity_I64);
6519
6520 assign(op1, get_gpr_w1(r1 + 1));
6521 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6522 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6523 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6524 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6525
6526 return "m";
6527}
6528
florian55085f82012-11-21 00:36:55 +00006529static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006530s390_irgen_MFY(UChar r1, IRTemp op2addr)
6531{
6532 IRTemp op1 = newTemp(Ity_I32);
6533 IRTemp op2 = newTemp(Ity_I32);
6534 IRTemp result = newTemp(Ity_I64);
6535
6536 assign(op1, get_gpr_w1(r1 + 1));
6537 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6538 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6539 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6540 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6541
6542 return "mfy";
6543}
6544
florian55085f82012-11-21 00:36:55 +00006545static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006546s390_irgen_MH(UChar r1, IRTemp op2addr)
6547{
6548 IRTemp op1 = newTemp(Ity_I32);
6549 IRTemp op2 = newTemp(Ity_I16);
6550 IRTemp result = newTemp(Ity_I64);
6551
6552 assign(op1, get_gpr_w1(r1));
6553 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6554 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6555 ));
6556 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6557
6558 return "mh";
6559}
6560
florian55085f82012-11-21 00:36:55 +00006561static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006562s390_irgen_MHY(UChar r1, IRTemp op2addr)
6563{
6564 IRTemp op1 = newTemp(Ity_I32);
6565 IRTemp op2 = newTemp(Ity_I16);
6566 IRTemp result = newTemp(Ity_I64);
6567
6568 assign(op1, get_gpr_w1(r1));
6569 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6570 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6571 ));
6572 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6573
6574 return "mhy";
6575}
6576
florian55085f82012-11-21 00:36:55 +00006577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006578s390_irgen_MHI(UChar r1, UShort i2)
6579{
6580 IRTemp op1 = newTemp(Ity_I32);
6581 Short op2;
6582 IRTemp result = newTemp(Ity_I64);
6583
6584 assign(op1, get_gpr_w1(r1));
6585 op2 = (Short)i2;
6586 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6587 mkU16((UShort)op2))));
6588 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6589
6590 return "mhi";
6591}
6592
florian55085f82012-11-21 00:36:55 +00006593static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006594s390_irgen_MGHI(UChar r1, UShort i2)
6595{
6596 IRTemp op1 = newTemp(Ity_I64);
6597 Short op2;
6598 IRTemp result = newTemp(Ity_I128);
6599
6600 assign(op1, get_gpr_dw0(r1));
6601 op2 = (Short)i2;
6602 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6603 mkU16((UShort)op2))));
6604 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6605
6606 return "mghi";
6607}
6608
florian55085f82012-11-21 00:36:55 +00006609static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006610s390_irgen_MLR(UChar r1, UChar r2)
6611{
6612 IRTemp op1 = newTemp(Ity_I32);
6613 IRTemp op2 = newTemp(Ity_I32);
6614 IRTemp result = newTemp(Ity_I64);
6615
6616 assign(op1, get_gpr_w1(r1 + 1));
6617 assign(op2, get_gpr_w1(r2));
6618 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6619 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6620 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6621
6622 return "mlr";
6623}
6624
florian55085f82012-11-21 00:36:55 +00006625static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006626s390_irgen_MLGR(UChar r1, UChar r2)
6627{
6628 IRTemp op1 = newTemp(Ity_I64);
6629 IRTemp op2 = newTemp(Ity_I64);
6630 IRTemp result = newTemp(Ity_I128);
6631
6632 assign(op1, get_gpr_dw0(r1 + 1));
6633 assign(op2, get_gpr_dw0(r2));
6634 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6635 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6636 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6637
6638 return "mlgr";
6639}
6640
florian55085f82012-11-21 00:36:55 +00006641static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006642s390_irgen_ML(UChar r1, IRTemp op2addr)
6643{
6644 IRTemp op1 = newTemp(Ity_I32);
6645 IRTemp op2 = newTemp(Ity_I32);
6646 IRTemp result = newTemp(Ity_I64);
6647
6648 assign(op1, get_gpr_w1(r1 + 1));
6649 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6650 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6651 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6652 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6653
6654 return "ml";
6655}
6656
florian55085f82012-11-21 00:36:55 +00006657static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006658s390_irgen_MLG(UChar r1, IRTemp op2addr)
6659{
6660 IRTemp op1 = newTemp(Ity_I64);
6661 IRTemp op2 = newTemp(Ity_I64);
6662 IRTemp result = newTemp(Ity_I128);
6663
6664 assign(op1, get_gpr_dw0(r1 + 1));
6665 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6666 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6667 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6668 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6669
6670 return "mlg";
6671}
6672
florian55085f82012-11-21 00:36:55 +00006673static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006674s390_irgen_MSR(UChar r1, UChar r2)
6675{
6676 IRTemp op1 = newTemp(Ity_I32);
6677 IRTemp op2 = newTemp(Ity_I32);
6678 IRTemp result = newTemp(Ity_I64);
6679
6680 assign(op1, get_gpr_w1(r1));
6681 assign(op2, get_gpr_w1(r2));
6682 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6683 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6684
6685 return "msr";
6686}
6687
florian55085f82012-11-21 00:36:55 +00006688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006689s390_irgen_MSGR(UChar r1, UChar r2)
6690{
6691 IRTemp op1 = newTemp(Ity_I64);
6692 IRTemp op2 = newTemp(Ity_I64);
6693 IRTemp result = newTemp(Ity_I128);
6694
6695 assign(op1, get_gpr_dw0(r1));
6696 assign(op2, get_gpr_dw0(r2));
6697 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6698 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6699
6700 return "msgr";
6701}
6702
florian55085f82012-11-21 00:36:55 +00006703static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006704s390_irgen_MSGFR(UChar r1, UChar r2)
6705{
6706 IRTemp op1 = newTemp(Ity_I64);
6707 IRTemp op2 = newTemp(Ity_I32);
6708 IRTemp result = newTemp(Ity_I128);
6709
6710 assign(op1, get_gpr_dw0(r1));
6711 assign(op2, get_gpr_w1(r2));
6712 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6713 ));
6714 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6715
6716 return "msgfr";
6717}
6718
florian55085f82012-11-21 00:36:55 +00006719static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006720s390_irgen_MS(UChar r1, IRTemp op2addr)
6721{
6722 IRTemp op1 = newTemp(Ity_I32);
6723 IRTemp op2 = newTemp(Ity_I32);
6724 IRTemp result = newTemp(Ity_I64);
6725
6726 assign(op1, get_gpr_w1(r1));
6727 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6728 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6729 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6730
6731 return "ms";
6732}
6733
florian55085f82012-11-21 00:36:55 +00006734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006735s390_irgen_MSY(UChar r1, IRTemp op2addr)
6736{
6737 IRTemp op1 = newTemp(Ity_I32);
6738 IRTemp op2 = newTemp(Ity_I32);
6739 IRTemp result = newTemp(Ity_I64);
6740
6741 assign(op1, get_gpr_w1(r1));
6742 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6743 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6744 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6745
6746 return "msy";
6747}
6748
florian55085f82012-11-21 00:36:55 +00006749static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006750s390_irgen_MSG(UChar r1, IRTemp op2addr)
6751{
6752 IRTemp op1 = newTemp(Ity_I64);
6753 IRTemp op2 = newTemp(Ity_I64);
6754 IRTemp result = newTemp(Ity_I128);
6755
6756 assign(op1, get_gpr_dw0(r1));
6757 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6758 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6759 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6760
6761 return "msg";
6762}
6763
florian55085f82012-11-21 00:36:55 +00006764static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006765s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6766{
6767 IRTemp op1 = newTemp(Ity_I64);
6768 IRTemp op2 = newTemp(Ity_I32);
6769 IRTemp result = newTemp(Ity_I128);
6770
6771 assign(op1, get_gpr_dw0(r1));
6772 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6773 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6774 ));
6775 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6776
6777 return "msgf";
6778}
6779
florian55085f82012-11-21 00:36:55 +00006780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006781s390_irgen_MSFI(UChar r1, UInt i2)
6782{
6783 IRTemp op1 = newTemp(Ity_I32);
6784 Int op2;
6785 IRTemp result = newTemp(Ity_I64);
6786
6787 assign(op1, get_gpr_w1(r1));
6788 op2 = (Int)i2;
6789 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6790 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6791
6792 return "msfi";
6793}
6794
florian55085f82012-11-21 00:36:55 +00006795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006796s390_irgen_MSGFI(UChar r1, UInt i2)
6797{
6798 IRTemp op1 = newTemp(Ity_I64);
6799 Int op2;
6800 IRTemp result = newTemp(Ity_I128);
6801
6802 assign(op1, get_gpr_dw0(r1));
6803 op2 = (Int)i2;
6804 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6805 op2))));
6806 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6807
6808 return "msgfi";
6809}
6810
florian55085f82012-11-21 00:36:55 +00006811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006812s390_irgen_OR(UChar r1, UChar r2)
6813{
6814 IRTemp op1 = newTemp(Ity_I32);
6815 IRTemp op2 = newTemp(Ity_I32);
6816 IRTemp result = newTemp(Ity_I32);
6817
6818 assign(op1, get_gpr_w1(r1));
6819 assign(op2, get_gpr_w1(r2));
6820 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6821 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6822 put_gpr_w1(r1, mkexpr(result));
6823
6824 return "or";
6825}
6826
florian55085f82012-11-21 00:36:55 +00006827static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006828s390_irgen_OGR(UChar r1, UChar r2)
6829{
6830 IRTemp op1 = newTemp(Ity_I64);
6831 IRTemp op2 = newTemp(Ity_I64);
6832 IRTemp result = newTemp(Ity_I64);
6833
6834 assign(op1, get_gpr_dw0(r1));
6835 assign(op2, get_gpr_dw0(r2));
6836 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6837 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6838 put_gpr_dw0(r1, mkexpr(result));
6839
6840 return "ogr";
6841}
6842
florian55085f82012-11-21 00:36:55 +00006843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006844s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6845{
6846 IRTemp op2 = newTemp(Ity_I32);
6847 IRTemp op3 = newTemp(Ity_I32);
6848 IRTemp result = newTemp(Ity_I32);
6849
6850 assign(op2, get_gpr_w1(r2));
6851 assign(op3, get_gpr_w1(r3));
6852 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6853 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6854 put_gpr_w1(r1, mkexpr(result));
6855
6856 return "ork";
6857}
6858
florian55085f82012-11-21 00:36:55 +00006859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006860s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6861{
6862 IRTemp op2 = newTemp(Ity_I64);
6863 IRTemp op3 = newTemp(Ity_I64);
6864 IRTemp result = newTemp(Ity_I64);
6865
6866 assign(op2, get_gpr_dw0(r2));
6867 assign(op3, get_gpr_dw0(r3));
6868 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6869 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6870 put_gpr_dw0(r1, mkexpr(result));
6871
6872 return "ogrk";
6873}
6874
florian55085f82012-11-21 00:36:55 +00006875static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006876s390_irgen_O(UChar r1, IRTemp op2addr)
6877{
6878 IRTemp op1 = newTemp(Ity_I32);
6879 IRTemp op2 = newTemp(Ity_I32);
6880 IRTemp result = newTemp(Ity_I32);
6881
6882 assign(op1, get_gpr_w1(r1));
6883 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6884 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6885 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6886 put_gpr_w1(r1, mkexpr(result));
6887
6888 return "o";
6889}
6890
florian55085f82012-11-21 00:36:55 +00006891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006892s390_irgen_OY(UChar r1, IRTemp op2addr)
6893{
6894 IRTemp op1 = newTemp(Ity_I32);
6895 IRTemp op2 = newTemp(Ity_I32);
6896 IRTemp result = newTemp(Ity_I32);
6897
6898 assign(op1, get_gpr_w1(r1));
6899 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6900 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6901 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6902 put_gpr_w1(r1, mkexpr(result));
6903
6904 return "oy";
6905}
6906
florian55085f82012-11-21 00:36:55 +00006907static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006908s390_irgen_OG(UChar r1, IRTemp op2addr)
6909{
6910 IRTemp op1 = newTemp(Ity_I64);
6911 IRTemp op2 = newTemp(Ity_I64);
6912 IRTemp result = newTemp(Ity_I64);
6913
6914 assign(op1, get_gpr_dw0(r1));
6915 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6916 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6917 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6918 put_gpr_dw0(r1, mkexpr(result));
6919
6920 return "og";
6921}
6922
florian55085f82012-11-21 00:36:55 +00006923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006924s390_irgen_OI(UChar i2, IRTemp op1addr)
6925{
6926 IRTemp op1 = newTemp(Ity_I8);
6927 UChar op2;
6928 IRTemp result = newTemp(Ity_I8);
6929
6930 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6931 op2 = i2;
6932 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6933 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6934 store(mkexpr(op1addr), mkexpr(result));
6935
6936 return "oi";
6937}
6938
florian55085f82012-11-21 00:36:55 +00006939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006940s390_irgen_OIY(UChar i2, IRTemp op1addr)
6941{
6942 IRTemp op1 = newTemp(Ity_I8);
6943 UChar op2;
6944 IRTemp result = newTemp(Ity_I8);
6945
6946 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6947 op2 = i2;
6948 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6949 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6950 store(mkexpr(op1addr), mkexpr(result));
6951
6952 return "oiy";
6953}
6954
florian55085f82012-11-21 00:36:55 +00006955static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006956s390_irgen_OIHF(UChar r1, UInt i2)
6957{
6958 IRTemp op1 = newTemp(Ity_I32);
6959 UInt op2;
6960 IRTemp result = newTemp(Ity_I32);
6961
6962 assign(op1, get_gpr_w0(r1));
6963 op2 = i2;
6964 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6965 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6966 put_gpr_w0(r1, mkexpr(result));
6967
6968 return "oihf";
6969}
6970
florian55085f82012-11-21 00:36:55 +00006971static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006972s390_irgen_OIHH(UChar r1, UShort i2)
6973{
6974 IRTemp op1 = newTemp(Ity_I16);
6975 UShort op2;
6976 IRTemp result = newTemp(Ity_I16);
6977
6978 assign(op1, get_gpr_hw0(r1));
6979 op2 = i2;
6980 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6981 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6982 put_gpr_hw0(r1, mkexpr(result));
6983
6984 return "oihh";
6985}
6986
florian55085f82012-11-21 00:36:55 +00006987static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006988s390_irgen_OIHL(UChar r1, UShort i2)
6989{
6990 IRTemp op1 = newTemp(Ity_I16);
6991 UShort op2;
6992 IRTemp result = newTemp(Ity_I16);
6993
6994 assign(op1, get_gpr_hw1(r1));
6995 op2 = i2;
6996 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6997 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6998 put_gpr_hw1(r1, mkexpr(result));
6999
7000 return "oihl";
7001}
7002
florian55085f82012-11-21 00:36:55 +00007003static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007004s390_irgen_OILF(UChar r1, UInt i2)
7005{
7006 IRTemp op1 = newTemp(Ity_I32);
7007 UInt op2;
7008 IRTemp result = newTemp(Ity_I32);
7009
7010 assign(op1, get_gpr_w1(r1));
7011 op2 = i2;
7012 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7013 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7014 put_gpr_w1(r1, mkexpr(result));
7015
7016 return "oilf";
7017}
7018
florian55085f82012-11-21 00:36:55 +00007019static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007020s390_irgen_OILH(UChar r1, UShort i2)
7021{
7022 IRTemp op1 = newTemp(Ity_I16);
7023 UShort op2;
7024 IRTemp result = newTemp(Ity_I16);
7025
7026 assign(op1, get_gpr_hw2(r1));
7027 op2 = i2;
7028 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7029 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7030 put_gpr_hw2(r1, mkexpr(result));
7031
7032 return "oilh";
7033}
7034
florian55085f82012-11-21 00:36:55 +00007035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007036s390_irgen_OILL(UChar r1, UShort i2)
7037{
7038 IRTemp op1 = newTemp(Ity_I16);
7039 UShort op2;
7040 IRTemp result = newTemp(Ity_I16);
7041
7042 assign(op1, get_gpr_hw3(r1));
7043 op2 = i2;
7044 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7045 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7046 put_gpr_hw3(r1, mkexpr(result));
7047
7048 return "oill";
7049}
7050
florian55085f82012-11-21 00:36:55 +00007051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007052s390_irgen_PFD(void)
7053{
7054
7055 return "pfd";
7056}
7057
florian55085f82012-11-21 00:36:55 +00007058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007059s390_irgen_PFDRL(void)
7060{
7061
7062 return "pfdrl";
7063}
7064
florian55085f82012-11-21 00:36:55 +00007065static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007066s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7067{
7068 IRTemp amount = newTemp(Ity_I64);
7069 IRTemp op = newTemp(Ity_I32);
7070
7071 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7072 assign(op, get_gpr_w1(r3));
7073 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7074 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7075 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7076
7077 return "rll";
7078}
7079
florian55085f82012-11-21 00:36:55 +00007080static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007081s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7082{
7083 IRTemp amount = newTemp(Ity_I64);
7084 IRTemp op = newTemp(Ity_I64);
7085
7086 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7087 assign(op, get_gpr_dw0(r3));
7088 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7089 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7090 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7091
7092 return "rllg";
7093}
7094
florian55085f82012-11-21 00:36:55 +00007095static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007096s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7097{
7098 UChar from;
7099 UChar to;
7100 UChar rot;
7101 UChar t_bit;
7102 ULong mask;
7103 ULong maskc;
7104 IRTemp result = newTemp(Ity_I64);
7105 IRTemp op2 = newTemp(Ity_I64);
7106
7107 from = i3 & 63;
7108 to = i4 & 63;
7109 rot = i5 & 63;
7110 t_bit = i3 & 128;
7111 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7112 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7113 mkU8(64 - rot))));
7114 if (from <= to) {
7115 mask = ~0ULL;
7116 mask = (mask >> from) & (mask << (63 - to));
7117 maskc = ~mask;
7118 } else {
7119 maskc = ~0ULL;
7120 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7121 mask = ~maskc;
7122 }
7123 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7124 ), mkU64(mask)));
7125 if (t_bit == 0) {
7126 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7127 mkU64(maskc)), mkexpr(result)));
7128 }
7129 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7130
7131 return "rnsbg";
7132}
7133
florian55085f82012-11-21 00:36:55 +00007134static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007135s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7136{
7137 UChar from;
7138 UChar to;
7139 UChar rot;
7140 UChar t_bit;
7141 ULong mask;
7142 ULong maskc;
7143 IRTemp result = newTemp(Ity_I64);
7144 IRTemp op2 = newTemp(Ity_I64);
7145
7146 from = i3 & 63;
7147 to = i4 & 63;
7148 rot = i5 & 63;
7149 t_bit = i3 & 128;
7150 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7151 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7152 mkU8(64 - rot))));
7153 if (from <= to) {
7154 mask = ~0ULL;
7155 mask = (mask >> from) & (mask << (63 - to));
7156 maskc = ~mask;
7157 } else {
7158 maskc = ~0ULL;
7159 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7160 mask = ~maskc;
7161 }
7162 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7163 ), mkU64(mask)));
7164 if (t_bit == 0) {
7165 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7166 mkU64(maskc)), mkexpr(result)));
7167 }
7168 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7169
7170 return "rxsbg";
7171}
7172
florian55085f82012-11-21 00:36:55 +00007173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007174s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7175{
7176 UChar from;
7177 UChar to;
7178 UChar rot;
7179 UChar t_bit;
7180 ULong mask;
7181 ULong maskc;
7182 IRTemp result = newTemp(Ity_I64);
7183 IRTemp op2 = newTemp(Ity_I64);
7184
7185 from = i3 & 63;
7186 to = i4 & 63;
7187 rot = i5 & 63;
7188 t_bit = i3 & 128;
7189 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7190 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7191 mkU8(64 - rot))));
7192 if (from <= to) {
7193 mask = ~0ULL;
7194 mask = (mask >> from) & (mask << (63 - to));
7195 maskc = ~mask;
7196 } else {
7197 maskc = ~0ULL;
7198 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7199 mask = ~maskc;
7200 }
7201 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7202 ), mkU64(mask)));
7203 if (t_bit == 0) {
7204 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7205 mkU64(maskc)), mkexpr(result)));
7206 }
7207 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7208
7209 return "rosbg";
7210}
7211
florian55085f82012-11-21 00:36:55 +00007212static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007213s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7214{
7215 UChar from;
7216 UChar to;
7217 UChar rot;
7218 UChar z_bit;
7219 ULong mask;
7220 ULong maskc;
7221 IRTemp op2 = newTemp(Ity_I64);
7222 IRTemp result = newTemp(Ity_I64);
7223
7224 from = i3 & 63;
7225 to = i4 & 63;
7226 rot = i5 & 63;
7227 z_bit = i4 & 128;
7228 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7229 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7230 mkU8(64 - rot))));
7231 if (from <= to) {
7232 mask = ~0ULL;
7233 mask = (mask >> from) & (mask << (63 - to));
7234 maskc = ~mask;
7235 } else {
7236 maskc = ~0ULL;
7237 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7238 mask = ~maskc;
7239 }
7240 if (z_bit == 0) {
7241 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7242 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7243 } else {
7244 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7245 }
7246 assign(result, get_gpr_dw0(r1));
7247 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7248
7249 return "risbg";
7250}
7251
florian55085f82012-11-21 00:36:55 +00007252static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007253s390_irgen_SAR(UChar r1, UChar r2)
7254{
7255 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007256 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007257 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7258
7259 return "sar";
7260}
7261
florian55085f82012-11-21 00:36:55 +00007262static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007263s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7264{
7265 IRTemp p1 = newTemp(Ity_I64);
7266 IRTemp p2 = newTemp(Ity_I64);
7267 IRTemp op = newTemp(Ity_I64);
7268 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007269 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007270 IRTemp shift_amount = newTemp(Ity_I64);
7271
7272 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7273 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7274 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7275 ));
7276 sign_mask = 1ULL << 63;
7277 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7278 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007279 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7280 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007281 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7282 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7283 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7284
7285 return "slda";
7286}
7287
florian55085f82012-11-21 00:36:55 +00007288static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007289s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7290{
7291 IRTemp p1 = newTemp(Ity_I64);
7292 IRTemp p2 = newTemp(Ity_I64);
7293 IRTemp result = newTemp(Ity_I64);
7294
7295 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7296 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7297 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7298 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7299 mkexpr(op2addr), mkU64(63)))));
7300 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7301 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7302
7303 return "sldl";
7304}
7305
florian55085f82012-11-21 00:36:55 +00007306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007307s390_irgen_SLA(UChar r1, IRTemp op2addr)
7308{
7309 IRTemp uop = newTemp(Ity_I32);
7310 IRTemp result = newTemp(Ity_I32);
7311 UInt sign_mask;
7312 IRTemp shift_amount = newTemp(Ity_I64);
7313 IRTemp op = newTemp(Ity_I32);
7314
7315 assign(op, get_gpr_w1(r1));
7316 assign(uop, get_gpr_w1(r1));
7317 sign_mask = 2147483648U;
7318 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7319 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7320 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7321 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7322 put_gpr_w1(r1, mkexpr(result));
7323 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7324
7325 return "sla";
7326}
7327
florian55085f82012-11-21 00:36:55 +00007328static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007329s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7330{
7331 IRTemp uop = newTemp(Ity_I32);
7332 IRTemp result = newTemp(Ity_I32);
7333 UInt sign_mask;
7334 IRTemp shift_amount = newTemp(Ity_I64);
7335 IRTemp op = newTemp(Ity_I32);
7336
7337 assign(op, get_gpr_w1(r3));
7338 assign(uop, get_gpr_w1(r3));
7339 sign_mask = 2147483648U;
7340 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7341 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7342 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7343 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7344 put_gpr_w1(r1, mkexpr(result));
7345 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7346
7347 return "slak";
7348}
7349
florian55085f82012-11-21 00:36:55 +00007350static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007351s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7352{
7353 IRTemp uop = newTemp(Ity_I64);
7354 IRTemp result = newTemp(Ity_I64);
7355 ULong sign_mask;
7356 IRTemp shift_amount = newTemp(Ity_I64);
7357 IRTemp op = newTemp(Ity_I64);
7358
7359 assign(op, get_gpr_dw0(r3));
7360 assign(uop, get_gpr_dw0(r3));
7361 sign_mask = 9223372036854775808ULL;
7362 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7363 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7364 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7365 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7366 put_gpr_dw0(r1, mkexpr(result));
7367 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7368
7369 return "slag";
7370}
7371
florian55085f82012-11-21 00:36:55 +00007372static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007373s390_irgen_SLL(UChar r1, IRTemp op2addr)
7374{
7375 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7376 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7377
7378 return "sll";
7379}
7380
florian55085f82012-11-21 00:36:55 +00007381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007382s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7383{
7384 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7385 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7386
7387 return "sllk";
7388}
7389
florian55085f82012-11-21 00:36:55 +00007390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007391s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7392{
7393 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7394 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7395
7396 return "sllg";
7397}
7398
florian55085f82012-11-21 00:36:55 +00007399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007400s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7401{
7402 IRTemp p1 = newTemp(Ity_I64);
7403 IRTemp p2 = newTemp(Ity_I64);
7404 IRTemp result = newTemp(Ity_I64);
7405
7406 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7407 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7408 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7409 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7410 mkexpr(op2addr), mkU64(63)))));
7411 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7412 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7413 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7414
7415 return "srda";
7416}
7417
florian55085f82012-11-21 00:36:55 +00007418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007419s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7420{
7421 IRTemp p1 = newTemp(Ity_I64);
7422 IRTemp p2 = newTemp(Ity_I64);
7423 IRTemp result = newTemp(Ity_I64);
7424
7425 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7426 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7427 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7428 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7429 mkexpr(op2addr), mkU64(63)))));
7430 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7431 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7432
7433 return "srdl";
7434}
7435
florian55085f82012-11-21 00:36:55 +00007436static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007437s390_irgen_SRA(UChar r1, IRTemp op2addr)
7438{
7439 IRTemp result = newTemp(Ity_I32);
7440 IRTemp op = newTemp(Ity_I32);
7441
7442 assign(op, get_gpr_w1(r1));
7443 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7444 mkexpr(op2addr), mkU64(63)))));
7445 put_gpr_w1(r1, mkexpr(result));
7446 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7447
7448 return "sra";
7449}
7450
florian55085f82012-11-21 00:36:55 +00007451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007452s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7453{
7454 IRTemp result = newTemp(Ity_I32);
7455 IRTemp op = newTemp(Ity_I32);
7456
7457 assign(op, get_gpr_w1(r3));
7458 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7459 mkexpr(op2addr), mkU64(63)))));
7460 put_gpr_w1(r1, mkexpr(result));
7461 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7462
7463 return "srak";
7464}
7465
florian55085f82012-11-21 00:36:55 +00007466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007467s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7468{
7469 IRTemp result = newTemp(Ity_I64);
7470 IRTemp op = newTemp(Ity_I64);
7471
7472 assign(op, get_gpr_dw0(r3));
7473 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7474 mkexpr(op2addr), mkU64(63)))));
7475 put_gpr_dw0(r1, mkexpr(result));
7476 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7477
7478 return "srag";
7479}
7480
florian55085f82012-11-21 00:36:55 +00007481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007482s390_irgen_SRL(UChar r1, IRTemp op2addr)
7483{
7484 IRTemp op = newTemp(Ity_I32);
7485
7486 assign(op, get_gpr_w1(r1));
7487 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7488 mkexpr(op2addr), mkU64(63)))));
7489
7490 return "srl";
7491}
7492
florian55085f82012-11-21 00:36:55 +00007493static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007494s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7495{
7496 IRTemp op = newTemp(Ity_I32);
7497
7498 assign(op, get_gpr_w1(r3));
7499 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7500 mkexpr(op2addr), mkU64(63)))));
7501
7502 return "srlk";
7503}
7504
florian55085f82012-11-21 00:36:55 +00007505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007506s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7507{
7508 IRTemp op = newTemp(Ity_I64);
7509
7510 assign(op, get_gpr_dw0(r3));
7511 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7512 mkexpr(op2addr), mkU64(63)))));
7513
7514 return "srlg";
7515}
7516
florian55085f82012-11-21 00:36:55 +00007517static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007518s390_irgen_ST(UChar r1, IRTemp op2addr)
7519{
7520 store(mkexpr(op2addr), get_gpr_w1(r1));
7521
7522 return "st";
7523}
7524
florian55085f82012-11-21 00:36:55 +00007525static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007526s390_irgen_STY(UChar r1, IRTemp op2addr)
7527{
7528 store(mkexpr(op2addr), get_gpr_w1(r1));
7529
7530 return "sty";
7531}
7532
florian55085f82012-11-21 00:36:55 +00007533static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007534s390_irgen_STG(UChar r1, IRTemp op2addr)
7535{
7536 store(mkexpr(op2addr), get_gpr_dw0(r1));
7537
7538 return "stg";
7539}
7540
florian55085f82012-11-21 00:36:55 +00007541static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007542s390_irgen_STRL(UChar r1, UInt i2)
7543{
7544 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7545 get_gpr_w1(r1));
7546
7547 return "strl";
7548}
7549
florian55085f82012-11-21 00:36:55 +00007550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007551s390_irgen_STGRL(UChar r1, UInt i2)
7552{
7553 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7554 get_gpr_dw0(r1));
7555
7556 return "stgrl";
7557}
7558
florian55085f82012-11-21 00:36:55 +00007559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007560s390_irgen_STC(UChar r1, IRTemp op2addr)
7561{
7562 store(mkexpr(op2addr), get_gpr_b7(r1));
7563
7564 return "stc";
7565}
7566
florian55085f82012-11-21 00:36:55 +00007567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007568s390_irgen_STCY(UChar r1, IRTemp op2addr)
7569{
7570 store(mkexpr(op2addr), get_gpr_b7(r1));
7571
7572 return "stcy";
7573}
7574
florian55085f82012-11-21 00:36:55 +00007575static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007576s390_irgen_STCH(UChar r1, IRTemp op2addr)
7577{
7578 store(mkexpr(op2addr), get_gpr_b3(r1));
7579
7580 return "stch";
7581}
7582
florian55085f82012-11-21 00:36:55 +00007583static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007584s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7585{
7586 UChar mask;
7587 UChar n;
7588
7589 mask = (UChar)r3;
7590 n = 0;
7591 if ((mask & 8) != 0) {
7592 store(mkexpr(op2addr), get_gpr_b4(r1));
7593 n = n + 1;
7594 }
7595 if ((mask & 4) != 0) {
7596 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7597 n = n + 1;
7598 }
7599 if ((mask & 2) != 0) {
7600 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7601 n = n + 1;
7602 }
7603 if ((mask & 1) != 0) {
7604 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7605 }
7606
7607 return "stcm";
7608}
7609
florian55085f82012-11-21 00:36:55 +00007610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007611s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7612{
7613 UChar mask;
7614 UChar n;
7615
7616 mask = (UChar)r3;
7617 n = 0;
7618 if ((mask & 8) != 0) {
7619 store(mkexpr(op2addr), get_gpr_b4(r1));
7620 n = n + 1;
7621 }
7622 if ((mask & 4) != 0) {
7623 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7624 n = n + 1;
7625 }
7626 if ((mask & 2) != 0) {
7627 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7628 n = n + 1;
7629 }
7630 if ((mask & 1) != 0) {
7631 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7632 }
7633
7634 return "stcmy";
7635}
7636
florian55085f82012-11-21 00:36:55 +00007637static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007638s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7639{
7640 UChar mask;
7641 UChar n;
7642
7643 mask = (UChar)r3;
7644 n = 0;
7645 if ((mask & 8) != 0) {
7646 store(mkexpr(op2addr), get_gpr_b0(r1));
7647 n = n + 1;
7648 }
7649 if ((mask & 4) != 0) {
7650 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7651 n = n + 1;
7652 }
7653 if ((mask & 2) != 0) {
7654 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7655 n = n + 1;
7656 }
7657 if ((mask & 1) != 0) {
7658 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7659 }
7660
7661 return "stcmh";
7662}
7663
florian55085f82012-11-21 00:36:55 +00007664static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007665s390_irgen_STH(UChar r1, IRTemp op2addr)
7666{
7667 store(mkexpr(op2addr), get_gpr_hw3(r1));
7668
7669 return "sth";
7670}
7671
florian55085f82012-11-21 00:36:55 +00007672static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007673s390_irgen_STHY(UChar r1, IRTemp op2addr)
7674{
7675 store(mkexpr(op2addr), get_gpr_hw3(r1));
7676
7677 return "sthy";
7678}
7679
florian55085f82012-11-21 00:36:55 +00007680static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007681s390_irgen_STHRL(UChar r1, UInt i2)
7682{
7683 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7684 get_gpr_hw3(r1));
7685
7686 return "sthrl";
7687}
7688
florian55085f82012-11-21 00:36:55 +00007689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007690s390_irgen_STHH(UChar r1, IRTemp op2addr)
7691{
7692 store(mkexpr(op2addr), get_gpr_hw1(r1));
7693
7694 return "sthh";
7695}
7696
florian55085f82012-11-21 00:36:55 +00007697static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007698s390_irgen_STFH(UChar r1, IRTemp op2addr)
7699{
7700 store(mkexpr(op2addr), get_gpr_w0(r1));
7701
7702 return "stfh";
7703}
7704
florian55085f82012-11-21 00:36:55 +00007705static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007706s390_irgen_STOC(UChar r1, IRTemp op2addr)
7707{
7708 /* condition is checked in format handler */
7709 store(mkexpr(op2addr), get_gpr_w1(r1));
7710
7711 return "stoc";
7712}
7713
florian55085f82012-11-21 00:36:55 +00007714static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007715s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7716{
7717 /* condition is checked in format handler */
7718 store(mkexpr(op2addr), get_gpr_dw0(r1));
7719
7720 return "stocg";
7721}
7722
florian55085f82012-11-21 00:36:55 +00007723static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007724s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7725{
7726 store(mkexpr(op2addr), get_gpr_dw0(r1));
7727 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7728
7729 return "stpq";
7730}
7731
florian55085f82012-11-21 00:36:55 +00007732static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007733s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7734{
7735 store(mkexpr(op2addr), get_gpr_b7(r1));
7736 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7737
7738 return "strvh";
7739}
7740
florian55085f82012-11-21 00:36:55 +00007741static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007742s390_irgen_STRV(UChar r1, IRTemp op2addr)
7743{
7744 store(mkexpr(op2addr), get_gpr_b7(r1));
7745 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7746 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7747 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7748
7749 return "strv";
7750}
7751
florian55085f82012-11-21 00:36:55 +00007752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007753s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7754{
7755 store(mkexpr(op2addr), get_gpr_b7(r1));
7756 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7757 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7758 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7759 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7760 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7761 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7762 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7763
7764 return "strvg";
7765}
7766
florian55085f82012-11-21 00:36:55 +00007767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007768s390_irgen_SR(UChar r1, UChar r2)
7769{
7770 IRTemp op1 = newTemp(Ity_I32);
7771 IRTemp op2 = newTemp(Ity_I32);
7772 IRTemp result = newTemp(Ity_I32);
7773
7774 assign(op1, get_gpr_w1(r1));
7775 assign(op2, get_gpr_w1(r2));
7776 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7777 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7778 put_gpr_w1(r1, mkexpr(result));
7779
7780 return "sr";
7781}
7782
florian55085f82012-11-21 00:36:55 +00007783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007784s390_irgen_SGR(UChar r1, UChar r2)
7785{
7786 IRTemp op1 = newTemp(Ity_I64);
7787 IRTemp op2 = newTemp(Ity_I64);
7788 IRTemp result = newTemp(Ity_I64);
7789
7790 assign(op1, get_gpr_dw0(r1));
7791 assign(op2, get_gpr_dw0(r2));
7792 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7793 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7794 put_gpr_dw0(r1, mkexpr(result));
7795
7796 return "sgr";
7797}
7798
florian55085f82012-11-21 00:36:55 +00007799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007800s390_irgen_SGFR(UChar r1, UChar r2)
7801{
7802 IRTemp op1 = newTemp(Ity_I64);
7803 IRTemp op2 = newTemp(Ity_I64);
7804 IRTemp result = newTemp(Ity_I64);
7805
7806 assign(op1, get_gpr_dw0(r1));
7807 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7808 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7809 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7810 put_gpr_dw0(r1, mkexpr(result));
7811
7812 return "sgfr";
7813}
7814
florian55085f82012-11-21 00:36:55 +00007815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007816s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7817{
7818 IRTemp op2 = newTemp(Ity_I32);
7819 IRTemp op3 = newTemp(Ity_I32);
7820 IRTemp result = newTemp(Ity_I32);
7821
7822 assign(op2, get_gpr_w1(r2));
7823 assign(op3, get_gpr_w1(r3));
7824 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7825 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7826 put_gpr_w1(r1, mkexpr(result));
7827
7828 return "srk";
7829}
7830
florian55085f82012-11-21 00:36:55 +00007831static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007832s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7833{
7834 IRTemp op2 = newTemp(Ity_I64);
7835 IRTemp op3 = newTemp(Ity_I64);
7836 IRTemp result = newTemp(Ity_I64);
7837
7838 assign(op2, get_gpr_dw0(r2));
7839 assign(op3, get_gpr_dw0(r3));
7840 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7841 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7842 put_gpr_dw0(r1, mkexpr(result));
7843
7844 return "sgrk";
7845}
7846
florian55085f82012-11-21 00:36:55 +00007847static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007848s390_irgen_S(UChar r1, IRTemp op2addr)
7849{
7850 IRTemp op1 = newTemp(Ity_I32);
7851 IRTemp op2 = newTemp(Ity_I32);
7852 IRTemp result = newTemp(Ity_I32);
7853
7854 assign(op1, get_gpr_w1(r1));
7855 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7856 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7857 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7858 put_gpr_w1(r1, mkexpr(result));
7859
7860 return "s";
7861}
7862
florian55085f82012-11-21 00:36:55 +00007863static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007864s390_irgen_SY(UChar r1, IRTemp op2addr)
7865{
7866 IRTemp op1 = newTemp(Ity_I32);
7867 IRTemp op2 = newTemp(Ity_I32);
7868 IRTemp result = newTemp(Ity_I32);
7869
7870 assign(op1, get_gpr_w1(r1));
7871 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7872 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7873 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7874 put_gpr_w1(r1, mkexpr(result));
7875
7876 return "sy";
7877}
7878
florian55085f82012-11-21 00:36:55 +00007879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007880s390_irgen_SG(UChar r1, IRTemp op2addr)
7881{
7882 IRTemp op1 = newTemp(Ity_I64);
7883 IRTemp op2 = newTemp(Ity_I64);
7884 IRTemp result = newTemp(Ity_I64);
7885
7886 assign(op1, get_gpr_dw0(r1));
7887 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7888 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7889 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7890 put_gpr_dw0(r1, mkexpr(result));
7891
7892 return "sg";
7893}
7894
florian55085f82012-11-21 00:36:55 +00007895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007896s390_irgen_SGF(UChar r1, IRTemp op2addr)
7897{
7898 IRTemp op1 = newTemp(Ity_I64);
7899 IRTemp op2 = newTemp(Ity_I64);
7900 IRTemp result = newTemp(Ity_I64);
7901
7902 assign(op1, get_gpr_dw0(r1));
7903 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7904 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7905 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7906 put_gpr_dw0(r1, mkexpr(result));
7907
7908 return "sgf";
7909}
7910
florian55085f82012-11-21 00:36:55 +00007911static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007912s390_irgen_SH(UChar r1, IRTemp op2addr)
7913{
7914 IRTemp op1 = newTemp(Ity_I32);
7915 IRTemp op2 = newTemp(Ity_I32);
7916 IRTemp result = newTemp(Ity_I32);
7917
7918 assign(op1, get_gpr_w1(r1));
7919 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7920 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7921 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7922 put_gpr_w1(r1, mkexpr(result));
7923
7924 return "sh";
7925}
7926
florian55085f82012-11-21 00:36:55 +00007927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007928s390_irgen_SHY(UChar r1, IRTemp op2addr)
7929{
7930 IRTemp op1 = newTemp(Ity_I32);
7931 IRTemp op2 = newTemp(Ity_I32);
7932 IRTemp result = newTemp(Ity_I32);
7933
7934 assign(op1, get_gpr_w1(r1));
7935 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7936 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7937 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7938 put_gpr_w1(r1, mkexpr(result));
7939
7940 return "shy";
7941}
7942
florian55085f82012-11-21 00:36:55 +00007943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007944s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7945{
7946 IRTemp op2 = newTemp(Ity_I32);
7947 IRTemp op3 = newTemp(Ity_I32);
7948 IRTemp result = newTemp(Ity_I32);
7949
7950 assign(op2, get_gpr_w0(r1));
7951 assign(op3, get_gpr_w0(r2));
7952 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7953 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7954 put_gpr_w0(r1, mkexpr(result));
7955
7956 return "shhhr";
7957}
7958
florian55085f82012-11-21 00:36:55 +00007959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007960s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7961{
7962 IRTemp op2 = newTemp(Ity_I32);
7963 IRTemp op3 = newTemp(Ity_I32);
7964 IRTemp result = newTemp(Ity_I32);
7965
7966 assign(op2, get_gpr_w0(r1));
7967 assign(op3, get_gpr_w1(r2));
7968 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7969 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7970 put_gpr_w0(r1, mkexpr(result));
7971
7972 return "shhlr";
7973}
7974
florian55085f82012-11-21 00:36:55 +00007975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007976s390_irgen_SLR(UChar r1, UChar r2)
7977{
7978 IRTemp op1 = newTemp(Ity_I32);
7979 IRTemp op2 = newTemp(Ity_I32);
7980 IRTemp result = newTemp(Ity_I32);
7981
7982 assign(op1, get_gpr_w1(r1));
7983 assign(op2, get_gpr_w1(r2));
7984 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7985 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7986 put_gpr_w1(r1, mkexpr(result));
7987
7988 return "slr";
7989}
7990
florian55085f82012-11-21 00:36:55 +00007991static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007992s390_irgen_SLGR(UChar r1, UChar r2)
7993{
7994 IRTemp op1 = newTemp(Ity_I64);
7995 IRTemp op2 = newTemp(Ity_I64);
7996 IRTemp result = newTemp(Ity_I64);
7997
7998 assign(op1, get_gpr_dw0(r1));
7999 assign(op2, get_gpr_dw0(r2));
8000 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8001 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8002 put_gpr_dw0(r1, mkexpr(result));
8003
8004 return "slgr";
8005}
8006
florian55085f82012-11-21 00:36:55 +00008007static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008008s390_irgen_SLGFR(UChar r1, UChar r2)
8009{
8010 IRTemp op1 = newTemp(Ity_I64);
8011 IRTemp op2 = newTemp(Ity_I64);
8012 IRTemp result = newTemp(Ity_I64);
8013
8014 assign(op1, get_gpr_dw0(r1));
8015 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8016 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8018 put_gpr_dw0(r1, mkexpr(result));
8019
8020 return "slgfr";
8021}
8022
florian55085f82012-11-21 00:36:55 +00008023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008024s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8025{
8026 IRTemp op2 = newTemp(Ity_I32);
8027 IRTemp op3 = newTemp(Ity_I32);
8028 IRTemp result = newTemp(Ity_I32);
8029
8030 assign(op2, get_gpr_w1(r2));
8031 assign(op3, get_gpr_w1(r3));
8032 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8033 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8034 put_gpr_w1(r1, mkexpr(result));
8035
8036 return "slrk";
8037}
8038
florian55085f82012-11-21 00:36:55 +00008039static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008040s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8041{
8042 IRTemp op2 = newTemp(Ity_I64);
8043 IRTemp op3 = newTemp(Ity_I64);
8044 IRTemp result = newTemp(Ity_I64);
8045
8046 assign(op2, get_gpr_dw0(r2));
8047 assign(op3, get_gpr_dw0(r3));
8048 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8049 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8050 put_gpr_dw0(r1, mkexpr(result));
8051
8052 return "slgrk";
8053}
8054
florian55085f82012-11-21 00:36:55 +00008055static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008056s390_irgen_SL(UChar r1, IRTemp op2addr)
8057{
8058 IRTemp op1 = newTemp(Ity_I32);
8059 IRTemp op2 = newTemp(Ity_I32);
8060 IRTemp result = newTemp(Ity_I32);
8061
8062 assign(op1, get_gpr_w1(r1));
8063 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8064 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8065 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8066 put_gpr_w1(r1, mkexpr(result));
8067
8068 return "sl";
8069}
8070
florian55085f82012-11-21 00:36:55 +00008071static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008072s390_irgen_SLY(UChar r1, IRTemp op2addr)
8073{
8074 IRTemp op1 = newTemp(Ity_I32);
8075 IRTemp op2 = newTemp(Ity_I32);
8076 IRTemp result = newTemp(Ity_I32);
8077
8078 assign(op1, get_gpr_w1(r1));
8079 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8080 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8081 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8082 put_gpr_w1(r1, mkexpr(result));
8083
8084 return "sly";
8085}
8086
florian55085f82012-11-21 00:36:55 +00008087static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008088s390_irgen_SLG(UChar r1, IRTemp op2addr)
8089{
8090 IRTemp op1 = newTemp(Ity_I64);
8091 IRTemp op2 = newTemp(Ity_I64);
8092 IRTemp result = newTemp(Ity_I64);
8093
8094 assign(op1, get_gpr_dw0(r1));
8095 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8096 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8097 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8098 put_gpr_dw0(r1, mkexpr(result));
8099
8100 return "slg";
8101}
8102
florian55085f82012-11-21 00:36:55 +00008103static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008104s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8105{
8106 IRTemp op1 = newTemp(Ity_I64);
8107 IRTemp op2 = newTemp(Ity_I64);
8108 IRTemp result = newTemp(Ity_I64);
8109
8110 assign(op1, get_gpr_dw0(r1));
8111 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8112 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8113 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8114 put_gpr_dw0(r1, mkexpr(result));
8115
8116 return "slgf";
8117}
8118
florian55085f82012-11-21 00:36:55 +00008119static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008120s390_irgen_SLFI(UChar r1, UInt i2)
8121{
8122 IRTemp op1 = newTemp(Ity_I32);
8123 UInt op2;
8124 IRTemp result = newTemp(Ity_I32);
8125
8126 assign(op1, get_gpr_w1(r1));
8127 op2 = i2;
8128 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8129 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8130 mkU32(op2)));
8131 put_gpr_w1(r1, mkexpr(result));
8132
8133 return "slfi";
8134}
8135
florian55085f82012-11-21 00:36:55 +00008136static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008137s390_irgen_SLGFI(UChar r1, UInt i2)
8138{
8139 IRTemp op1 = newTemp(Ity_I64);
8140 ULong op2;
8141 IRTemp result = newTemp(Ity_I64);
8142
8143 assign(op1, get_gpr_dw0(r1));
8144 op2 = (ULong)i2;
8145 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8146 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8147 mkU64(op2)));
8148 put_gpr_dw0(r1, mkexpr(result));
8149
8150 return "slgfi";
8151}
8152
florian55085f82012-11-21 00:36:55 +00008153static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008154s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8155{
8156 IRTemp op2 = newTemp(Ity_I32);
8157 IRTemp op3 = newTemp(Ity_I32);
8158 IRTemp result = newTemp(Ity_I32);
8159
8160 assign(op2, get_gpr_w0(r1));
8161 assign(op3, get_gpr_w0(r2));
8162 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8163 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8164 put_gpr_w0(r1, mkexpr(result));
8165
8166 return "slhhhr";
8167}
8168
florian55085f82012-11-21 00:36:55 +00008169static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008170s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8171{
8172 IRTemp op2 = newTemp(Ity_I32);
8173 IRTemp op3 = newTemp(Ity_I32);
8174 IRTemp result = newTemp(Ity_I32);
8175
8176 assign(op2, get_gpr_w0(r1));
8177 assign(op3, get_gpr_w1(r2));
8178 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8179 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8180 put_gpr_w0(r1, mkexpr(result));
8181
8182 return "slhhlr";
8183}
8184
florian55085f82012-11-21 00:36:55 +00008185static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008186s390_irgen_SLBR(UChar r1, UChar r2)
8187{
8188 IRTemp op1 = newTemp(Ity_I32);
8189 IRTemp op2 = newTemp(Ity_I32);
8190 IRTemp result = newTemp(Ity_I32);
8191 IRTemp borrow_in = newTemp(Ity_I32);
8192
8193 assign(op1, get_gpr_w1(r1));
8194 assign(op2, get_gpr_w1(r2));
8195 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8196 s390_call_calculate_cc(), mkU8(1))));
8197 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8198 mkexpr(borrow_in)));
8199 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8200 put_gpr_w1(r1, mkexpr(result));
8201
8202 return "slbr";
8203}
8204
florian55085f82012-11-21 00:36:55 +00008205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008206s390_irgen_SLBGR(UChar r1, UChar r2)
8207{
8208 IRTemp op1 = newTemp(Ity_I64);
8209 IRTemp op2 = newTemp(Ity_I64);
8210 IRTemp result = newTemp(Ity_I64);
8211 IRTemp borrow_in = newTemp(Ity_I64);
8212
8213 assign(op1, get_gpr_dw0(r1));
8214 assign(op2, get_gpr_dw0(r2));
8215 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8216 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8217 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8218 mkexpr(borrow_in)));
8219 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8220 put_gpr_dw0(r1, mkexpr(result));
8221
8222 return "slbgr";
8223}
8224
florian55085f82012-11-21 00:36:55 +00008225static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008226s390_irgen_SLB(UChar r1, IRTemp op2addr)
8227{
8228 IRTemp op1 = newTemp(Ity_I32);
8229 IRTemp op2 = newTemp(Ity_I32);
8230 IRTemp result = newTemp(Ity_I32);
8231 IRTemp borrow_in = newTemp(Ity_I32);
8232
8233 assign(op1, get_gpr_w1(r1));
8234 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8235 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8236 s390_call_calculate_cc(), mkU8(1))));
8237 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8238 mkexpr(borrow_in)));
8239 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8240 put_gpr_w1(r1, mkexpr(result));
8241
8242 return "slb";
8243}
8244
florian55085f82012-11-21 00:36:55 +00008245static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008246s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8247{
8248 IRTemp op1 = newTemp(Ity_I64);
8249 IRTemp op2 = newTemp(Ity_I64);
8250 IRTemp result = newTemp(Ity_I64);
8251 IRTemp borrow_in = newTemp(Ity_I64);
8252
8253 assign(op1, get_gpr_dw0(r1));
8254 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8255 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8256 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8257 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8258 mkexpr(borrow_in)));
8259 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8260 put_gpr_dw0(r1, mkexpr(result));
8261
8262 return "slbg";
8263}
8264
florian55085f82012-11-21 00:36:55 +00008265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008266s390_irgen_SVC(UChar i)
8267{
8268 IRTemp sysno = newTemp(Ity_I64);
8269
8270 if (i != 0) {
8271 assign(sysno, mkU64(i));
8272 } else {
8273 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8274 }
8275 system_call(mkexpr(sysno));
8276
8277 return "svc";
8278}
8279
florian55085f82012-11-21 00:36:55 +00008280static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008281s390_irgen_TM(UChar i2, IRTemp op1addr)
8282{
8283 UChar mask;
8284 IRTemp value = newTemp(Ity_I8);
8285
8286 mask = i2;
8287 assign(value, load(Ity_I8, mkexpr(op1addr)));
8288 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8289 mkU8(mask)));
8290
8291 return "tm";
8292}
8293
florian55085f82012-11-21 00:36:55 +00008294static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008295s390_irgen_TMY(UChar i2, IRTemp op1addr)
8296{
8297 UChar mask;
8298 IRTemp value = newTemp(Ity_I8);
8299
8300 mask = i2;
8301 assign(value, load(Ity_I8, mkexpr(op1addr)));
8302 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8303 mkU8(mask)));
8304
8305 return "tmy";
8306}
8307
florian55085f82012-11-21 00:36:55 +00008308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008309s390_irgen_TMHH(UChar r1, UShort i2)
8310{
8311 UShort mask;
8312 IRTemp value = newTemp(Ity_I16);
8313
8314 mask = i2;
8315 assign(value, get_gpr_hw0(r1));
8316 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8317 mkU16(mask)));
8318
8319 return "tmhh";
8320}
8321
florian55085f82012-11-21 00:36:55 +00008322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008323s390_irgen_TMHL(UChar r1, UShort i2)
8324{
8325 UShort mask;
8326 IRTemp value = newTemp(Ity_I16);
8327
8328 mask = i2;
8329 assign(value, get_gpr_hw1(r1));
8330 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8331 mkU16(mask)));
8332
8333 return "tmhl";
8334}
8335
florian55085f82012-11-21 00:36:55 +00008336static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008337s390_irgen_TMLH(UChar r1, UShort i2)
8338{
8339 UShort mask;
8340 IRTemp value = newTemp(Ity_I16);
8341
8342 mask = i2;
8343 assign(value, get_gpr_hw2(r1));
8344 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8345 mkU16(mask)));
8346
8347 return "tmlh";
8348}
8349
florian55085f82012-11-21 00:36:55 +00008350static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008351s390_irgen_TMLL(UChar r1, UShort i2)
8352{
8353 UShort mask;
8354 IRTemp value = newTemp(Ity_I16);
8355
8356 mask = i2;
8357 assign(value, get_gpr_hw3(r1));
8358 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8359 mkU16(mask)));
8360
8361 return "tmll";
8362}
8363
florian55085f82012-11-21 00:36:55 +00008364static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008365s390_irgen_EFPC(UChar r1)
8366{
8367 put_gpr_w1(r1, get_fpc_w0());
8368
8369 return "efpc";
8370}
8371
florian55085f82012-11-21 00:36:55 +00008372static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008373s390_irgen_LER(UChar r1, UChar r2)
8374{
8375 put_fpr_w0(r1, get_fpr_w0(r2));
8376
8377 return "ler";
8378}
8379
florian55085f82012-11-21 00:36:55 +00008380static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008381s390_irgen_LDR(UChar r1, UChar r2)
8382{
8383 put_fpr_dw0(r1, get_fpr_dw0(r2));
8384
8385 return "ldr";
8386}
8387
florian55085f82012-11-21 00:36:55 +00008388static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008389s390_irgen_LXR(UChar r1, UChar r2)
8390{
8391 put_fpr_dw0(r1, get_fpr_dw0(r2));
8392 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8393
8394 return "lxr";
8395}
8396
florian55085f82012-11-21 00:36:55 +00008397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008398s390_irgen_LE(UChar r1, IRTemp op2addr)
8399{
8400 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8401
8402 return "le";
8403}
8404
florian55085f82012-11-21 00:36:55 +00008405static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008406s390_irgen_LD(UChar r1, IRTemp op2addr)
8407{
8408 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8409
8410 return "ld";
8411}
8412
florian55085f82012-11-21 00:36:55 +00008413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008414s390_irgen_LEY(UChar r1, IRTemp op2addr)
8415{
8416 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8417
8418 return "ley";
8419}
8420
florian55085f82012-11-21 00:36:55 +00008421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008422s390_irgen_LDY(UChar r1, IRTemp op2addr)
8423{
8424 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8425
8426 return "ldy";
8427}
8428
florian55085f82012-11-21 00:36:55 +00008429static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008430s390_irgen_LFPC(IRTemp op2addr)
8431{
8432 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8433
8434 return "lfpc";
8435}
8436
florian55085f82012-11-21 00:36:55 +00008437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008438s390_irgen_LZER(UChar r1)
8439{
8440 put_fpr_w0(r1, mkF32i(0x0));
8441
8442 return "lzer";
8443}
8444
florian55085f82012-11-21 00:36:55 +00008445static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008446s390_irgen_LZDR(UChar r1)
8447{
8448 put_fpr_dw0(r1, mkF64i(0x0));
8449
8450 return "lzdr";
8451}
8452
florian55085f82012-11-21 00:36:55 +00008453static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008454s390_irgen_LZXR(UChar r1)
8455{
8456 put_fpr_dw0(r1, mkF64i(0x0));
8457 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8458
8459 return "lzxr";
8460}
8461
florian55085f82012-11-21 00:36:55 +00008462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008463s390_irgen_SRNM(IRTemp op2addr)
8464{
florianf0fa1be2012-09-18 20:24:38 +00008465 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008466
florianf0fa1be2012-09-18 20:24:38 +00008467 input_mask = 3;
8468 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008469
florianf0fa1be2012-09-18 20:24:38 +00008470 put_fpc_w0(binop(Iop_Or32,
8471 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8472 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8473 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008474 return "srnm";
8475}
8476
florian55085f82012-11-21 00:36:55 +00008477static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008478s390_irgen_SRNMB(IRTemp op2addr)
8479{
8480 UInt input_mask, fpc_mask;
8481
8482 input_mask = 7;
8483 fpc_mask = 7;
8484
8485 put_fpc_w0(binop(Iop_Or32,
8486 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8487 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8488 mkU32(input_mask))));
8489 return "srnmb";
8490}
8491
florian81a4bfe2012-09-20 01:25:28 +00008492static void
florianf0fa1be2012-09-18 20:24:38 +00008493s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8494{
8495 if (b2 == 0) { /* This is the typical case */
8496 if (d2 > 3) {
8497 if (s390_host_has_fpext && d2 == 7) {
8498 /* ok */
8499 } else {
8500 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008501 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008502 }
8503 }
8504 }
8505
8506 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8507}
8508
8509
florian55085f82012-11-21 00:36:55 +00008510static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008511s390_irgen_SFPC(UChar r1)
8512{
8513 put_fpc_w0(get_gpr_w1(r1));
8514
8515 return "sfpc";
8516}
8517
florian55085f82012-11-21 00:36:55 +00008518static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008519s390_irgen_STE(UChar r1, IRTemp op2addr)
8520{
8521 store(mkexpr(op2addr), get_fpr_w0(r1));
8522
8523 return "ste";
8524}
8525
florian55085f82012-11-21 00:36:55 +00008526static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008527s390_irgen_STD(UChar r1, IRTemp op2addr)
8528{
8529 store(mkexpr(op2addr), get_fpr_dw0(r1));
8530
8531 return "std";
8532}
8533
florian55085f82012-11-21 00:36:55 +00008534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008535s390_irgen_STEY(UChar r1, IRTemp op2addr)
8536{
8537 store(mkexpr(op2addr), get_fpr_w0(r1));
8538
8539 return "stey";
8540}
8541
florian55085f82012-11-21 00:36:55 +00008542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008543s390_irgen_STDY(UChar r1, IRTemp op2addr)
8544{
8545 store(mkexpr(op2addr), get_fpr_dw0(r1));
8546
8547 return "stdy";
8548}
8549
florian55085f82012-11-21 00:36:55 +00008550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008551s390_irgen_STFPC(IRTemp op2addr)
8552{
8553 store(mkexpr(op2addr), get_fpc_w0());
8554
8555 return "stfpc";
8556}
8557
florian55085f82012-11-21 00:36:55 +00008558static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008559s390_irgen_AEBR(UChar r1, UChar r2)
8560{
8561 IRTemp op1 = newTemp(Ity_F32);
8562 IRTemp op2 = newTemp(Ity_F32);
8563 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008564 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008565
8566 assign(op1, get_fpr_w0(r1));
8567 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008568 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008569 mkexpr(op2)));
8570 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8571 put_fpr_w0(r1, mkexpr(result));
8572
8573 return "aebr";
8574}
8575
florian55085f82012-11-21 00:36:55 +00008576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008577s390_irgen_ADBR(UChar r1, UChar r2)
8578{
8579 IRTemp op1 = newTemp(Ity_F64);
8580 IRTemp op2 = newTemp(Ity_F64);
8581 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008582 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008583
8584 assign(op1, get_fpr_dw0(r1));
8585 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008586 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008587 mkexpr(op2)));
8588 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8589 put_fpr_dw0(r1, mkexpr(result));
8590
8591 return "adbr";
8592}
8593
florian55085f82012-11-21 00:36:55 +00008594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008595s390_irgen_AEB(UChar r1, IRTemp op2addr)
8596{
8597 IRTemp op1 = newTemp(Ity_F32);
8598 IRTemp op2 = newTemp(Ity_F32);
8599 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008600 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008601
8602 assign(op1, get_fpr_w0(r1));
8603 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008604 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008605 mkexpr(op2)));
8606 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8607 put_fpr_w0(r1, mkexpr(result));
8608
8609 return "aeb";
8610}
8611
florian55085f82012-11-21 00:36:55 +00008612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008613s390_irgen_ADB(UChar r1, IRTemp op2addr)
8614{
8615 IRTemp op1 = newTemp(Ity_F64);
8616 IRTemp op2 = newTemp(Ity_F64);
8617 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008618 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008619
8620 assign(op1, get_fpr_dw0(r1));
8621 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008622 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008623 mkexpr(op2)));
8624 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8625 put_fpr_dw0(r1, mkexpr(result));
8626
8627 return "adb";
8628}
8629
florian55085f82012-11-21 00:36:55 +00008630static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008631s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8632 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008633{
florian125e20d2012-10-07 15:42:37 +00008634 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008635 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008636 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008637 }
sewardj2019a972011-03-07 16:04:07 +00008638 IRTemp op2 = newTemp(Ity_I32);
8639
8640 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008641 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008642 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008643
8644 return "cefbr";
8645}
8646
florian55085f82012-11-21 00:36:55 +00008647static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008648s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8649 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008650{
8651 IRTemp op2 = newTemp(Ity_I32);
8652
8653 assign(op2, get_gpr_w1(r2));
8654 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8655
8656 return "cdfbr";
8657}
8658
florian55085f82012-11-21 00:36:55 +00008659static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008660s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8661 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008662{
florian125e20d2012-10-07 15:42:37 +00008663 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008664 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008665 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008666 }
sewardj2019a972011-03-07 16:04:07 +00008667 IRTemp op2 = newTemp(Ity_I64);
8668
8669 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008670 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008671 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008672
8673 return "cegbr";
8674}
8675
florian55085f82012-11-21 00:36:55 +00008676static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008677s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8678 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008679{
florian125e20d2012-10-07 15:42:37 +00008680 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008681 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008682 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008683 }
sewardj2019a972011-03-07 16:04:07 +00008684 IRTemp op2 = newTemp(Ity_I64);
8685
8686 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008687 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008688 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008689
8690 return "cdgbr";
8691}
8692
florian55085f82012-11-21 00:36:55 +00008693static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008694s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8695 UChar r1, UChar r2)
8696{
floriane75dafa2012-09-01 17:54:09 +00008697 if (! s390_host_has_fpext) {
8698 emulation_failure(EmFail_S390X_fpext);
8699 } else {
8700 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008701
floriane75dafa2012-09-01 17:54:09 +00008702 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008703 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008704 mkexpr(op2)));
8705 }
florian1c8f7ff2012-09-01 00:12:11 +00008706 return "celfbr";
8707}
8708
florian55085f82012-11-21 00:36:55 +00008709static const HChar *
floriand2129202012-09-01 20:01:39 +00008710s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8711 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008712{
floriane75dafa2012-09-01 17:54:09 +00008713 if (! s390_host_has_fpext) {
8714 emulation_failure(EmFail_S390X_fpext);
8715 } else {
8716 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008717
floriane75dafa2012-09-01 17:54:09 +00008718 assign(op2, get_gpr_w1(r2));
8719 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8720 }
florian1c8f7ff2012-09-01 00:12:11 +00008721 return "cdlfbr";
8722}
8723
florian55085f82012-11-21 00:36:55 +00008724static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008725s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8726 UChar r1, UChar r2)
8727{
floriane75dafa2012-09-01 17:54:09 +00008728 if (! s390_host_has_fpext) {
8729 emulation_failure(EmFail_S390X_fpext);
8730 } else {
8731 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008732
floriane75dafa2012-09-01 17:54:09 +00008733 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008734 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008735 mkexpr(op2)));
8736 }
florian1c8f7ff2012-09-01 00:12:11 +00008737 return "celgbr";
8738}
8739
florian55085f82012-11-21 00:36:55 +00008740static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008741s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8742 UChar r1, UChar r2)
8743{
floriane75dafa2012-09-01 17:54:09 +00008744 if (! s390_host_has_fpext) {
8745 emulation_failure(EmFail_S390X_fpext);
8746 } else {
8747 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008748
floriane75dafa2012-09-01 17:54:09 +00008749 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008750 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8751 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008752 mkexpr(op2)));
8753 }
florian1c8f7ff2012-09-01 00:12:11 +00008754 return "cdlgbr";
8755}
8756
florian55085f82012-11-21 00:36:55 +00008757static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008758s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8759 UChar r1, UChar r2)
8760{
floriane75dafa2012-09-01 17:54:09 +00008761 if (! s390_host_has_fpext) {
8762 emulation_failure(EmFail_S390X_fpext);
8763 } else {
8764 IRTemp op = newTemp(Ity_F32);
8765 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008766 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008767
floriane75dafa2012-09-01 17:54:09 +00008768 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008769 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008770 mkexpr(op)));
8771 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008772 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008773 }
florian1c8f7ff2012-09-01 00:12:11 +00008774 return "clfebr";
8775}
8776
florian55085f82012-11-21 00:36:55 +00008777static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008778s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8779 UChar r1, UChar r2)
8780{
floriane75dafa2012-09-01 17:54:09 +00008781 if (! s390_host_has_fpext) {
8782 emulation_failure(EmFail_S390X_fpext);
8783 } else {
8784 IRTemp op = newTemp(Ity_F64);
8785 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008786 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008787
floriane75dafa2012-09-01 17:54:09 +00008788 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008789 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008790 mkexpr(op)));
8791 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008792 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008793 }
florian1c8f7ff2012-09-01 00:12:11 +00008794 return "clfdbr";
8795}
8796
florian55085f82012-11-21 00:36:55 +00008797static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008798s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8799 UChar r1, UChar r2)
8800{
floriane75dafa2012-09-01 17:54:09 +00008801 if (! s390_host_has_fpext) {
8802 emulation_failure(EmFail_S390X_fpext);
8803 } else {
8804 IRTemp op = newTemp(Ity_F32);
8805 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008806 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008807
floriane75dafa2012-09-01 17:54:09 +00008808 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008809 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008810 mkexpr(op)));
8811 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008812 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008813 }
florian1c8f7ff2012-09-01 00:12:11 +00008814 return "clgebr";
8815}
8816
florian55085f82012-11-21 00:36:55 +00008817static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008818s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8819 UChar r1, UChar r2)
8820{
floriane75dafa2012-09-01 17:54:09 +00008821 if (! s390_host_has_fpext) {
8822 emulation_failure(EmFail_S390X_fpext);
8823 } else {
8824 IRTemp op = newTemp(Ity_F64);
8825 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008826 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008827
floriane75dafa2012-09-01 17:54:09 +00008828 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008829 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008830 mkexpr(op)));
8831 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008832 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008833 }
florian1c8f7ff2012-09-01 00:12:11 +00008834 return "clgdbr";
8835}
8836
florian55085f82012-11-21 00:36:55 +00008837static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008838s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8839 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008840{
8841 IRTemp op = newTemp(Ity_F32);
8842 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008843 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008844
8845 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008846 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008847 mkexpr(op)));
8848 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008849 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008850
8851 return "cfebr";
8852}
8853
florian55085f82012-11-21 00:36:55 +00008854static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008855s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8856 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008857{
8858 IRTemp op = newTemp(Ity_F64);
8859 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008860 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008861
8862 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008863 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008864 mkexpr(op)));
8865 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008866 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008867
8868 return "cfdbr";
8869}
8870
florian55085f82012-11-21 00:36:55 +00008871static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008872s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8873 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008874{
8875 IRTemp op = newTemp(Ity_F32);
8876 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008877 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008878
8879 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008880 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008881 mkexpr(op)));
8882 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008883 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008884
8885 return "cgebr";
8886}
8887
florian55085f82012-11-21 00:36:55 +00008888static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008889s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8890 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008891{
8892 IRTemp op = newTemp(Ity_F64);
8893 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008894 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008895
8896 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008897 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008898 mkexpr(op)));
8899 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008900 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008901
8902 return "cgdbr";
8903}
8904
florian55085f82012-11-21 00:36:55 +00008905static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008906s390_irgen_DEBR(UChar r1, UChar r2)
8907{
8908 IRTemp op1 = newTemp(Ity_F32);
8909 IRTemp op2 = newTemp(Ity_F32);
8910 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008911 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008912
8913 assign(op1, get_fpr_w0(r1));
8914 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008915 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008916 mkexpr(op2)));
8917 put_fpr_w0(r1, mkexpr(result));
8918
8919 return "debr";
8920}
8921
florian55085f82012-11-21 00:36:55 +00008922static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008923s390_irgen_DDBR(UChar r1, UChar r2)
8924{
8925 IRTemp op1 = newTemp(Ity_F64);
8926 IRTemp op2 = newTemp(Ity_F64);
8927 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008928 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008929
8930 assign(op1, get_fpr_dw0(r1));
8931 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008932 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008933 mkexpr(op2)));
8934 put_fpr_dw0(r1, mkexpr(result));
8935
8936 return "ddbr";
8937}
8938
florian55085f82012-11-21 00:36:55 +00008939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008940s390_irgen_DEB(UChar r1, IRTemp op2addr)
8941{
8942 IRTemp op1 = newTemp(Ity_F32);
8943 IRTemp op2 = newTemp(Ity_F32);
8944 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008945 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008946
8947 assign(op1, get_fpr_w0(r1));
8948 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008949 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008950 mkexpr(op2)));
8951 put_fpr_w0(r1, mkexpr(result));
8952
8953 return "deb";
8954}
8955
florian55085f82012-11-21 00:36:55 +00008956static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008957s390_irgen_DDB(UChar r1, IRTemp op2addr)
8958{
8959 IRTemp op1 = newTemp(Ity_F64);
8960 IRTemp op2 = newTemp(Ity_F64);
8961 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008962 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008963
8964 assign(op1, get_fpr_dw0(r1));
8965 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008966 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008967 mkexpr(op2)));
8968 put_fpr_dw0(r1, mkexpr(result));
8969
8970 return "ddb";
8971}
8972
florian55085f82012-11-21 00:36:55 +00008973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008974s390_irgen_LTEBR(UChar r1, UChar r2)
8975{
8976 IRTemp result = newTemp(Ity_F32);
8977
8978 assign(result, get_fpr_w0(r2));
8979 put_fpr_w0(r1, mkexpr(result));
8980 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8981
8982 return "ltebr";
8983}
8984
florian55085f82012-11-21 00:36:55 +00008985static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008986s390_irgen_LTDBR(UChar r1, UChar r2)
8987{
8988 IRTemp result = newTemp(Ity_F64);
8989
8990 assign(result, get_fpr_dw0(r2));
8991 put_fpr_dw0(r1, mkexpr(result));
8992 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8993
8994 return "ltdbr";
8995}
8996
florian55085f82012-11-21 00:36:55 +00008997static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008998s390_irgen_LCEBR(UChar r1, UChar r2)
8999{
9000 IRTemp result = newTemp(Ity_F32);
9001
9002 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9003 put_fpr_w0(r1, mkexpr(result));
9004 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9005
9006 return "lcebr";
9007}
9008
florian55085f82012-11-21 00:36:55 +00009009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009010s390_irgen_LCDBR(UChar r1, UChar r2)
9011{
9012 IRTemp result = newTemp(Ity_F64);
9013
9014 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9015 put_fpr_dw0(r1, mkexpr(result));
9016 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9017
9018 return "lcdbr";
9019}
9020
florian55085f82012-11-21 00:36:55 +00009021static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009022s390_irgen_LDEBR(UChar r1, UChar r2)
9023{
9024 IRTemp op = newTemp(Ity_F32);
9025
9026 assign(op, get_fpr_w0(r2));
9027 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9028
9029 return "ldebr";
9030}
9031
florian55085f82012-11-21 00:36:55 +00009032static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009033s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9034{
9035 IRTemp op = newTemp(Ity_F32);
9036
9037 assign(op, load(Ity_F32, mkexpr(op2addr)));
9038 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9039
9040 return "ldeb";
9041}
9042
florian55085f82012-11-21 00:36:55 +00009043static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009044s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9045 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009046{
florian125e20d2012-10-07 15:42:37 +00009047 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009048 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009049 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009050 }
sewardj2019a972011-03-07 16:04:07 +00009051 IRTemp op = newTemp(Ity_F64);
9052
9053 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009054 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009055 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009056
9057 return "ledbr";
9058}
9059
florian55085f82012-11-21 00:36:55 +00009060static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009061s390_irgen_MEEBR(UChar r1, UChar r2)
9062{
9063 IRTemp op1 = newTemp(Ity_F32);
9064 IRTemp op2 = newTemp(Ity_F32);
9065 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009066 IRRoundingMode rounding_mode =
9067 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009068
9069 assign(op1, get_fpr_w0(r1));
9070 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009071 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009072 mkexpr(op2)));
9073 put_fpr_w0(r1, mkexpr(result));
9074
9075 return "meebr";
9076}
9077
florian55085f82012-11-21 00:36:55 +00009078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009079s390_irgen_MDBR(UChar r1, UChar r2)
9080{
9081 IRTemp op1 = newTemp(Ity_F64);
9082 IRTemp op2 = newTemp(Ity_F64);
9083 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009084 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009085
9086 assign(op1, get_fpr_dw0(r1));
9087 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009088 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009089 mkexpr(op2)));
9090 put_fpr_dw0(r1, mkexpr(result));
9091
9092 return "mdbr";
9093}
9094
florian55085f82012-11-21 00:36:55 +00009095static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009096s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9097{
9098 IRTemp op1 = newTemp(Ity_F32);
9099 IRTemp op2 = newTemp(Ity_F32);
9100 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009101 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009102
9103 assign(op1, get_fpr_w0(r1));
9104 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009105 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009106 mkexpr(op2)));
9107 put_fpr_w0(r1, mkexpr(result));
9108
9109 return "meeb";
9110}
9111
florian55085f82012-11-21 00:36:55 +00009112static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009113s390_irgen_MDB(UChar r1, IRTemp op2addr)
9114{
9115 IRTemp op1 = newTemp(Ity_F64);
9116 IRTemp op2 = newTemp(Ity_F64);
9117 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009118 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009119
9120 assign(op1, get_fpr_dw0(r1));
9121 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009122 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009123 mkexpr(op2)));
9124 put_fpr_dw0(r1, mkexpr(result));
9125
9126 return "mdb";
9127}
9128
florian55085f82012-11-21 00:36:55 +00009129static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009130s390_irgen_SEBR(UChar r1, UChar r2)
9131{
9132 IRTemp op1 = newTemp(Ity_F32);
9133 IRTemp op2 = newTemp(Ity_F32);
9134 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009135 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009136
9137 assign(op1, get_fpr_w0(r1));
9138 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009139 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009140 mkexpr(op2)));
9141 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9142 put_fpr_w0(r1, mkexpr(result));
9143
9144 return "sebr";
9145}
9146
florian55085f82012-11-21 00:36:55 +00009147static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009148s390_irgen_SDBR(UChar r1, UChar r2)
9149{
9150 IRTemp op1 = newTemp(Ity_F64);
9151 IRTemp op2 = newTemp(Ity_F64);
9152 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009153 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009154
9155 assign(op1, get_fpr_dw0(r1));
9156 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009157 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009158 mkexpr(op2)));
9159 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9160 put_fpr_dw0(r1, mkexpr(result));
9161
9162 return "sdbr";
9163}
9164
florian55085f82012-11-21 00:36:55 +00009165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009166s390_irgen_SEB(UChar r1, IRTemp op2addr)
9167{
9168 IRTemp op1 = newTemp(Ity_F32);
9169 IRTemp op2 = newTemp(Ity_F32);
9170 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009171 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009172
9173 assign(op1, get_fpr_w0(r1));
9174 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009175 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009176 mkexpr(op2)));
9177 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9178 put_fpr_w0(r1, mkexpr(result));
9179
9180 return "seb";
9181}
9182
florian55085f82012-11-21 00:36:55 +00009183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009184s390_irgen_SDB(UChar r1, IRTemp op2addr)
9185{
9186 IRTemp op1 = newTemp(Ity_F64);
9187 IRTemp op2 = newTemp(Ity_F64);
9188 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009189 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009190
9191 assign(op1, get_fpr_dw0(r1));
9192 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009193 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009194 mkexpr(op2)));
9195 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9196 put_fpr_dw0(r1, mkexpr(result));
9197
9198 return "sdb";
9199}
9200
florian55085f82012-11-21 00:36:55 +00009201static const HChar *
florian12390202012-11-10 22:34:14 +00009202s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9203{
9204 IRTemp op1 = newTemp(Ity_D64);
9205 IRTemp op2 = newTemp(Ity_D64);
9206 IRTemp result = newTemp(Ity_D64);
9207 IRTemp rounding_mode;
9208
9209 vassert(s390_host_has_dfp);
9210 vassert(m4 == 0 || s390_host_has_fpext);
9211 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9212 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9213 rounding_mode = encode_dfp_rounding_mode(m4);
9214 assign(op1, get_dpr_dw0(r2));
9215 assign(op2, get_dpr_dw0(r3));
9216 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9217 mkexpr(op2)));
9218 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9219 put_dpr_dw0(r1, mkexpr(result));
9220
9221 return (m4 == 0) ? "adtr" : "adtra";
9222}
9223
florian55085f82012-11-21 00:36:55 +00009224static const HChar *
floriane38f6412012-12-21 17:32:12 +00009225s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9226{
9227 IRTemp op1 = newTemp(Ity_D128);
9228 IRTemp op2 = newTemp(Ity_D128);
9229 IRTemp result = newTemp(Ity_D128);
9230 IRTemp rounding_mode;
9231
9232 vassert(s390_host_has_dfp);
9233 vassert(m4 == 0 || s390_host_has_fpext);
9234 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9235 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9236 rounding_mode = encode_dfp_rounding_mode(m4);
9237 assign(op1, get_dpr_pair(r2));
9238 assign(op2, get_dpr_pair(r3));
9239 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9240 mkexpr(op2)));
9241 put_dpr_pair(r1, mkexpr(result));
9242
9243 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9244
9245 return (m4 == 0) ? "axtr" : "axtra";
9246}
9247
9248static const HChar *
9249s390_irgen_CDTR(UChar r1, UChar r2)
9250{
9251 IRTemp op1 = newTemp(Ity_D64);
9252 IRTemp op2 = newTemp(Ity_D64);
9253 IRTemp cc_vex = newTemp(Ity_I32);
9254 IRTemp cc_s390 = newTemp(Ity_I32);
9255
9256 assign(op1, get_dpr_dw0(r1));
9257 assign(op2, get_dpr_dw0(r2));
9258 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9259
florian2d3d87f2012-12-21 21:05:17 +00009260 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009261 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9262
9263 return "cdtr";
9264}
9265
9266static const HChar *
9267s390_irgen_CXTR(UChar r1, UChar r2)
9268{
9269 IRTemp op1 = newTemp(Ity_D128);
9270 IRTemp op2 = newTemp(Ity_D128);
9271 IRTemp cc_vex = newTemp(Ity_I32);
9272 IRTemp cc_s390 = newTemp(Ity_I32);
9273
9274 assign(op1, get_dpr_pair(r1));
9275 assign(op2, get_dpr_pair(r2));
9276 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9277
florian2d3d87f2012-12-21 21:05:17 +00009278 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009279 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9280
9281 return "cxtr";
9282}
9283
9284static const HChar *
florian12390202012-11-10 22:34:14 +00009285s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9286{
9287 IRTemp op1 = newTemp(Ity_D64);
9288 IRTemp op2 = newTemp(Ity_D64);
9289 IRTemp result = newTemp(Ity_D64);
9290 IRTemp rounding_mode;
9291
9292 vassert(s390_host_has_dfp);
9293 vassert(m4 == 0 || s390_host_has_fpext);
9294 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9295 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9296 rounding_mode = encode_dfp_rounding_mode(m4);
9297 assign(op1, get_dpr_dw0(r2));
9298 assign(op2, get_dpr_dw0(r3));
9299 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9300 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009301 put_dpr_dw0(r1, mkexpr(result));
9302
9303 return (m4 == 0) ? "ddtr" : "ddtra";
9304}
9305
florian55085f82012-11-21 00:36:55 +00009306static const HChar *
floriane38f6412012-12-21 17:32:12 +00009307s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9308{
9309 IRTemp op1 = newTemp(Ity_D128);
9310 IRTemp op2 = newTemp(Ity_D128);
9311 IRTemp result = newTemp(Ity_D128);
9312 IRTemp rounding_mode;
9313
9314 vassert(s390_host_has_dfp);
9315 vassert(m4 == 0 || s390_host_has_fpext);
9316 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9317 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9318 rounding_mode = encode_dfp_rounding_mode(m4);
9319 assign(op1, get_dpr_pair(r2));
9320 assign(op2, get_dpr_pair(r3));
9321 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9322 mkexpr(op2)));
9323 put_dpr_pair(r1, mkexpr(result));
9324
9325 return (m4 == 0) ? "dxtr" : "dxtra";
9326}
9327
9328static const HChar *
9329s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9330{
9331 IRTemp op = newTemp(Ity_D32);
9332
9333 vassert(s390_host_has_dfp);
9334
9335 assign(op, get_dpr_w0(r2));
9336 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9337
9338 return "ldetr";
9339}
9340
9341static const HChar *
9342s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9343{
9344 IRTemp op = newTemp(Ity_D64);
9345
9346 assign(op, get_dpr_dw0(r2));
9347 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9348
9349 return "lxdtr";
9350}
9351
9352static const HChar *
9353s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9354 UChar r1, UChar r2)
9355{
9356 vassert(s390_host_has_dfp);
9357 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9358 emulation_warning(EmWarn_S390X_fpext_rounding);
9359 m3 = S390_DFP_ROUND_PER_FPC_0;
9360 }
9361 IRTemp result = newTemp(Ity_D64);
9362
9363 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9364 get_dpr_pair(r2)));
9365 put_dpr_dw0(r1, mkexpr(result));
9366
9367 return "ldxtr";
9368}
9369
9370static const HChar *
9371s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9372 UChar r1, UChar r2)
9373{
9374 vassert(s390_host_has_dfp);
9375 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9376 emulation_warning(EmWarn_S390X_fpext_rounding);
9377 m3 = S390_DFP_ROUND_PER_FPC_0;
9378 }
9379 IRTemp op = newTemp(Ity_D64);
9380
9381 assign(op, get_dpr_dw0(r2));
9382 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9383 mkexpr(op)));
9384
9385 return "ledtr";
9386}
9387
9388static const HChar *
9389s390_irgen_LTDTR(UChar r1, UChar r2)
9390{
9391 IRTemp result = newTemp(Ity_D64);
9392
9393 assign(result, get_dpr_dw0(r2));
9394 put_dpr_dw0(r1, mkexpr(result));
9395 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9396
9397 return "ltdtr";
9398}
9399
9400static const HChar *
9401s390_irgen_LTXTR(UChar r1, UChar r2)
9402{
9403 IRTemp result = newTemp(Ity_D128);
9404
9405 assign(result, get_dpr_pair(r2));
9406 put_dpr_pair(r1, mkexpr(result));
9407 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9408
9409 return "ltxtr";
9410}
9411
9412static const HChar *
florian12390202012-11-10 22:34:14 +00009413s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9414{
9415 IRTemp op1 = newTemp(Ity_D64);
9416 IRTemp op2 = newTemp(Ity_D64);
9417 IRTemp result = newTemp(Ity_D64);
9418 IRTemp rounding_mode;
9419
9420 vassert(s390_host_has_dfp);
9421 vassert(m4 == 0 || s390_host_has_fpext);
9422 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9423 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9424 rounding_mode = encode_dfp_rounding_mode(m4);
9425 assign(op1, get_dpr_dw0(r2));
9426 assign(op2, get_dpr_dw0(r3));
9427 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9428 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009429 put_dpr_dw0(r1, mkexpr(result));
9430
9431 return (m4 == 0) ? "mdtr" : "mdtra";
9432}
9433
florian55085f82012-11-21 00:36:55 +00009434static const HChar *
floriane38f6412012-12-21 17:32:12 +00009435s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9436{
9437 IRTemp op1 = newTemp(Ity_D128);
9438 IRTemp op2 = newTemp(Ity_D128);
9439 IRTemp result = newTemp(Ity_D128);
9440 IRTemp rounding_mode;
9441
9442 vassert(s390_host_has_dfp);
9443 vassert(m4 == 0 || s390_host_has_fpext);
9444 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9445 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9446 rounding_mode = encode_dfp_rounding_mode(m4);
9447 assign(op1, get_dpr_pair(r2));
9448 assign(op2, get_dpr_pair(r3));
9449 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9450 mkexpr(op2)));
9451 put_dpr_pair(r1, mkexpr(result));
9452
9453 return (m4 == 0) ? "mxtr" : "mxtra";
9454}
9455
9456static const HChar *
florian12390202012-11-10 22:34:14 +00009457s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9458{
9459 IRTemp op1 = newTemp(Ity_D64);
9460 IRTemp op2 = newTemp(Ity_D64);
9461 IRTemp result = newTemp(Ity_D64);
9462 IRTemp rounding_mode;
9463
9464 vassert(s390_host_has_dfp);
9465 vassert(m4 == 0 || s390_host_has_fpext);
9466 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9467 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9468 rounding_mode = encode_dfp_rounding_mode(m4);
9469 assign(op1, get_dpr_dw0(r2));
9470 assign(op2, get_dpr_dw0(r3));
9471 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9472 mkexpr(op2)));
9473 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9474 put_dpr_dw0(r1, mkexpr(result));
9475
9476 return (m4 == 0) ? "sdtr" : "sdtra";
9477}
9478
floriane38f6412012-12-21 17:32:12 +00009479static const HChar *
9480s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9481{
9482 IRTemp op1 = newTemp(Ity_D128);
9483 IRTemp op2 = newTemp(Ity_D128);
9484 IRTemp result = newTemp(Ity_D128);
9485 IRTemp rounding_mode;
9486
9487 vassert(s390_host_has_dfp);
9488 vassert(m4 == 0 || s390_host_has_fpext);
9489 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9490 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9491 rounding_mode = encode_dfp_rounding_mode(m4);
9492 assign(op1, get_dpr_pair(r2));
9493 assign(op2, get_dpr_pair(r3));
9494 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
9495 mkexpr(op2)));
9496 put_dpr_pair(r1, mkexpr(result));
9497
9498 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9499
9500 return (m4 == 0) ? "sxtr" : "sxtra";
9501}
sewardj2019a972011-03-07 16:04:07 +00009502
florian55085f82012-11-21 00:36:55 +00009503static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009504s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9505{
florian79e839e2012-05-05 02:20:30 +00009506 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009507
florian79e839e2012-05-05 02:20:30 +00009508 assign(len, mkU64(length));
9509 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009510
9511 return "clc";
9512}
9513
florian55085f82012-11-21 00:36:55 +00009514static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009515s390_irgen_CLCL(UChar r1, UChar r2)
9516{
9517 IRTemp addr1 = newTemp(Ity_I64);
9518 IRTemp addr2 = newTemp(Ity_I64);
9519 IRTemp addr1_load = newTemp(Ity_I64);
9520 IRTemp addr2_load = newTemp(Ity_I64);
9521 IRTemp len1 = newTemp(Ity_I32);
9522 IRTemp len2 = newTemp(Ity_I32);
9523 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9524 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9525 IRTemp single1 = newTemp(Ity_I8);
9526 IRTemp single2 = newTemp(Ity_I8);
9527 IRTemp pad = newTemp(Ity_I8);
9528
9529 assign(addr1, get_gpr_dw0(r1));
9530 assign(r1p1, get_gpr_w1(r1 + 1));
9531 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9532 assign(addr2, get_gpr_dw0(r2));
9533 assign(r2p1, get_gpr_w1(r2 + 1));
9534 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9535 assign(pad, get_gpr_b4(r2 + 1));
9536
9537 /* len1 == 0 and len2 == 0? Exit */
9538 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009539 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9540 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009541
9542 /* Because mkite evaluates both the then-clause and the else-clause
9543 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9544 may be NULL and loading from there would segfault. So we provide a
9545 valid dummy address in that case. Loading from there does no harm and
9546 the value will be discarded at runtime. */
9547 assign(addr1_load,
9548 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9549 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9550 assign(single1,
9551 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9552 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9553
9554 assign(addr2_load,
9555 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9556 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9557 assign(single2,
9558 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9559 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9560
9561 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9562 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009563 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009564
9565 /* Update len1 and addr1, unless len1 == 0. */
9566 put_gpr_dw0(r1,
9567 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9568 mkexpr(addr1),
9569 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9570
9571 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9572 put_gpr_w1(r1 + 1,
9573 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9574 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9575 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9576
9577 /* Update len2 and addr2, unless len2 == 0. */
9578 put_gpr_dw0(r2,
9579 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9580 mkexpr(addr2),
9581 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9582
9583 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9584 put_gpr_w1(r2 + 1,
9585 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9586 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9587 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9588
florian6820ba52012-07-26 02:01:50 +00009589 iterate();
florianb0c9a132011-09-08 15:37:39 +00009590
9591 return "clcl";
9592}
9593
florian55085f82012-11-21 00:36:55 +00009594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009595s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9596{
9597 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9598
9599 addr1 = newTemp(Ity_I64);
9600 addr3 = newTemp(Ity_I64);
9601 addr1_load = newTemp(Ity_I64);
9602 addr3_load = newTemp(Ity_I64);
9603 len1 = newTemp(Ity_I64);
9604 len3 = newTemp(Ity_I64);
9605 single1 = newTemp(Ity_I8);
9606 single3 = newTemp(Ity_I8);
9607
9608 assign(addr1, get_gpr_dw0(r1));
9609 assign(len1, get_gpr_dw0(r1 + 1));
9610 assign(addr3, get_gpr_dw0(r3));
9611 assign(len3, get_gpr_dw0(r3 + 1));
9612
9613 /* len1 == 0 and len3 == 0? Exit */
9614 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009615 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9616 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009617
9618 /* A mux requires both ways to be possible. This is a way to prevent clcle
9619 from reading from addr1 if it should read from the pad. Since the pad
9620 has no address, just read from the instruction, we discard that anyway */
9621 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009622 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9623 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009624
9625 /* same for addr3 */
9626 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009627 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9628 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009629
9630 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009631 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9632 unop(Iop_64to8, mkexpr(pad2)),
9633 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009634
9635 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009636 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9637 unop(Iop_64to8, mkexpr(pad2)),
9638 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009639
9640 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9641 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009642 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009643
9644 /* If a length in 0 we must not change this length and the address */
9645 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009646 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9647 mkexpr(addr1),
9648 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009649
9650 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009651 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9652 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009653
9654 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009655 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9656 mkexpr(addr3),
9657 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009658
9659 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009660 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9661 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009662
florian6820ba52012-07-26 02:01:50 +00009663 iterate();
sewardj2019a972011-03-07 16:04:07 +00009664
9665 return "clcle";
9666}
floriana64c2432011-07-16 02:11:50 +00009667
florianb0bf6602012-05-05 00:01:16 +00009668
sewardj2019a972011-03-07 16:04:07 +00009669static void
9670s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9671{
florianb0bf6602012-05-05 00:01:16 +00009672 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9673}
sewardj2019a972011-03-07 16:04:07 +00009674
sewardj2019a972011-03-07 16:04:07 +00009675
florianb0bf6602012-05-05 00:01:16 +00009676static void
9677s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9678{
9679 s390_irgen_xonc(Iop_And8, length, start1, start2);
9680}
sewardj2019a972011-03-07 16:04:07 +00009681
sewardj2019a972011-03-07 16:04:07 +00009682
florianb0bf6602012-05-05 00:01:16 +00009683static void
9684s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9685{
9686 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009687}
9688
9689
9690static void
9691s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9692{
9693 IRTemp current1 = newTemp(Ity_I8);
9694 IRTemp current2 = newTemp(Ity_I8);
9695 IRTemp counter = newTemp(Ity_I64);
9696
9697 assign(counter, get_counter_dw0());
9698 put_counter_dw0(mkU64(0));
9699
9700 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9701 mkexpr(counter))));
9702 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9703 mkexpr(counter))));
9704 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9705 False);
9706
9707 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009708 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009709
9710 /* Check for end of field */
9711 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009712 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009713 put_counter_dw0(mkU64(0));
9714}
9715
9716static void
9717s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9718{
9719 IRTemp counter = newTemp(Ity_I64);
9720
9721 assign(counter, get_counter_dw0());
9722
9723 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9724 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9725
9726 /* Check for end of field */
9727 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009728 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009729 put_counter_dw0(mkU64(0));
9730}
9731
florianf87d4fb2012-05-05 02:55:24 +00009732static void
9733s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9734{
9735 IRTemp op = newTemp(Ity_I8);
9736 IRTemp op1 = newTemp(Ity_I8);
9737 IRTemp result = newTemp(Ity_I64);
9738 IRTemp counter = newTemp(Ity_I64);
9739
9740 assign(counter, get_counter_dw0());
9741
9742 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9743
9744 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9745
9746 assign(op1, load(Ity_I8, mkexpr(result)));
9747 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9748
9749 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009750 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009751 put_counter_dw0(mkU64(0));
9752}
sewardj2019a972011-03-07 16:04:07 +00009753
9754
9755static void
9756s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009757 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +00009758 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +00009759{
9760 struct SS {
9761 unsigned int op : 8;
9762 unsigned int l : 8;
9763 unsigned int b1 : 4;
9764 unsigned int d1 : 12;
9765 unsigned int b2 : 4;
9766 unsigned int d2 : 12;
9767 };
9768 union {
9769 struct SS dec;
9770 unsigned long bytes;
9771 } ss;
9772 IRTemp cond;
9773 IRDirty *d;
9774 IRTemp torun;
9775
9776 IRTemp start1 = newTemp(Ity_I64);
9777 IRTemp start2 = newTemp(Ity_I64);
9778 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9779 cond = newTemp(Ity_I1);
9780 torun = newTemp(Ity_I64);
9781
9782 assign(torun, load(Ity_I64, mkexpr(addr2)));
9783 /* Start with a check that the saved code is still correct */
9784 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9785 /* If not, save the new value */
9786 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9787 mkIRExprVec_1(mkexpr(torun)));
9788 d->guard = mkexpr(cond);
9789 stmt(IRStmt_Dirty(d));
9790
9791 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009792 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9793 mkU64(guest_IA_curr_instr)));
9794 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009795 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009796
9797 ss.bytes = last_execute_target;
9798 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9799 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9800 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9801 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9802 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9803 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9804 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009805
sewardj2019a972011-03-07 16:04:07 +00009806 last_execute_target = 0;
9807}
9808
florian55085f82012-11-21 00:36:55 +00009809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009810s390_irgen_EX(UChar r1, IRTemp addr2)
9811{
9812 switch(last_execute_target & 0xff00000000000000ULL) {
9813 case 0:
9814 {
9815 /* no code information yet */
9816 IRDirty *d;
9817
9818 /* so safe the code... */
9819 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9820 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9821 stmt(IRStmt_Dirty(d));
9822 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009823 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9824 mkU64(guest_IA_curr_instr)));
9825 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009826 restart_if(IRExpr_Const(IRConst_U1(True)));
9827
sewardj2019a972011-03-07 16:04:07 +00009828 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009829 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009830 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009831 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009832 break;
9833 }
9834
9835 case 0xd200000000000000ULL:
9836 /* special case MVC */
9837 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +00009838 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +00009839
9840 case 0xd500000000000000ULL:
9841 /* special case CLC */
9842 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +00009843 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +00009844
9845 case 0xd700000000000000ULL:
9846 /* special case XC */
9847 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009848 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +00009849
florianb0bf6602012-05-05 00:01:16 +00009850 case 0xd600000000000000ULL:
9851 /* special case OC */
9852 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009853 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +00009854
9855 case 0xd400000000000000ULL:
9856 /* special case NC */
9857 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009858 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +00009859
florianf87d4fb2012-05-05 02:55:24 +00009860 case 0xdc00000000000000ULL:
9861 /* special case TR */
9862 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +00009863 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +00009864
sewardj2019a972011-03-07 16:04:07 +00009865 default:
9866 {
9867 /* everything else will get a self checking prefix that also checks the
9868 register content */
9869 IRDirty *d;
9870 UChar *bytes;
9871 IRTemp cond;
9872 IRTemp orperand;
9873 IRTemp torun;
9874
9875 cond = newTemp(Ity_I1);
9876 orperand = newTemp(Ity_I64);
9877 torun = newTemp(Ity_I64);
9878
9879 if (r1 == 0)
9880 assign(orperand, mkU64(0));
9881 else
9882 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9883 /* This code is going to be translated */
9884 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9885 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9886
9887 /* Start with a check that saved code is still correct */
9888 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9889 mkU64(last_execute_target)));
9890 /* If not, save the new value */
9891 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9892 mkIRExprVec_1(mkexpr(torun)));
9893 d->guard = mkexpr(cond);
9894 stmt(IRStmt_Dirty(d));
9895
9896 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009897 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9898 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009899 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009900
9901 /* Now comes the actual translation */
9902 bytes = (UChar *) &last_execute_target;
9903 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9904 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009905 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009906 vex_printf(" which was executed by\n");
9907 /* dont make useless translations in the next execute */
9908 last_execute_target = 0;
9909 }
9910 }
9911 return "ex";
9912}
9913
florian55085f82012-11-21 00:36:55 +00009914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009915s390_irgen_EXRL(UChar r1, UInt offset)
9916{
9917 IRTemp addr = newTemp(Ity_I64);
9918 /* we might save one round trip because we know the target */
9919 if (!last_execute_target)
9920 last_execute_target = *(ULong *)(HWord)
9921 (guest_IA_curr_instr + offset * 2UL);
9922 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9923 s390_irgen_EX(r1, addr);
9924 return "exrl";
9925}
9926
florian55085f82012-11-21 00:36:55 +00009927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009928s390_irgen_IPM(UChar r1)
9929{
9930 // As long as we dont support SPM, lets just assume 0 as program mask
9931 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9932 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9933
9934 return "ipm";
9935}
9936
9937
florian55085f82012-11-21 00:36:55 +00009938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009939s390_irgen_SRST(UChar r1, UChar r2)
9940{
9941 IRTemp address = newTemp(Ity_I64);
9942 IRTemp next = newTemp(Ity_I64);
9943 IRTemp delim = newTemp(Ity_I8);
9944 IRTemp counter = newTemp(Ity_I64);
9945 IRTemp byte = newTemp(Ity_I8);
9946
9947 assign(address, get_gpr_dw0(r2));
9948 assign(next, get_gpr_dw0(r1));
9949
9950 assign(counter, get_counter_dw0());
9951 put_counter_dw0(mkU64(0));
9952
9953 // start = next? CC=2 and out r1 and r2 unchanged
9954 s390_cc_set(2);
9955 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009956 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009957
9958 assign(byte, load(Ity_I8, mkexpr(address)));
9959 assign(delim, get_gpr_b7(0));
9960
9961 // byte = delim? CC=1, R1=address
9962 s390_cc_set(1);
9963 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009964 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009965
9966 // else: all equal, no end yet, loop
9967 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9968 put_gpr_dw0(r1, mkexpr(next));
9969 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009970
florian6820ba52012-07-26 02:01:50 +00009971 iterate();
sewardj2019a972011-03-07 16:04:07 +00009972
9973 return "srst";
9974}
9975
florian55085f82012-11-21 00:36:55 +00009976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009977s390_irgen_CLST(UChar r1, UChar r2)
9978{
9979 IRTemp address1 = newTemp(Ity_I64);
9980 IRTemp address2 = newTemp(Ity_I64);
9981 IRTemp end = newTemp(Ity_I8);
9982 IRTemp counter = newTemp(Ity_I64);
9983 IRTemp byte1 = newTemp(Ity_I8);
9984 IRTemp byte2 = newTemp(Ity_I8);
9985
9986 assign(address1, get_gpr_dw0(r1));
9987 assign(address2, get_gpr_dw0(r2));
9988 assign(end, get_gpr_b7(0));
9989 assign(counter, get_counter_dw0());
9990 put_counter_dw0(mkU64(0));
9991 assign(byte1, load(Ity_I8, mkexpr(address1)));
9992 assign(byte2, load(Ity_I8, mkexpr(address2)));
9993
9994 // end in both? all equal, reset r1 and r2 to start values
9995 s390_cc_set(0);
9996 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9997 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009998 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9999 binop(Iop_Or8,
10000 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10001 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010002
10003 put_gpr_dw0(r1, mkexpr(address1));
10004 put_gpr_dw0(r2, mkexpr(address2));
10005
10006 // End found in string1
10007 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010008 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010009
10010 // End found in string2
10011 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010012 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010013
10014 // string1 < string2
10015 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010016 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10017 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010018
10019 // string2 < string1
10020 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010021 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10022 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010023
10024 // else: all equal, no end yet, loop
10025 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10026 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10027 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010028
florian6820ba52012-07-26 02:01:50 +000010029 iterate();
sewardj2019a972011-03-07 16:04:07 +000010030
10031 return "clst";
10032}
10033
10034static void
10035s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10036{
10037 UChar reg;
10038 IRTemp addr = newTemp(Ity_I64);
10039
10040 assign(addr, mkexpr(op2addr));
10041 reg = r1;
10042 do {
10043 IRTemp old = addr;
10044
10045 reg %= 16;
10046 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10047 addr = newTemp(Ity_I64);
10048 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10049 reg++;
10050 } while (reg != (r3 + 1));
10051}
10052
florian55085f82012-11-21 00:36:55 +000010053static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010054s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10055{
10056 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10057
10058 return "lm";
10059}
10060
florian55085f82012-11-21 00:36:55 +000010061static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010062s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10063{
10064 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10065
10066 return "lmy";
10067}
10068
florian55085f82012-11-21 00:36:55 +000010069static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010070s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10071{
10072 UChar reg;
10073 IRTemp addr = newTemp(Ity_I64);
10074
10075 assign(addr, mkexpr(op2addr));
10076 reg = r1;
10077 do {
10078 IRTemp old = addr;
10079
10080 reg %= 16;
10081 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10082 addr = newTemp(Ity_I64);
10083 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10084 reg++;
10085 } while (reg != (r3 + 1));
10086
10087 return "lmh";
10088}
10089
florian55085f82012-11-21 00:36:55 +000010090static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010091s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10092{
10093 UChar reg;
10094 IRTemp addr = newTemp(Ity_I64);
10095
10096 assign(addr, mkexpr(op2addr));
10097 reg = r1;
10098 do {
10099 IRTemp old = addr;
10100
10101 reg %= 16;
10102 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10103 addr = newTemp(Ity_I64);
10104 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10105 reg++;
10106 } while (reg != (r3 + 1));
10107
10108 return "lmg";
10109}
10110
10111static void
10112s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10113{
10114 UChar reg;
10115 IRTemp addr = newTemp(Ity_I64);
10116
10117 assign(addr, mkexpr(op2addr));
10118 reg = r1;
10119 do {
10120 IRTemp old = addr;
10121
10122 reg %= 16;
10123 store(mkexpr(addr), get_gpr_w1(reg));
10124 addr = newTemp(Ity_I64);
10125 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10126 reg++;
10127 } while( reg != (r3 + 1));
10128}
10129
florian55085f82012-11-21 00:36:55 +000010130static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010131s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10132{
10133 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10134
10135 return "stm";
10136}
10137
florian55085f82012-11-21 00:36:55 +000010138static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010139s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10140{
10141 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10142
10143 return "stmy";
10144}
10145
florian55085f82012-11-21 00:36:55 +000010146static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010147s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10148{
10149 UChar reg;
10150 IRTemp addr = newTemp(Ity_I64);
10151
10152 assign(addr, mkexpr(op2addr));
10153 reg = r1;
10154 do {
10155 IRTemp old = addr;
10156
10157 reg %= 16;
10158 store(mkexpr(addr), get_gpr_w0(reg));
10159 addr = newTemp(Ity_I64);
10160 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10161 reg++;
10162 } while( reg != (r3 + 1));
10163
10164 return "stmh";
10165}
10166
florian55085f82012-11-21 00:36:55 +000010167static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010168s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10169{
10170 UChar reg;
10171 IRTemp addr = newTemp(Ity_I64);
10172
10173 assign(addr, mkexpr(op2addr));
10174 reg = r1;
10175 do {
10176 IRTemp old = addr;
10177
10178 reg %= 16;
10179 store(mkexpr(addr), get_gpr_dw0(reg));
10180 addr = newTemp(Ity_I64);
10181 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10182 reg++;
10183 } while( reg != (r3 + 1));
10184
10185 return "stmg";
10186}
10187
10188static void
florianb0bf6602012-05-05 00:01:16 +000010189s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010190{
10191 IRTemp old1 = newTemp(Ity_I8);
10192 IRTemp old2 = newTemp(Ity_I8);
10193 IRTemp new1 = newTemp(Ity_I8);
10194 IRTemp counter = newTemp(Ity_I32);
10195 IRTemp addr1 = newTemp(Ity_I64);
10196
10197 assign(counter, get_counter_w0());
10198
10199 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10200 unop(Iop_32Uto64, mkexpr(counter))));
10201
10202 assign(old1, load(Ity_I8, mkexpr(addr1)));
10203 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10204 unop(Iop_32Uto64,mkexpr(counter)))));
10205 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10206
10207 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010208 if (op == Iop_Xor8) {
10209 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010210 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10211 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010212 } else
10213 store(mkexpr(addr1), mkexpr(new1));
10214 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10215 get_counter_w1()));
10216
10217 /* Check for end of field */
10218 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010219 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010220 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10221 False);
10222 put_counter_dw0(mkU64(0));
10223}
10224
florian55085f82012-11-21 00:36:55 +000010225static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010226s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10227{
florianb0bf6602012-05-05 00:01:16 +000010228 IRTemp len = newTemp(Ity_I32);
10229
10230 assign(len, mkU32(length));
10231 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010232
10233 return "xc";
10234}
10235
sewardjb63967e2011-03-24 08:50:04 +000010236static void
10237s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10238{
10239 IRTemp counter = newTemp(Ity_I32);
10240 IRTemp start = newTemp(Ity_I64);
10241 IRTemp addr = newTemp(Ity_I64);
10242
10243 assign(start,
10244 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
10245
10246 if (length < 8) {
10247 UInt i;
10248
10249 for (i = 0; i <= length; ++i) {
10250 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
10251 }
10252 } else {
10253 assign(counter, get_counter_w0());
10254
10255 assign(addr, binop(Iop_Add64, mkexpr(start),
10256 unop(Iop_32Uto64, mkexpr(counter))));
10257
10258 store(mkexpr(addr), mkU8(0));
10259
10260 /* Check for end of field */
10261 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010262 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000010263
10264 /* Reset counter */
10265 put_counter_dw0(mkU64(0));
10266 }
10267
10268 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
10269
sewardj7ee97522011-05-09 21:45:04 +000010270 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000010271 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
10272}
10273
florian55085f82012-11-21 00:36:55 +000010274static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010275s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
10276{
florianb0bf6602012-05-05 00:01:16 +000010277 IRTemp len = newTemp(Ity_I32);
10278
10279 assign(len, mkU32(length));
10280 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010281
10282 return "nc";
10283}
10284
florian55085f82012-11-21 00:36:55 +000010285static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010286s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
10287{
florianb0bf6602012-05-05 00:01:16 +000010288 IRTemp len = newTemp(Ity_I32);
10289
10290 assign(len, mkU32(length));
10291 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010292
10293 return "oc";
10294}
10295
10296
florian55085f82012-11-21 00:36:55 +000010297static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010298s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
10299{
florian79e839e2012-05-05 02:20:30 +000010300 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010301
florian79e839e2012-05-05 02:20:30 +000010302 assign(len, mkU64(length));
10303 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010304
10305 return "mvc";
10306}
10307
florian55085f82012-11-21 00:36:55 +000010308static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010309s390_irgen_MVCL(UChar r1, UChar r2)
10310{
10311 IRTemp addr1 = newTemp(Ity_I64);
10312 IRTemp addr2 = newTemp(Ity_I64);
10313 IRTemp addr2_load = newTemp(Ity_I64);
10314 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10315 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10316 IRTemp len1 = newTemp(Ity_I32);
10317 IRTemp len2 = newTemp(Ity_I32);
10318 IRTemp pad = newTemp(Ity_I8);
10319 IRTemp single = newTemp(Ity_I8);
10320
10321 assign(addr1, get_gpr_dw0(r1));
10322 assign(r1p1, get_gpr_w1(r1 + 1));
10323 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10324 assign(addr2, get_gpr_dw0(r2));
10325 assign(r2p1, get_gpr_w1(r2 + 1));
10326 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10327 assign(pad, get_gpr_b4(r2 + 1));
10328
10329 /* len1 == 0 ? */
10330 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010331 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010332
10333 /* Check for destructive overlap:
10334 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10335 s390_cc_set(3);
10336 IRTemp cond1 = newTemp(Ity_I32);
10337 assign(cond1, unop(Iop_1Uto32,
10338 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10339 IRTemp cond2 = newTemp(Ity_I32);
10340 assign(cond2, unop(Iop_1Uto32,
10341 binop(Iop_CmpLT64U, mkexpr(addr1),
10342 binop(Iop_Add64, mkexpr(addr2),
10343 unop(Iop_32Uto64, mkexpr(len1))))));
10344 IRTemp cond3 = newTemp(Ity_I32);
10345 assign(cond3, unop(Iop_1Uto32,
10346 binop(Iop_CmpLT64U,
10347 mkexpr(addr1),
10348 binop(Iop_Add64, mkexpr(addr2),
10349 unop(Iop_32Uto64, mkexpr(len2))))));
10350
florian6820ba52012-07-26 02:01:50 +000010351 next_insn_if(binop(Iop_CmpEQ32,
10352 binop(Iop_And32,
10353 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10354 mkexpr(cond3)),
10355 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010356
10357 /* See s390_irgen_CLCL for explanation why we cannot load directly
10358 and need two steps. */
10359 assign(addr2_load,
10360 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10361 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10362 assign(single,
10363 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10364 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10365
10366 store(mkexpr(addr1), mkexpr(single));
10367
10368 /* Update addr1 and len1 */
10369 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10370 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10371
10372 /* Update addr2 and len2 */
10373 put_gpr_dw0(r2,
10374 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10375 mkexpr(addr2),
10376 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10377
10378 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10379 put_gpr_w1(r2 + 1,
10380 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10381 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10382 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10383
10384 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010385 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010386
10387 return "mvcl";
10388}
10389
10390
florian55085f82012-11-21 00:36:55 +000010391static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010392s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10393{
10394 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10395
10396 addr1 = newTemp(Ity_I64);
10397 addr3 = newTemp(Ity_I64);
10398 addr3_load = newTemp(Ity_I64);
10399 len1 = newTemp(Ity_I64);
10400 len3 = newTemp(Ity_I64);
10401 single = newTemp(Ity_I8);
10402
10403 assign(addr1, get_gpr_dw0(r1));
10404 assign(len1, get_gpr_dw0(r1 + 1));
10405 assign(addr3, get_gpr_dw0(r3));
10406 assign(len3, get_gpr_dw0(r3 + 1));
10407
10408 // len1 == 0 ?
10409 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010410 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010411
10412 /* This is a hack to prevent mvcle from reading from addr3 if it
10413 should read from the pad. Since the pad has no address, just
10414 read from the instruction, we discard that anyway */
10415 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010416 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10417 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010418
10419 assign(single,
florian6ad49522011-09-09 02:38:55 +000010420 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10421 unop(Iop_64to8, mkexpr(pad2)),
10422 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010423 store(mkexpr(addr1), mkexpr(single));
10424
10425 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10426
10427 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10428
10429 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010430 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10431 mkexpr(addr3),
10432 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010433
10434 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010435 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10436 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010437
sewardj2019a972011-03-07 16:04:07 +000010438 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010439 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010440
10441 return "mvcle";
10442}
10443
florian55085f82012-11-21 00:36:55 +000010444static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010445s390_irgen_MVST(UChar r1, UChar r2)
10446{
10447 IRTemp addr1 = newTemp(Ity_I64);
10448 IRTemp addr2 = newTemp(Ity_I64);
10449 IRTemp end = newTemp(Ity_I8);
10450 IRTemp byte = newTemp(Ity_I8);
10451 IRTemp counter = newTemp(Ity_I64);
10452
10453 assign(addr1, get_gpr_dw0(r1));
10454 assign(addr2, get_gpr_dw0(r2));
10455 assign(counter, get_counter_dw0());
10456 assign(end, get_gpr_b7(0));
10457 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10458 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10459
10460 // We use unlimited as cpu-determined number
10461 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010462 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010463
10464 // and always set cc=1 at the end + update r1
10465 s390_cc_set(1);
10466 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10467 put_counter_dw0(mkU64(0));
10468
10469 return "mvst";
10470}
10471
10472static void
10473s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10474{
10475 IRTemp op1 = newTemp(Ity_I64);
10476 IRTemp result = newTemp(Ity_I64);
10477
10478 assign(op1, binop(Iop_32HLto64,
10479 get_gpr_w1(r1), // high 32 bits
10480 get_gpr_w1(r1 + 1))); // low 32 bits
10481 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10482 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10483 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10484}
10485
10486static void
10487s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10488{
10489 IRTemp op1 = newTemp(Ity_I128);
10490 IRTemp result = newTemp(Ity_I128);
10491
10492 assign(op1, binop(Iop_64HLto128,
10493 get_gpr_dw0(r1), // high 64 bits
10494 get_gpr_dw0(r1 + 1))); // low 64 bits
10495 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10496 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10497 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10498}
10499
10500static void
10501s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10502{
10503 IRTemp op1 = newTemp(Ity_I64);
10504 IRTemp result = newTemp(Ity_I128);
10505
10506 assign(op1, get_gpr_dw0(r1 + 1));
10507 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10508 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10509 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10510}
10511
florian55085f82012-11-21 00:36:55 +000010512static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010513s390_irgen_DR(UChar r1, UChar r2)
10514{
10515 IRTemp op2 = newTemp(Ity_I32);
10516
10517 assign(op2, get_gpr_w1(r2));
10518
10519 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10520
10521 return "dr";
10522}
10523
florian55085f82012-11-21 00:36:55 +000010524static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010525s390_irgen_D(UChar r1, IRTemp op2addr)
10526{
10527 IRTemp op2 = newTemp(Ity_I32);
10528
10529 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10530
10531 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10532
10533 return "d";
10534}
10535
florian55085f82012-11-21 00:36:55 +000010536static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010537s390_irgen_DLR(UChar r1, UChar r2)
10538{
10539 IRTemp op2 = newTemp(Ity_I32);
10540
10541 assign(op2, get_gpr_w1(r2));
10542
10543 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10544
florian7cd1cde2012-08-16 23:57:43 +000010545 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010546}
10547
florian55085f82012-11-21 00:36:55 +000010548static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010549s390_irgen_DL(UChar r1, IRTemp op2addr)
10550{
10551 IRTemp op2 = newTemp(Ity_I32);
10552
10553 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10554
10555 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10556
10557 return "dl";
10558}
10559
florian55085f82012-11-21 00:36:55 +000010560static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010561s390_irgen_DLG(UChar r1, IRTemp op2addr)
10562{
10563 IRTemp op2 = newTemp(Ity_I64);
10564
10565 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10566
10567 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10568
10569 return "dlg";
10570}
10571
florian55085f82012-11-21 00:36:55 +000010572static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010573s390_irgen_DLGR(UChar r1, UChar r2)
10574{
10575 IRTemp op2 = newTemp(Ity_I64);
10576
10577 assign(op2, get_gpr_dw0(r2));
10578
10579 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10580
10581 return "dlgr";
10582}
10583
florian55085f82012-11-21 00:36:55 +000010584static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010585s390_irgen_DSGR(UChar r1, UChar r2)
10586{
10587 IRTemp op2 = newTemp(Ity_I64);
10588
10589 assign(op2, get_gpr_dw0(r2));
10590
10591 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10592
10593 return "dsgr";
10594}
10595
florian55085f82012-11-21 00:36:55 +000010596static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010597s390_irgen_DSG(UChar r1, IRTemp op2addr)
10598{
10599 IRTemp op2 = newTemp(Ity_I64);
10600
10601 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10602
10603 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10604
10605 return "dsg";
10606}
10607
florian55085f82012-11-21 00:36:55 +000010608static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010609s390_irgen_DSGFR(UChar r1, UChar r2)
10610{
10611 IRTemp op2 = newTemp(Ity_I64);
10612
10613 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10614
10615 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10616
10617 return "dsgfr";
10618}
10619
florian55085f82012-11-21 00:36:55 +000010620static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010621s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10622{
10623 IRTemp op2 = newTemp(Ity_I64);
10624
10625 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10626
10627 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10628
10629 return "dsgf";
10630}
10631
10632static void
10633s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10634{
10635 UChar reg;
10636 IRTemp addr = newTemp(Ity_I64);
10637
10638 assign(addr, mkexpr(op2addr));
10639 reg = r1;
10640 do {
10641 IRTemp old = addr;
10642
10643 reg %= 16;
10644 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10645 addr = newTemp(Ity_I64);
10646 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10647 reg++;
10648 } while (reg != (r3 + 1));
10649}
10650
florian55085f82012-11-21 00:36:55 +000010651static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010652s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10653{
10654 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10655
10656 return "lam";
10657}
10658
florian55085f82012-11-21 00:36:55 +000010659static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010660s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10661{
10662 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10663
10664 return "lamy";
10665}
10666
10667static void
10668s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10669{
10670 UChar reg;
10671 IRTemp addr = newTemp(Ity_I64);
10672
10673 assign(addr, mkexpr(op2addr));
10674 reg = r1;
10675 do {
10676 IRTemp old = addr;
10677
10678 reg %= 16;
10679 store(mkexpr(addr), get_ar_w0(reg));
10680 addr = newTemp(Ity_I64);
10681 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10682 reg++;
10683 } while (reg != (r3 + 1));
10684}
10685
florian55085f82012-11-21 00:36:55 +000010686static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010687s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10688{
10689 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10690
10691 return "stam";
10692}
10693
florian55085f82012-11-21 00:36:55 +000010694static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010695s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10696{
10697 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10698
10699 return "stamy";
10700}
10701
10702
10703/* Implementation for 32-bit compare-and-swap */
10704static void
10705s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10706{
10707 IRCAS *cas;
10708 IRTemp op1 = newTemp(Ity_I32);
10709 IRTemp old_mem = newTemp(Ity_I32);
10710 IRTemp op3 = newTemp(Ity_I32);
10711 IRTemp result = newTemp(Ity_I32);
10712 IRTemp nequal = newTemp(Ity_I1);
10713
10714 assign(op1, get_gpr_w1(r1));
10715 assign(op3, get_gpr_w1(r3));
10716
10717 /* The first and second operands are compared. If they are equal,
10718 the third operand is stored at the second- operand location. */
10719 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10720 Iend_BE, mkexpr(op2addr),
10721 NULL, mkexpr(op1), /* expected value */
10722 NULL, mkexpr(op3) /* new value */);
10723 stmt(IRStmt_CAS(cas));
10724
10725 /* Set CC. Operands compared equal -> 0, else 1. */
10726 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10727 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10728
10729 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10730 Otherwise, store the old_value from memory in r1 and yield. */
10731 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10732 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010733 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010734}
10735
florian55085f82012-11-21 00:36:55 +000010736static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010737s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10738{
10739 s390_irgen_cas_32(r1, r3, op2addr);
10740
10741 return "cs";
10742}
10743
florian55085f82012-11-21 00:36:55 +000010744static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010745s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10746{
10747 s390_irgen_cas_32(r1, r3, op2addr);
10748
10749 return "csy";
10750}
10751
florian55085f82012-11-21 00:36:55 +000010752static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010753s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10754{
10755 IRCAS *cas;
10756 IRTemp op1 = newTemp(Ity_I64);
10757 IRTemp old_mem = newTemp(Ity_I64);
10758 IRTemp op3 = newTemp(Ity_I64);
10759 IRTemp result = newTemp(Ity_I64);
10760 IRTemp nequal = newTemp(Ity_I1);
10761
10762 assign(op1, get_gpr_dw0(r1));
10763 assign(op3, get_gpr_dw0(r3));
10764
10765 /* The first and second operands are compared. If they are equal,
10766 the third operand is stored at the second- operand location. */
10767 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10768 Iend_BE, mkexpr(op2addr),
10769 NULL, mkexpr(op1), /* expected value */
10770 NULL, mkexpr(op3) /* new value */);
10771 stmt(IRStmt_CAS(cas));
10772
10773 /* Set CC. Operands compared equal -> 0, else 1. */
10774 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10775 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10776
10777 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10778 Otherwise, store the old_value from memory in r1 and yield. */
10779 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10780 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010781 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010782
10783 return "csg";
10784}
10785
florian448cbba2012-06-06 02:26:01 +000010786/* Implementation for 32-bit compare-double-and-swap */
10787static void
10788s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10789{
10790 IRCAS *cas;
10791 IRTemp op1_high = newTemp(Ity_I32);
10792 IRTemp op1_low = newTemp(Ity_I32);
10793 IRTemp old_mem_high = newTemp(Ity_I32);
10794 IRTemp old_mem_low = newTemp(Ity_I32);
10795 IRTemp op3_high = newTemp(Ity_I32);
10796 IRTemp op3_low = newTemp(Ity_I32);
10797 IRTemp result = newTemp(Ity_I32);
10798 IRTemp nequal = newTemp(Ity_I1);
10799
10800 assign(op1_high, get_gpr_w1(r1));
10801 assign(op1_low, get_gpr_w1(r1+1));
10802 assign(op3_high, get_gpr_w1(r3));
10803 assign(op3_low, get_gpr_w1(r3+1));
10804
10805 /* The first and second operands are compared. If they are equal,
10806 the third operand is stored at the second-operand location. */
10807 cas = mkIRCAS(old_mem_high, old_mem_low,
10808 Iend_BE, mkexpr(op2addr),
10809 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10810 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10811 stmt(IRStmt_CAS(cas));
10812
10813 /* Set CC. Operands compared equal -> 0, else 1. */
10814 assign(result, unop(Iop_1Uto32,
10815 binop(Iop_CmpNE32,
10816 binop(Iop_Or32,
10817 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10818 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10819 mkU32(0))));
10820
10821 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10822
10823 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10824 Otherwise, store the old_value from memory in r1 and yield. */
10825 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10826 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10827 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010828 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010829}
10830
florian55085f82012-11-21 00:36:55 +000010831static const HChar *
florian448cbba2012-06-06 02:26:01 +000010832s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10833{
10834 s390_irgen_cdas_32(r1, r3, op2addr);
10835
10836 return "cds";
10837}
10838
florian55085f82012-11-21 00:36:55 +000010839static const HChar *
florian448cbba2012-06-06 02:26:01 +000010840s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10841{
10842 s390_irgen_cdas_32(r1, r3, op2addr);
10843
10844 return "cdsy";
10845}
10846
florian55085f82012-11-21 00:36:55 +000010847static const HChar *
florian448cbba2012-06-06 02:26:01 +000010848s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10849{
10850 IRCAS *cas;
10851 IRTemp op1_high = newTemp(Ity_I64);
10852 IRTemp op1_low = newTemp(Ity_I64);
10853 IRTemp old_mem_high = newTemp(Ity_I64);
10854 IRTemp old_mem_low = newTemp(Ity_I64);
10855 IRTemp op3_high = newTemp(Ity_I64);
10856 IRTemp op3_low = newTemp(Ity_I64);
10857 IRTemp result = newTemp(Ity_I64);
10858 IRTemp nequal = newTemp(Ity_I1);
10859
10860 assign(op1_high, get_gpr_dw0(r1));
10861 assign(op1_low, get_gpr_dw0(r1+1));
10862 assign(op3_high, get_gpr_dw0(r3));
10863 assign(op3_low, get_gpr_dw0(r3+1));
10864
10865 /* The first and second operands are compared. If they are equal,
10866 the third operand is stored at the second-operand location. */
10867 cas = mkIRCAS(old_mem_high, old_mem_low,
10868 Iend_BE, mkexpr(op2addr),
10869 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10870 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10871 stmt(IRStmt_CAS(cas));
10872
10873 /* Set CC. Operands compared equal -> 0, else 1. */
10874 assign(result, unop(Iop_1Uto64,
10875 binop(Iop_CmpNE64,
10876 binop(Iop_Or64,
10877 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10878 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10879 mkU64(0))));
10880
10881 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10882
10883 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10884 Otherwise, store the old_value from memory in r1 and yield. */
10885 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10886 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10887 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010888 yield_if(mkexpr(nequal));
10889
florian448cbba2012-06-06 02:26:01 +000010890 return "cdsg";
10891}
10892
sewardj2019a972011-03-07 16:04:07 +000010893
10894/* Binary floating point */
10895
florian55085f82012-11-21 00:36:55 +000010896static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010897s390_irgen_AXBR(UChar r1, UChar r2)
10898{
10899 IRTemp op1 = newTemp(Ity_F128);
10900 IRTemp op2 = newTemp(Ity_F128);
10901 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010902 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010903
10904 assign(op1, get_fpr_pair(r1));
10905 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010906 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010907 mkexpr(op2)));
10908 put_fpr_pair(r1, mkexpr(result));
10909
10910 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10911
10912 return "axbr";
10913}
10914
florian55085f82012-11-21 00:36:55 +000010915static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010916s390_irgen_CEBR(UChar r1, UChar r2)
10917{
10918 IRTemp op1 = newTemp(Ity_F32);
10919 IRTemp op2 = newTemp(Ity_F32);
10920 IRTemp cc_vex = newTemp(Ity_I32);
10921 IRTemp cc_s390 = newTemp(Ity_I32);
10922
10923 assign(op1, get_fpr_w0(r1));
10924 assign(op2, get_fpr_w0(r2));
10925 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10926
florian2d3d87f2012-12-21 21:05:17 +000010927 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010928 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10929
10930 return "cebr";
10931}
10932
florian55085f82012-11-21 00:36:55 +000010933static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010934s390_irgen_CDBR(UChar r1, UChar r2)
10935{
10936 IRTemp op1 = newTemp(Ity_F64);
10937 IRTemp op2 = newTemp(Ity_F64);
10938 IRTemp cc_vex = newTemp(Ity_I32);
10939 IRTemp cc_s390 = newTemp(Ity_I32);
10940
10941 assign(op1, get_fpr_dw0(r1));
10942 assign(op2, get_fpr_dw0(r2));
10943 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10944
florian2d3d87f2012-12-21 21:05:17 +000010945 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010946 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10947
10948 return "cdbr";
10949}
10950
florian55085f82012-11-21 00:36:55 +000010951static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010952s390_irgen_CXBR(UChar r1, UChar r2)
10953{
10954 IRTemp op1 = newTemp(Ity_F128);
10955 IRTemp op2 = newTemp(Ity_F128);
10956 IRTemp cc_vex = newTemp(Ity_I32);
10957 IRTemp cc_s390 = newTemp(Ity_I32);
10958
10959 assign(op1, get_fpr_pair(r1));
10960 assign(op2, get_fpr_pair(r2));
10961 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10962
florian2d3d87f2012-12-21 21:05:17 +000010963 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010964 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10965
10966 return "cxbr";
10967}
10968
florian55085f82012-11-21 00:36:55 +000010969static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010970s390_irgen_CEB(UChar r1, IRTemp op2addr)
10971{
10972 IRTemp op1 = newTemp(Ity_F32);
10973 IRTemp op2 = newTemp(Ity_F32);
10974 IRTemp cc_vex = newTemp(Ity_I32);
10975 IRTemp cc_s390 = newTemp(Ity_I32);
10976
10977 assign(op1, get_fpr_w0(r1));
10978 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10979 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10980
florian2d3d87f2012-12-21 21:05:17 +000010981 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010982 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10983
10984 return "ceb";
10985}
10986
florian55085f82012-11-21 00:36:55 +000010987static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010988s390_irgen_CDB(UChar r1, IRTemp op2addr)
10989{
10990 IRTemp op1 = newTemp(Ity_F64);
10991 IRTemp op2 = newTemp(Ity_F64);
10992 IRTemp cc_vex = newTemp(Ity_I32);
10993 IRTemp cc_s390 = newTemp(Ity_I32);
10994
10995 assign(op1, get_fpr_dw0(r1));
10996 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10997 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10998
florian2d3d87f2012-12-21 21:05:17 +000010999 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011000 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11001
11002 return "cdb";
11003}
11004
florian55085f82012-11-21 00:36:55 +000011005static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011006s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11007 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011008{
11009 IRTemp op2 = newTemp(Ity_I32);
11010
11011 assign(op2, get_gpr_w1(r2));
11012 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11013
11014 return "cxfbr";
11015}
11016
florian55085f82012-11-21 00:36:55 +000011017static const HChar *
floriand2129202012-09-01 20:01:39 +000011018s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11019 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011020{
floriane75dafa2012-09-01 17:54:09 +000011021 if (! s390_host_has_fpext) {
11022 emulation_failure(EmFail_S390X_fpext);
11023 } else {
11024 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011025
floriane75dafa2012-09-01 17:54:09 +000011026 assign(op2, get_gpr_w1(r2));
11027 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11028 }
florian1c8f7ff2012-09-01 00:12:11 +000011029 return "cxlfbr";
11030}
11031
11032
florian55085f82012-11-21 00:36:55 +000011033static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011034s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11035 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011036{
11037 IRTemp op2 = newTemp(Ity_I64);
11038
11039 assign(op2, get_gpr_dw0(r2));
11040 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11041
11042 return "cxgbr";
11043}
11044
florian55085f82012-11-21 00:36:55 +000011045static const HChar *
floriand2129202012-09-01 20:01:39 +000011046s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11047 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011048{
floriane75dafa2012-09-01 17:54:09 +000011049 if (! s390_host_has_fpext) {
11050 emulation_failure(EmFail_S390X_fpext);
11051 } else {
11052 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011053
floriane75dafa2012-09-01 17:54:09 +000011054 assign(op2, get_gpr_dw0(r2));
11055 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11056 }
florian1c8f7ff2012-09-01 00:12:11 +000011057 return "cxlgbr";
11058}
11059
florian55085f82012-11-21 00:36:55 +000011060static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011061s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11062 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011063{
11064 IRTemp op = newTemp(Ity_F128);
11065 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011066 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011067
11068 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011069 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011070 mkexpr(op)));
11071 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011072 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011073
11074 return "cfxbr";
11075}
11076
florian55085f82012-11-21 00:36:55 +000011077static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011078s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11079 UChar r1, UChar r2)
11080{
floriane75dafa2012-09-01 17:54:09 +000011081 if (! s390_host_has_fpext) {
11082 emulation_failure(EmFail_S390X_fpext);
11083 } else {
11084 IRTemp op = newTemp(Ity_F128);
11085 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011086 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011087
floriane75dafa2012-09-01 17:54:09 +000011088 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011089 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011090 mkexpr(op)));
11091 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011092 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011093 }
florian1c8f7ff2012-09-01 00:12:11 +000011094 return "clfxbr";
11095}
11096
11097
florian55085f82012-11-21 00:36:55 +000011098static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011099s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11100 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011101{
11102 IRTemp op = newTemp(Ity_F128);
11103 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011104 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011105
11106 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011107 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011108 mkexpr(op)));
11109 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011110 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011111
11112 return "cgxbr";
11113}
11114
florian55085f82012-11-21 00:36:55 +000011115static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011116s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11117 UChar r1, UChar r2)
11118{
floriane75dafa2012-09-01 17:54:09 +000011119 if (! s390_host_has_fpext) {
11120 emulation_failure(EmFail_S390X_fpext);
11121 } else {
11122 IRTemp op = newTemp(Ity_F128);
11123 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011124 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011125
floriane75dafa2012-09-01 17:54:09 +000011126 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011127 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011128 mkexpr(op)));
11129 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011130 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11131 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011132 }
florian1c8f7ff2012-09-01 00:12:11 +000011133 return "clgxbr";
11134}
11135
florian55085f82012-11-21 00:36:55 +000011136static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011137s390_irgen_DXBR(UChar r1, UChar r2)
11138{
11139 IRTemp op1 = newTemp(Ity_F128);
11140 IRTemp op2 = newTemp(Ity_F128);
11141 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011142 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011143
11144 assign(op1, get_fpr_pair(r1));
11145 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011146 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011147 mkexpr(op2)));
11148 put_fpr_pair(r1, mkexpr(result));
11149
11150 return "dxbr";
11151}
11152
florian55085f82012-11-21 00:36:55 +000011153static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011154s390_irgen_LTXBR(UChar r1, UChar r2)
11155{
11156 IRTemp result = newTemp(Ity_F128);
11157
11158 assign(result, get_fpr_pair(r2));
11159 put_fpr_pair(r1, mkexpr(result));
11160 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11161
11162 return "ltxbr";
11163}
11164
florian55085f82012-11-21 00:36:55 +000011165static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011166s390_irgen_LCXBR(UChar r1, UChar r2)
11167{
11168 IRTemp result = newTemp(Ity_F128);
11169
11170 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11171 put_fpr_pair(r1, mkexpr(result));
11172 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11173
11174 return "lcxbr";
11175}
11176
florian55085f82012-11-21 00:36:55 +000011177static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011178s390_irgen_LXDBR(UChar r1, UChar r2)
11179{
11180 IRTemp op = newTemp(Ity_F64);
11181
11182 assign(op, get_fpr_dw0(r2));
11183 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11184
11185 return "lxdbr";
11186}
11187
florian55085f82012-11-21 00:36:55 +000011188static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011189s390_irgen_LXEBR(UChar r1, UChar r2)
11190{
11191 IRTemp op = newTemp(Ity_F32);
11192
11193 assign(op, get_fpr_w0(r2));
11194 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11195
11196 return "lxebr";
11197}
11198
florian55085f82012-11-21 00:36:55 +000011199static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011200s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11201{
11202 IRTemp op = newTemp(Ity_F64);
11203
11204 assign(op, load(Ity_F64, mkexpr(op2addr)));
11205 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11206
11207 return "lxdb";
11208}
11209
florian55085f82012-11-21 00:36:55 +000011210static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011211s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11212{
11213 IRTemp op = newTemp(Ity_F32);
11214
11215 assign(op, load(Ity_F32, mkexpr(op2addr)));
11216 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11217
11218 return "lxeb";
11219}
11220
florian55085f82012-11-21 00:36:55 +000011221static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011222s390_irgen_LNEBR(UChar r1, UChar r2)
11223{
11224 IRTemp result = newTemp(Ity_F32);
11225
11226 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11227 put_fpr_w0(r1, mkexpr(result));
11228 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11229
11230 return "lnebr";
11231}
11232
florian55085f82012-11-21 00:36:55 +000011233static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011234s390_irgen_LNDBR(UChar r1, UChar r2)
11235{
11236 IRTemp result = newTemp(Ity_F64);
11237
11238 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11239 put_fpr_dw0(r1, mkexpr(result));
11240 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11241
11242 return "lndbr";
11243}
11244
florian55085f82012-11-21 00:36:55 +000011245static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011246s390_irgen_LNXBR(UChar r1, UChar r2)
11247{
11248 IRTemp result = newTemp(Ity_F128);
11249
11250 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
11251 put_fpr_pair(r1, mkexpr(result));
11252 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11253
11254 return "lnxbr";
11255}
11256
florian55085f82012-11-21 00:36:55 +000011257static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011258s390_irgen_LPEBR(UChar r1, UChar r2)
11259{
11260 IRTemp result = newTemp(Ity_F32);
11261
11262 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
11263 put_fpr_w0(r1, mkexpr(result));
11264 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11265
11266 return "lpebr";
11267}
11268
florian55085f82012-11-21 00:36:55 +000011269static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011270s390_irgen_LPDBR(UChar r1, UChar r2)
11271{
11272 IRTemp result = newTemp(Ity_F64);
11273
11274 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11275 put_fpr_dw0(r1, mkexpr(result));
11276 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11277
11278 return "lpdbr";
11279}
11280
florian55085f82012-11-21 00:36:55 +000011281static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011282s390_irgen_LPXBR(UChar r1, UChar r2)
11283{
11284 IRTemp result = newTemp(Ity_F128);
11285
11286 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11287 put_fpr_pair(r1, mkexpr(result));
11288 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11289
11290 return "lpxbr";
11291}
11292
florian55085f82012-11-21 00:36:55 +000011293static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011294s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11295 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011296{
florian125e20d2012-10-07 15:42:37 +000011297 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011298 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011299 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011300 }
sewardj2019a972011-03-07 16:04:07 +000011301 IRTemp result = newTemp(Ity_F64);
11302
floriandb4fcaa2012-09-05 19:54:08 +000011303 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011304 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011305 put_fpr_dw0(r1, mkexpr(result));
11306
11307 return "ldxbr";
11308}
11309
florian55085f82012-11-21 00:36:55 +000011310static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011311s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11312 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011313{
florian125e20d2012-10-07 15:42:37 +000011314 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011315 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011316 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011317 }
sewardj2019a972011-03-07 16:04:07 +000011318 IRTemp result = newTemp(Ity_F32);
11319
floriandb4fcaa2012-09-05 19:54:08 +000011320 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011321 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011322 put_fpr_w0(r1, mkexpr(result));
11323
11324 return "lexbr";
11325}
11326
florian55085f82012-11-21 00:36:55 +000011327static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011328s390_irgen_MXBR(UChar r1, UChar r2)
11329{
11330 IRTemp op1 = newTemp(Ity_F128);
11331 IRTemp op2 = newTemp(Ity_F128);
11332 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011333 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011334
11335 assign(op1, get_fpr_pair(r1));
11336 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011337 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011338 mkexpr(op2)));
11339 put_fpr_pair(r1, mkexpr(result));
11340
11341 return "mxbr";
11342}
11343
florian55085f82012-11-21 00:36:55 +000011344static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011345s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11346{
florian125e20d2012-10-07 15:42:37 +000011347 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011348
floriandb4fcaa2012-09-05 19:54:08 +000011349 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011350 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011351
11352 return "maebr";
11353}
11354
florian55085f82012-11-21 00:36:55 +000011355static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011356s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11357{
florian125e20d2012-10-07 15:42:37 +000011358 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011359
floriandb4fcaa2012-09-05 19:54:08 +000011360 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011361 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011362
11363 return "madbr";
11364}
11365
florian55085f82012-11-21 00:36:55 +000011366static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011367s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11368{
11369 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011370 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011371
floriandb4fcaa2012-09-05 19:54:08 +000011372 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011373 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011374
11375 return "maeb";
11376}
11377
florian55085f82012-11-21 00:36:55 +000011378static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011379s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11380{
11381 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011382 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011383
floriandb4fcaa2012-09-05 19:54:08 +000011384 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011385 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011386
11387 return "madb";
11388}
11389
florian55085f82012-11-21 00:36:55 +000011390static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011391s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11392{
florian125e20d2012-10-07 15:42:37 +000011393 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011394
floriandb4fcaa2012-09-05 19:54:08 +000011395 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011396 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011397
11398 return "msebr";
11399}
11400
florian55085f82012-11-21 00:36:55 +000011401static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011402s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11403{
florian125e20d2012-10-07 15:42:37 +000011404 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011405
floriandb4fcaa2012-09-05 19:54:08 +000011406 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011407 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011408
11409 return "msdbr";
11410}
11411
florian55085f82012-11-21 00:36:55 +000011412static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011413s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11414{
11415 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011416 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011417
floriandb4fcaa2012-09-05 19:54:08 +000011418 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011419 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011420
11421 return "mseb";
11422}
11423
florian55085f82012-11-21 00:36:55 +000011424static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011425s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11426{
11427 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011428 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011429
floriandb4fcaa2012-09-05 19:54:08 +000011430 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011431 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011432
11433 return "msdb";
11434}
11435
florian55085f82012-11-21 00:36:55 +000011436static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011437s390_irgen_SQEBR(UChar r1, UChar r2)
11438{
11439 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011440 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011441
floriandb4fcaa2012-09-05 19:54:08 +000011442 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011443 put_fpr_w0(r1, mkexpr(result));
11444
11445 return "sqebr";
11446}
11447
florian55085f82012-11-21 00:36:55 +000011448static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011449s390_irgen_SQDBR(UChar r1, UChar r2)
11450{
11451 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011452 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011453
floriandb4fcaa2012-09-05 19:54:08 +000011454 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011455 put_fpr_dw0(r1, mkexpr(result));
11456
11457 return "sqdbr";
11458}
11459
florian55085f82012-11-21 00:36:55 +000011460static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011461s390_irgen_SQXBR(UChar r1, UChar r2)
11462{
11463 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011464 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011465
floriandb4fcaa2012-09-05 19:54:08 +000011466 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11467 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011468 put_fpr_pair(r1, mkexpr(result));
11469
11470 return "sqxbr";
11471}
11472
florian55085f82012-11-21 00:36:55 +000011473static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011474s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11475{
11476 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011477 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011478
11479 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011480 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011481
11482 return "sqeb";
11483}
11484
florian55085f82012-11-21 00:36:55 +000011485static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011486s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11487{
11488 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011489 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011490
11491 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011492 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011493
11494 return "sqdb";
11495}
11496
florian55085f82012-11-21 00:36:55 +000011497static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011498s390_irgen_SXBR(UChar r1, UChar r2)
11499{
11500 IRTemp op1 = newTemp(Ity_F128);
11501 IRTemp op2 = newTemp(Ity_F128);
11502 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011503 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011504
11505 assign(op1, get_fpr_pair(r1));
11506 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011507 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011508 mkexpr(op2)));
11509 put_fpr_pair(r1, mkexpr(result));
11510 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11511
11512 return "sxbr";
11513}
11514
florian55085f82012-11-21 00:36:55 +000011515static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011516s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11517{
11518 IRTemp value = newTemp(Ity_F32);
11519
11520 assign(value, get_fpr_w0(r1));
11521
11522 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11523
11524 return "tceb";
11525}
11526
florian55085f82012-11-21 00:36:55 +000011527static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011528s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11529{
11530 IRTemp value = newTemp(Ity_F64);
11531
11532 assign(value, get_fpr_dw0(r1));
11533
11534 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11535
11536 return "tcdb";
11537}
11538
florian55085f82012-11-21 00:36:55 +000011539static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011540s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11541{
11542 IRTemp value = newTemp(Ity_F128);
11543
11544 assign(value, get_fpr_pair(r1));
11545
11546 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11547
11548 return "tcxb";
11549}
11550
florian55085f82012-11-21 00:36:55 +000011551static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011552s390_irgen_LCDFR(UChar r1, UChar r2)
11553{
11554 IRTemp result = newTemp(Ity_F64);
11555
11556 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11557 put_fpr_dw0(r1, mkexpr(result));
11558
11559 return "lcdfr";
11560}
11561
florian55085f82012-11-21 00:36:55 +000011562static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011563s390_irgen_LNDFR(UChar r1, UChar r2)
11564{
11565 IRTemp result = newTemp(Ity_F64);
11566
11567 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11568 put_fpr_dw0(r1, mkexpr(result));
11569
11570 return "lndfr";
11571}
11572
florian55085f82012-11-21 00:36:55 +000011573static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011574s390_irgen_LPDFR(UChar r1, UChar r2)
11575{
11576 IRTemp result = newTemp(Ity_F64);
11577
11578 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11579 put_fpr_dw0(r1, mkexpr(result));
11580
11581 return "lpdfr";
11582}
11583
florian55085f82012-11-21 00:36:55 +000011584static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011585s390_irgen_LDGR(UChar r1, UChar r2)
11586{
11587 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11588
11589 return "ldgr";
11590}
11591
florian55085f82012-11-21 00:36:55 +000011592static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011593s390_irgen_LGDR(UChar r1, UChar r2)
11594{
11595 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11596
11597 return "lgdr";
11598}
11599
11600
florian55085f82012-11-21 00:36:55 +000011601static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011602s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11603{
11604 IRTemp sign = newTemp(Ity_I64);
11605 IRTemp value = newTemp(Ity_I64);
11606
11607 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11608 mkU64(1ULL << 63)));
11609 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11610 mkU64((1ULL << 63) - 1)));
11611 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11612 mkexpr(sign))));
11613
11614 return "cpsdr";
11615}
11616
11617
sewardj2019a972011-03-07 16:04:07 +000011618static IRExpr *
11619s390_call_cvb(IRExpr *in)
11620{
11621 IRExpr **args, *call;
11622
11623 args = mkIRExprVec_1(in);
11624 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11625 "s390_do_cvb", &s390_do_cvb, args);
11626
11627 /* Nothing is excluded from definedness checking. */
11628 call->Iex.CCall.cee->mcx_mask = 0;
11629
11630 return call;
11631}
11632
florian55085f82012-11-21 00:36:55 +000011633static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011634s390_irgen_CVB(UChar r1, IRTemp op2addr)
11635{
11636 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11637
11638 return "cvb";
11639}
11640
florian55085f82012-11-21 00:36:55 +000011641static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011642s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11643{
11644 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11645
11646 return "cvby";
11647}
11648
11649
sewardj2019a972011-03-07 16:04:07 +000011650static IRExpr *
11651s390_call_cvd(IRExpr *in)
11652{
11653 IRExpr **args, *call;
11654
11655 args = mkIRExprVec_1(in);
11656 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11657 "s390_do_cvd", &s390_do_cvd, args);
11658
11659 /* Nothing is excluded from definedness checking. */
11660 call->Iex.CCall.cee->mcx_mask = 0;
11661
11662 return call;
11663}
11664
florian55085f82012-11-21 00:36:55 +000011665static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011666s390_irgen_CVD(UChar r1, IRTemp op2addr)
11667{
florian11b8ee82012-08-06 13:35:33 +000011668 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011669
11670 return "cvd";
11671}
11672
florian55085f82012-11-21 00:36:55 +000011673static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011674s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11675{
11676 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11677
11678 return "cvdy";
11679}
11680
florian55085f82012-11-21 00:36:55 +000011681static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011682s390_irgen_FLOGR(UChar r1, UChar r2)
11683{
11684 IRTemp input = newTemp(Ity_I64);
11685 IRTemp not_zero = newTemp(Ity_I64);
11686 IRTemp tmpnum = newTemp(Ity_I64);
11687 IRTemp num = newTemp(Ity_I64);
11688 IRTemp shift_amount = newTemp(Ity_I8);
11689
11690 /* We use the "count leading zeroes" operator because the number of
11691 leading zeroes is identical with the bit position of the first '1' bit.
11692 However, that operator does not work when the input value is zero.
11693 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11694 the modified value. If input == 0, then the result is 64. Otherwise,
11695 the result of Clz64 is what we want. */
11696
11697 assign(input, get_gpr_dw0(r2));
11698 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11699 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11700
11701 /* num = (input == 0) ? 64 : tmpnum */
11702 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11703 /* == 0 */ mkU64(64),
11704 /* != 0 */ mkexpr(tmpnum)));
11705
11706 put_gpr_dw0(r1, mkexpr(num));
11707
11708 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11709 is to first shift the input value by NUM + 1 bits to the left which
11710 causes the leftmost '1' bit to disappear. Then we shift logically to
11711 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11712 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11713 the width of the value-to-be-shifted, we need to special case
11714 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11715 For both such INPUT values the result will be 0. */
11716
11717 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11718 mkU64(1))));
11719
11720 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011721 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11722 /* == 0 || == 1*/ mkU64(0),
11723 /* otherwise */
11724 binop(Iop_Shr64,
11725 binop(Iop_Shl64, mkexpr(input),
11726 mkexpr(shift_amount)),
11727 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011728
11729 /* Compare the original value as an unsigned integer with 0. */
11730 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11731 mktemp(Ity_I64, mkU64(0)), False);
11732
11733 return "flogr";
11734}
11735
florian55085f82012-11-21 00:36:55 +000011736static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011737s390_irgen_STCK(IRTemp op2addr)
11738{
11739 IRDirty *d;
11740 IRTemp cc = newTemp(Ity_I64);
11741
11742 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11743 &s390x_dirtyhelper_STCK,
11744 mkIRExprVec_1(mkexpr(op2addr)));
11745 d->mFx = Ifx_Write;
11746 d->mAddr = mkexpr(op2addr);
11747 d->mSize = 8;
11748 stmt(IRStmt_Dirty(d));
11749 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11750 mkexpr(cc), mkU64(0), mkU64(0));
11751 return "stck";
11752}
11753
florian55085f82012-11-21 00:36:55 +000011754static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011755s390_irgen_STCKF(IRTemp op2addr)
11756{
florianc5c669b2012-08-26 14:32:28 +000011757 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011758 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011759 } else {
11760 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011761
florianc5c669b2012-08-26 14:32:28 +000011762 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11763 &s390x_dirtyhelper_STCKF,
11764 mkIRExprVec_1(mkexpr(op2addr)));
11765 d->mFx = Ifx_Write;
11766 d->mAddr = mkexpr(op2addr);
11767 d->mSize = 8;
11768 stmt(IRStmt_Dirty(d));
11769 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11770 mkexpr(cc), mkU64(0), mkU64(0));
11771 }
sewardj1e5fea62011-05-17 16:18:36 +000011772 return "stckf";
11773}
11774
florian55085f82012-11-21 00:36:55 +000011775static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011776s390_irgen_STCKE(IRTemp op2addr)
11777{
11778 IRDirty *d;
11779 IRTemp cc = newTemp(Ity_I64);
11780
11781 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11782 &s390x_dirtyhelper_STCKE,
11783 mkIRExprVec_1(mkexpr(op2addr)));
11784 d->mFx = Ifx_Write;
11785 d->mAddr = mkexpr(op2addr);
11786 d->mSize = 16;
11787 stmt(IRStmt_Dirty(d));
11788 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11789 mkexpr(cc), mkU64(0), mkU64(0));
11790 return "stcke";
11791}
11792
florian55085f82012-11-21 00:36:55 +000011793static const HChar *
florian933065d2011-07-11 01:48:02 +000011794s390_irgen_STFLE(IRTemp op2addr)
11795{
florian4e0083e2012-08-26 03:41:56 +000011796 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011797 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011798 return "stfle";
11799 }
11800
florian933065d2011-07-11 01:48:02 +000011801 IRDirty *d;
11802 IRTemp cc = newTemp(Ity_I64);
11803
11804 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11805 &s390x_dirtyhelper_STFLE,
11806 mkIRExprVec_1(mkexpr(op2addr)));
11807
11808 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11809
sewardjc9069f22012-06-01 16:09:50 +000011810 d->nFxState = 1;
11811 vex_bzero(&d->fxState, sizeof(d->fxState));
11812
florian933065d2011-07-11 01:48:02 +000011813 d->fxState[0].fx = Ifx_Modify; /* read then write */
11814 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11815 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011816
11817 d->mAddr = mkexpr(op2addr);
11818 /* Pretend all double words are written */
11819 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11820 d->mFx = Ifx_Write;
11821
11822 stmt(IRStmt_Dirty(d));
11823
11824 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11825
11826 return "stfle";
11827}
11828
florian55085f82012-11-21 00:36:55 +000011829static const HChar *
floriana4384a32011-08-11 16:58:45 +000011830s390_irgen_CKSM(UChar r1,UChar r2)
11831{
11832 IRTemp addr = newTemp(Ity_I64);
11833 IRTemp op = newTemp(Ity_I32);
11834 IRTemp len = newTemp(Ity_I64);
11835 IRTemp oldval = newTemp(Ity_I32);
11836 IRTemp mask = newTemp(Ity_I32);
11837 IRTemp newop = newTemp(Ity_I32);
11838 IRTemp result = newTemp(Ity_I32);
11839 IRTemp result1 = newTemp(Ity_I32);
11840 IRTemp inc = newTemp(Ity_I64);
11841
11842 assign(oldval, get_gpr_w1(r1));
11843 assign(addr, get_gpr_dw0(r2));
11844 assign(len, get_gpr_dw0(r2+1));
11845
11846 /* Condition code is always zero. */
11847 s390_cc_set(0);
11848
11849 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011850 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011851
11852 /* Assiging the increment variable to adjust address and length
11853 later on. */
11854 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11855 mkexpr(len), mkU64(4)));
11856
11857 /* If length < 4 the final 4-byte 2nd operand value is computed by
11858 appending the remaining bytes to the right with 0. This is done
11859 by AND'ing the 4 bytes loaded from memory with an appropriate
11860 mask. If length >= 4, that mask is simply 0xffffffff. */
11861
11862 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11863 /* Mask computation when len < 4:
11864 0xffffffff << (32 - (len % 4)*8) */
11865 binop(Iop_Shl32, mkU32(0xffffffff),
11866 unop(Iop_32to8,
11867 binop(Iop_Sub32, mkU32(32),
11868 binop(Iop_Shl32,
11869 unop(Iop_64to32,
11870 binop(Iop_And64,
11871 mkexpr(len), mkU64(3))),
11872 mkU8(3))))),
11873 mkU32(0xffffffff)));
11874
11875 assign(op, load(Ity_I32, mkexpr(addr)));
11876 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11877 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11878
11879 /* Checking for carry */
11880 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11881 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11882 mkexpr(result)));
11883
11884 put_gpr_w1(r1, mkexpr(result1));
11885 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11886 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11887
florian6820ba52012-07-26 02:01:50 +000011888 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011889
11890 return "cksm";
11891}
11892
florian55085f82012-11-21 00:36:55 +000011893static const HChar *
florian9af37692012-01-15 21:01:16 +000011894s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11895{
11896 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11897 src_addr = newTemp(Ity_I64);
11898 des_addr = newTemp(Ity_I64);
11899 tab_addr = newTemp(Ity_I64);
11900 test_byte = newTemp(Ity_I8);
11901 src_len = newTemp(Ity_I64);
11902
11903 assign(src_addr, get_gpr_dw0(r2));
11904 assign(des_addr, get_gpr_dw0(r1));
11905 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011906 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011907 assign(test_byte, get_gpr_b7(0));
11908
11909 IRTemp op = newTemp(Ity_I8);
11910 IRTemp op1 = newTemp(Ity_I8);
11911 IRTemp result = newTemp(Ity_I64);
11912
11913 /* End of source string? We're done; proceed to next insn */
11914 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011915 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011916
11917 /* Load character from source string, index translation table and
11918 store translated character in op1. */
11919 assign(op, load(Ity_I8, mkexpr(src_addr)));
11920
11921 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11922 mkexpr(tab_addr)));
11923 assign(op1, load(Ity_I8, mkexpr(result)));
11924
11925 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11926 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011927 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011928 }
11929 store(get_gpr_dw0(r1), mkexpr(op1));
11930
11931 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11932 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11933 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11934
florian6820ba52012-07-26 02:01:50 +000011935 iterate();
florian9af37692012-01-15 21:01:16 +000011936
11937 return "troo";
11938}
11939
florian55085f82012-11-21 00:36:55 +000011940static const HChar *
florian730448f2012-02-04 17:07:07 +000011941s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11942{
11943 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11944 src_addr = newTemp(Ity_I64);
11945 des_addr = newTemp(Ity_I64);
11946 tab_addr = newTemp(Ity_I64);
11947 test_byte = newTemp(Ity_I8);
11948 src_len = newTemp(Ity_I64);
11949
11950 assign(src_addr, get_gpr_dw0(r2));
11951 assign(des_addr, get_gpr_dw0(r1));
11952 assign(tab_addr, get_gpr_dw0(1));
11953 assign(src_len, get_gpr_dw0(r1+1));
11954 assign(test_byte, get_gpr_b7(0));
11955
11956 IRTemp op = newTemp(Ity_I16);
11957 IRTemp op1 = newTemp(Ity_I8);
11958 IRTemp result = newTemp(Ity_I64);
11959
11960 /* End of source string? We're done; proceed to next insn */
11961 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011962 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011963
11964 /* Load character from source string, index translation table and
11965 store translated character in op1. */
11966 assign(op, load(Ity_I16, mkexpr(src_addr)));
11967
11968 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11969 mkexpr(tab_addr)));
11970
11971 assign(op1, load(Ity_I8, mkexpr(result)));
11972
11973 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11974 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011975 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011976 }
11977 store(get_gpr_dw0(r1), mkexpr(op1));
11978
11979 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11980 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11981 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11982
florian6820ba52012-07-26 02:01:50 +000011983 iterate();
florian730448f2012-02-04 17:07:07 +000011984
11985 return "trto";
11986}
11987
florian55085f82012-11-21 00:36:55 +000011988static const HChar *
florian730448f2012-02-04 17:07:07 +000011989s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11990{
11991 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11992 src_addr = newTemp(Ity_I64);
11993 des_addr = newTemp(Ity_I64);
11994 tab_addr = newTemp(Ity_I64);
11995 test_byte = newTemp(Ity_I16);
11996 src_len = newTemp(Ity_I64);
11997
11998 assign(src_addr, get_gpr_dw0(r2));
11999 assign(des_addr, get_gpr_dw0(r1));
12000 assign(tab_addr, get_gpr_dw0(1));
12001 assign(src_len, get_gpr_dw0(r1+1));
12002 assign(test_byte, get_gpr_hw3(0));
12003
12004 IRTemp op = newTemp(Ity_I8);
12005 IRTemp op1 = newTemp(Ity_I16);
12006 IRTemp result = newTemp(Ity_I64);
12007
12008 /* End of source string? We're done; proceed to next insn */
12009 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012010 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012011
12012 /* Load character from source string, index translation table and
12013 store translated character in op1. */
12014 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12015
12016 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12017 mkexpr(tab_addr)));
12018 assign(op1, load(Ity_I16, mkexpr(result)));
12019
12020 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12021 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012022 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012023 }
12024 store(get_gpr_dw0(r1), mkexpr(op1));
12025
12026 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12027 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12028 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12029
florian6820ba52012-07-26 02:01:50 +000012030 iterate();
florian730448f2012-02-04 17:07:07 +000012031
12032 return "trot";
12033}
12034
florian55085f82012-11-21 00:36:55 +000012035static const HChar *
florian730448f2012-02-04 17:07:07 +000012036s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12037{
12038 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12039 src_addr = newTemp(Ity_I64);
12040 des_addr = newTemp(Ity_I64);
12041 tab_addr = newTemp(Ity_I64);
12042 test_byte = newTemp(Ity_I16);
12043 src_len = newTemp(Ity_I64);
12044
12045 assign(src_addr, get_gpr_dw0(r2));
12046 assign(des_addr, get_gpr_dw0(r1));
12047 assign(tab_addr, get_gpr_dw0(1));
12048 assign(src_len, get_gpr_dw0(r1+1));
12049 assign(test_byte, get_gpr_hw3(0));
12050
12051 IRTemp op = newTemp(Ity_I16);
12052 IRTemp op1 = newTemp(Ity_I16);
12053 IRTemp result = newTemp(Ity_I64);
12054
12055 /* End of source string? We're done; proceed to next insn */
12056 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012057 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012058
12059 /* Load character from source string, index translation table and
12060 store translated character in op1. */
12061 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12062
12063 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12064 mkexpr(tab_addr)));
12065 assign(op1, load(Ity_I16, mkexpr(result)));
12066
12067 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12068 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012069 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012070 }
12071
12072 store(get_gpr_dw0(r1), mkexpr(op1));
12073
12074 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12075 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12076 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12077
florian6820ba52012-07-26 02:01:50 +000012078 iterate();
florian730448f2012-02-04 17:07:07 +000012079
12080 return "trtt";
12081}
12082
florian55085f82012-11-21 00:36:55 +000012083static const HChar *
florian730448f2012-02-04 17:07:07 +000012084s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12085{
florianf87d4fb2012-05-05 02:55:24 +000012086 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012087
florianf87d4fb2012-05-05 02:55:24 +000012088 assign(len, mkU64(length));
12089 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012090
12091 return "tr";
12092}
12093
florian55085f82012-11-21 00:36:55 +000012094static const HChar *
florian730448f2012-02-04 17:07:07 +000012095s390_irgen_TRE(UChar r1,UChar r2)
12096{
12097 IRTemp src_addr, tab_addr, src_len, test_byte;
12098 src_addr = newTemp(Ity_I64);
12099 tab_addr = newTemp(Ity_I64);
12100 src_len = newTemp(Ity_I64);
12101 test_byte = newTemp(Ity_I8);
12102
12103 assign(src_addr, get_gpr_dw0(r1));
12104 assign(src_len, get_gpr_dw0(r1+1));
12105 assign(tab_addr, get_gpr_dw0(r2));
12106 assign(test_byte, get_gpr_b7(0));
12107
12108 IRTemp op = newTemp(Ity_I8);
12109 IRTemp op1 = newTemp(Ity_I8);
12110 IRTemp result = newTemp(Ity_I64);
12111
12112 /* End of source string? We're done; proceed to next insn */
12113 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012114 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012115
12116 /* Load character from source string and compare with test byte */
12117 assign(op, load(Ity_I8, mkexpr(src_addr)));
12118
12119 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012120 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012121
12122 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12123 mkexpr(tab_addr)));
12124
12125 assign(op1, load(Ity_I8, mkexpr(result)));
12126
12127 store(get_gpr_dw0(r1), mkexpr(op1));
12128 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12129 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12130
florian6820ba52012-07-26 02:01:50 +000012131 iterate();
florian730448f2012-02-04 17:07:07 +000012132
12133 return "tre";
12134}
12135
floriana0100c92012-07-20 00:06:35 +000012136static IRExpr *
12137s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12138{
12139 IRExpr **args, *call;
12140 args = mkIRExprVec_2(srcval, low_surrogate);
12141 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12142 "s390_do_cu21", &s390_do_cu21, args);
12143
12144 /* Nothing is excluded from definedness checking. */
12145 call->Iex.CCall.cee->mcx_mask = 0;
12146
12147 return call;
12148}
12149
florian55085f82012-11-21 00:36:55 +000012150static const HChar *
floriana0100c92012-07-20 00:06:35 +000012151s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12152{
12153 IRTemp addr1 = newTemp(Ity_I64);
12154 IRTemp addr2 = newTemp(Ity_I64);
12155 IRTemp len1 = newTemp(Ity_I64);
12156 IRTemp len2 = newTemp(Ity_I64);
12157
12158 assign(addr1, get_gpr_dw0(r1));
12159 assign(addr2, get_gpr_dw0(r2));
12160 assign(len1, get_gpr_dw0(r1 + 1));
12161 assign(len2, get_gpr_dw0(r2 + 1));
12162
12163 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12164 there are less than 2 bytes left, then the 2nd operand is exhausted
12165 and we're done here. cc = 0 */
12166 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012167 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012168
12169 /* There are at least two bytes there. Read them. */
12170 IRTemp srcval = newTemp(Ity_I32);
12171 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12172
12173 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12174 inside the interval [0xd800 - 0xdbff] */
12175 IRTemp is_high_surrogate = newTemp(Ity_I32);
12176 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12177 mkU32(1), mkU32(0));
12178 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12179 mkU32(1), mkU32(0));
12180 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12181
12182 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12183 then the 2nd operand is exhausted and we're done here. cc = 0 */
12184 IRExpr *not_enough_bytes =
12185 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12186
florian6820ba52012-07-26 02:01:50 +000012187 next_insn_if(binop(Iop_CmpEQ32,
12188 binop(Iop_And32, mkexpr(is_high_surrogate),
12189 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012190
12191 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12192 surrogate, read the next two bytes (low surrogate). */
12193 IRTemp low_surrogate = newTemp(Ity_I32);
12194 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12195
12196 assign(low_surrogate,
12197 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12198 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12199 mkU32(0))); // any value is fine; it will not be used
12200
12201 /* Call the helper */
12202 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012203 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12204 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012205
12206 /* Before we can test whether the 1st operand is exhausted we need to
12207 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12208 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12209 IRExpr *invalid_low_surrogate =
12210 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12211
12212 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012213 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012214 }
12215
12216 /* Now test whether the 1st operand is exhausted */
12217 IRTemp num_bytes = newTemp(Ity_I64);
12218 assign(num_bytes, binop(Iop_And64,
12219 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12220 mkU64(0xff)));
12221 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012222 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012223
12224 /* Extract the bytes to be stored at addr1 */
12225 IRTemp data = newTemp(Ity_I64);
12226 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12227
12228 /* To store the bytes construct 4 dirty helper calls. The helper calls
12229 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12230 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012231 UInt i;
floriana0100c92012-07-20 00:06:35 +000012232 for (i = 1; i <= 4; ++i) {
12233 IRDirty *d;
12234
12235 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12236 &s390x_dirtyhelper_CUxy,
12237 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12238 mkexpr(num_bytes)));
12239 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12240 d->mFx = Ifx_Write;
12241 d->mAddr = mkexpr(addr1);
12242 d->mSize = i;
12243 stmt(IRStmt_Dirty(d));
12244 }
12245
12246 /* Update source address and length */
12247 IRTemp num_src_bytes = newTemp(Ity_I64);
12248 assign(num_src_bytes,
12249 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12250 mkU64(4), mkU64(2)));
12251 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12252 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12253
12254 /* Update destination address and length */
12255 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12256 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12257
florian6820ba52012-07-26 02:01:50 +000012258 iterate();
floriana0100c92012-07-20 00:06:35 +000012259
12260 return "cu21";
12261}
12262
florian2a415a12012-07-21 17:41:36 +000012263static IRExpr *
12264s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
12265{
12266 IRExpr **args, *call;
12267 args = mkIRExprVec_2(srcval, low_surrogate);
12268 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12269 "s390_do_cu24", &s390_do_cu24, args);
12270
12271 /* Nothing is excluded from definedness checking. */
12272 call->Iex.CCall.cee->mcx_mask = 0;
12273
12274 return call;
12275}
12276
florian55085f82012-11-21 00:36:55 +000012277static const HChar *
florian2a415a12012-07-21 17:41:36 +000012278s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
12279{
12280 IRTemp addr1 = newTemp(Ity_I64);
12281 IRTemp addr2 = newTemp(Ity_I64);
12282 IRTemp len1 = newTemp(Ity_I64);
12283 IRTemp len2 = newTemp(Ity_I64);
12284
12285 assign(addr1, get_gpr_dw0(r1));
12286 assign(addr2, get_gpr_dw0(r2));
12287 assign(len1, get_gpr_dw0(r1 + 1));
12288 assign(len2, get_gpr_dw0(r2 + 1));
12289
12290 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12291 there are less than 2 bytes left, then the 2nd operand is exhausted
12292 and we're done here. cc = 0 */
12293 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012294 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012295
12296 /* There are at least two bytes there. Read them. */
12297 IRTemp srcval = newTemp(Ity_I32);
12298 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12299
12300 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12301 inside the interval [0xd800 - 0xdbff] */
12302 IRTemp is_high_surrogate = newTemp(Ity_I32);
12303 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12304 mkU32(1), mkU32(0));
12305 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12306 mkU32(1), mkU32(0));
12307 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12308
12309 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12310 then the 2nd operand is exhausted and we're done here. cc = 0 */
12311 IRExpr *not_enough_bytes =
12312 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12313
florian6820ba52012-07-26 02:01:50 +000012314 next_insn_if(binop(Iop_CmpEQ32,
12315 binop(Iop_And32, mkexpr(is_high_surrogate),
12316 not_enough_bytes),
12317 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012318
12319 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12320 surrogate, read the next two bytes (low surrogate). */
12321 IRTemp low_surrogate = newTemp(Ity_I32);
12322 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12323
12324 assign(low_surrogate,
12325 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12326 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12327 mkU32(0))); // any value is fine; it will not be used
12328
12329 /* Call the helper */
12330 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012331 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12332 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012333
12334 /* Before we can test whether the 1st operand is exhausted we need to
12335 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12336 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12337 IRExpr *invalid_low_surrogate =
12338 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12339
12340 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012341 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012342 }
12343
12344 /* Now test whether the 1st operand is exhausted */
12345 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012346 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012347
12348 /* Extract the bytes to be stored at addr1 */
12349 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12350
12351 store(mkexpr(addr1), data);
12352
12353 /* Update source address and length */
12354 IRTemp num_src_bytes = newTemp(Ity_I64);
12355 assign(num_src_bytes,
12356 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12357 mkU64(4), mkU64(2)));
12358 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12359 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12360
12361 /* Update destination address and length */
12362 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12363 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12364
florian6820ba52012-07-26 02:01:50 +000012365 iterate();
florian2a415a12012-07-21 17:41:36 +000012366
12367 return "cu24";
12368}
floriana4384a32011-08-11 16:58:45 +000012369
florian956194b2012-07-28 22:18:32 +000012370static IRExpr *
12371s390_call_cu42(IRExpr *srcval)
12372{
12373 IRExpr **args, *call;
12374 args = mkIRExprVec_1(srcval);
12375 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12376 "s390_do_cu42", &s390_do_cu42, args);
12377
12378 /* Nothing is excluded from definedness checking. */
12379 call->Iex.CCall.cee->mcx_mask = 0;
12380
12381 return call;
12382}
12383
florian55085f82012-11-21 00:36:55 +000012384static const HChar *
florian956194b2012-07-28 22:18:32 +000012385s390_irgen_CU42(UChar r1, UChar r2)
12386{
12387 IRTemp addr1 = newTemp(Ity_I64);
12388 IRTemp addr2 = newTemp(Ity_I64);
12389 IRTemp len1 = newTemp(Ity_I64);
12390 IRTemp len2 = newTemp(Ity_I64);
12391
12392 assign(addr1, get_gpr_dw0(r1));
12393 assign(addr2, get_gpr_dw0(r2));
12394 assign(len1, get_gpr_dw0(r1 + 1));
12395 assign(len2, get_gpr_dw0(r2 + 1));
12396
12397 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12398 there are less than 4 bytes left, then the 2nd operand is exhausted
12399 and we're done here. cc = 0 */
12400 s390_cc_set(0);
12401 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12402
12403 /* Read the 2nd operand. */
12404 IRTemp srcval = newTemp(Ity_I32);
12405 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12406
12407 /* Call the helper */
12408 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012409 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012410
12411 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12412 cc=2 outranks cc=1 (1st operand exhausted) */
12413 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12414
12415 s390_cc_set(2);
12416 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12417
12418 /* Now test whether the 1st operand is exhausted */
12419 IRTemp num_bytes = newTemp(Ity_I64);
12420 assign(num_bytes, binop(Iop_And64,
12421 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12422 mkU64(0xff)));
12423 s390_cc_set(1);
12424 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12425
12426 /* Extract the bytes to be stored at addr1 */
12427 IRTemp data = newTemp(Ity_I64);
12428 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12429
12430 /* To store the bytes construct 2 dirty helper calls. The helper calls
12431 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12432 that only one of them will be called at runtime. */
12433
12434 Int i;
12435 for (i = 2; i <= 4; ++i) {
12436 IRDirty *d;
12437
12438 if (i == 3) continue; // skip this one
12439
12440 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12441 &s390x_dirtyhelper_CUxy,
12442 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12443 mkexpr(num_bytes)));
12444 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12445 d->mFx = Ifx_Write;
12446 d->mAddr = mkexpr(addr1);
12447 d->mSize = i;
12448 stmt(IRStmt_Dirty(d));
12449 }
12450
12451 /* Update source address and length */
12452 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12453 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12454
12455 /* Update destination address and length */
12456 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12457 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12458
12459 iterate();
12460
12461 return "cu42";
12462}
12463
florian6d9b9b22012-08-03 18:35:39 +000012464static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012465s390_call_cu41(IRExpr *srcval)
12466{
12467 IRExpr **args, *call;
12468 args = mkIRExprVec_1(srcval);
12469 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12470 "s390_do_cu41", &s390_do_cu41, args);
12471
12472 /* Nothing is excluded from definedness checking. */
12473 call->Iex.CCall.cee->mcx_mask = 0;
12474
12475 return call;
12476}
12477
florian55085f82012-11-21 00:36:55 +000012478static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012479s390_irgen_CU41(UChar r1, UChar r2)
12480{
12481 IRTemp addr1 = newTemp(Ity_I64);
12482 IRTemp addr2 = newTemp(Ity_I64);
12483 IRTemp len1 = newTemp(Ity_I64);
12484 IRTemp len2 = newTemp(Ity_I64);
12485
12486 assign(addr1, get_gpr_dw0(r1));
12487 assign(addr2, get_gpr_dw0(r2));
12488 assign(len1, get_gpr_dw0(r1 + 1));
12489 assign(len2, get_gpr_dw0(r2 + 1));
12490
12491 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12492 there are less than 4 bytes left, then the 2nd operand is exhausted
12493 and we're done here. cc = 0 */
12494 s390_cc_set(0);
12495 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12496
12497 /* Read the 2nd operand. */
12498 IRTemp srcval = newTemp(Ity_I32);
12499 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12500
12501 /* Call the helper */
12502 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012503 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012504
12505 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12506 cc=2 outranks cc=1 (1st operand exhausted) */
12507 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12508
12509 s390_cc_set(2);
12510 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12511
12512 /* Now test whether the 1st operand is exhausted */
12513 IRTemp num_bytes = newTemp(Ity_I64);
12514 assign(num_bytes, binop(Iop_And64,
12515 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12516 mkU64(0xff)));
12517 s390_cc_set(1);
12518 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12519
12520 /* Extract the bytes to be stored at addr1 */
12521 IRTemp data = newTemp(Ity_I64);
12522 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12523
12524 /* To store the bytes construct 4 dirty helper calls. The helper calls
12525 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12526 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012527 UInt i;
florianaf2194f2012-08-06 00:07:54 +000012528 for (i = 1; i <= 4; ++i) {
12529 IRDirty *d;
12530
12531 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12532 &s390x_dirtyhelper_CUxy,
12533 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12534 mkexpr(num_bytes)));
12535 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12536 d->mFx = Ifx_Write;
12537 d->mAddr = mkexpr(addr1);
12538 d->mSize = i;
12539 stmt(IRStmt_Dirty(d));
12540 }
12541
12542 /* Update source address and length */
12543 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12544 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12545
12546 /* Update destination address and length */
12547 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12548 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12549
12550 iterate();
12551
12552 return "cu41";
12553}
12554
12555static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012556s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012557{
12558 IRExpr **args, *call;
12559 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012560 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12561 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012562
12563 /* Nothing is excluded from definedness checking. */
12564 call->Iex.CCall.cee->mcx_mask = 0;
12565
12566 return call;
12567}
12568
12569static IRExpr *
12570s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12571 IRExpr *byte4, IRExpr *stuff)
12572{
12573 IRExpr **args, *call;
12574 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12575 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12576 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12577
12578 /* Nothing is excluded from definedness checking. */
12579 call->Iex.CCall.cee->mcx_mask = 0;
12580
12581 return call;
12582}
12583
florian3f8a96a2012-08-05 02:59:55 +000012584static IRExpr *
12585s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12586 IRExpr *byte4, IRExpr *stuff)
12587{
12588 IRExpr **args, *call;
12589 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12590 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12591 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12592
12593 /* Nothing is excluded from definedness checking. */
12594 call->Iex.CCall.cee->mcx_mask = 0;
12595
12596 return call;
12597}
12598
12599static void
12600s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012601{
12602 IRTemp addr1 = newTemp(Ity_I64);
12603 IRTemp addr2 = newTemp(Ity_I64);
12604 IRTemp len1 = newTemp(Ity_I64);
12605 IRTemp len2 = newTemp(Ity_I64);
12606
12607 assign(addr1, get_gpr_dw0(r1));
12608 assign(addr2, get_gpr_dw0(r2));
12609 assign(len1, get_gpr_dw0(r1 + 1));
12610 assign(len2, get_gpr_dw0(r2 + 1));
12611
12612 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12613
12614 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12615 there is less than 1 byte left, then the 2nd operand is exhausted
12616 and we're done here. cc = 0 */
12617 s390_cc_set(0);
12618 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12619
12620 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012621 IRTemp byte1 = newTemp(Ity_I64);
12622 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012623
12624 /* Call the helper to get number of bytes and invalid byte indicator */
12625 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012626 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012627 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012628
12629 /* Check for invalid 1st byte */
12630 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12631 s390_cc_set(2);
12632 next_insn_if(is_invalid);
12633
12634 /* How many bytes do we have to read? */
12635 IRTemp num_src_bytes = newTemp(Ity_I64);
12636 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12637
12638 /* Now test whether the 2nd operand is exhausted */
12639 s390_cc_set(0);
12640 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12641
12642 /* Read the remaining bytes */
12643 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12644
12645 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12646 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012647 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012648 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12649 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012650 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012651 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12652 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012653 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012654
12655 /* Call the helper to get the converted value and invalid byte indicator.
12656 We can pass at most 5 arguments; therefore some encoding is needed
12657 here */
12658 IRExpr *stuff = binop(Iop_Or64,
12659 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12660 mkU64(extended_checking));
12661 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012662
12663 if (is_cu12) {
12664 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12665 byte4, stuff));
12666 } else {
12667 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12668 byte4, stuff));
12669 }
florian6d9b9b22012-08-03 18:35:39 +000012670
12671 /* Check for invalid character */
12672 s390_cc_set(2);
12673 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12674 next_insn_if(is_invalid);
12675
12676 /* Now test whether the 1st operand is exhausted */
12677 IRTemp num_bytes = newTemp(Ity_I64);
12678 assign(num_bytes, binop(Iop_And64,
12679 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12680 mkU64(0xff)));
12681 s390_cc_set(1);
12682 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12683
12684 /* Extract the bytes to be stored at addr1 */
12685 IRTemp data = newTemp(Ity_I64);
12686 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12687
florian3f8a96a2012-08-05 02:59:55 +000012688 if (is_cu12) {
12689 /* To store the bytes construct 2 dirty helper calls. The helper calls
12690 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12691 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012692
florian3f8a96a2012-08-05 02:59:55 +000012693 Int i;
12694 for (i = 2; i <= 4; ++i) {
12695 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012696
florian3f8a96a2012-08-05 02:59:55 +000012697 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012698
florian3f8a96a2012-08-05 02:59:55 +000012699 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12700 &s390x_dirtyhelper_CUxy,
12701 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12702 mkexpr(num_bytes)));
12703 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12704 d->mFx = Ifx_Write;
12705 d->mAddr = mkexpr(addr1);
12706 d->mSize = i;
12707 stmt(IRStmt_Dirty(d));
12708 }
12709 } else {
12710 // cu14
12711 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012712 }
12713
12714 /* Update source address and length */
12715 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12716 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12717
12718 /* Update destination address and length */
12719 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12720 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12721
12722 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012723}
12724
florian55085f82012-11-21 00:36:55 +000012725static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012726s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12727{
12728 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012729
12730 return "cu12";
12731}
12732
florian55085f82012-11-21 00:36:55 +000012733static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012734s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12735{
12736 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12737
12738 return "cu14";
12739}
12740
florian8c88cb62012-08-26 18:58:13 +000012741static IRExpr *
12742s390_call_ecag(IRExpr *op2addr)
12743{
12744 IRExpr **args, *call;
12745
12746 args = mkIRExprVec_1(op2addr);
12747 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12748 "s390_do_ecag", &s390_do_ecag, args);
12749
12750 /* Nothing is excluded from definedness checking. */
12751 call->Iex.CCall.cee->mcx_mask = 0;
12752
12753 return call;
12754}
12755
florian55085f82012-11-21 00:36:55 +000012756static const HChar *
floriand2129202012-09-01 20:01:39 +000012757s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012758{
12759 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012760 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012761 } else {
12762 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12763 }
12764
12765 return "ecag";
12766}
12767
12768
florianb7def222012-12-04 04:45:32 +000012769/* New insns are added here.
12770 If an insn is contingent on a facility being installed also
12771 check whether the list of supported facilities in function
12772 s390x_dirtyhelper_STFLE needs updating */
12773
sewardj2019a972011-03-07 16:04:07 +000012774/*------------------------------------------------------------*/
12775/*--- Build IR for special instructions ---*/
12776/*------------------------------------------------------------*/
12777
florianb4df7682011-07-05 02:09:01 +000012778static void
sewardj2019a972011-03-07 16:04:07 +000012779s390_irgen_client_request(void)
12780{
12781 if (0)
12782 vex_printf("%%R3 = client_request ( %%R2 )\n");
12783
florianf9e1ed72012-04-17 02:41:56 +000012784 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12785 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012786
florianf9e1ed72012-04-17 02:41:56 +000012787 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012788 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012789
12790 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012791}
12792
florianb4df7682011-07-05 02:09:01 +000012793static void
sewardj2019a972011-03-07 16:04:07 +000012794s390_irgen_guest_NRADDR(void)
12795{
12796 if (0)
12797 vex_printf("%%R3 = guest_NRADDR\n");
12798
floriane88b3c92011-07-05 02:48:39 +000012799 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012800}
12801
florianb4df7682011-07-05 02:09:01 +000012802static void
sewardj2019a972011-03-07 16:04:07 +000012803s390_irgen_call_noredir(void)
12804{
florianf9e1ed72012-04-17 02:41:56 +000012805 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12806 + S390_SPECIAL_OP_SIZE;
12807
sewardj2019a972011-03-07 16:04:07 +000012808 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012809 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012810
12811 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012812 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012813
12814 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012815 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012816}
12817
12818/* Force proper alignment for the structures below. */
12819#pragma pack(1)
12820
12821
12822static s390_decode_t
12823s390_decode_2byte_and_irgen(UChar *bytes)
12824{
12825 typedef union {
12826 struct {
12827 unsigned int op : 16;
12828 } E;
12829 struct {
12830 unsigned int op : 8;
12831 unsigned int i : 8;
12832 } I;
12833 struct {
12834 unsigned int op : 8;
12835 unsigned int r1 : 4;
12836 unsigned int r2 : 4;
12837 } RR;
12838 } formats;
12839 union {
12840 formats fmt;
12841 UShort value;
12842 } ovl;
12843
12844 vassert(sizeof(formats) == 2);
12845
florianffbd84d2012-12-09 02:06:29 +000012846 ((UChar *)(&ovl.value))[0] = bytes[0];
12847 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000012848
12849 switch (ovl.value & 0xffff) {
12850 case 0x0101: /* PR */ goto unimplemented;
12851 case 0x0102: /* UPT */ goto unimplemented;
12852 case 0x0104: /* PTFF */ goto unimplemented;
12853 case 0x0107: /* SCKPF */ goto unimplemented;
12854 case 0x010a: /* PFPO */ goto unimplemented;
12855 case 0x010b: /* TAM */ goto unimplemented;
12856 case 0x010c: /* SAM24 */ goto unimplemented;
12857 case 0x010d: /* SAM31 */ goto unimplemented;
12858 case 0x010e: /* SAM64 */ goto unimplemented;
12859 case 0x01ff: /* TRAP2 */ goto unimplemented;
12860 }
12861
12862 switch ((ovl.value & 0xff00) >> 8) {
12863 case 0x04: /* SPM */ goto unimplemented;
12864 case 0x05: /* BALR */ goto unimplemented;
12865 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12866 goto ok;
12867 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12868 goto ok;
12869 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12870 case 0x0b: /* BSM */ goto unimplemented;
12871 case 0x0c: /* BASSM */ goto unimplemented;
12872 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12873 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012874 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12875 goto ok;
12876 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12877 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012878 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12879 goto ok;
12880 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12881 goto ok;
12882 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12883 goto ok;
12884 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12885 goto ok;
12886 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12887 goto ok;
12888 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12889 goto ok;
12890 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12891 goto ok;
12892 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12893 goto ok;
12894 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12895 goto ok;
12896 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12897 goto ok;
12898 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12899 goto ok;
12900 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12901 goto ok;
12902 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12903 goto ok;
12904 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12905 goto ok;
12906 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12907 goto ok;
12908 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12909 goto ok;
12910 case 0x20: /* LPDR */ goto unimplemented;
12911 case 0x21: /* LNDR */ goto unimplemented;
12912 case 0x22: /* LTDR */ goto unimplemented;
12913 case 0x23: /* LCDR */ goto unimplemented;
12914 case 0x24: /* HDR */ goto unimplemented;
12915 case 0x25: /* LDXR */ goto unimplemented;
12916 case 0x26: /* MXR */ goto unimplemented;
12917 case 0x27: /* MXDR */ goto unimplemented;
12918 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12919 goto ok;
12920 case 0x29: /* CDR */ goto unimplemented;
12921 case 0x2a: /* ADR */ goto unimplemented;
12922 case 0x2b: /* SDR */ goto unimplemented;
12923 case 0x2c: /* MDR */ goto unimplemented;
12924 case 0x2d: /* DDR */ goto unimplemented;
12925 case 0x2e: /* AWR */ goto unimplemented;
12926 case 0x2f: /* SWR */ goto unimplemented;
12927 case 0x30: /* LPER */ goto unimplemented;
12928 case 0x31: /* LNER */ goto unimplemented;
12929 case 0x32: /* LTER */ goto unimplemented;
12930 case 0x33: /* LCER */ goto unimplemented;
12931 case 0x34: /* HER */ goto unimplemented;
12932 case 0x35: /* LEDR */ goto unimplemented;
12933 case 0x36: /* AXR */ goto unimplemented;
12934 case 0x37: /* SXR */ goto unimplemented;
12935 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12936 goto ok;
12937 case 0x39: /* CER */ goto unimplemented;
12938 case 0x3a: /* AER */ goto unimplemented;
12939 case 0x3b: /* SER */ goto unimplemented;
12940 case 0x3c: /* MDER */ goto unimplemented;
12941 case 0x3d: /* DER */ goto unimplemented;
12942 case 0x3e: /* AUR */ goto unimplemented;
12943 case 0x3f: /* SUR */ goto unimplemented;
12944 }
12945
12946 return S390_DECODE_UNKNOWN_INSN;
12947
12948ok:
12949 return S390_DECODE_OK;
12950
12951unimplemented:
12952 return S390_DECODE_UNIMPLEMENTED_INSN;
12953}
12954
12955static s390_decode_t
12956s390_decode_4byte_and_irgen(UChar *bytes)
12957{
12958 typedef union {
12959 struct {
12960 unsigned int op1 : 8;
12961 unsigned int r1 : 4;
12962 unsigned int op2 : 4;
12963 unsigned int i2 : 16;
12964 } RI;
12965 struct {
12966 unsigned int op : 16;
12967 unsigned int : 8;
12968 unsigned int r1 : 4;
12969 unsigned int r2 : 4;
12970 } RRE;
12971 struct {
12972 unsigned int op : 16;
12973 unsigned int r1 : 4;
12974 unsigned int : 4;
12975 unsigned int r3 : 4;
12976 unsigned int r2 : 4;
12977 } RRF;
12978 struct {
12979 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012980 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012981 unsigned int m4 : 4;
12982 unsigned int r1 : 4;
12983 unsigned int r2 : 4;
12984 } RRF2;
12985 struct {
12986 unsigned int op : 16;
12987 unsigned int r3 : 4;
12988 unsigned int : 4;
12989 unsigned int r1 : 4;
12990 unsigned int r2 : 4;
12991 } RRF3;
12992 struct {
12993 unsigned int op : 16;
12994 unsigned int r3 : 4;
12995 unsigned int : 4;
12996 unsigned int r1 : 4;
12997 unsigned int r2 : 4;
12998 } RRR;
12999 struct {
13000 unsigned int op : 16;
13001 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013002 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013003 unsigned int r1 : 4;
13004 unsigned int r2 : 4;
13005 } RRF4;
13006 struct {
floriane38f6412012-12-21 17:32:12 +000013007 unsigned int op : 16;
13008 unsigned int : 4;
13009 unsigned int m4 : 4;
13010 unsigned int r1 : 4;
13011 unsigned int r2 : 4;
13012 } RRF5;
13013 struct {
sewardj2019a972011-03-07 16:04:07 +000013014 unsigned int op : 8;
13015 unsigned int r1 : 4;
13016 unsigned int r3 : 4;
13017 unsigned int b2 : 4;
13018 unsigned int d2 : 12;
13019 } RS;
13020 struct {
13021 unsigned int op : 8;
13022 unsigned int r1 : 4;
13023 unsigned int r3 : 4;
13024 unsigned int i2 : 16;
13025 } RSI;
13026 struct {
13027 unsigned int op : 8;
13028 unsigned int r1 : 4;
13029 unsigned int x2 : 4;
13030 unsigned int b2 : 4;
13031 unsigned int d2 : 12;
13032 } RX;
13033 struct {
13034 unsigned int op : 16;
13035 unsigned int b2 : 4;
13036 unsigned int d2 : 12;
13037 } S;
13038 struct {
13039 unsigned int op : 8;
13040 unsigned int i2 : 8;
13041 unsigned int b1 : 4;
13042 unsigned int d1 : 12;
13043 } SI;
13044 } formats;
13045 union {
13046 formats fmt;
13047 UInt value;
13048 } ovl;
13049
13050 vassert(sizeof(formats) == 4);
13051
florianffbd84d2012-12-09 02:06:29 +000013052 ((UChar *)(&ovl.value))[0] = bytes[0];
13053 ((UChar *)(&ovl.value))[1] = bytes[1];
13054 ((UChar *)(&ovl.value))[2] = bytes[2];
13055 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013056
13057 switch ((ovl.value & 0xff0f0000) >> 16) {
13058 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13059 ovl.fmt.RI.i2); goto ok;
13060 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13061 ovl.fmt.RI.i2); goto ok;
13062 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13063 ovl.fmt.RI.i2); goto ok;
13064 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13065 ovl.fmt.RI.i2); goto ok;
13066 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13067 ovl.fmt.RI.i2); goto ok;
13068 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13069 ovl.fmt.RI.i2); goto ok;
13070 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13071 ovl.fmt.RI.i2); goto ok;
13072 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13073 ovl.fmt.RI.i2); goto ok;
13074 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13075 ovl.fmt.RI.i2); goto ok;
13076 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13077 ovl.fmt.RI.i2); goto ok;
13078 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13079 ovl.fmt.RI.i2); goto ok;
13080 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13081 ovl.fmt.RI.i2); goto ok;
13082 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13083 ovl.fmt.RI.i2); goto ok;
13084 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13085 ovl.fmt.RI.i2); goto ok;
13086 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13087 ovl.fmt.RI.i2); goto ok;
13088 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13089 ovl.fmt.RI.i2); goto ok;
13090 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13091 ovl.fmt.RI.i2); goto ok;
13092 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13093 ovl.fmt.RI.i2); goto ok;
13094 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13095 ovl.fmt.RI.i2); goto ok;
13096 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13097 ovl.fmt.RI.i2); goto ok;
13098 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13099 goto ok;
13100 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13101 ovl.fmt.RI.i2); goto ok;
13102 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13103 ovl.fmt.RI.i2); goto ok;
13104 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13105 ovl.fmt.RI.i2); goto ok;
13106 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13107 goto ok;
13108 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13109 ovl.fmt.RI.i2); goto ok;
13110 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13111 goto ok;
13112 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13113 ovl.fmt.RI.i2); goto ok;
13114 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13115 goto ok;
13116 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13117 ovl.fmt.RI.i2); goto ok;
13118 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13119 goto ok;
13120 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13121 ovl.fmt.RI.i2); goto ok;
13122 }
13123
13124 switch ((ovl.value & 0xffff0000) >> 16) {
13125 case 0x8000: /* SSM */ goto unimplemented;
13126 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013127 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013128 case 0xb202: /* STIDP */ goto unimplemented;
13129 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013130 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13131 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013132 case 0xb206: /* SCKC */ goto unimplemented;
13133 case 0xb207: /* STCKC */ goto unimplemented;
13134 case 0xb208: /* SPT */ goto unimplemented;
13135 case 0xb209: /* STPT */ goto unimplemented;
13136 case 0xb20a: /* SPKA */ goto unimplemented;
13137 case 0xb20b: /* IPK */ goto unimplemented;
13138 case 0xb20d: /* PTLB */ goto unimplemented;
13139 case 0xb210: /* SPX */ goto unimplemented;
13140 case 0xb211: /* STPX */ goto unimplemented;
13141 case 0xb212: /* STAP */ goto unimplemented;
13142 case 0xb214: /* SIE */ goto unimplemented;
13143 case 0xb218: /* PC */ goto unimplemented;
13144 case 0xb219: /* SAC */ goto unimplemented;
13145 case 0xb21a: /* CFC */ goto unimplemented;
13146 case 0xb221: /* IPTE */ goto unimplemented;
13147 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13148 case 0xb223: /* IVSK */ goto unimplemented;
13149 case 0xb224: /* IAC */ goto unimplemented;
13150 case 0xb225: /* SSAR */ goto unimplemented;
13151 case 0xb226: /* EPAR */ goto unimplemented;
13152 case 0xb227: /* ESAR */ goto unimplemented;
13153 case 0xb228: /* PT */ goto unimplemented;
13154 case 0xb229: /* ISKE */ goto unimplemented;
13155 case 0xb22a: /* RRBE */ goto unimplemented;
13156 case 0xb22b: /* SSKE */ goto unimplemented;
13157 case 0xb22c: /* TB */ goto unimplemented;
13158 case 0xb22d: /* DXR */ goto unimplemented;
13159 case 0xb22e: /* PGIN */ goto unimplemented;
13160 case 0xb22f: /* PGOUT */ goto unimplemented;
13161 case 0xb230: /* CSCH */ goto unimplemented;
13162 case 0xb231: /* HSCH */ goto unimplemented;
13163 case 0xb232: /* MSCH */ goto unimplemented;
13164 case 0xb233: /* SSCH */ goto unimplemented;
13165 case 0xb234: /* STSCH */ goto unimplemented;
13166 case 0xb235: /* TSCH */ goto unimplemented;
13167 case 0xb236: /* TPI */ goto unimplemented;
13168 case 0xb237: /* SAL */ goto unimplemented;
13169 case 0xb238: /* RSCH */ goto unimplemented;
13170 case 0xb239: /* STCRW */ goto unimplemented;
13171 case 0xb23a: /* STCPS */ goto unimplemented;
13172 case 0xb23b: /* RCHP */ goto unimplemented;
13173 case 0xb23c: /* SCHM */ goto unimplemented;
13174 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013175 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13176 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013177 case 0xb244: /* SQDR */ goto unimplemented;
13178 case 0xb245: /* SQER */ goto unimplemented;
13179 case 0xb246: /* STURA */ goto unimplemented;
13180 case 0xb247: /* MSTA */ goto unimplemented;
13181 case 0xb248: /* PALB */ goto unimplemented;
13182 case 0xb249: /* EREG */ goto unimplemented;
13183 case 0xb24a: /* ESTA */ goto unimplemented;
13184 case 0xb24b: /* LURA */ goto unimplemented;
13185 case 0xb24c: /* TAR */ goto unimplemented;
13186 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13187 ovl.fmt.RRE.r2); goto ok;
13188 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13189 goto ok;
13190 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13191 goto ok;
13192 case 0xb250: /* CSP */ goto unimplemented;
13193 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13194 ovl.fmt.RRE.r2); goto ok;
13195 case 0xb254: /* MVPG */ goto unimplemented;
13196 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13197 ovl.fmt.RRE.r2); goto ok;
13198 case 0xb257: /* CUSE */ goto unimplemented;
13199 case 0xb258: /* BSG */ goto unimplemented;
13200 case 0xb25a: /* BSA */ goto unimplemented;
13201 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13202 ovl.fmt.RRE.r2); goto ok;
13203 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13204 ovl.fmt.RRE.r2); goto ok;
13205 case 0xb263: /* CMPSC */ goto unimplemented;
13206 case 0xb274: /* SIGA */ goto unimplemented;
13207 case 0xb276: /* XSCH */ goto unimplemented;
13208 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013209 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 +000013210 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013211 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 +000013212 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013213 case 0xb280: /* LPP */ goto unimplemented;
13214 case 0xb284: /* LCCTL */ goto unimplemented;
13215 case 0xb285: /* LPCTL */ goto unimplemented;
13216 case 0xb286: /* QSI */ goto unimplemented;
13217 case 0xb287: /* LSCTL */ goto unimplemented;
13218 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013219 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13220 goto ok;
13221 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13222 goto ok;
13223 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13224 goto ok;
florian730448f2012-02-04 17:07:07 +000013225 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 +000013226 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13227 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13228 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013229 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13230 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13231 goto ok;
florian933065d2011-07-11 01:48:02 +000013232 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13233 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013234 case 0xb2b1: /* STFL */ goto unimplemented;
13235 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013236 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13237 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013238 case 0xb2b9: /* SRNMT */ goto unimplemented;
13239 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013240 case 0xb2e0: /* SCCTR */ goto unimplemented;
13241 case 0xb2e1: /* SPCTR */ goto unimplemented;
13242 case 0xb2e4: /* ECCTR */ goto unimplemented;
13243 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013244 case 0xb2e8: /* PPA */ goto unimplemented;
13245 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013246 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013247 case 0xb2f8: /* TEND */ goto unimplemented;
13248 case 0xb2fa: /* NIAI */ goto unimplemented;
13249 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013250 case 0xb2ff: /* TRAP4 */ goto unimplemented;
13251 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
13252 ovl.fmt.RRE.r2); goto ok;
13253 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
13254 ovl.fmt.RRE.r2); goto ok;
13255 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
13256 ovl.fmt.RRE.r2); goto ok;
13257 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
13258 ovl.fmt.RRE.r2); goto ok;
13259 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
13260 ovl.fmt.RRE.r2); goto ok;
13261 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
13262 ovl.fmt.RRE.r2); goto ok;
13263 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
13264 ovl.fmt.RRE.r2); goto ok;
13265 case 0xb307: /* MXDBR */ goto unimplemented;
13266 case 0xb308: /* KEBR */ goto unimplemented;
13267 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
13268 ovl.fmt.RRE.r2); goto ok;
13269 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
13270 ovl.fmt.RRE.r2); goto ok;
13271 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
13272 ovl.fmt.RRE.r2); goto ok;
13273 case 0xb30c: /* MDEBR */ goto unimplemented;
13274 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
13275 ovl.fmt.RRE.r2); goto ok;
13276 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
13277 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13278 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
13279 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13280 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
13281 ovl.fmt.RRE.r2); goto ok;
13282 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
13283 ovl.fmt.RRE.r2); goto ok;
13284 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
13285 ovl.fmt.RRE.r2); goto ok;
13286 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
13287 ovl.fmt.RRE.r2); goto ok;
13288 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
13289 ovl.fmt.RRE.r2); goto ok;
13290 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
13291 ovl.fmt.RRE.r2); goto ok;
13292 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
13293 ovl.fmt.RRE.r2); goto ok;
13294 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
13295 ovl.fmt.RRE.r2); goto ok;
13296 case 0xb318: /* KDBR */ goto unimplemented;
13297 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
13298 ovl.fmt.RRE.r2); goto ok;
13299 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
13300 ovl.fmt.RRE.r2); goto ok;
13301 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13302 ovl.fmt.RRE.r2); goto ok;
13303 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13304 ovl.fmt.RRE.r2); goto ok;
13305 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13306 ovl.fmt.RRE.r2); goto ok;
13307 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13308 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13309 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13310 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13311 case 0xb324: /* LDER */ goto unimplemented;
13312 case 0xb325: /* LXDR */ goto unimplemented;
13313 case 0xb326: /* LXER */ goto unimplemented;
13314 case 0xb32e: /* MAER */ goto unimplemented;
13315 case 0xb32f: /* MSER */ goto unimplemented;
13316 case 0xb336: /* SQXR */ goto unimplemented;
13317 case 0xb337: /* MEER */ goto unimplemented;
13318 case 0xb338: /* MAYLR */ goto unimplemented;
13319 case 0xb339: /* MYLR */ goto unimplemented;
13320 case 0xb33a: /* MAYR */ goto unimplemented;
13321 case 0xb33b: /* MYR */ goto unimplemented;
13322 case 0xb33c: /* MAYHR */ goto unimplemented;
13323 case 0xb33d: /* MYHR */ goto unimplemented;
13324 case 0xb33e: /* MADR */ goto unimplemented;
13325 case 0xb33f: /* MSDR */ goto unimplemented;
13326 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13327 ovl.fmt.RRE.r2); goto ok;
13328 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13329 ovl.fmt.RRE.r2); goto ok;
13330 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13331 ovl.fmt.RRE.r2); goto ok;
13332 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13333 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013334 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13335 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13336 ovl.fmt.RRF2.r2); goto ok;
13337 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13338 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13339 ovl.fmt.RRF2.r2); goto ok;
13340 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13341 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13342 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013343 case 0xb347: /* FIXBR */ goto unimplemented;
13344 case 0xb348: /* KXBR */ goto unimplemented;
13345 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13346 ovl.fmt.RRE.r2); goto ok;
13347 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13348 ovl.fmt.RRE.r2); goto ok;
13349 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13350 ovl.fmt.RRE.r2); goto ok;
13351 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13352 ovl.fmt.RRE.r2); goto ok;
13353 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13354 ovl.fmt.RRE.r2); goto ok;
13355 case 0xb350: /* TBEDR */ goto unimplemented;
13356 case 0xb351: /* TBDR */ goto unimplemented;
13357 case 0xb353: /* DIEBR */ goto unimplemented;
13358 case 0xb357: /* FIEBR */ goto unimplemented;
13359 case 0xb358: /* THDER */ goto unimplemented;
13360 case 0xb359: /* THDR */ goto unimplemented;
13361 case 0xb35b: /* DIDBR */ goto unimplemented;
13362 case 0xb35f: /* FIDBR */ goto unimplemented;
13363 case 0xb360: /* LPXR */ goto unimplemented;
13364 case 0xb361: /* LNXR */ goto unimplemented;
13365 case 0xb362: /* LTXR */ goto unimplemented;
13366 case 0xb363: /* LCXR */ goto unimplemented;
13367 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13368 ovl.fmt.RRE.r2); goto ok;
13369 case 0xb366: /* LEXR */ goto unimplemented;
13370 case 0xb367: /* FIXR */ goto unimplemented;
13371 case 0xb369: /* CXR */ goto unimplemented;
13372 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13373 ovl.fmt.RRE.r2); goto ok;
13374 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13375 ovl.fmt.RRE.r2); goto ok;
13376 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13377 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13378 goto ok;
13379 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13380 ovl.fmt.RRE.r2); goto ok;
13381 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13382 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13383 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13384 case 0xb377: /* FIER */ goto unimplemented;
13385 case 0xb37f: /* FIDR */ goto unimplemented;
13386 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13387 case 0xb385: /* SFASR */ goto unimplemented;
13388 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013389 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13390 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13391 ovl.fmt.RRF2.r2); goto ok;
13392 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13393 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13394 ovl.fmt.RRF2.r2); goto ok;
13395 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13396 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13397 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013398 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13399 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13400 ovl.fmt.RRF2.r2); goto ok;
13401 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13402 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13403 ovl.fmt.RRF2.r2); goto ok;
13404 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13405 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13406 ovl.fmt.RRF2.r2); goto ok;
13407 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13408 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13409 ovl.fmt.RRF2.r2); goto ok;
13410 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13411 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13412 ovl.fmt.RRF2.r2); goto ok;
13413 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13414 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13415 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013416 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13417 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13418 ovl.fmt.RRF2.r2); goto ok;
13419 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13420 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13421 ovl.fmt.RRF2.r2); goto ok;
13422 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13423 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13424 ovl.fmt.RRF2.r2); goto ok;
13425 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13426 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13427 ovl.fmt.RRF2.r2); goto ok;
13428 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13429 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13430 ovl.fmt.RRF2.r2); goto ok;
13431 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13432 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13433 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013434 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13435 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13436 ovl.fmt.RRF2.r2); goto ok;
13437 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13438 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13439 ovl.fmt.RRF2.r2); goto ok;
13440 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13441 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13442 ovl.fmt.RRF2.r2); goto ok;
13443 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13444 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13445 ovl.fmt.RRF2.r2); goto ok;
13446 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13447 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13448 ovl.fmt.RRF2.r2); goto ok;
13449 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13450 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13451 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013452 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13453 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13454 ovl.fmt.RRF2.r2); goto ok;
13455 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13456 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13457 ovl.fmt.RRF2.r2); goto ok;
13458 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13459 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13460 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013461 case 0xb3b4: /* CEFR */ goto unimplemented;
13462 case 0xb3b5: /* CDFR */ goto unimplemented;
13463 case 0xb3b6: /* CXFR */ goto unimplemented;
13464 case 0xb3b8: /* CFER */ goto unimplemented;
13465 case 0xb3b9: /* CFDR */ goto unimplemented;
13466 case 0xb3ba: /* CFXR */ goto unimplemented;
13467 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13468 ovl.fmt.RRE.r2); goto ok;
13469 case 0xb3c4: /* CEGR */ goto unimplemented;
13470 case 0xb3c5: /* CDGR */ goto unimplemented;
13471 case 0xb3c6: /* CXGR */ goto unimplemented;
13472 case 0xb3c8: /* CGER */ goto unimplemented;
13473 case 0xb3c9: /* CGDR */ goto unimplemented;
13474 case 0xb3ca: /* CGXR */ goto unimplemented;
13475 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13476 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013477 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13478 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13479 ovl.fmt.RRF4.r2); goto ok;
13480 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13481 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13482 ovl.fmt.RRF4.r2); goto ok;
13483 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13484 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13485 ovl.fmt.RRF4.r2); goto ok;
13486 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13487 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13488 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000013489 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
13490 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13491 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
13492 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13493 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013494 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13495 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013496 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013497 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
13498 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13499 ovl.fmt.RRF4.r2); goto ok;
13500 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
13501 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13502 ovl.fmt.RRF4.r2); goto ok;
13503 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
13504 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13505 ovl.fmt.RRF4.r2); goto ok;
13506 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
13507 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13508 ovl.fmt.RRF4.r2); goto ok;
13509 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
13510 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13511 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
13512 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13513 ovl.fmt.RRF2.r2); goto ok;
13514 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
13515 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013516 case 0xb3df: /* FIXTR */ goto unimplemented;
13517 case 0xb3e0: /* KDTR */ goto unimplemented;
13518 case 0xb3e1: /* CGDTR */ goto unimplemented;
13519 case 0xb3e2: /* CUDTR */ goto unimplemented;
13520 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013521 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
13522 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013523 case 0xb3e5: /* EEDTR */ goto unimplemented;
13524 case 0xb3e7: /* ESDTR */ goto unimplemented;
13525 case 0xb3e8: /* KXTR */ goto unimplemented;
13526 case 0xb3e9: /* CGXTR */ goto unimplemented;
13527 case 0xb3ea: /* CUXTR */ goto unimplemented;
13528 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013529 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
13530 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013531 case 0xb3ed: /* EEXTR */ goto unimplemented;
13532 case 0xb3ef: /* ESXTR */ goto unimplemented;
13533 case 0xb3f1: /* CDGTR */ goto unimplemented;
13534 case 0xb3f2: /* CDUTR */ goto unimplemented;
13535 case 0xb3f3: /* CDSTR */ goto unimplemented;
13536 case 0xb3f4: /* CEDTR */ goto unimplemented;
13537 case 0xb3f5: /* QADTR */ goto unimplemented;
13538 case 0xb3f6: /* IEDTR */ goto unimplemented;
13539 case 0xb3f7: /* RRDTR */ goto unimplemented;
13540 case 0xb3f9: /* CXGTR */ goto unimplemented;
13541 case 0xb3fa: /* CXUTR */ goto unimplemented;
13542 case 0xb3fb: /* CXSTR */ goto unimplemented;
13543 case 0xb3fc: /* CEXTR */ goto unimplemented;
13544 case 0xb3fd: /* QAXTR */ goto unimplemented;
13545 case 0xb3fe: /* IEXTR */ goto unimplemented;
13546 case 0xb3ff: /* RRXTR */ goto unimplemented;
13547 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13548 ovl.fmt.RRE.r2); goto ok;
13549 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13550 ovl.fmt.RRE.r2); goto ok;
13551 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13552 ovl.fmt.RRE.r2); goto ok;
13553 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13554 ovl.fmt.RRE.r2); goto ok;
13555 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13556 ovl.fmt.RRE.r2); goto ok;
13557 case 0xb905: /* LURAG */ goto unimplemented;
13558 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13559 ovl.fmt.RRE.r2); goto ok;
13560 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13561 ovl.fmt.RRE.r2); goto ok;
13562 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13563 ovl.fmt.RRE.r2); goto ok;
13564 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13565 ovl.fmt.RRE.r2); goto ok;
13566 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13567 ovl.fmt.RRE.r2); goto ok;
13568 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13569 ovl.fmt.RRE.r2); goto ok;
13570 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13571 ovl.fmt.RRE.r2); goto ok;
13572 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13573 ovl.fmt.RRE.r2); goto ok;
13574 case 0xb90e: /* EREGG */ goto unimplemented;
13575 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13576 ovl.fmt.RRE.r2); goto ok;
13577 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13578 ovl.fmt.RRE.r2); goto ok;
13579 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13580 ovl.fmt.RRE.r2); goto ok;
13581 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13582 ovl.fmt.RRE.r2); goto ok;
13583 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13584 ovl.fmt.RRE.r2); goto ok;
13585 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13586 ovl.fmt.RRE.r2); goto ok;
13587 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13588 ovl.fmt.RRE.r2); goto ok;
13589 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13590 ovl.fmt.RRE.r2); goto ok;
13591 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13592 ovl.fmt.RRE.r2); goto ok;
13593 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13594 ovl.fmt.RRE.r2); goto ok;
13595 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13596 ovl.fmt.RRE.r2); goto ok;
13597 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13598 ovl.fmt.RRE.r2); goto ok;
13599 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13600 ovl.fmt.RRE.r2); goto ok;
13601 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13602 ovl.fmt.RRE.r2); goto ok;
13603 case 0xb91e: /* KMAC */ goto unimplemented;
13604 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13605 ovl.fmt.RRE.r2); goto ok;
13606 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13607 ovl.fmt.RRE.r2); goto ok;
13608 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13609 ovl.fmt.RRE.r2); goto ok;
13610 case 0xb925: /* STURG */ goto unimplemented;
13611 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13612 ovl.fmt.RRE.r2); goto ok;
13613 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13614 ovl.fmt.RRE.r2); goto ok;
13615 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013616 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013617 case 0xb92b: /* KMO */ goto unimplemented;
13618 case 0xb92c: /* PCC */ goto unimplemented;
13619 case 0xb92d: /* KMCTR */ goto unimplemented;
13620 case 0xb92e: /* KM */ goto unimplemented;
13621 case 0xb92f: /* KMC */ goto unimplemented;
13622 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13623 ovl.fmt.RRE.r2); goto ok;
13624 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13625 ovl.fmt.RRE.r2); goto ok;
13626 case 0xb93e: /* KIMD */ goto unimplemented;
13627 case 0xb93f: /* KLMD */ goto unimplemented;
13628 case 0xb941: /* CFDTR */ goto unimplemented;
13629 case 0xb942: /* CLGDTR */ goto unimplemented;
13630 case 0xb943: /* CLFDTR */ goto unimplemented;
13631 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13632 ovl.fmt.RRE.r2); goto ok;
13633 case 0xb949: /* CFXTR */ goto unimplemented;
13634 case 0xb94a: /* CLGXTR */ goto unimplemented;
13635 case 0xb94b: /* CLFXTR */ goto unimplemented;
13636 case 0xb951: /* CDFTR */ goto unimplemented;
13637 case 0xb952: /* CDLGTR */ goto unimplemented;
13638 case 0xb953: /* CDLFTR */ goto unimplemented;
13639 case 0xb959: /* CXFTR */ goto unimplemented;
13640 case 0xb95a: /* CXLGTR */ goto unimplemented;
13641 case 0xb95b: /* CXLFTR */ goto unimplemented;
13642 case 0xb960: /* CGRT */ goto unimplemented;
13643 case 0xb961: /* CLGRT */ goto unimplemented;
13644 case 0xb972: /* CRT */ goto unimplemented;
13645 case 0xb973: /* CLRT */ goto unimplemented;
13646 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13647 ovl.fmt.RRE.r2); goto ok;
13648 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13649 ovl.fmt.RRE.r2); goto ok;
13650 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13651 ovl.fmt.RRE.r2); goto ok;
13652 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13653 ovl.fmt.RRE.r2); goto ok;
13654 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13655 ovl.fmt.RRE.r2); goto ok;
13656 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13657 ovl.fmt.RRE.r2); goto ok;
13658 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13659 ovl.fmt.RRE.r2); goto ok;
13660 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13661 ovl.fmt.RRE.r2); goto ok;
13662 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13663 ovl.fmt.RRE.r2); goto ok;
13664 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13665 ovl.fmt.RRE.r2); goto ok;
13666 case 0xb98a: /* CSPG */ goto unimplemented;
13667 case 0xb98d: /* EPSW */ goto unimplemented;
13668 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013669 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013670 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13671 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13672 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13673 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13674 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13675 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013676 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13677 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013678 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13679 ovl.fmt.RRE.r2); goto ok;
13680 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13681 ovl.fmt.RRE.r2); goto ok;
13682 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13683 ovl.fmt.RRE.r2); goto ok;
13684 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13685 ovl.fmt.RRE.r2); goto ok;
13686 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13687 ovl.fmt.RRE.r2); goto ok;
13688 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13689 ovl.fmt.RRE.r2); goto ok;
13690 case 0xb99a: /* EPAIR */ goto unimplemented;
13691 case 0xb99b: /* ESAIR */ goto unimplemented;
13692 case 0xb99d: /* ESEA */ goto unimplemented;
13693 case 0xb99e: /* PTI */ goto unimplemented;
13694 case 0xb99f: /* SSAIR */ goto unimplemented;
13695 case 0xb9a2: /* PTF */ goto unimplemented;
13696 case 0xb9aa: /* LPTEA */ goto unimplemented;
13697 case 0xb9ae: /* RRBM */ goto unimplemented;
13698 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013699 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13700 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13701 goto ok;
florian2a415a12012-07-21 17:41:36 +000013702 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13703 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13704 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013705 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13706 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013707 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13708 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013709 case 0xb9bd: /* TRTRE */ goto unimplemented;
13710 case 0xb9be: /* SRSTU */ goto unimplemented;
13711 case 0xb9bf: /* TRTE */ goto unimplemented;
13712 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13713 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13714 goto ok;
13715 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13716 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13717 goto ok;
13718 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13719 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13720 goto ok;
13721 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13722 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13723 goto ok;
13724 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13725 ovl.fmt.RRE.r2); goto ok;
13726 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13727 ovl.fmt.RRE.r2); goto ok;
13728 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13729 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13730 goto ok;
13731 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13732 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13733 goto ok;
13734 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13735 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13736 goto ok;
13737 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13738 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13739 goto ok;
13740 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13741 ovl.fmt.RRE.r2); goto ok;
13742 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13743 ovl.fmt.RRE.r2); goto ok;
13744 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013745 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13746 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13747 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013748 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13749 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13750 goto ok;
13751 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13752 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13753 goto ok;
13754 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13755 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13756 goto ok;
13757 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13758 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13759 goto ok;
13760 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13761 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13762 goto ok;
13763 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13764 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13765 goto ok;
13766 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13767 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13768 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013769 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13770 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13771 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013772 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13773 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13774 goto ok;
13775 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13776 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13777 goto ok;
13778 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13779 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13780 goto ok;
13781 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13782 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13783 goto ok;
13784 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13785 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13786 goto ok;
13787 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13788 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13789 goto ok;
13790 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13791 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13792 goto ok;
13793 }
13794
13795 switch ((ovl.value & 0xff000000) >> 24) {
13796 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13797 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13798 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13799 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13800 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13801 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13802 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13803 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13804 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13805 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13806 case 0x45: /* BAL */ goto unimplemented;
13807 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13808 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13809 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13810 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13811 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13812 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13813 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13814 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13815 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13816 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13817 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13818 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13819 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13820 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13821 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13822 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13823 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13824 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13825 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13826 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13827 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13828 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13829 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13830 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13831 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13832 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13833 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13834 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13835 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13836 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13837 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13838 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13839 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13840 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13841 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13842 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13843 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13844 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13845 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13846 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13847 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13848 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13849 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13850 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13851 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13852 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13853 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13854 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13855 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13856 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13857 case 0x67: /* MXD */ goto unimplemented;
13858 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13859 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13860 case 0x69: /* CD */ goto unimplemented;
13861 case 0x6a: /* AD */ goto unimplemented;
13862 case 0x6b: /* SD */ goto unimplemented;
13863 case 0x6c: /* MD */ goto unimplemented;
13864 case 0x6d: /* DD */ goto unimplemented;
13865 case 0x6e: /* AW */ goto unimplemented;
13866 case 0x6f: /* SW */ goto unimplemented;
13867 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13868 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13869 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13870 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13871 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13872 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13873 case 0x79: /* CE */ goto unimplemented;
13874 case 0x7a: /* AE */ goto unimplemented;
13875 case 0x7b: /* SE */ goto unimplemented;
13876 case 0x7c: /* MDE */ goto unimplemented;
13877 case 0x7d: /* DE */ goto unimplemented;
13878 case 0x7e: /* AU */ goto unimplemented;
13879 case 0x7f: /* SU */ goto unimplemented;
13880 case 0x83: /* DIAG */ goto unimplemented;
13881 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13882 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13883 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13884 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13885 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13886 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13887 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13888 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13889 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13890 ovl.fmt.RS.d2); goto ok;
13891 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13892 ovl.fmt.RS.d2); goto ok;
13893 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13894 ovl.fmt.RS.d2); goto ok;
13895 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13896 ovl.fmt.RS.d2); goto ok;
13897 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13898 ovl.fmt.RS.d2); goto ok;
13899 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13900 ovl.fmt.RS.d2); goto ok;
13901 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13902 ovl.fmt.RS.d2); goto ok;
13903 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13904 ovl.fmt.RS.d2); goto ok;
13905 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13906 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13907 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13908 ovl.fmt.SI.d1); goto ok;
13909 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13910 ovl.fmt.SI.d1); goto ok;
13911 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13912 ovl.fmt.SI.d1); goto ok;
13913 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13914 ovl.fmt.SI.d1); goto ok;
13915 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13916 ovl.fmt.SI.d1); goto ok;
13917 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13918 ovl.fmt.SI.d1); goto ok;
13919 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13920 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13921 case 0x99: /* TRACE */ goto unimplemented;
13922 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13923 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13924 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13925 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13926 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13927 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13928 goto ok;
13929 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13930 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13931 goto ok;
13932 case 0xac: /* STNSM */ goto unimplemented;
13933 case 0xad: /* STOSM */ goto unimplemented;
13934 case 0xae: /* SIGP */ goto unimplemented;
13935 case 0xaf: /* MC */ goto unimplemented;
13936 case 0xb1: /* LRA */ goto unimplemented;
13937 case 0xb6: /* STCTL */ goto unimplemented;
13938 case 0xb7: /* LCTL */ goto unimplemented;
13939 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13940 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013941 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13942 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013943 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13944 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13945 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13946 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13947 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13948 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13949 }
13950
13951 return S390_DECODE_UNKNOWN_INSN;
13952
13953ok:
13954 return S390_DECODE_OK;
13955
13956unimplemented:
13957 return S390_DECODE_UNIMPLEMENTED_INSN;
13958}
13959
13960static s390_decode_t
13961s390_decode_6byte_and_irgen(UChar *bytes)
13962{
13963 typedef union {
13964 struct {
13965 unsigned int op1 : 8;
13966 unsigned int r1 : 4;
13967 unsigned int r3 : 4;
13968 unsigned int i2 : 16;
13969 unsigned int : 8;
13970 unsigned int op2 : 8;
13971 } RIE;
13972 struct {
13973 unsigned int op1 : 8;
13974 unsigned int r1 : 4;
13975 unsigned int r2 : 4;
13976 unsigned int i3 : 8;
13977 unsigned int i4 : 8;
13978 unsigned int i5 : 8;
13979 unsigned int op2 : 8;
13980 } RIE_RRUUU;
13981 struct {
13982 unsigned int op1 : 8;
13983 unsigned int r1 : 4;
13984 unsigned int : 4;
13985 unsigned int i2 : 16;
13986 unsigned int m3 : 4;
13987 unsigned int : 4;
13988 unsigned int op2 : 8;
13989 } RIEv1;
13990 struct {
13991 unsigned int op1 : 8;
13992 unsigned int r1 : 4;
13993 unsigned int r2 : 4;
13994 unsigned int i4 : 16;
13995 unsigned int m3 : 4;
13996 unsigned int : 4;
13997 unsigned int op2 : 8;
13998 } RIE_RRPU;
13999 struct {
14000 unsigned int op1 : 8;
14001 unsigned int r1 : 4;
14002 unsigned int m3 : 4;
14003 unsigned int i4 : 16;
14004 unsigned int i2 : 8;
14005 unsigned int op2 : 8;
14006 } RIEv3;
14007 struct {
14008 unsigned int op1 : 8;
14009 unsigned int r1 : 4;
14010 unsigned int op2 : 4;
14011 unsigned int i2 : 32;
14012 } RIL;
14013 struct {
14014 unsigned int op1 : 8;
14015 unsigned int r1 : 4;
14016 unsigned int m3 : 4;
14017 unsigned int b4 : 4;
14018 unsigned int d4 : 12;
14019 unsigned int i2 : 8;
14020 unsigned int op2 : 8;
14021 } RIS;
14022 struct {
14023 unsigned int op1 : 8;
14024 unsigned int r1 : 4;
14025 unsigned int r2 : 4;
14026 unsigned int b4 : 4;
14027 unsigned int d4 : 12;
14028 unsigned int m3 : 4;
14029 unsigned int : 4;
14030 unsigned int op2 : 8;
14031 } RRS;
14032 struct {
14033 unsigned int op1 : 8;
14034 unsigned int l1 : 4;
14035 unsigned int : 4;
14036 unsigned int b1 : 4;
14037 unsigned int d1 : 12;
14038 unsigned int : 8;
14039 unsigned int op2 : 8;
14040 } RSL;
14041 struct {
14042 unsigned int op1 : 8;
14043 unsigned int r1 : 4;
14044 unsigned int r3 : 4;
14045 unsigned int b2 : 4;
14046 unsigned int dl2 : 12;
14047 unsigned int dh2 : 8;
14048 unsigned int op2 : 8;
14049 } RSY;
14050 struct {
14051 unsigned int op1 : 8;
14052 unsigned int r1 : 4;
14053 unsigned int x2 : 4;
14054 unsigned int b2 : 4;
14055 unsigned int d2 : 12;
14056 unsigned int : 8;
14057 unsigned int op2 : 8;
14058 } RXE;
14059 struct {
14060 unsigned int op1 : 8;
14061 unsigned int r3 : 4;
14062 unsigned int x2 : 4;
14063 unsigned int b2 : 4;
14064 unsigned int d2 : 12;
14065 unsigned int r1 : 4;
14066 unsigned int : 4;
14067 unsigned int op2 : 8;
14068 } RXF;
14069 struct {
14070 unsigned int op1 : 8;
14071 unsigned int r1 : 4;
14072 unsigned int x2 : 4;
14073 unsigned int b2 : 4;
14074 unsigned int dl2 : 12;
14075 unsigned int dh2 : 8;
14076 unsigned int op2 : 8;
14077 } RXY;
14078 struct {
14079 unsigned int op1 : 8;
14080 unsigned int i2 : 8;
14081 unsigned int b1 : 4;
14082 unsigned int dl1 : 12;
14083 unsigned int dh1 : 8;
14084 unsigned int op2 : 8;
14085 } SIY;
14086 struct {
14087 unsigned int op : 8;
14088 unsigned int l : 8;
14089 unsigned int b1 : 4;
14090 unsigned int d1 : 12;
14091 unsigned int b2 : 4;
14092 unsigned int d2 : 12;
14093 } SS;
14094 struct {
14095 unsigned int op : 8;
14096 unsigned int l1 : 4;
14097 unsigned int l2 : 4;
14098 unsigned int b1 : 4;
14099 unsigned int d1 : 12;
14100 unsigned int b2 : 4;
14101 unsigned int d2 : 12;
14102 } SS_LLRDRD;
14103 struct {
14104 unsigned int op : 8;
14105 unsigned int r1 : 4;
14106 unsigned int r3 : 4;
14107 unsigned int b2 : 4;
14108 unsigned int d2 : 12;
14109 unsigned int b4 : 4;
14110 unsigned int d4 : 12;
14111 } SS_RRRDRD2;
14112 struct {
14113 unsigned int op : 16;
14114 unsigned int b1 : 4;
14115 unsigned int d1 : 12;
14116 unsigned int b2 : 4;
14117 unsigned int d2 : 12;
14118 } SSE;
14119 struct {
14120 unsigned int op1 : 8;
14121 unsigned int r3 : 4;
14122 unsigned int op2 : 4;
14123 unsigned int b1 : 4;
14124 unsigned int d1 : 12;
14125 unsigned int b2 : 4;
14126 unsigned int d2 : 12;
14127 } SSF;
14128 struct {
14129 unsigned int op : 16;
14130 unsigned int b1 : 4;
14131 unsigned int d1 : 12;
14132 unsigned int i2 : 16;
14133 } SIL;
14134 } formats;
14135 union {
14136 formats fmt;
14137 ULong value;
14138 } ovl;
14139
14140 vassert(sizeof(formats) == 6);
14141
florianffbd84d2012-12-09 02:06:29 +000014142 ((UChar *)(&ovl.value))[0] = bytes[0];
14143 ((UChar *)(&ovl.value))[1] = bytes[1];
14144 ((UChar *)(&ovl.value))[2] = bytes[2];
14145 ((UChar *)(&ovl.value))[3] = bytes[3];
14146 ((UChar *)(&ovl.value))[4] = bytes[4];
14147 ((UChar *)(&ovl.value))[5] = bytes[5];
14148 ((UChar *)(&ovl.value))[6] = 0x0;
14149 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014150
14151 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14152 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
14153 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14154 ovl.fmt.RXY.dl2,
14155 ovl.fmt.RXY.dh2); goto ok;
14156 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14157 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
14158 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14159 ovl.fmt.RXY.dl2,
14160 ovl.fmt.RXY.dh2); goto ok;
14161 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
14162 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14163 ovl.fmt.RXY.dl2,
14164 ovl.fmt.RXY.dh2); goto ok;
14165 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
14166 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14167 ovl.fmt.RXY.dl2,
14168 ovl.fmt.RXY.dh2); goto ok;
14169 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
14170 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14171 ovl.fmt.RXY.dl2,
14172 ovl.fmt.RXY.dh2); goto ok;
14173 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
14174 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14175 ovl.fmt.RXY.dl2,
14176 ovl.fmt.RXY.dh2); goto ok;
14177 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
14178 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14179 ovl.fmt.RXY.dl2,
14180 ovl.fmt.RXY.dh2); goto ok;
14181 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, 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 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, 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 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14190 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
14191 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14192 ovl.fmt.RXY.dl2,
14193 ovl.fmt.RXY.dh2); goto ok;
14194 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
14195 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14196 ovl.fmt.RXY.dl2,
14197 ovl.fmt.RXY.dh2); goto ok;
14198 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
14199 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
14200 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14201 ovl.fmt.RXY.dl2,
14202 ovl.fmt.RXY.dh2); goto ok;
14203 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
14204 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14205 ovl.fmt.RXY.dl2,
14206 ovl.fmt.RXY.dh2); goto ok;
14207 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
14208 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14209 ovl.fmt.RXY.dl2,
14210 ovl.fmt.RXY.dh2); goto ok;
14211 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
14212 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14213 ovl.fmt.RXY.dl2,
14214 ovl.fmt.RXY.dh2); goto ok;
14215 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
14216 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14217 ovl.fmt.RXY.dl2,
14218 ovl.fmt.RXY.dh2); goto ok;
14219 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
14220 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14221 ovl.fmt.RXY.dl2,
14222 ovl.fmt.RXY.dh2); goto ok;
14223 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
14224 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14225 ovl.fmt.RXY.dl2,
14226 ovl.fmt.RXY.dh2); goto ok;
14227 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
14228 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14229 ovl.fmt.RXY.dl2,
14230 ovl.fmt.RXY.dh2); goto ok;
14231 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
14232 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14233 ovl.fmt.RXY.dl2,
14234 ovl.fmt.RXY.dh2); goto ok;
14235 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
14236 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14237 ovl.fmt.RXY.dl2,
14238 ovl.fmt.RXY.dh2); goto ok;
14239 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
14240 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14241 ovl.fmt.RXY.dl2,
14242 ovl.fmt.RXY.dh2); goto ok;
14243 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
14244 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14245 ovl.fmt.RXY.dl2,
14246 ovl.fmt.RXY.dh2); goto ok;
14247 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
14248 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14249 ovl.fmt.RXY.dl2,
14250 ovl.fmt.RXY.dh2); goto ok;
14251 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
14252 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14253 ovl.fmt.RXY.dl2,
14254 ovl.fmt.RXY.dh2); goto ok;
14255 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
14256 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14257 ovl.fmt.RXY.dl2,
14258 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014259 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014260 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
14261 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14262 ovl.fmt.RXY.dl2,
14263 ovl.fmt.RXY.dh2); goto ok;
14264 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
14265 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
14266 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14267 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14268 ovl.fmt.RXY.dh2); goto ok;
14269 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
14270 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14271 ovl.fmt.RXY.dl2,
14272 ovl.fmt.RXY.dh2); goto ok;
14273 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
14274 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14275 ovl.fmt.RXY.dl2,
14276 ovl.fmt.RXY.dh2); goto ok;
14277 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
14278 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14279 ovl.fmt.RXY.dl2,
14280 ovl.fmt.RXY.dh2); goto ok;
14281 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
14282 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14283 ovl.fmt.RXY.dl2,
14284 ovl.fmt.RXY.dh2); goto ok;
14285 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
14286 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14287 ovl.fmt.RXY.dl2,
14288 ovl.fmt.RXY.dh2); goto ok;
14289 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
14290 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14291 ovl.fmt.RXY.dl2,
14292 ovl.fmt.RXY.dh2); goto ok;
14293 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
14294 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14295 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14296 ovl.fmt.RXY.dh2); goto ok;
14297 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
14298 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14299 ovl.fmt.RXY.dl2,
14300 ovl.fmt.RXY.dh2); goto ok;
14301 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
14302 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14303 ovl.fmt.RXY.dl2,
14304 ovl.fmt.RXY.dh2); goto ok;
14305 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
14306 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14307 ovl.fmt.RXY.dl2,
14308 ovl.fmt.RXY.dh2); goto ok;
14309 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
14310 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14311 ovl.fmt.RXY.dl2,
14312 ovl.fmt.RXY.dh2); goto ok;
14313 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
14314 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14315 ovl.fmt.RXY.dl2,
14316 ovl.fmt.RXY.dh2); goto ok;
14317 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
14318 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14319 ovl.fmt.RXY.dl2,
14320 ovl.fmt.RXY.dh2); goto ok;
14321 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14322 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14323 ovl.fmt.RXY.dl2,
14324 ovl.fmt.RXY.dh2); goto ok;
14325 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14326 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14327 ovl.fmt.RXY.dl2,
14328 ovl.fmt.RXY.dh2); goto ok;
14329 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14330 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14331 ovl.fmt.RXY.dl2,
14332 ovl.fmt.RXY.dh2); goto ok;
14333 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14334 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14335 ovl.fmt.RXY.dl2,
14336 ovl.fmt.RXY.dh2); goto ok;
14337 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14338 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14339 ovl.fmt.RXY.dl2,
14340 ovl.fmt.RXY.dh2); goto ok;
14341 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14342 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14343 ovl.fmt.RXY.dl2,
14344 ovl.fmt.RXY.dh2); goto ok;
14345 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14346 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14347 ovl.fmt.RXY.dl2,
14348 ovl.fmt.RXY.dh2); goto ok;
14349 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14350 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14351 ovl.fmt.RXY.dl2,
14352 ovl.fmt.RXY.dh2); goto ok;
14353 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
14354 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14355 ovl.fmt.RXY.dl2,
14356 ovl.fmt.RXY.dh2); goto ok;
14357 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14358 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14359 ovl.fmt.RXY.dl2,
14360 ovl.fmt.RXY.dh2); goto ok;
14361 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14362 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14363 ovl.fmt.RXY.dl2,
14364 ovl.fmt.RXY.dh2); goto ok;
14365 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14366 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14367 ovl.fmt.RXY.dl2,
14368 ovl.fmt.RXY.dh2); goto ok;
14369 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14370 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14371 ovl.fmt.RXY.dl2,
14372 ovl.fmt.RXY.dh2); goto ok;
14373 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14374 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14375 ovl.fmt.RXY.dl2,
14376 ovl.fmt.RXY.dh2); goto ok;
14377 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14378 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14379 ovl.fmt.RXY.dl2,
14380 ovl.fmt.RXY.dh2); goto ok;
14381 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14382 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14383 ovl.fmt.RXY.dl2,
14384 ovl.fmt.RXY.dh2); goto ok;
14385 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14386 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14387 ovl.fmt.RXY.dl2,
14388 ovl.fmt.RXY.dh2); goto ok;
14389 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14390 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14391 ovl.fmt.RXY.dl2,
14392 ovl.fmt.RXY.dh2); goto ok;
14393 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14394 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14395 ovl.fmt.RXY.dl2,
14396 ovl.fmt.RXY.dh2); goto ok;
14397 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14398 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14399 ovl.fmt.RXY.dl2,
14400 ovl.fmt.RXY.dh2); goto ok;
14401 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14402 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14403 ovl.fmt.RXY.dl2,
14404 ovl.fmt.RXY.dh2); goto ok;
14405 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14406 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14407 ovl.fmt.RXY.dl2,
14408 ovl.fmt.RXY.dh2); goto ok;
14409 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14410 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14411 ovl.fmt.RXY.dl2,
14412 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014413 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014414 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14415 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14416 ovl.fmt.RXY.dl2,
14417 ovl.fmt.RXY.dh2); goto ok;
14418 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14419 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14420 ovl.fmt.RXY.dl2,
14421 ovl.fmt.RXY.dh2); goto ok;
14422 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14423 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14424 ovl.fmt.RXY.dl2,
14425 ovl.fmt.RXY.dh2); goto ok;
14426 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14427 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14428 ovl.fmt.RXY.dl2,
14429 ovl.fmt.RXY.dh2); goto ok;
14430 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14431 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14432 ovl.fmt.RXY.dl2,
14433 ovl.fmt.RXY.dh2); goto ok;
14434 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14435 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14436 ovl.fmt.RXY.dl2,
14437 ovl.fmt.RXY.dh2); goto ok;
14438 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14439 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14440 ovl.fmt.RXY.dl2,
14441 ovl.fmt.RXY.dh2); goto ok;
14442 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14443 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14444 ovl.fmt.RXY.dl2,
14445 ovl.fmt.RXY.dh2); goto ok;
14446 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14447 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14448 ovl.fmt.RXY.dl2,
14449 ovl.fmt.RXY.dh2); goto ok;
14450 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14451 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14452 ovl.fmt.RXY.dl2,
14453 ovl.fmt.RXY.dh2); goto ok;
14454 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14455 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14456 ovl.fmt.RXY.dl2,
14457 ovl.fmt.RXY.dh2); goto ok;
14458 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14459 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14460 ovl.fmt.RXY.dl2,
14461 ovl.fmt.RXY.dh2); goto ok;
14462 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14463 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14464 ovl.fmt.RXY.dl2,
14465 ovl.fmt.RXY.dh2); goto ok;
14466 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14467 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14468 ovl.fmt.RXY.dl2,
14469 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014470 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
14471 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
14472 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014473 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14474 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14475 ovl.fmt.RXY.dl2,
14476 ovl.fmt.RXY.dh2); goto ok;
14477 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14478 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14479 ovl.fmt.RXY.dl2,
14480 ovl.fmt.RXY.dh2); goto ok;
14481 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14482 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14483 ovl.fmt.RXY.dl2,
14484 ovl.fmt.RXY.dh2); goto ok;
14485 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14486 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14487 ovl.fmt.RXY.dl2,
14488 ovl.fmt.RXY.dh2); goto ok;
14489 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14490 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14491 ovl.fmt.RXY.dl2,
14492 ovl.fmt.RXY.dh2); goto ok;
14493 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14494 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14495 ovl.fmt.RXY.dl2,
14496 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014497 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014498 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14499 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14500 ovl.fmt.RXY.dl2,
14501 ovl.fmt.RXY.dh2); goto ok;
14502 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14503 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14504 ovl.fmt.RXY.dl2,
14505 ovl.fmt.RXY.dh2); goto ok;
14506 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14507 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14508 ovl.fmt.RXY.dl2,
14509 ovl.fmt.RXY.dh2); goto ok;
14510 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14511 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14512 ovl.fmt.RXY.dl2,
14513 ovl.fmt.RXY.dh2); goto ok;
14514 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14515 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14516 ovl.fmt.RSY.dl2,
14517 ovl.fmt.RSY.dh2); goto ok;
14518 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14519 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14520 ovl.fmt.RSY.dl2,
14521 ovl.fmt.RSY.dh2); goto ok;
14522 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14523 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14524 ovl.fmt.RSY.dl2,
14525 ovl.fmt.RSY.dh2); goto ok;
14526 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14527 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14528 ovl.fmt.RSY.dl2,
14529 ovl.fmt.RSY.dh2); goto ok;
14530 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14531 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14532 ovl.fmt.RSY.dl2,
14533 ovl.fmt.RSY.dh2); goto ok;
14534 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14535 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14536 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14537 ovl.fmt.RSY.dl2,
14538 ovl.fmt.RSY.dh2); goto ok;
14539 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14540 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14541 ovl.fmt.RSY.dl2,
14542 ovl.fmt.RSY.dh2); goto ok;
14543 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14544 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14545 ovl.fmt.RSY.dl2,
14546 ovl.fmt.RSY.dh2); goto ok;
14547 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14548 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14549 ovl.fmt.RSY.dl2,
14550 ovl.fmt.RSY.dh2); goto ok;
14551 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14552 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14553 ovl.fmt.RSY.dl2,
14554 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014555 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014556 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14557 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14558 ovl.fmt.RSY.dl2,
14559 ovl.fmt.RSY.dh2); goto ok;
14560 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14561 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14562 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14563 ovl.fmt.RSY.dl2,
14564 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014565 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014566 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14567 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14568 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14569 ovl.fmt.RSY.dh2); goto ok;
14570 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14571 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14572 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14573 ovl.fmt.RSY.dh2); goto ok;
14574 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14575 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14576 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14577 ovl.fmt.RSY.dl2,
14578 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014579 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14580 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14581 ovl.fmt.RSY.dl2,
14582 ovl.fmt.RSY.dh2); goto ok;
14583 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14584 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14585 ovl.fmt.RSY.dl2,
14586 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014587 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14588 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14589 ovl.fmt.RSY.dl2,
14590 ovl.fmt.RSY.dh2); goto ok;
14591 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14592 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14593 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14594 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014595 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14596 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14597 ovl.fmt.RSY.dl2,
14598 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014599 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14600 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14601 ovl.fmt.SIY.dh1); goto ok;
14602 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14603 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14604 ovl.fmt.SIY.dh1); goto ok;
14605 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14606 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14607 ovl.fmt.SIY.dh1); goto ok;
14608 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14609 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14610 ovl.fmt.SIY.dh1); goto ok;
14611 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14612 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14613 ovl.fmt.SIY.dh1); goto ok;
14614 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14615 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14616 ovl.fmt.SIY.dh1); goto ok;
14617 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14618 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14619 ovl.fmt.SIY.dh1); goto ok;
14620 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14621 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14622 ovl.fmt.SIY.dh1); goto ok;
14623 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14624 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14625 ovl.fmt.SIY.dh1); goto ok;
14626 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14627 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14628 ovl.fmt.SIY.dh1); goto ok;
14629 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14630 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14631 ovl.fmt.RSY.dl2,
14632 ovl.fmt.RSY.dh2); goto ok;
14633 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14634 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14635 ovl.fmt.RSY.dl2,
14636 ovl.fmt.RSY.dh2); goto ok;
14637 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14638 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14639 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14640 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14641 ovl.fmt.RSY.dl2,
14642 ovl.fmt.RSY.dh2); goto ok;
14643 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14644 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14645 ovl.fmt.RSY.dl2,
14646 ovl.fmt.RSY.dh2); goto ok;
14647 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14648 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14649 ovl.fmt.RSY.dl2,
14650 ovl.fmt.RSY.dh2); goto ok;
14651 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14652 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14653 ovl.fmt.RSY.dl2,
14654 ovl.fmt.RSY.dh2); goto ok;
14655 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14656 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14657 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14658 ovl.fmt.RSY.dh2); goto ok;
14659 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14660 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14661 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14662 ovl.fmt.RSY.dl2,
14663 ovl.fmt.RSY.dh2); goto ok;
14664 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14665 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14666 ovl.fmt.RSY.dl2,
14667 ovl.fmt.RSY.dh2); goto ok;
14668 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14669 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14670 ovl.fmt.RSY.dl2,
14671 ovl.fmt.RSY.dh2); goto ok;
14672 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14673 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14674 ovl.fmt.RSY.dl2,
14675 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014676 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14677 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14678 ovl.fmt.RSY.dl2,
14679 ovl.fmt.RSY.dh2,
14680 S390_XMNM_LOCG); goto ok;
14681 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14682 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14683 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14684 ovl.fmt.RSY.dh2,
14685 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014686 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14687 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14688 ovl.fmt.RSY.dl2,
14689 ovl.fmt.RSY.dh2); goto ok;
14690 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14691 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14692 ovl.fmt.RSY.dl2,
14693 ovl.fmt.RSY.dh2); goto ok;
14694 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14695 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14696 ovl.fmt.RSY.dl2,
14697 ovl.fmt.RSY.dh2); goto ok;
14698 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14699 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14700 ovl.fmt.RSY.dl2,
14701 ovl.fmt.RSY.dh2); goto ok;
14702 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14703 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14704 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14705 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014706 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14707 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14708 ovl.fmt.RSY.dl2,
14709 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14710 goto ok;
14711 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14712 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14713 ovl.fmt.RSY.dl2,
14714 ovl.fmt.RSY.dh2,
14715 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014716 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14717 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14718 ovl.fmt.RSY.dl2,
14719 ovl.fmt.RSY.dh2); goto ok;
14720 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14721 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14722 ovl.fmt.RSY.dl2,
14723 ovl.fmt.RSY.dh2); goto ok;
14724 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14725 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14726 ovl.fmt.RSY.dl2,
14727 ovl.fmt.RSY.dh2); goto ok;
14728 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14729 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14730 ovl.fmt.RSY.dl2,
14731 ovl.fmt.RSY.dh2); goto ok;
14732 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14733 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14734 ovl.fmt.RSY.dl2,
14735 ovl.fmt.RSY.dh2); goto ok;
14736 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14737 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14738 goto ok;
14739 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14740 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14741 goto ok;
14742 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14743 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14744 ovl.fmt.RIE_RRUUU.r1,
14745 ovl.fmt.RIE_RRUUU.r2,
14746 ovl.fmt.RIE_RRUUU.i3,
14747 ovl.fmt.RIE_RRUUU.i4,
14748 ovl.fmt.RIE_RRUUU.i5);
14749 goto ok;
14750 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14751 ovl.fmt.RIE_RRUUU.r1,
14752 ovl.fmt.RIE_RRUUU.r2,
14753 ovl.fmt.RIE_RRUUU.i3,
14754 ovl.fmt.RIE_RRUUU.i4,
14755 ovl.fmt.RIE_RRUUU.i5);
14756 goto ok;
14757 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14758 ovl.fmt.RIE_RRUUU.r1,
14759 ovl.fmt.RIE_RRUUU.r2,
14760 ovl.fmt.RIE_RRUUU.i3,
14761 ovl.fmt.RIE_RRUUU.i4,
14762 ovl.fmt.RIE_RRUUU.i5);
14763 goto ok;
14764 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14765 ovl.fmt.RIE_RRUUU.r1,
14766 ovl.fmt.RIE_RRUUU.r2,
14767 ovl.fmt.RIE_RRUUU.i3,
14768 ovl.fmt.RIE_RRUUU.i4,
14769 ovl.fmt.RIE_RRUUU.i5);
14770 goto ok;
florian2289cd42012-12-05 04:23:42 +000014771 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014772 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14773 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14774 ovl.fmt.RIE_RRPU.r1,
14775 ovl.fmt.RIE_RRPU.r2,
14776 ovl.fmt.RIE_RRPU.i4,
14777 ovl.fmt.RIE_RRPU.m3); goto ok;
14778 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14779 ovl.fmt.RIE_RRPU.r1,
14780 ovl.fmt.RIE_RRPU.r2,
14781 ovl.fmt.RIE_RRPU.i4,
14782 ovl.fmt.RIE_RRPU.m3); goto ok;
14783 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14784 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14785 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14786 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14787 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14788 ovl.fmt.RIE_RRPU.r1,
14789 ovl.fmt.RIE_RRPU.r2,
14790 ovl.fmt.RIE_RRPU.i4,
14791 ovl.fmt.RIE_RRPU.m3); goto ok;
14792 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14793 ovl.fmt.RIE_RRPU.r1,
14794 ovl.fmt.RIE_RRPU.r2,
14795 ovl.fmt.RIE_RRPU.i4,
14796 ovl.fmt.RIE_RRPU.m3); goto ok;
14797 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14798 ovl.fmt.RIEv3.r1,
14799 ovl.fmt.RIEv3.m3,
14800 ovl.fmt.RIEv3.i4,
14801 ovl.fmt.RIEv3.i2); goto ok;
14802 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14803 ovl.fmt.RIEv3.r1,
14804 ovl.fmt.RIEv3.m3,
14805 ovl.fmt.RIEv3.i4,
14806 ovl.fmt.RIEv3.i2); goto ok;
14807 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14808 ovl.fmt.RIEv3.r1,
14809 ovl.fmt.RIEv3.m3,
14810 ovl.fmt.RIEv3.i4,
14811 ovl.fmt.RIEv3.i2); goto ok;
14812 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14813 ovl.fmt.RIEv3.r1,
14814 ovl.fmt.RIEv3.m3,
14815 ovl.fmt.RIEv3.i4,
14816 ovl.fmt.RIEv3.i2); goto ok;
14817 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14818 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14819 goto ok;
14820 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14821 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14822 ovl.fmt.RIE.i2); goto ok;
14823 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14824 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14825 ovl.fmt.RIE.i2); goto ok;
14826 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14827 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14828 ovl.fmt.RIE.i2); goto ok;
14829 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14830 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14831 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14832 goto ok;
14833 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14834 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14835 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14836 goto ok;
14837 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14838 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14839 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14840 goto ok;
14841 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14842 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14843 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14844 goto ok;
14845 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14846 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14847 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14848 ovl.fmt.RIS.i2); goto ok;
14849 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14850 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14851 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14852 ovl.fmt.RIS.i2); goto ok;
14853 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14854 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14855 ovl.fmt.RIS.d4,
14856 ovl.fmt.RIS.i2); goto ok;
14857 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14858 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14859 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14860 ovl.fmt.RIS.i2); goto ok;
14861 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14862 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14863 ovl.fmt.RXE.d2); goto ok;
14864 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14865 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14866 ovl.fmt.RXE.d2); goto ok;
14867 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14868 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14869 ovl.fmt.RXE.d2); goto ok;
14870 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14871 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14872 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14873 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14874 ovl.fmt.RXE.d2); goto ok;
14875 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14876 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14877 ovl.fmt.RXE.d2); goto ok;
14878 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14879 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14880 ovl.fmt.RXE.d2); goto ok;
14881 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14882 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14883 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14884 ovl.fmt.RXE.d2); goto ok;
14885 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14886 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14887 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14888 ovl.fmt.RXF.r1); goto ok;
14889 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14890 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14891 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14892 ovl.fmt.RXF.r1); goto ok;
14893 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14894 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14895 ovl.fmt.RXE.d2); goto ok;
14896 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14897 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14898 ovl.fmt.RXE.d2); goto ok;
14899 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14900 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14901 ovl.fmt.RXE.d2); goto ok;
14902 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14903 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14904 ovl.fmt.RXE.d2); goto ok;
14905 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14906 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14907 ovl.fmt.RXE.d2); goto ok;
14908 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14909 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14910 ovl.fmt.RXE.d2); goto ok;
14911 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14912 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14913 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14914 ovl.fmt.RXE.d2); goto ok;
14915 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14916 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14917 ovl.fmt.RXE.d2); goto ok;
14918 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14919 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14920 ovl.fmt.RXE.d2); goto ok;
14921 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14922 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14923 ovl.fmt.RXE.d2); goto ok;
14924 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14925 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14926 ovl.fmt.RXE.d2); goto ok;
14927 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14928 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14929 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14930 ovl.fmt.RXF.r1); goto ok;
14931 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14932 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14933 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14934 ovl.fmt.RXF.r1); goto ok;
14935 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14936 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14937 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14938 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14939 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14940 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14941 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14942 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14943 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14944 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14945 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14946 case 0xed000000003bULL: /* MY */ goto unimplemented;
14947 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14948 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14949 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14950 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14951 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14952 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14953 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14954 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14955 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14956 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14957 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14958 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14959 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14960 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14961 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14962 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14963 ovl.fmt.RXY.dl2,
14964 ovl.fmt.RXY.dh2); goto ok;
14965 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14966 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14967 ovl.fmt.RXY.dl2,
14968 ovl.fmt.RXY.dh2); goto ok;
14969 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14970 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14971 ovl.fmt.RXY.dl2,
14972 ovl.fmt.RXY.dh2); goto ok;
14973 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14974 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14975 ovl.fmt.RXY.dl2,
14976 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014977 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
14978 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
14979 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
14980 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014981 }
14982
14983 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14984 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14985 ovl.fmt.RIL.i2); goto ok;
14986 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14987 ovl.fmt.RIL.i2); goto ok;
14988 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14989 ovl.fmt.RIL.i2); goto ok;
14990 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14991 ovl.fmt.RIL.i2); goto ok;
14992 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14993 ovl.fmt.RIL.i2); goto ok;
14994 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14995 ovl.fmt.RIL.i2); goto ok;
14996 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14997 ovl.fmt.RIL.i2); goto ok;
14998 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14999 ovl.fmt.RIL.i2); goto ok;
15000 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15001 ovl.fmt.RIL.i2); goto ok;
15002 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15003 ovl.fmt.RIL.i2); goto ok;
15004 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15005 ovl.fmt.RIL.i2); goto ok;
15006 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15007 ovl.fmt.RIL.i2); goto ok;
15008 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15009 ovl.fmt.RIL.i2); goto ok;
15010 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15011 ovl.fmt.RIL.i2); goto ok;
15012 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15013 ovl.fmt.RIL.i2); goto ok;
15014 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15015 ovl.fmt.RIL.i2); goto ok;
15016 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15017 ovl.fmt.RIL.i2); goto ok;
15018 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15019 ovl.fmt.RIL.i2); goto ok;
15020 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15021 ovl.fmt.RIL.i2); goto ok;
15022 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15023 ovl.fmt.RIL.i2); goto ok;
15024 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15025 ovl.fmt.RIL.i2); goto ok;
15026 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15027 ovl.fmt.RIL.i2); goto ok;
15028 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15029 ovl.fmt.RIL.i2); goto ok;
15030 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15031 ovl.fmt.RIL.i2); goto ok;
15032 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15033 ovl.fmt.RIL.i2); goto ok;
15034 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15035 ovl.fmt.RIL.i2); goto ok;
15036 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15037 ovl.fmt.RIL.i2); goto ok;
15038 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15039 ovl.fmt.RIL.i2); goto ok;
15040 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15041 ovl.fmt.RIL.i2); goto ok;
15042 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15043 ovl.fmt.RIL.i2); goto ok;
15044 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15045 ovl.fmt.RIL.i2); goto ok;
15046 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15047 ovl.fmt.RIL.i2); goto ok;
15048 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15049 ovl.fmt.RIL.i2); goto ok;
15050 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15051 ovl.fmt.RIL.i2); goto ok;
15052 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15053 ovl.fmt.RIL.i2); goto ok;
15054 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15055 ovl.fmt.RIL.i2); goto ok;
15056 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15057 ovl.fmt.RIL.i2); goto ok;
15058 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15059 ovl.fmt.RIL.i2); goto ok;
15060 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15061 ovl.fmt.RIL.i2); goto ok;
15062 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15063 ovl.fmt.RIL.i2); goto ok;
15064 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15065 ovl.fmt.RIL.i2); goto ok;
15066 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15067 ovl.fmt.RIL.i2); goto ok;
15068 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15069 ovl.fmt.RIL.i2); goto ok;
15070 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15071 ovl.fmt.RIL.i2); goto ok;
15072 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15073 ovl.fmt.RIL.i2); goto ok;
15074 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15075 ovl.fmt.RIL.i2); goto ok;
15076 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15077 ovl.fmt.RIL.i2); goto ok;
15078 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15079 ovl.fmt.RIL.i2); goto ok;
15080 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15081 ovl.fmt.RIL.i2); goto ok;
15082 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15083 case 0xc801ULL: /* ECTG */ goto unimplemented;
15084 case 0xc802ULL: /* CSST */ goto unimplemented;
15085 case 0xc804ULL: /* LPD */ goto unimplemented;
15086 case 0xc805ULL: /* LPDG */ goto unimplemented;
15087 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15088 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15089 ovl.fmt.RIL.i2); goto ok;
15090 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15091 ovl.fmt.RIL.i2); goto ok;
15092 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15093 ovl.fmt.RIL.i2); goto ok;
15094 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15095 ovl.fmt.RIL.i2); goto ok;
15096 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15097 ovl.fmt.RIL.i2); goto ok;
15098 }
15099
15100 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015101 case 0xc5ULL: /* BPRP */ goto unimplemented;
15102 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015103 case 0xd0ULL: /* TRTR */ goto unimplemented;
15104 case 0xd1ULL: /* MVN */ goto unimplemented;
15105 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15106 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15107 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15108 case 0xd3ULL: /* MVZ */ goto unimplemented;
15109 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15110 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15111 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15112 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15113 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15114 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15115 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15116 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15117 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015118 case 0xd7ULL:
15119 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15120 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15121 else
15122 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15123 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15124 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15125 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015126 case 0xd9ULL: /* MVCK */ goto unimplemented;
15127 case 0xdaULL: /* MVCP */ goto unimplemented;
15128 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015129 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15130 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15131 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015132 case 0xddULL: /* TRT */ goto unimplemented;
15133 case 0xdeULL: /* ED */ goto unimplemented;
15134 case 0xdfULL: /* EDMK */ goto unimplemented;
15135 case 0xe1ULL: /* PKU */ goto unimplemented;
15136 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15137 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15138 case 0xe9ULL: /* PKA */ goto unimplemented;
15139 case 0xeaULL: /* UNPKA */ goto unimplemented;
15140 case 0xeeULL: /* PLO */ goto unimplemented;
15141 case 0xefULL: /* LMD */ goto unimplemented;
15142 case 0xf0ULL: /* SRP */ goto unimplemented;
15143 case 0xf1ULL: /* MVO */ goto unimplemented;
15144 case 0xf2ULL: /* PACK */ goto unimplemented;
15145 case 0xf3ULL: /* UNPK */ goto unimplemented;
15146 case 0xf8ULL: /* ZAP */ goto unimplemented;
15147 case 0xf9ULL: /* CP */ goto unimplemented;
15148 case 0xfaULL: /* AP */ goto unimplemented;
15149 case 0xfbULL: /* SP */ goto unimplemented;
15150 case 0xfcULL: /* MP */ goto unimplemented;
15151 case 0xfdULL: /* DP */ goto unimplemented;
15152 }
15153
15154 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15155 case 0xe500ULL: /* LASP */ goto unimplemented;
15156 case 0xe501ULL: /* TPROT */ goto unimplemented;
15157 case 0xe502ULL: /* STRAG */ goto unimplemented;
15158 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15159 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15160 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15161 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15162 goto ok;
15163 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15164 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15165 goto ok;
15166 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
15167 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15168 goto ok;
15169 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
15170 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15171 goto ok;
15172 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
15173 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15174 goto ok;
15175 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
15176 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15177 goto ok;
15178 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
15179 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15180 goto ok;
15181 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
15182 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15183 goto ok;
15184 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
15185 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15186 goto ok;
florian2289cd42012-12-05 04:23:42 +000015187 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
15188 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015189 }
15190
15191 return S390_DECODE_UNKNOWN_INSN;
15192
15193ok:
15194 return S390_DECODE_OK;
15195
15196unimplemented:
15197 return S390_DECODE_UNIMPLEMENTED_INSN;
15198}
15199
15200/* Handle "special" instructions. */
15201static s390_decode_t
15202s390_decode_special_and_irgen(UChar *bytes)
15203{
15204 s390_decode_t status = S390_DECODE_OK;
15205
15206 /* Got a "Special" instruction preamble. Which one is it? */
15207 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
15208 s390_irgen_client_request();
15209 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
15210 s390_irgen_guest_NRADDR();
15211 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
15212 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000015213 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
15214 vex_inject_ir(irsb, Iend_BE);
15215
15216 /* Invalidate the current insn. The reason is that the IRop we're
15217 injecting here can change. In which case the translation has to
15218 be redone. For ease of handling, we simply invalidate all the
15219 time. */
15220 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
15221 mkU64(guest_IA_curr_instr)));
15222 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
15223 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
15224 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
15225 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
15226
15227 put_IA(mkaddr_expr(guest_IA_next_instr));
15228 dis_res->whatNext = Dis_StopHere;
15229 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000015230 } else {
15231 /* We don't know what it is. */
15232 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
15233 }
15234
15235 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15236
15237 return status;
15238}
15239
15240
15241/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000015242static UInt
sewardj2019a972011-03-07 16:04:07 +000015243s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
15244{
15245 s390_decode_t status;
15246
15247 dis_res = dres;
15248
15249 /* Spot the 8-byte preamble: 18ff lr r15,r15
15250 1811 lr r1,r1
15251 1822 lr r2,r2
15252 1833 lr r3,r3 */
15253 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
15254 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
15255 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
15256
15257 /* Handle special instruction that follows that preamble. */
15258 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000015259
15260 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15261 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15262
15263 status =
15264 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000015265 } else {
15266 /* Handle normal instructions. */
15267 switch (insn_length) {
15268 case 2:
15269 status = s390_decode_2byte_and_irgen(bytes);
15270 break;
15271
15272 case 4:
15273 status = s390_decode_4byte_and_irgen(bytes);
15274 break;
15275
15276 case 6:
15277 status = s390_decode_6byte_and_irgen(bytes);
15278 break;
15279
15280 default:
15281 status = S390_DECODE_ERROR;
15282 break;
15283 }
15284 }
florian5fcbba22011-07-27 20:40:22 +000015285 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000015286 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
15287 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000015288 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000015289 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000015290 }
15291
15292 if (status == S390_DECODE_OK) return insn_length; /* OK */
15293
15294 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000015295 if (sigill_diag) {
15296 vex_printf("vex s390->IR: ");
15297 switch (status) {
15298 case S390_DECODE_UNKNOWN_INSN:
15299 vex_printf("unknown insn: ");
15300 break;
sewardj2019a972011-03-07 16:04:07 +000015301
sewardj442e51a2012-12-06 18:08:04 +000015302 case S390_DECODE_UNIMPLEMENTED_INSN:
15303 vex_printf("unimplemented insn: ");
15304 break;
sewardj2019a972011-03-07 16:04:07 +000015305
sewardj442e51a2012-12-06 18:08:04 +000015306 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
15307 vex_printf("unimplemented special insn: ");
15308 break;
sewardj2019a972011-03-07 16:04:07 +000015309
sewardj442e51a2012-12-06 18:08:04 +000015310 default:
15311 case S390_DECODE_ERROR:
15312 vex_printf("decoding error: ");
15313 break;
15314 }
15315
15316 vex_printf("%02x%02x", bytes[0], bytes[1]);
15317 if (insn_length > 2) {
15318 vex_printf(" %02x%02x", bytes[2], bytes[3]);
15319 }
15320 if (insn_length > 4) {
15321 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15322 }
15323 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000015324 }
15325
sewardj2019a972011-03-07 16:04:07 +000015326 return 0; /* Failed */
15327}
15328
15329
sewardj2019a972011-03-07 16:04:07 +000015330/* Disassemble a single instruction INSN into IR. */
15331static DisResult
florian420c5012011-07-22 02:12:28 +000015332disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015333{
15334 UChar byte;
15335 UInt insn_length;
15336 DisResult dres;
15337
15338 /* ---------------------------------------------------- */
15339 /* --- Compute instruction length -- */
15340 /* ---------------------------------------------------- */
15341
15342 /* Get the first byte of the insn. */
15343 byte = insn[0];
15344
15345 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15346 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15347 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15348
15349 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15350
15351 /* ---------------------------------------------------- */
15352 /* --- Initialise the DisResult data -- */
15353 /* ---------------------------------------------------- */
15354 dres.whatNext = Dis_Continue;
15355 dres.len = insn_length;
15356 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015357 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015358
floriana99f20e2011-07-17 14:16:41 +000015359 /* fixs390: consider chasing of conditional jumps */
15360
sewardj2019a972011-03-07 16:04:07 +000015361 /* Normal and special instruction handling starts here. */
15362 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15363 /* All decode failures end up here. The decoder has already issued an
15364 error message.
15365 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015366 not been executed, and (is currently) the next to be executed.
15367 The insn address in the guest state needs to be set to
15368 guest_IA_curr_instr, otherwise the complaint will report an
15369 incorrect address. */
15370 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015371
florian8844a632012-04-13 04:04:06 +000015372 dres.whatNext = Dis_StopHere;
15373 dres.jk_StopHere = Ijk_NoDecode;
15374 dres.continueAt = 0;
15375 dres.len = 0;
15376 } else {
15377 /* Decode success */
15378 switch (dres.whatNext) {
15379 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015380 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015381 break;
15382 case Dis_ResteerU:
15383 case Dis_ResteerC:
15384 put_IA(mkaddr_expr(dres.continueAt));
15385 break;
15386 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015387 if (dres.jk_StopHere == Ijk_EmWarn ||
15388 dres.jk_StopHere == Ijk_EmFail) {
15389 /* We assume here, that emulation warnings are not given for
15390 insns that transfer control. There is no good way to
15391 do that. */
15392 put_IA(mkaddr_expr(guest_IA_next_instr));
15393 }
florian8844a632012-04-13 04:04:06 +000015394 break;
15395 default:
15396 vassert(0);
15397 }
sewardj2019a972011-03-07 16:04:07 +000015398 }
15399
15400 return dres;
15401}
15402
15403
15404/*------------------------------------------------------------*/
15405/*--- Top-level fn ---*/
15406/*------------------------------------------------------------*/
15407
15408/* Disassemble a single instruction into IR. The instruction
15409 is located in host memory at &guest_code[delta]. */
15410
15411DisResult
15412disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015413 Bool (*resteerOkFn)(void *, Addr64),
15414 Bool resteerCisOk,
15415 void *callback_opaque,
15416 UChar *guest_code,
15417 Long delta,
15418 Addr64 guest_IP,
15419 VexArch guest_arch,
15420 VexArchInfo *archinfo,
15421 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000015422 Bool host_bigendian,
15423 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000015424{
15425 vassert(guest_arch == VexArchS390X);
15426
15427 /* The instruction decoder requires a big-endian machine. */
15428 vassert(host_bigendian == True);
15429
15430 /* Set globals (see top of this file) */
15431 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015432 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015433 resteer_fn = resteerOkFn;
15434 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000015435 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000015436
florian420c5012011-07-22 02:12:28 +000015437 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015438}
15439
15440/*---------------------------------------------------------------*/
15441/*--- end guest_s390_toIR.c ---*/
15442/*---------------------------------------------------------------*/