blob: 64a01b7f82e60544c057dc6cba9cb0da633e3c44 [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
sewardj2019a972011-03-07 16:04:07 +000044#include "host_s390_defs.h" /* S390_ROUND_xyzzy */
45
sewardj2019a972011-03-07 16:04:07 +000046
47/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000048/*--- Forward declarations ---*/
49/*------------------------------------------------------------*/
50static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000051static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000052static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000053
54
55/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000056/*--- Globals ---*/
57/*------------------------------------------------------------*/
58
59/* The IRSB* into which we're generating code. */
60static IRSB *irsb;
61
62/* The guest address for the instruction currently being
63 translated. */
64static Addr64 guest_IA_curr_instr;
65
66/* The guest address for the instruction following the current instruction. */
67static Addr64 guest_IA_next_instr;
68
69/* Result of disassembly step. */
70static DisResult *dis_res;
71
floriana64c2432011-07-16 02:11:50 +000072/* Resteer function and callback data */
73static Bool (*resteer_fn)(void *, Addr64);
74static void *resteer_data;
75
sewardj2019a972011-03-07 16:04:07 +000076/* The last seen execute target instruction */
77ULong last_execute_target;
78
79/* The possible outcomes of a decoding operation */
80typedef enum {
81 S390_DECODE_OK,
82 S390_DECODE_UNKNOWN_INSN,
83 S390_DECODE_UNIMPLEMENTED_INSN,
84 S390_DECODE_UNKNOWN_SPECIAL_INSN,
85 S390_DECODE_ERROR
86} s390_decode_t;
87
florian428dfdd2012-03-27 03:09:49 +000088
sewardj2019a972011-03-07 16:04:07 +000089/*------------------------------------------------------------*/
90/*--- Helpers for constructing IR. ---*/
91/*------------------------------------------------------------*/
92
93/* Sign extend a value with the given number of bits. This is a
94 macro because it allows us to overload the type of the value.
95 Note that VALUE must have a signed type! */
96#undef sign_extend
97#define sign_extend(value,num_bits) \
98(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
99 (sizeof(__typeof__(value)) * 8 - (num_bits)))
100
101
102/* Add a statement to the current irsb. */
103static __inline__ void
104stmt(IRStmt *st)
105{
106 addStmtToIRSB(irsb, st);
107}
108
109/* Allocate a new temporary of the given type. */
110static __inline__ IRTemp
111newTemp(IRType type)
112{
113 vassert(isPlausibleIRType(type));
114
115 return newIRTemp(irsb->tyenv, type);
116}
117
118/* Create an expression node for a temporary */
119static __inline__ IRExpr *
120mkexpr(IRTemp tmp)
121{
122 return IRExpr_RdTmp(tmp);
123}
124
florian8844a632012-04-13 04:04:06 +0000125/* Generate an expression node for an address. */
126static __inline__ IRExpr *
127mkaddr_expr(Addr64 addr)
128{
129 return IRExpr_Const(IRConst_U64(addr));
130}
131
sewardj2019a972011-03-07 16:04:07 +0000132/* Add a statement that assigns to a temporary */
133static __inline__ void
134assign(IRTemp dst, IRExpr *expr)
135{
136 stmt(IRStmt_WrTmp(dst, expr));
137}
138
florian8844a632012-04-13 04:04:06 +0000139/* Write an address into the guest_IA */
140static __inline__ void
141put_IA(IRExpr *address)
142{
143 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
144}
145
sewardj2019a972011-03-07 16:04:07 +0000146/* Create a temporary of the given type and assign the expression to it */
147static __inline__ IRTemp
148mktemp(IRType type, IRExpr *expr)
149{
150 IRTemp temp = newTemp(type);
151
152 assign(temp, expr);
153
154 return temp;
155}
156
157/* Create a unary expression */
158static __inline__ IRExpr *
159unop(IROp kind, IRExpr *op)
160{
161 return IRExpr_Unop(kind, op);
162}
163
164/* Create a binary expression */
165static __inline__ IRExpr *
166binop(IROp kind, IRExpr *op1, IRExpr *op2)
167{
168 return IRExpr_Binop(kind, op1, op2);
169}
170
171/* Create a ternary expression */
172static __inline__ IRExpr *
173triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
174{
175 return IRExpr_Triop(kind, op1, op2, op3);
176}
177
178/* Create a quaternary expression */
179static __inline__ IRExpr *
180qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
181{
182 return IRExpr_Qop(kind, op1, op2, op3, op4);
183}
184
185/* Create an expression node for an 8-bit integer constant */
186static __inline__ IRExpr *
187mkU8(UInt value)
188{
189 vassert(value < 256);
190
191 return IRExpr_Const(IRConst_U8((UChar)value));
192}
193
194/* Create an expression node for a 16-bit integer constant */
195static __inline__ IRExpr *
196mkU16(UInt value)
197{
198 vassert(value < 65536);
199
200 return IRExpr_Const(IRConst_U16((UShort)value));
201}
202
203/* Create an expression node for a 32-bit integer constant */
204static __inline__ IRExpr *
205mkU32(UInt value)
206{
207 return IRExpr_Const(IRConst_U32(value));
208}
209
210/* Create an expression node for a 64-bit integer constant */
211static __inline__ IRExpr *
212mkU64(ULong value)
213{
214 return IRExpr_Const(IRConst_U64(value));
215}
216
217/* Create an expression node for a 32-bit floating point constant
218 whose value is given by a bit pattern. */
219static __inline__ IRExpr *
220mkF32i(UInt value)
221{
222 return IRExpr_Const(IRConst_F32i(value));
223}
224
225/* Create an expression node for a 32-bit floating point constant
226 whose value is given by a bit pattern. */
227static __inline__ IRExpr *
228mkF64i(ULong value)
229{
230 return IRExpr_Const(IRConst_F64i(value));
231}
232
233/* Little helper function for my sanity. ITE = if-then-else */
234static IRExpr *
235mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
236{
237 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
238
239 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
240}
241
242/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
243static void __inline__
244store(IRExpr *addr, IRExpr *data)
245{
246 stmt(IRStmt_Store(Iend_BE, addr, data));
247}
248
249/* Create an expression that loads a TYPE sized value from ADDR.
250 This is a big-endian machine. */
251static __inline__ IRExpr *
252load(IRType type, IRExpr *addr)
253{
254 return IRExpr_Load(Iend_BE, type, addr);
255}
256
257/* Function call */
258static void
259call_function(IRExpr *callee_address)
260{
florian8844a632012-04-13 04:04:06 +0000261 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000262
florian8844a632012-04-13 04:04:06 +0000263 dis_res->whatNext = Dis_StopHere;
264 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000265}
266
floriana64c2432011-07-16 02:11:50 +0000267/* Function call with known target. */
268static void
269call_function_and_chase(Addr64 callee_address)
270{
271 if (resteer_fn(resteer_data, callee_address)) {
272 dis_res->whatNext = Dis_ResteerU;
273 dis_res->continueAt = callee_address;
274 } else {
florian8844a632012-04-13 04:04:06 +0000275 put_IA(mkaddr_expr(callee_address));
276
floriana64c2432011-07-16 02:11:50 +0000277 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000278 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000279 }
280}
281
sewardj2019a972011-03-07 16:04:07 +0000282/* Function return sequence */
283static void
284return_from_function(IRExpr *return_address)
285{
florian8844a632012-04-13 04:04:06 +0000286 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000287
florian8844a632012-04-13 04:04:06 +0000288 dis_res->whatNext = Dis_StopHere;
289 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000290}
291
292/* A conditional branch whose target is not known at instrumentation time.
293
294 if (condition) goto computed_target;
295
296 Needs to be represented as:
297
298 if (! condition) goto next_instruction;
299 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000300*/
301static void
florianf321da72012-07-21 20:32:57 +0000302if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000303{
304 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
305
florianf321da72012-07-21 20:32:57 +0000306 condition = unop(Iop_Not1, condition);
307
florian8844a632012-04-13 04:04:06 +0000308 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
309 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000310
florian8844a632012-04-13 04:04:06 +0000311 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000312
florian8844a632012-04-13 04:04:06 +0000313 dis_res->whatNext = Dis_StopHere;
314 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000315}
316
317/* A conditional branch whose target is known at instrumentation time. */
318static void
319if_condition_goto(IRExpr *condition, Addr64 target)
320{
321 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
322
florian8844a632012-04-13 04:04:06 +0000323 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
324 S390X_GUEST_OFFSET(guest_IA)));
325
florian7346c7a2012-04-13 21:14:24 +0000326 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000327
328 dis_res->whatNext = Dis_StopHere;
329 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000330}
331
332/* An unconditional branch. Target may or may not be known at instrumentation
333 time. */
334static void
335always_goto(IRExpr *target)
336{
florian8844a632012-04-13 04:04:06 +0000337 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000338
florian8844a632012-04-13 04:04:06 +0000339 dis_res->whatNext = Dis_StopHere;
340 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000341}
342
florian8844a632012-04-13 04:04:06 +0000343
floriana64c2432011-07-16 02:11:50 +0000344/* An unconditional branch to a known target. */
345static void
346always_goto_and_chase(Addr64 target)
347{
348 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000349 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000350 dis_res->whatNext = Dis_ResteerU;
351 dis_res->continueAt = target;
352 } else {
florian8844a632012-04-13 04:04:06 +0000353 put_IA(mkaddr_expr(target));
354
355 dis_res->whatNext = Dis_StopHere;
356 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000357 }
358}
359
sewardj2019a972011-03-07 16:04:07 +0000360/* A system call */
361static void
362system_call(IRExpr *sysno)
363{
364 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000366
sewardj69007022011-04-28 20:13:45 +0000367 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
369 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000370
florian8844a632012-04-13 04:04:06 +0000371 put_IA(mkaddr_expr(guest_IA_next_instr));
372
sewardj2019a972011-03-07 16:04:07 +0000373 /* It's important that all ArchRegs carry their up-to-date value
374 at this point. So we declare an end-of-block here, which
375 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000376 dis_res->whatNext = Dis_StopHere;
377 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000378}
379
florian6820ba52012-07-26 02:01:50 +0000380/* A side exit that branches back to the current insn if CONDITION is
381 true. Does not set DisResult. */
382static void
383iterate_if(IRExpr *condition)
384{
385 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
386
387 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
388 S390X_GUEST_OFFSET(guest_IA)));
389}
390
391/* A side exit that branches back to the current insn.
392 Does not set DisResult. */
393static __inline__ void
394iterate(void)
395{
396 iterate_if(IRExpr_Const(IRConst_U1(True)));
397}
398
399/* A side exit that branches back to the insn immediately following the
400 current insn if CONDITION is true. Does not set DisResult. */
401static void
402next_insn_if(IRExpr *condition)
403{
404 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
405
406 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
407 S390X_GUEST_OFFSET(guest_IA)));
408}
409
410/* Convenience function to restart the current insn */
411static void
412restart_if(IRExpr *condition)
413{
414 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
415
416 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
417 S390X_GUEST_OFFSET(guest_IA)));
418}
419
420/* Convenience function to yield to thread scheduler */
421static void
422yield_if(IRExpr *condition)
423{
424 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
425 S390X_GUEST_OFFSET(guest_IA)));
426}
427
sewardj2019a972011-03-07 16:04:07 +0000428static __inline__ IRExpr *get_fpr_dw0(UInt);
429static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000430static __inline__ IRExpr *get_dpr_dw0(UInt);
431static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000432
433/* Read a floating point register pair and combine their contents into a
434 128-bit value */
435static IRExpr *
436get_fpr_pair(UInt archreg)
437{
438 IRExpr *high = get_fpr_dw0(archreg);
439 IRExpr *low = get_fpr_dw0(archreg + 2);
440
441 return binop(Iop_F64HLtoF128, high, low);
442}
443
444/* Write a 128-bit floating point value into a register pair. */
445static void
446put_fpr_pair(UInt archreg, IRExpr *expr)
447{
448 IRExpr *high = unop(Iop_F128HItoF64, expr);
449 IRExpr *low = unop(Iop_F128LOtoF64, expr);
450
451 put_fpr_dw0(archreg, high);
452 put_fpr_dw0(archreg + 2, low);
453}
454
floriane75dafa2012-09-01 17:54:09 +0000455/* Terminate the current IRSB with an emulation failure. */
456static void
457emulation_failure(VexEmNote fail_kind)
458{
459 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000460 dis_res->whatNext = Dis_StopHere;
461 dis_res->jk_StopHere = Ijk_EmFail;
462}
sewardj2019a972011-03-07 16:04:07 +0000463
florian4b8efad2012-09-02 18:07:08 +0000464/* Terminate the current IRSB with an emulation warning. */
465static void
466emulation_warning(VexEmNote warn_kind)
467{
468 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
469 dis_res->whatNext = Dis_StopHere;
470 dis_res->jk_StopHere = Ijk_EmWarn;
471}
472
sewardj2019a972011-03-07 16:04:07 +0000473/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000474/*--- IR Debugging aids. ---*/
475/*------------------------------------------------------------*/
476#if 0
477
478static ULong
479s390_do_print(HChar *text, ULong value)
480{
481 vex_printf("%s %llu\n", text, value);
482 return 0;
483}
484
485static void
486s390_print(HChar *text, IRExpr *value)
487{
488 IRDirty *d;
489
490 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
491 mkIRExprVec_2(mkU64((ULong)text), value));
492 stmt(IRStmt_Dirty(d));
493}
494#endif
495
496
497/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000498/*--- Build the flags thunk. ---*/
499/*------------------------------------------------------------*/
500
501/* Completely fill the flags thunk. We're always filling all fields.
502 Apparently, that is better for redundant PUT elimination. */
503static void
504s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
505{
506 UInt op_off, dep1_off, dep2_off, ndep_off;
507
florian428dfdd2012-03-27 03:09:49 +0000508 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
509 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
510 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
511 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000512
513 stmt(IRStmt_Put(op_off, op));
514 stmt(IRStmt_Put(dep1_off, dep1));
515 stmt(IRStmt_Put(dep2_off, dep2));
516 stmt(IRStmt_Put(ndep_off, ndep));
517}
518
519
520/* Create an expression for V and widen the result to 64 bit. */
521static IRExpr *
522s390_cc_widen(IRTemp v, Bool sign_extend)
523{
524 IRExpr *expr;
525
526 expr = mkexpr(v);
527
528 switch (typeOfIRTemp(irsb->tyenv, v)) {
529 case Ity_I64:
530 break;
531 case Ity_I32:
532 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
533 break;
534 case Ity_I16:
535 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
536 break;
537 case Ity_I8:
538 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
539 break;
540 default:
541 vpanic("s390_cc_widen");
542 }
543
544 return expr;
545}
546
547static void
548s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
549{
550 IRExpr *op, *dep1, *dep2, *ndep;
551
552 op = mkU64(opc);
553 dep1 = s390_cc_widen(d1, sign_extend);
554 dep2 = mkU64(0);
555 ndep = mkU64(0);
556
557 s390_cc_thunk_fill(op, dep1, dep2, ndep);
558}
559
560
561static void
562s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
563{
564 IRExpr *op, *dep1, *dep2, *ndep;
565
566 op = mkU64(opc);
567 dep1 = s390_cc_widen(d1, sign_extend);
568 dep2 = s390_cc_widen(d2, sign_extend);
569 ndep = mkU64(0);
570
571 s390_cc_thunk_fill(op, dep1, dep2, ndep);
572}
573
574
575/* memcheck believes that the NDEP field in the flags thunk is always
576 defined. But for some flag computations (e.g. add with carry) that is
577 just not true. We therefore need to convey to memcheck that the value
578 of the ndep field does matter and therefore we make the DEP2 field
579 depend on it:
580
581 DEP2 = original_DEP2 ^ NDEP
582
583 In s390_calculate_cc we exploit that (a^b)^b == a
584 I.e. we xor the DEP2 value with the NDEP value to recover the
585 original_DEP2 value. */
586static void
587s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
588{
589 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
590
591 op = mkU64(opc);
592 dep1 = s390_cc_widen(d1, sign_extend);
593 dep2 = s390_cc_widen(d2, sign_extend);
594 ndep = s390_cc_widen(nd, sign_extend);
595
596 dep2x = binop(Iop_Xor64, dep2, ndep);
597
598 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
599}
600
601
602/* Write one floating point value into the flags thunk */
603static void
604s390_cc_thunk_put1f(UInt opc, IRTemp d1)
605{
606 IRExpr *op, *dep1, *dep2, *ndep;
607
608 op = mkU64(opc);
609 dep1 = mkexpr(d1);
610 dep2 = mkU64(0);
611 ndep = mkU64(0);
612
613 s390_cc_thunk_fill(op, dep1, dep2, ndep);
614}
615
616
617/* Write a floating point value and an integer into the flags thunk. The
618 integer value is zero-extended first. */
619static void
620s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
621{
622 IRExpr *op, *dep1, *dep2, *ndep;
623
624 op = mkU64(opc);
625 dep1 = mkexpr(d1);
626 dep2 = s390_cc_widen(d2, False);
627 ndep = mkU64(0);
628
629 s390_cc_thunk_fill(op, dep1, dep2, ndep);
630}
631
632
633/* Write a 128-bit floating point value into the flags thunk. This is
634 done by splitting the value into two 64-bits values. */
635static void
636s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
637{
638 IRExpr *op, *hi, *lo, *ndep;
639
640 op = mkU64(opc);
641 hi = unop(Iop_F128HItoF64, mkexpr(d1));
642 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
643 ndep = mkU64(0);
644
645 s390_cc_thunk_fill(op, hi, lo, ndep);
646}
647
648
649/* Write a 128-bit floating point value and an integer into the flags thunk.
650 The integer value is zero-extended first. */
651static void
652s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
653{
654 IRExpr *op, *hi, *lo, *lox, *ndep;
655
656 op = mkU64(opc);
657 hi = unop(Iop_F128HItoF64, mkexpr(d1));
658 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
659 ndep = s390_cc_widen(nd, False);
660
661 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
662
663 s390_cc_thunk_fill(op, hi, lox, ndep);
664}
665
666
667static void
668s390_cc_set(UInt val)
669{
670 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
671 mkU64(val), mkU64(0), mkU64(0));
672}
673
674/* Build IR to calculate the condition code from flags thunk.
675 Returns an expression of type Ity_I32 */
676static IRExpr *
677s390_call_calculate_cc(void)
678{
679 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
680
florian428dfdd2012-03-27 03:09:49 +0000681 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
682 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
683 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
684 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000685
686 args = mkIRExprVec_4(op, dep1, dep2, ndep);
687 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
688 "s390_calculate_cc", &s390_calculate_cc, args);
689
690 /* Exclude OP and NDEP from definedness checking. We're only
691 interested in DEP1 and DEP2. */
692 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
693
694 return call;
695}
696
697/* Build IR to calculate the internal condition code for a "compare and branch"
698 insn. Returns an expression of type Ity_I32 */
699static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000700s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000701{
florianff9613f2012-05-12 15:26:44 +0000702 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000703
florianff9613f2012-05-12 15:26:44 +0000704 switch (opc) {
705 case S390_CC_OP_SIGNED_COMPARE:
706 dep1 = s390_cc_widen(op1, True);
707 dep2 = s390_cc_widen(op2, True);
708 break;
709
710 case S390_CC_OP_UNSIGNED_COMPARE:
711 dep1 = s390_cc_widen(op1, False);
712 dep2 = s390_cc_widen(op2, False);
713 break;
714
715 default:
716 vpanic("s390_call_calculate_icc");
717 }
718
719 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000720 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000721
florianff9613f2012-05-12 15:26:44 +0000722 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000723 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000724 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000725
florianff9613f2012-05-12 15:26:44 +0000726 /* Exclude the requested condition, OP and NDEP from definedness
727 checking. We're only interested in DEP1 and DEP2. */
728 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000729
730 return call;
731}
732
733/* Build IR to calculate the condition code from flags thunk.
734 Returns an expression of type Ity_I32 */
735static IRExpr *
736s390_call_calculate_cond(UInt m)
737{
738 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
739
740 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000741 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
742 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
743 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
744 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000745
746 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
747 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
748 "s390_calculate_cond", &s390_calculate_cond, args);
749
750 /* Exclude the requested condition, OP and NDEP from definedness
751 checking. We're only interested in DEP1 and DEP2. */
752 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
753
754 return call;
755}
756
757#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
758#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
759#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
760#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
761#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
762#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
763#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
764 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
765#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
766 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000767
768
sewardj2019a972011-03-07 16:04:07 +0000769
770
771/*------------------------------------------------------------*/
772/*--- Guest register access ---*/
773/*------------------------------------------------------------*/
774
775
776/*------------------------------------------------------------*/
777/*--- ar registers ---*/
778/*------------------------------------------------------------*/
779
780/* Return the guest state offset of a ar register. */
781static UInt
782ar_offset(UInt archreg)
783{
784 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000785 S390X_GUEST_OFFSET(guest_a0),
786 S390X_GUEST_OFFSET(guest_a1),
787 S390X_GUEST_OFFSET(guest_a2),
788 S390X_GUEST_OFFSET(guest_a3),
789 S390X_GUEST_OFFSET(guest_a4),
790 S390X_GUEST_OFFSET(guest_a5),
791 S390X_GUEST_OFFSET(guest_a6),
792 S390X_GUEST_OFFSET(guest_a7),
793 S390X_GUEST_OFFSET(guest_a8),
794 S390X_GUEST_OFFSET(guest_a9),
795 S390X_GUEST_OFFSET(guest_a10),
796 S390X_GUEST_OFFSET(guest_a11),
797 S390X_GUEST_OFFSET(guest_a12),
798 S390X_GUEST_OFFSET(guest_a13),
799 S390X_GUEST_OFFSET(guest_a14),
800 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000801 };
802
803 vassert(archreg < 16);
804
805 return offset[archreg];
806}
807
808
809/* Return the guest state offset of word #0 of a ar register. */
810static __inline__ UInt
811ar_w0_offset(UInt archreg)
812{
813 return ar_offset(archreg) + 0;
814}
815
816/* Write word #0 of a ar to the guest state. */
817static __inline__ void
818put_ar_w0(UInt archreg, IRExpr *expr)
819{
820 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
821
822 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
823}
824
825/* Read word #0 of a ar register. */
826static __inline__ IRExpr *
827get_ar_w0(UInt archreg)
828{
829 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
830}
831
832
833/*------------------------------------------------------------*/
834/*--- fpr registers ---*/
835/*------------------------------------------------------------*/
836
837/* Return the guest state offset of a fpr register. */
838static UInt
839fpr_offset(UInt archreg)
840{
841 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000842 S390X_GUEST_OFFSET(guest_f0),
843 S390X_GUEST_OFFSET(guest_f1),
844 S390X_GUEST_OFFSET(guest_f2),
845 S390X_GUEST_OFFSET(guest_f3),
846 S390X_GUEST_OFFSET(guest_f4),
847 S390X_GUEST_OFFSET(guest_f5),
848 S390X_GUEST_OFFSET(guest_f6),
849 S390X_GUEST_OFFSET(guest_f7),
850 S390X_GUEST_OFFSET(guest_f8),
851 S390X_GUEST_OFFSET(guest_f9),
852 S390X_GUEST_OFFSET(guest_f10),
853 S390X_GUEST_OFFSET(guest_f11),
854 S390X_GUEST_OFFSET(guest_f12),
855 S390X_GUEST_OFFSET(guest_f13),
856 S390X_GUEST_OFFSET(guest_f14),
857 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000858 };
859
860 vassert(archreg < 16);
861
862 return offset[archreg];
863}
864
865
866/* Return the guest state offset of word #0 of a fpr register. */
867static __inline__ UInt
868fpr_w0_offset(UInt archreg)
869{
870 return fpr_offset(archreg) + 0;
871}
872
873/* Write word #0 of a fpr to the guest state. */
874static __inline__ void
875put_fpr_w0(UInt archreg, IRExpr *expr)
876{
877 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
878
879 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
880}
881
882/* Read word #0 of a fpr register. */
883static __inline__ IRExpr *
884get_fpr_w0(UInt archreg)
885{
886 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
887}
888
889/* Return the guest state offset of double word #0 of a fpr register. */
890static __inline__ UInt
891fpr_dw0_offset(UInt archreg)
892{
893 return fpr_offset(archreg) + 0;
894}
895
896/* Write double word #0 of a fpr to the guest state. */
897static __inline__ void
898put_fpr_dw0(UInt archreg, IRExpr *expr)
899{
900 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
901
902 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
903}
904
905/* Read double word #0 of a fpr register. */
906static __inline__ IRExpr *
907get_fpr_dw0(UInt archreg)
908{
909 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
910}
911
florian12390202012-11-10 22:34:14 +0000912/* Write double word #0 of a fpr containg DFP value to the guest state. */
913static __inline__ void
914put_dpr_dw0(UInt archreg, IRExpr *expr)
915{
916 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
917
918 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
919}
920
921/* Read double word #0 of a fpr register containing DFP value. */
922static __inline__ IRExpr *
923get_dpr_dw0(UInt archreg)
924{
925 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
926}
sewardj2019a972011-03-07 16:04:07 +0000927
928/*------------------------------------------------------------*/
929/*--- gpr registers ---*/
930/*------------------------------------------------------------*/
931
932/* Return the guest state offset of a gpr register. */
933static UInt
934gpr_offset(UInt archreg)
935{
936 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000937 S390X_GUEST_OFFSET(guest_r0),
938 S390X_GUEST_OFFSET(guest_r1),
939 S390X_GUEST_OFFSET(guest_r2),
940 S390X_GUEST_OFFSET(guest_r3),
941 S390X_GUEST_OFFSET(guest_r4),
942 S390X_GUEST_OFFSET(guest_r5),
943 S390X_GUEST_OFFSET(guest_r6),
944 S390X_GUEST_OFFSET(guest_r7),
945 S390X_GUEST_OFFSET(guest_r8),
946 S390X_GUEST_OFFSET(guest_r9),
947 S390X_GUEST_OFFSET(guest_r10),
948 S390X_GUEST_OFFSET(guest_r11),
949 S390X_GUEST_OFFSET(guest_r12),
950 S390X_GUEST_OFFSET(guest_r13),
951 S390X_GUEST_OFFSET(guest_r14),
952 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000953 };
954
955 vassert(archreg < 16);
956
957 return offset[archreg];
958}
959
960
961/* Return the guest state offset of word #0 of a gpr register. */
962static __inline__ UInt
963gpr_w0_offset(UInt archreg)
964{
965 return gpr_offset(archreg) + 0;
966}
967
968/* Write word #0 of a gpr to the guest state. */
969static __inline__ void
970put_gpr_w0(UInt archreg, IRExpr *expr)
971{
972 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
973
974 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
975}
976
977/* Read word #0 of a gpr register. */
978static __inline__ IRExpr *
979get_gpr_w0(UInt archreg)
980{
981 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
982}
983
984/* Return the guest state offset of double word #0 of a gpr register. */
985static __inline__ UInt
986gpr_dw0_offset(UInt archreg)
987{
988 return gpr_offset(archreg) + 0;
989}
990
991/* Write double word #0 of a gpr to the guest state. */
992static __inline__ void
993put_gpr_dw0(UInt archreg, IRExpr *expr)
994{
995 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
996
997 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
998}
999
1000/* Read double word #0 of a gpr register. */
1001static __inline__ IRExpr *
1002get_gpr_dw0(UInt archreg)
1003{
1004 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1005}
1006
1007/* Return the guest state offset of half word #1 of a gpr register. */
1008static __inline__ UInt
1009gpr_hw1_offset(UInt archreg)
1010{
1011 return gpr_offset(archreg) + 2;
1012}
1013
1014/* Write half word #1 of a gpr to the guest state. */
1015static __inline__ void
1016put_gpr_hw1(UInt archreg, IRExpr *expr)
1017{
1018 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1019
1020 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1021}
1022
1023/* Read half word #1 of a gpr register. */
1024static __inline__ IRExpr *
1025get_gpr_hw1(UInt archreg)
1026{
1027 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1028}
1029
1030/* Return the guest state offset of byte #6 of a gpr register. */
1031static __inline__ UInt
1032gpr_b6_offset(UInt archreg)
1033{
1034 return gpr_offset(archreg) + 6;
1035}
1036
1037/* Write byte #6 of a gpr to the guest state. */
1038static __inline__ void
1039put_gpr_b6(UInt archreg, IRExpr *expr)
1040{
1041 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1042
1043 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1044}
1045
1046/* Read byte #6 of a gpr register. */
1047static __inline__ IRExpr *
1048get_gpr_b6(UInt archreg)
1049{
1050 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1051}
1052
1053/* Return the guest state offset of byte #3 of a gpr register. */
1054static __inline__ UInt
1055gpr_b3_offset(UInt archreg)
1056{
1057 return gpr_offset(archreg) + 3;
1058}
1059
1060/* Write byte #3 of a gpr to the guest state. */
1061static __inline__ void
1062put_gpr_b3(UInt archreg, IRExpr *expr)
1063{
1064 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1065
1066 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1067}
1068
1069/* Read byte #3 of a gpr register. */
1070static __inline__ IRExpr *
1071get_gpr_b3(UInt archreg)
1072{
1073 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1074}
1075
1076/* Return the guest state offset of byte #0 of a gpr register. */
1077static __inline__ UInt
1078gpr_b0_offset(UInt archreg)
1079{
1080 return gpr_offset(archreg) + 0;
1081}
1082
1083/* Write byte #0 of a gpr to the guest state. */
1084static __inline__ void
1085put_gpr_b0(UInt archreg, IRExpr *expr)
1086{
1087 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1088
1089 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1090}
1091
1092/* Read byte #0 of a gpr register. */
1093static __inline__ IRExpr *
1094get_gpr_b0(UInt archreg)
1095{
1096 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1097}
1098
1099/* Return the guest state offset of word #1 of a gpr register. */
1100static __inline__ UInt
1101gpr_w1_offset(UInt archreg)
1102{
1103 return gpr_offset(archreg) + 4;
1104}
1105
1106/* Write word #1 of a gpr to the guest state. */
1107static __inline__ void
1108put_gpr_w1(UInt archreg, IRExpr *expr)
1109{
1110 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1111
1112 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1113}
1114
1115/* Read word #1 of a gpr register. */
1116static __inline__ IRExpr *
1117get_gpr_w1(UInt archreg)
1118{
1119 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1120}
1121
1122/* Return the guest state offset of half word #3 of a gpr register. */
1123static __inline__ UInt
1124gpr_hw3_offset(UInt archreg)
1125{
1126 return gpr_offset(archreg) + 6;
1127}
1128
1129/* Write half word #3 of a gpr to the guest state. */
1130static __inline__ void
1131put_gpr_hw3(UInt archreg, IRExpr *expr)
1132{
1133 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1134
1135 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1136}
1137
1138/* Read half word #3 of a gpr register. */
1139static __inline__ IRExpr *
1140get_gpr_hw3(UInt archreg)
1141{
1142 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1143}
1144
1145/* Return the guest state offset of byte #7 of a gpr register. */
1146static __inline__ UInt
1147gpr_b7_offset(UInt archreg)
1148{
1149 return gpr_offset(archreg) + 7;
1150}
1151
1152/* Write byte #7 of a gpr to the guest state. */
1153static __inline__ void
1154put_gpr_b7(UInt archreg, IRExpr *expr)
1155{
1156 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1157
1158 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1159}
1160
1161/* Read byte #7 of a gpr register. */
1162static __inline__ IRExpr *
1163get_gpr_b7(UInt archreg)
1164{
1165 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1166}
1167
1168/* Return the guest state offset of half word #0 of a gpr register. */
1169static __inline__ UInt
1170gpr_hw0_offset(UInt archreg)
1171{
1172 return gpr_offset(archreg) + 0;
1173}
1174
1175/* Write half word #0 of a gpr to the guest state. */
1176static __inline__ void
1177put_gpr_hw0(UInt archreg, IRExpr *expr)
1178{
1179 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1180
1181 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1182}
1183
1184/* Read half word #0 of a gpr register. */
1185static __inline__ IRExpr *
1186get_gpr_hw0(UInt archreg)
1187{
1188 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1189}
1190
1191/* Return the guest state offset of byte #4 of a gpr register. */
1192static __inline__ UInt
1193gpr_b4_offset(UInt archreg)
1194{
1195 return gpr_offset(archreg) + 4;
1196}
1197
1198/* Write byte #4 of a gpr to the guest state. */
1199static __inline__ void
1200put_gpr_b4(UInt archreg, IRExpr *expr)
1201{
1202 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1203
1204 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1205}
1206
1207/* Read byte #4 of a gpr register. */
1208static __inline__ IRExpr *
1209get_gpr_b4(UInt archreg)
1210{
1211 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1212}
1213
1214/* Return the guest state offset of byte #1 of a gpr register. */
1215static __inline__ UInt
1216gpr_b1_offset(UInt archreg)
1217{
1218 return gpr_offset(archreg) + 1;
1219}
1220
1221/* Write byte #1 of a gpr to the guest state. */
1222static __inline__ void
1223put_gpr_b1(UInt archreg, IRExpr *expr)
1224{
1225 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1226
1227 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1228}
1229
1230/* Read byte #1 of a gpr register. */
1231static __inline__ IRExpr *
1232get_gpr_b1(UInt archreg)
1233{
1234 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1235}
1236
1237/* Return the guest state offset of half word #2 of a gpr register. */
1238static __inline__ UInt
1239gpr_hw2_offset(UInt archreg)
1240{
1241 return gpr_offset(archreg) + 4;
1242}
1243
1244/* Write half word #2 of a gpr to the guest state. */
1245static __inline__ void
1246put_gpr_hw2(UInt archreg, IRExpr *expr)
1247{
1248 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1249
1250 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1251}
1252
1253/* Read half word #2 of a gpr register. */
1254static __inline__ IRExpr *
1255get_gpr_hw2(UInt archreg)
1256{
1257 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1258}
1259
1260/* Return the guest state offset of byte #5 of a gpr register. */
1261static __inline__ UInt
1262gpr_b5_offset(UInt archreg)
1263{
1264 return gpr_offset(archreg) + 5;
1265}
1266
1267/* Write byte #5 of a gpr to the guest state. */
1268static __inline__ void
1269put_gpr_b5(UInt archreg, IRExpr *expr)
1270{
1271 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1272
1273 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1274}
1275
1276/* Read byte #5 of a gpr register. */
1277static __inline__ IRExpr *
1278get_gpr_b5(UInt archreg)
1279{
1280 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1281}
1282
1283/* Return the guest state offset of byte #2 of a gpr register. */
1284static __inline__ UInt
1285gpr_b2_offset(UInt archreg)
1286{
1287 return gpr_offset(archreg) + 2;
1288}
1289
1290/* Write byte #2 of a gpr to the guest state. */
1291static __inline__ void
1292put_gpr_b2(UInt archreg, IRExpr *expr)
1293{
1294 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1295
1296 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1297}
1298
1299/* Read byte #2 of a gpr register. */
1300static __inline__ IRExpr *
1301get_gpr_b2(UInt archreg)
1302{
1303 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1304}
1305
1306/* Return the guest state offset of the counter register. */
1307static UInt
1308counter_offset(void)
1309{
floriane88b3c92011-07-05 02:48:39 +00001310 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001311}
1312
1313/* Return the guest state offset of double word #0 of the counter register. */
1314static __inline__ UInt
1315counter_dw0_offset(void)
1316{
1317 return counter_offset() + 0;
1318}
1319
1320/* Write double word #0 of the counter to the guest state. */
1321static __inline__ void
1322put_counter_dw0(IRExpr *expr)
1323{
1324 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1325
1326 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1327}
1328
1329/* Read double word #0 of the counter register. */
1330static __inline__ IRExpr *
1331get_counter_dw0(void)
1332{
1333 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1334}
1335
1336/* Return the guest state offset of word #0 of the counter register. */
1337static __inline__ UInt
1338counter_w0_offset(void)
1339{
1340 return counter_offset() + 0;
1341}
1342
1343/* Return the guest state offset of word #1 of the counter register. */
1344static __inline__ UInt
1345counter_w1_offset(void)
1346{
1347 return counter_offset() + 4;
1348}
1349
1350/* Write word #0 of the counter to the guest state. */
1351static __inline__ void
1352put_counter_w0(IRExpr *expr)
1353{
1354 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1355
1356 stmt(IRStmt_Put(counter_w0_offset(), expr));
1357}
1358
1359/* Read word #0 of the counter register. */
1360static __inline__ IRExpr *
1361get_counter_w0(void)
1362{
1363 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1364}
1365
1366/* Write word #1 of the counter to the guest state. */
1367static __inline__ void
1368put_counter_w1(IRExpr *expr)
1369{
1370 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1371
1372 stmt(IRStmt_Put(counter_w1_offset(), expr));
1373}
1374
1375/* Read word #1 of the counter register. */
1376static __inline__ IRExpr *
1377get_counter_w1(void)
1378{
1379 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1380}
1381
1382/* Return the guest state offset of the fpc register. */
1383static UInt
1384fpc_offset(void)
1385{
floriane88b3c92011-07-05 02:48:39 +00001386 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001387}
1388
1389/* Return the guest state offset of word #0 of the fpc register. */
1390static __inline__ UInt
1391fpc_w0_offset(void)
1392{
1393 return fpc_offset() + 0;
1394}
1395
1396/* Write word #0 of the fpc to the guest state. */
1397static __inline__ void
1398put_fpc_w0(IRExpr *expr)
1399{
1400 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1401
1402 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1403}
1404
1405/* Read word #0 of the fpc register. */
1406static __inline__ IRExpr *
1407get_fpc_w0(void)
1408{
1409 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1410}
1411
1412
1413/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001414/*--- Rounding modes ---*/
1415/*------------------------------------------------------------*/
1416
florian125e20d2012-10-07 15:42:37 +00001417/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001418 IRRoundingMode:
1419
1420 rounding mode | s390 | IR
1421 -------------------------
1422 to nearest | 00 | 00
1423 to zero | 01 | 11
1424 to +infinity | 10 | 10
1425 to -infinity | 11 | 01
1426
1427 So: IR = (4 - s390) & 3
1428*/
1429static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001430get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001431{
1432 IRTemp fpc_bits = newTemp(Ity_I32);
1433
1434 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1435 Prior to that bits [30:31] contained the bfp rounding mode with
1436 bit 29 being unused and having a value of 0. So we can always
1437 extract the least significant 3 bits. */
1438 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1439
1440 /* fixs390:
1441
1442
1443 if (! s390_host_has_fpext && rounding_mode > 3) {
1444 emulation warning @ runtime and
1445 set fpc to round nearest
1446 }
1447 */
1448
1449 /* For now silently adjust an unsupported rounding mode to "nearest" */
1450 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1451 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001452 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001453
1454 // rm_IR = (4 - rm_s390) & 3;
1455 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1456}
1457
1458/* Encode the s390 rounding mode as it appears in the m3 field of certain
1459 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1460 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1461 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1462 considers the default rounding mode (4.3.3). */
1463static IRTemp
1464encode_bfp_rounding_mode(UChar mode)
1465{
1466 IRExpr *rm;
1467
1468 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001469 case S390_BFP_ROUND_PER_FPC:
1470 rm = get_bfp_rounding_mode_from_fpc();
1471 break;
1472 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1473 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1474 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1475 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1476 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1477 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001478 default:
1479 vpanic("encode_bfp_rounding_mode");
1480 }
1481
1482 return mktemp(Ity_I32, rm);
1483}
1484
florianc8e4f562012-10-27 16:19:31 +00001485/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1486 IRRoundingMode:
1487
1488 rounding mode | s390 | IR
1489 ------------------------------------------------
1490 to nearest, ties to even | 000 | 000
1491 to zero | 001 | 011
1492 to +infinity | 010 | 010
1493 to -infinity | 011 | 001
1494 to nearest, ties away from 0 | 100 | 100
1495 to nearest, ties toward 0 | 101 | 111
1496 to away from 0 | 110 | 110
1497 to prepare for shorter precision | 111 | 101
1498
1499 So: IR = (s390 ^ ((s390 << 1) & 2))
1500*/
florianc8e4f562012-10-27 16:19:31 +00001501static IRExpr *
1502get_dfp_rounding_mode_from_fpc(void)
1503{
1504 IRTemp fpc_bits = newTemp(Ity_I32);
1505
1506 /* The dfp rounding mode is stored in bits [25:27].
1507 extract the bits at 25:27 and right shift 4 times. */
1508 assign(fpc_bits, binop(Iop_Shr32,
1509 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1510 mkU8(4)));
1511
1512 IRExpr *rm_s390 = mkexpr(fpc_bits);
1513 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1514
1515 return binop(Iop_Xor32, rm_s390,
1516 binop( Iop_And32,
1517 binop(Iop_Shl32, rm_s390, mkU8(1)),
1518 mkU32(2)));
1519}
1520
1521/* Encode the s390 rounding mode as it appears in the m3 field of certain
1522 instructions to VEX's IRRoundingMode. */
1523static IRTemp
1524encode_dfp_rounding_mode(UChar mode)
1525{
1526 IRExpr *rm;
1527
1528 switch (mode) {
1529 case S390_DFP_ROUND_PER_FPC_0:
1530 case S390_DFP_ROUND_PER_FPC_2:
1531 rm = get_dfp_rounding_mode_from_fpc(); break;
1532 case S390_DFP_ROUND_NEAREST_EVEN_4:
1533 case S390_DFP_ROUND_NEAREST_EVEN_8:
1534 rm = mkU32(Irrm_DFP_NEAREST); break;
1535 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1536 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1537 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1538 case S390_DFP_ROUND_PREPARE_SHORT_3:
1539 case S390_DFP_ROUND_PREPARE_SHORT_15:
1540 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1541 case S390_DFP_ROUND_ZERO_5:
1542 case S390_DFP_ROUND_ZERO_9:
1543 rm = mkU32(Irrm_DFP_ZERO ); break;
1544 case S390_DFP_ROUND_POSINF_6:
1545 case S390_DFP_ROUND_POSINF_10:
1546 rm = mkU32(Irrm_DFP_PosINF); break;
1547 case S390_DFP_ROUND_NEGINF_7:
1548 case S390_DFP_ROUND_NEGINF_11:
1549 rm = mkU32(Irrm_DFP_NegINF); break;
1550 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1551 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1552 case S390_DFP_ROUND_AWAY_0:
1553 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1554 default:
1555 vpanic("encode_dfp_rounding_mode");
1556 }
1557
1558 return mktemp(Ity_I32, rm);
1559}
florian12390202012-11-10 22:34:14 +00001560
florianc8e4f562012-10-27 16:19:31 +00001561
florian2c74d242012-09-12 19:38:42 +00001562/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001563/*--- Build IR for formats ---*/
1564/*------------------------------------------------------------*/
1565static void
1566s390_format_I(HChar *(*irgen)(UChar i),
1567 UChar i)
1568{
1569 HChar *mnm = irgen(i);
1570
sewardj7ee97522011-05-09 21:45:04 +00001571 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001572 s390_disasm(ENC2(MNM, UINT), mnm, i);
1573}
1574
1575static void
1576s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1577 UChar r1, UShort i2)
1578{
1579 irgen(r1, i2);
1580}
1581
1582static void
1583s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1584 UChar r1, UShort i2)
1585{
1586 HChar *mnm = irgen(r1, i2);
1587
sewardj7ee97522011-05-09 21:45:04 +00001588 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001589 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1590}
1591
1592static void
1593s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1594 UChar r1, UShort i2)
1595{
1596 HChar *mnm = irgen(r1, i2);
1597
sewardj7ee97522011-05-09 21:45:04 +00001598 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001599 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1600}
1601
1602static void
1603s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1604 UChar r1, UShort i2)
1605{
1606 HChar *mnm = irgen(r1, i2);
1607
sewardj7ee97522011-05-09 21:45:04 +00001608 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001609 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1610}
1611
1612static void
1613s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1614 UChar r1, UChar r3, UShort i2)
1615{
1616 HChar *mnm = irgen(r1, r3, i2);
1617
sewardj7ee97522011-05-09 21:45:04 +00001618 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001619 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1620}
1621
1622static void
1623s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1624 UChar r1, UChar r3, UShort i2)
1625{
1626 HChar *mnm = irgen(r1, r3, i2);
1627
sewardj7ee97522011-05-09 21:45:04 +00001628 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001629 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1630}
1631
1632static void
1633s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1634 UChar i5),
1635 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1636{
1637 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1638
sewardj7ee97522011-05-09 21:45:04 +00001639 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001640 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1641 i5);
1642}
1643
1644static void
1645s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1646 UChar r1, UChar r2, UShort i4, UChar m3)
1647{
1648 HChar *mnm = irgen(r1, r2, i4, m3);
1649
sewardj7ee97522011-05-09 21:45:04 +00001650 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001651 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1652 r2, m3, (Int)(Short)i4);
1653}
1654
1655static void
1656s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1657 UChar r1, UChar m3, UShort i4, UChar i2)
1658{
1659 HChar *mnm = irgen(r1, m3, i4, i2);
1660
sewardj7ee97522011-05-09 21:45:04 +00001661 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001662 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1663 r1, i2, m3, (Int)(Short)i4);
1664}
1665
1666static void
1667s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1668 UChar r1, UChar m3, UShort i4, UChar i2)
1669{
1670 HChar *mnm = irgen(r1, m3, i4, i2);
1671
sewardj7ee97522011-05-09 21:45:04 +00001672 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001673 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1674 (Int)(Char)i2, m3, (Int)(Short)i4);
1675}
1676
1677static void
1678s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1679 UChar r1, UInt i2)
1680{
1681 irgen(r1, i2);
1682}
1683
1684static void
1685s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1686 UChar r1, UInt i2)
1687{
1688 HChar *mnm = irgen(r1, i2);
1689
sewardj7ee97522011-05-09 21:45:04 +00001690 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001691 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1692}
1693
1694static void
1695s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1696 UChar r1, UInt i2)
1697{
1698 HChar *mnm = irgen(r1, i2);
1699
sewardj7ee97522011-05-09 21:45:04 +00001700 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001701 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1702}
1703
1704static void
1705s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1706 UChar r1, UInt i2)
1707{
1708 HChar *mnm = irgen(r1, i2);
1709
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, PCREL), mnm, r1, i2);
1712}
1713
1714static void
1715s390_format_RIL_UP(HChar *(*irgen)(void),
1716 UChar r1, UInt i2)
1717{
1718 HChar *mnm = irgen();
1719
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, UINT, PCREL), mnm, r1, i2);
1722}
1723
1724static void
1725s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1726 IRTemp op4addr),
1727 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1728{
1729 HChar *mnm;
1730 IRTemp op4addr = newTemp(Ity_I64);
1731
1732 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1733 mkU64(0)));
1734
1735 mnm = irgen(r1, m3, i2, op4addr);
1736
sewardj7ee97522011-05-09 21:45:04 +00001737 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001738 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1739 (Int)(Char)i2, m3, d4, 0, b4);
1740}
1741
1742static void
1743s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1744 IRTemp op4addr),
1745 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1746{
1747 HChar *mnm;
1748 IRTemp op4addr = newTemp(Ity_I64);
1749
1750 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1751 mkU64(0)));
1752
1753 mnm = irgen(r1, m3, i2, op4addr);
1754
sewardj7ee97522011-05-09 21:45:04 +00001755 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001756 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1757 i2, m3, d4, 0, b4);
1758}
1759
1760static void
1761s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1762 UChar r1, UChar r2)
1763{
1764 irgen(r1, r2);
1765}
1766
1767static void
1768s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1769 UChar r1, UChar r2)
1770{
1771 HChar *mnm = irgen(r1, r2);
1772
sewardj7ee97522011-05-09 21:45:04 +00001773 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001774 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1775}
1776
1777static void
1778s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1779 UChar r1, UChar r2)
1780{
1781 HChar *mnm = irgen(r1, r2);
1782
sewardj7ee97522011-05-09 21:45:04 +00001783 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001784 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1785}
1786
1787static void
1788s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1789 UChar r1, UChar r2)
1790{
1791 irgen(r1, r2);
1792}
1793
1794static void
1795s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1796 UChar r1, UChar r2)
1797{
1798 HChar *mnm = irgen(r1, r2);
1799
sewardj7ee97522011-05-09 21:45:04 +00001800 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001801 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1802}
1803
1804static void
1805s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1806 UChar r1, UChar r2)
1807{
1808 HChar *mnm = irgen(r1, r2);
1809
sewardj7ee97522011-05-09 21:45:04 +00001810 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001811 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1812}
1813
1814static void
1815s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1816 UChar r1, UChar r2)
1817{
1818 HChar *mnm = irgen(r1, r2);
1819
sewardj7ee97522011-05-09 21:45:04 +00001820 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001821 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1822}
1823
1824static void
1825s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1826 UChar r1, UChar r2)
1827{
1828 HChar *mnm = irgen(r1, r2);
1829
sewardj7ee97522011-05-09 21:45:04 +00001830 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001831 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1832}
1833
1834static void
1835s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1836 UChar r1)
1837{
1838 HChar *mnm = irgen(r1);
1839
sewardj7ee97522011-05-09 21:45:04 +00001840 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001841 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1842}
1843
1844static void
1845s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1846 UChar r1)
1847{
1848 HChar *mnm = irgen(r1);
1849
sewardj7ee97522011-05-09 21:45:04 +00001850 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001851 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1852}
1853
1854static void
florian9af37692012-01-15 21:01:16 +00001855s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1856 UChar m3, UChar r1, UChar r2)
1857{
florianfed3ea32012-07-19 14:54:03 +00001858 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001859
1860 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001861 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001862}
1863
1864static void
sewardj2019a972011-03-07 16:04:07 +00001865s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1866 UChar r1, UChar r3, UChar r2)
1867{
1868 HChar *mnm = irgen(r1, r3, r2);
1869
sewardj7ee97522011-05-09 21:45:04 +00001870 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001871 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1872}
1873
1874static void
florian4b8efad2012-09-02 18:07:08 +00001875s390_format_RRF_UUFF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1876 UChar m3, UChar m4, UChar r1, UChar r2)
1877{
1878 HChar *mnm = irgen(m3, m4, r1, r2);
1879
1880 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1881 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1882}
1883
1884static void
florian1c8f7ff2012-09-01 00:12:11 +00001885s390_format_RRF_UUFR(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1886 UChar m3, UChar m4, UChar r1, UChar r2)
1887{
1888 HChar *mnm = irgen(m3, m4, r1, r2);
1889
1890 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1891 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1892}
1893
1894static void
1895s390_format_RRF_UURF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1896 UChar m3, UChar m4, UChar r1, UChar r2)
1897{
1898 HChar *mnm = irgen(m3, m4, r1, r2);
1899
1900 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1901 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1902}
1903
1904
1905static void
sewardjd7bde722011-04-05 13:19:33 +00001906s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1907 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1908{
1909 irgen(m3, r1, r2);
1910
sewardj7ee97522011-05-09 21:45:04 +00001911 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001912 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1913}
1914
1915static void
sewardj2019a972011-03-07 16:04:07 +00001916s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1917 UChar r3, UChar r1, UChar r2)
1918{
1919 HChar *mnm = irgen(r3, r1, r2);
1920
sewardj7ee97522011-05-09 21:45:04 +00001921 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001922 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1923}
1924
1925static void
florian12390202012-11-10 22:34:14 +00001926s390_format_RRF_FUFF2(HChar *(*irgen)(UChar, UChar, UChar, UChar),
1927 UChar r3, UChar m4, UChar r1, UChar r2)
1928{
1929 HChar *mnm = irgen(r3, m4, r1, r2);
1930
1931 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1932 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
1933}
1934
1935static void
sewardj2019a972011-03-07 16:04:07 +00001936s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1937 UChar r3, UChar r1, UChar r2)
1938{
1939 HChar *mnm = irgen(r3, r1, r2);
1940
sewardj7ee97522011-05-09 21:45:04 +00001941 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001942 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1943}
1944
1945static void
1946s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1947 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1948{
1949 HChar *mnm;
1950 IRTemp op4addr = newTemp(Ity_I64);
1951
1952 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1953 mkU64(0)));
1954
1955 mnm = irgen(r1, r2, m3, op4addr);
1956
sewardj7ee97522011-05-09 21:45:04 +00001957 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001958 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1959 r2, m3, d4, 0, b4);
1960}
1961
1962static void
1963s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1964 UChar r1, UChar b2, UShort d2)
1965{
1966 HChar *mnm;
1967 IRTemp op2addr = newTemp(Ity_I64);
1968
1969 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1970 mkU64(0)));
1971
1972 mnm = irgen(r1, op2addr);
1973
sewardj7ee97522011-05-09 21:45:04 +00001974 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001975 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1976}
1977
1978static void
1979s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1980 UChar r1, UChar r3, UChar b2, UShort d2)
1981{
1982 HChar *mnm;
1983 IRTemp op2addr = newTemp(Ity_I64);
1984
1985 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1986 mkU64(0)));
1987
1988 mnm = irgen(r1, r3, op2addr);
1989
sewardj7ee97522011-05-09 21:45:04 +00001990 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001991 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1992}
1993
1994static void
1995s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1996 UChar r1, UChar r3, UChar b2, UShort d2)
1997{
1998 HChar *mnm;
1999 IRTemp op2addr = newTemp(Ity_I64);
2000
2001 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2002 mkU64(0)));
2003
2004 mnm = irgen(r1, r3, op2addr);
2005
sewardj7ee97522011-05-09 21:45:04 +00002006 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002007 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2008}
2009
2010static void
2011s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
2012 UChar r1, UChar r3, UChar b2, UShort d2)
2013{
2014 HChar *mnm;
2015 IRTemp op2addr = newTemp(Ity_I64);
2016
2017 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2018 mkU64(0)));
2019
2020 mnm = irgen(r1, r3, op2addr);
2021
sewardj7ee97522011-05-09 21:45:04 +00002022 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002023 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2024}
2025
2026static void
2027s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2028 UChar r1, UChar r3, UShort i2)
2029{
2030 HChar *mnm = irgen(r1, r3, i2);
2031
sewardj7ee97522011-05-09 21:45:04 +00002032 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002033 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2034}
2035
2036static void
2037s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2038 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2039{
2040 HChar *mnm;
2041 IRTemp op2addr = newTemp(Ity_I64);
2042 IRTemp d2 = newTemp(Ity_I64);
2043
2044 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2045 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2046 mkU64(0)));
2047
2048 mnm = irgen(r1, r3, op2addr);
2049
sewardj7ee97522011-05-09 21:45:04 +00002050 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002051 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2052}
2053
2054static void
2055s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
2056 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2057{
2058 HChar *mnm;
2059 IRTemp op2addr = newTemp(Ity_I64);
2060 IRTemp d2 = newTemp(Ity_I64);
2061
2062 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2063 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2064 mkU64(0)));
2065
2066 mnm = irgen(r1, r3, op2addr);
2067
sewardj7ee97522011-05-09 21:45:04 +00002068 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002069 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2070}
2071
2072static void
2073s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2074 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2075{
2076 HChar *mnm;
2077 IRTemp op2addr = newTemp(Ity_I64);
2078 IRTemp d2 = newTemp(Ity_I64);
2079
2080 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2081 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2082 mkU64(0)));
2083
2084 mnm = irgen(r1, r3, op2addr);
2085
sewardj7ee97522011-05-09 21:45:04 +00002086 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002087 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2088}
2089
2090static void
sewardjd7bde722011-04-05 13:19:33 +00002091s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2092 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2093 Int xmnm_kind)
2094{
2095 IRTemp op2addr = newTemp(Ity_I64);
2096 IRTemp d2 = newTemp(Ity_I64);
2097
florian6820ba52012-07-26 02:01:50 +00002098 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2099
sewardjd7bde722011-04-05 13:19:33 +00002100 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2101 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2102 mkU64(0)));
2103
2104 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002105
2106 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002107
sewardj7ee97522011-05-09 21:45:04 +00002108 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002109 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2110}
2111
2112static void
sewardj2019a972011-03-07 16:04:07 +00002113s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
2114 IRTemp op2addr),
2115 UChar r1, UChar x2, UChar b2, UShort d2)
2116{
2117 IRTemp op2addr = newTemp(Ity_I64);
2118
2119 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2120 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2121 mkU64(0)));
2122
2123 irgen(r1, x2, b2, d2, op2addr);
2124}
2125
2126static void
2127s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2128 UChar r1, UChar x2, UChar b2, UShort d2)
2129{
2130 HChar *mnm;
2131 IRTemp op2addr = newTemp(Ity_I64);
2132
2133 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2134 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2135 mkU64(0)));
2136
2137 mnm = irgen(r1, op2addr);
2138
sewardj7ee97522011-05-09 21:45:04 +00002139 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002140 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2141}
2142
2143static void
2144s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2145 UChar r1, UChar x2, UChar b2, UShort d2)
2146{
2147 HChar *mnm;
2148 IRTemp op2addr = newTemp(Ity_I64);
2149
2150 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2151 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2152 mkU64(0)));
2153
2154 mnm = irgen(r1, op2addr);
2155
sewardj7ee97522011-05-09 21:45:04 +00002156 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002157 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2158}
2159
2160static void
2161s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2162 UChar r1, UChar x2, UChar b2, UShort d2)
2163{
2164 HChar *mnm;
2165 IRTemp op2addr = newTemp(Ity_I64);
2166
2167 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2168 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2169 mkU64(0)));
2170
2171 mnm = irgen(r1, op2addr);
2172
sewardj7ee97522011-05-09 21:45:04 +00002173 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002174 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2175}
2176
2177static void
2178s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
2179 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2180{
2181 HChar *mnm;
2182 IRTemp op2addr = newTemp(Ity_I64);
2183
2184 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2185 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2186 mkU64(0)));
2187
2188 mnm = irgen(r3, op2addr, r1);
2189
sewardj7ee97522011-05-09 21:45:04 +00002190 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002191 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2192}
2193
2194static void
2195s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2196 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2197{
2198 HChar *mnm;
2199 IRTemp op2addr = newTemp(Ity_I64);
2200 IRTemp d2 = newTemp(Ity_I64);
2201
2202 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2203 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2204 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2205 mkU64(0)));
2206
2207 mnm = irgen(r1, op2addr);
2208
sewardj7ee97522011-05-09 21:45:04 +00002209 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002210 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2211}
2212
2213static void
2214s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2215 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2216{
2217 HChar *mnm;
2218 IRTemp op2addr = newTemp(Ity_I64);
2219 IRTemp d2 = newTemp(Ity_I64);
2220
2221 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2222 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2223 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2224 mkU64(0)));
2225
2226 mnm = irgen(r1, op2addr);
2227
sewardj7ee97522011-05-09 21:45:04 +00002228 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002229 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2230}
2231
2232static void
2233s390_format_RXY_URRD(HChar *(*irgen)(void),
2234 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2235{
2236 HChar *mnm;
2237 IRTemp op2addr = newTemp(Ity_I64);
2238 IRTemp d2 = newTemp(Ity_I64);
2239
2240 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2241 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2242 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2243 mkU64(0)));
2244
2245 mnm = irgen();
2246
sewardj7ee97522011-05-09 21:45:04 +00002247 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002248 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2249}
2250
2251static void
2252s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2253 UChar b2, UShort d2)
2254{
2255 HChar *mnm;
2256 IRTemp op2addr = newTemp(Ity_I64);
2257
2258 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2259 mkU64(0)));
2260
2261 mnm = irgen(op2addr);
2262
sewardj7ee97522011-05-09 21:45:04 +00002263 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002264 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2265}
2266
2267static void
2268s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2269 UChar i2, UChar b1, UShort d1)
2270{
2271 HChar *mnm;
2272 IRTemp op1addr = newTemp(Ity_I64);
2273
2274 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2275 mkU64(0)));
2276
2277 mnm = irgen(i2, op1addr);
2278
sewardj7ee97522011-05-09 21:45:04 +00002279 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002280 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2281}
2282
2283static void
2284s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2285 UChar i2, UChar b1, UShort dl1, UChar dh1)
2286{
2287 HChar *mnm;
2288 IRTemp op1addr = newTemp(Ity_I64);
2289 IRTemp d1 = newTemp(Ity_I64);
2290
2291 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2292 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2293 mkU64(0)));
2294
2295 mnm = irgen(i2, op1addr);
2296
sewardj7ee97522011-05-09 21:45:04 +00002297 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002298 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2299}
2300
2301static void
2302s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2303 UChar i2, UChar b1, UShort dl1, UChar dh1)
2304{
2305 HChar *mnm;
2306 IRTemp op1addr = newTemp(Ity_I64);
2307 IRTemp d1 = newTemp(Ity_I64);
2308
2309 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2310 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2311 mkU64(0)));
2312
2313 mnm = irgen(i2, op1addr);
2314
sewardj7ee97522011-05-09 21:45:04 +00002315 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002316 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2317}
2318
2319static void
2320s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2321 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2322{
2323 HChar *mnm;
2324 IRTemp op1addr = newTemp(Ity_I64);
2325 IRTemp op2addr = newTemp(Ity_I64);
2326
2327 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2328 mkU64(0)));
2329 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2330 mkU64(0)));
2331
2332 mnm = irgen(l, op1addr, op2addr);
2333
sewardj7ee97522011-05-09 21:45:04 +00002334 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002335 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2336}
2337
2338static void
2339s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2340 UChar b1, UShort d1, UShort i2)
2341{
2342 HChar *mnm;
2343 IRTemp op1addr = newTemp(Ity_I64);
2344
2345 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2346 mkU64(0)));
2347
2348 mnm = irgen(i2, op1addr);
2349
sewardj7ee97522011-05-09 21:45:04 +00002350 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002351 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2352}
2353
2354static void
2355s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2356 UChar b1, UShort d1, UShort i2)
2357{
2358 HChar *mnm;
2359 IRTemp op1addr = newTemp(Ity_I64);
2360
2361 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2362 mkU64(0)));
2363
2364 mnm = irgen(i2, op1addr);
2365
sewardj7ee97522011-05-09 21:45:04 +00002366 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002367 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2368}
2369
2370
2371
2372/*------------------------------------------------------------*/
2373/*--- Build IR for opcodes ---*/
2374/*------------------------------------------------------------*/
2375
2376static HChar *
2377s390_irgen_AR(UChar r1, UChar r2)
2378{
2379 IRTemp op1 = newTemp(Ity_I32);
2380 IRTemp op2 = newTemp(Ity_I32);
2381 IRTemp result = newTemp(Ity_I32);
2382
2383 assign(op1, get_gpr_w1(r1));
2384 assign(op2, get_gpr_w1(r2));
2385 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2386 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2387 put_gpr_w1(r1, mkexpr(result));
2388
2389 return "ar";
2390}
2391
2392static HChar *
2393s390_irgen_AGR(UChar r1, UChar r2)
2394{
2395 IRTemp op1 = newTemp(Ity_I64);
2396 IRTemp op2 = newTemp(Ity_I64);
2397 IRTemp result = newTemp(Ity_I64);
2398
2399 assign(op1, get_gpr_dw0(r1));
2400 assign(op2, get_gpr_dw0(r2));
2401 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2402 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2403 put_gpr_dw0(r1, mkexpr(result));
2404
2405 return "agr";
2406}
2407
2408static HChar *
2409s390_irgen_AGFR(UChar r1, UChar r2)
2410{
2411 IRTemp op1 = newTemp(Ity_I64);
2412 IRTemp op2 = newTemp(Ity_I64);
2413 IRTemp result = newTemp(Ity_I64);
2414
2415 assign(op1, get_gpr_dw0(r1));
2416 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2417 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2418 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2419 put_gpr_dw0(r1, mkexpr(result));
2420
2421 return "agfr";
2422}
2423
2424static HChar *
2425s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2426{
2427 IRTemp op2 = newTemp(Ity_I32);
2428 IRTemp op3 = newTemp(Ity_I32);
2429 IRTemp result = newTemp(Ity_I32);
2430
2431 assign(op2, get_gpr_w1(r2));
2432 assign(op3, get_gpr_w1(r3));
2433 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2434 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2435 put_gpr_w1(r1, mkexpr(result));
2436
2437 return "ark";
2438}
2439
2440static HChar *
2441s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2442{
2443 IRTemp op2 = newTemp(Ity_I64);
2444 IRTemp op3 = newTemp(Ity_I64);
2445 IRTemp result = newTemp(Ity_I64);
2446
2447 assign(op2, get_gpr_dw0(r2));
2448 assign(op3, get_gpr_dw0(r3));
2449 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2450 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2451 put_gpr_dw0(r1, mkexpr(result));
2452
2453 return "agrk";
2454}
2455
2456static HChar *
2457s390_irgen_A(UChar r1, IRTemp op2addr)
2458{
2459 IRTemp op1 = newTemp(Ity_I32);
2460 IRTemp op2 = newTemp(Ity_I32);
2461 IRTemp result = newTemp(Ity_I32);
2462
2463 assign(op1, get_gpr_w1(r1));
2464 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2465 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2466 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2467 put_gpr_w1(r1, mkexpr(result));
2468
2469 return "a";
2470}
2471
2472static HChar *
2473s390_irgen_AY(UChar r1, IRTemp op2addr)
2474{
2475 IRTemp op1 = newTemp(Ity_I32);
2476 IRTemp op2 = newTemp(Ity_I32);
2477 IRTemp result = newTemp(Ity_I32);
2478
2479 assign(op1, get_gpr_w1(r1));
2480 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2481 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2482 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2483 put_gpr_w1(r1, mkexpr(result));
2484
2485 return "ay";
2486}
2487
2488static HChar *
2489s390_irgen_AG(UChar r1, IRTemp op2addr)
2490{
2491 IRTemp op1 = newTemp(Ity_I64);
2492 IRTemp op2 = newTemp(Ity_I64);
2493 IRTemp result = newTemp(Ity_I64);
2494
2495 assign(op1, get_gpr_dw0(r1));
2496 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2497 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2498 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2499 put_gpr_dw0(r1, mkexpr(result));
2500
2501 return "ag";
2502}
2503
2504static HChar *
2505s390_irgen_AGF(UChar r1, IRTemp op2addr)
2506{
2507 IRTemp op1 = newTemp(Ity_I64);
2508 IRTemp op2 = newTemp(Ity_I64);
2509 IRTemp result = newTemp(Ity_I64);
2510
2511 assign(op1, get_gpr_dw0(r1));
2512 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2513 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2514 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2515 put_gpr_dw0(r1, mkexpr(result));
2516
2517 return "agf";
2518}
2519
2520static HChar *
2521s390_irgen_AFI(UChar r1, UInt i2)
2522{
2523 IRTemp op1 = newTemp(Ity_I32);
2524 Int op2;
2525 IRTemp result = newTemp(Ity_I32);
2526
2527 assign(op1, get_gpr_w1(r1));
2528 op2 = (Int)i2;
2529 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2530 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2531 mkU32((UInt)op2)));
2532 put_gpr_w1(r1, mkexpr(result));
2533
2534 return "afi";
2535}
2536
2537static HChar *
2538s390_irgen_AGFI(UChar r1, UInt i2)
2539{
2540 IRTemp op1 = newTemp(Ity_I64);
2541 Long op2;
2542 IRTemp result = newTemp(Ity_I64);
2543
2544 assign(op1, get_gpr_dw0(r1));
2545 op2 = (Long)(Int)i2;
2546 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2547 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2548 mkU64((ULong)op2)));
2549 put_gpr_dw0(r1, mkexpr(result));
2550
2551 return "agfi";
2552}
2553
2554static HChar *
2555s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2556{
2557 Int op2;
2558 IRTemp op3 = newTemp(Ity_I32);
2559 IRTemp result = newTemp(Ity_I32);
2560
2561 op2 = (Int)(Short)i2;
2562 assign(op3, get_gpr_w1(r3));
2563 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2564 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2565 op2)), op3);
2566 put_gpr_w1(r1, mkexpr(result));
2567
2568 return "ahik";
2569}
2570
2571static HChar *
2572s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2573{
2574 Long op2;
2575 IRTemp op3 = newTemp(Ity_I64);
2576 IRTemp result = newTemp(Ity_I64);
2577
2578 op2 = (Long)(Short)i2;
2579 assign(op3, get_gpr_dw0(r3));
2580 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2581 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2582 op2)), op3);
2583 put_gpr_dw0(r1, mkexpr(result));
2584
2585 return "aghik";
2586}
2587
2588static HChar *
2589s390_irgen_ASI(UChar i2, IRTemp op1addr)
2590{
2591 IRTemp op1 = newTemp(Ity_I32);
2592 Int op2;
2593 IRTemp result = newTemp(Ity_I32);
2594
2595 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2596 op2 = (Int)(Char)i2;
2597 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2598 store(mkexpr(op1addr), mkexpr(result));
2599 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2600 mkU32((UInt)op2)));
2601
2602 return "asi";
2603}
2604
2605static HChar *
2606s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2607{
2608 IRTemp op1 = newTemp(Ity_I64);
2609 Long op2;
2610 IRTemp result = newTemp(Ity_I64);
2611
2612 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2613 op2 = (Long)(Char)i2;
2614 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2615 store(mkexpr(op1addr), mkexpr(result));
2616 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2617 mkU64((ULong)op2)));
2618
2619 return "agsi";
2620}
2621
2622static HChar *
2623s390_irgen_AH(UChar r1, IRTemp op2addr)
2624{
2625 IRTemp op1 = newTemp(Ity_I32);
2626 IRTemp op2 = newTemp(Ity_I32);
2627 IRTemp result = newTemp(Ity_I32);
2628
2629 assign(op1, get_gpr_w1(r1));
2630 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2631 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2632 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2633 put_gpr_w1(r1, mkexpr(result));
2634
2635 return "ah";
2636}
2637
2638static HChar *
2639s390_irgen_AHY(UChar r1, IRTemp op2addr)
2640{
2641 IRTemp op1 = newTemp(Ity_I32);
2642 IRTemp op2 = newTemp(Ity_I32);
2643 IRTemp result = newTemp(Ity_I32);
2644
2645 assign(op1, get_gpr_w1(r1));
2646 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2647 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2648 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2649 put_gpr_w1(r1, mkexpr(result));
2650
2651 return "ahy";
2652}
2653
2654static HChar *
2655s390_irgen_AHI(UChar r1, UShort i2)
2656{
2657 IRTemp op1 = newTemp(Ity_I32);
2658 Int op2;
2659 IRTemp result = newTemp(Ity_I32);
2660
2661 assign(op1, get_gpr_w1(r1));
2662 op2 = (Int)(Short)i2;
2663 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2664 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2665 mkU32((UInt)op2)));
2666 put_gpr_w1(r1, mkexpr(result));
2667
2668 return "ahi";
2669}
2670
2671static HChar *
2672s390_irgen_AGHI(UChar r1, UShort i2)
2673{
2674 IRTemp op1 = newTemp(Ity_I64);
2675 Long op2;
2676 IRTemp result = newTemp(Ity_I64);
2677
2678 assign(op1, get_gpr_dw0(r1));
2679 op2 = (Long)(Short)i2;
2680 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2681 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2682 mkU64((ULong)op2)));
2683 put_gpr_dw0(r1, mkexpr(result));
2684
2685 return "aghi";
2686}
2687
2688static HChar *
2689s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2690{
2691 IRTemp op2 = newTemp(Ity_I32);
2692 IRTemp op3 = newTemp(Ity_I32);
2693 IRTemp result = newTemp(Ity_I32);
2694
2695 assign(op2, get_gpr_w0(r2));
2696 assign(op3, get_gpr_w0(r3));
2697 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2698 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2699 put_gpr_w0(r1, mkexpr(result));
2700
2701 return "ahhhr";
2702}
2703
2704static HChar *
2705s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2706{
2707 IRTemp op2 = newTemp(Ity_I32);
2708 IRTemp op3 = newTemp(Ity_I32);
2709 IRTemp result = newTemp(Ity_I32);
2710
2711 assign(op2, get_gpr_w0(r2));
2712 assign(op3, get_gpr_w1(r3));
2713 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2714 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2715 put_gpr_w0(r1, mkexpr(result));
2716
2717 return "ahhlr";
2718}
2719
2720static HChar *
2721s390_irgen_AIH(UChar r1, UInt i2)
2722{
2723 IRTemp op1 = newTemp(Ity_I32);
2724 Int op2;
2725 IRTemp result = newTemp(Ity_I32);
2726
2727 assign(op1, get_gpr_w0(r1));
2728 op2 = (Int)i2;
2729 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2730 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2731 mkU32((UInt)op2)));
2732 put_gpr_w0(r1, mkexpr(result));
2733
2734 return "aih";
2735}
2736
2737static HChar *
2738s390_irgen_ALR(UChar r1, UChar r2)
2739{
2740 IRTemp op1 = newTemp(Ity_I32);
2741 IRTemp op2 = newTemp(Ity_I32);
2742 IRTemp result = newTemp(Ity_I32);
2743
2744 assign(op1, get_gpr_w1(r1));
2745 assign(op2, get_gpr_w1(r2));
2746 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2747 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2748 put_gpr_w1(r1, mkexpr(result));
2749
2750 return "alr";
2751}
2752
2753static HChar *
2754s390_irgen_ALGR(UChar r1, UChar r2)
2755{
2756 IRTemp op1 = newTemp(Ity_I64);
2757 IRTemp op2 = newTemp(Ity_I64);
2758 IRTemp result = newTemp(Ity_I64);
2759
2760 assign(op1, get_gpr_dw0(r1));
2761 assign(op2, get_gpr_dw0(r2));
2762 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2763 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2764 put_gpr_dw0(r1, mkexpr(result));
2765
2766 return "algr";
2767}
2768
2769static HChar *
2770s390_irgen_ALGFR(UChar r1, UChar r2)
2771{
2772 IRTemp op1 = newTemp(Ity_I64);
2773 IRTemp op2 = newTemp(Ity_I64);
2774 IRTemp result = newTemp(Ity_I64);
2775
2776 assign(op1, get_gpr_dw0(r1));
2777 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2778 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2779 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2780 put_gpr_dw0(r1, mkexpr(result));
2781
2782 return "algfr";
2783}
2784
2785static HChar *
2786s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2787{
2788 IRTemp op2 = newTemp(Ity_I32);
2789 IRTemp op3 = newTemp(Ity_I32);
2790 IRTemp result = newTemp(Ity_I32);
2791
2792 assign(op2, get_gpr_w1(r2));
2793 assign(op3, get_gpr_w1(r3));
2794 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2795 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2796 put_gpr_w1(r1, mkexpr(result));
2797
2798 return "alrk";
2799}
2800
2801static HChar *
2802s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2803{
2804 IRTemp op2 = newTemp(Ity_I64);
2805 IRTemp op3 = newTemp(Ity_I64);
2806 IRTemp result = newTemp(Ity_I64);
2807
2808 assign(op2, get_gpr_dw0(r2));
2809 assign(op3, get_gpr_dw0(r3));
2810 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2811 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2812 put_gpr_dw0(r1, mkexpr(result));
2813
2814 return "algrk";
2815}
2816
2817static HChar *
2818s390_irgen_AL(UChar r1, IRTemp op2addr)
2819{
2820 IRTemp op1 = newTemp(Ity_I32);
2821 IRTemp op2 = newTemp(Ity_I32);
2822 IRTemp result = newTemp(Ity_I32);
2823
2824 assign(op1, get_gpr_w1(r1));
2825 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2826 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2827 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2828 put_gpr_w1(r1, mkexpr(result));
2829
2830 return "al";
2831}
2832
2833static HChar *
2834s390_irgen_ALY(UChar r1, IRTemp op2addr)
2835{
2836 IRTemp op1 = newTemp(Ity_I32);
2837 IRTemp op2 = newTemp(Ity_I32);
2838 IRTemp result = newTemp(Ity_I32);
2839
2840 assign(op1, get_gpr_w1(r1));
2841 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2842 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2843 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2844 put_gpr_w1(r1, mkexpr(result));
2845
2846 return "aly";
2847}
2848
2849static HChar *
2850s390_irgen_ALG(UChar r1, IRTemp op2addr)
2851{
2852 IRTemp op1 = newTemp(Ity_I64);
2853 IRTemp op2 = newTemp(Ity_I64);
2854 IRTemp result = newTemp(Ity_I64);
2855
2856 assign(op1, get_gpr_dw0(r1));
2857 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2858 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2859 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2860 put_gpr_dw0(r1, mkexpr(result));
2861
2862 return "alg";
2863}
2864
2865static HChar *
2866s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2867{
2868 IRTemp op1 = newTemp(Ity_I64);
2869 IRTemp op2 = newTemp(Ity_I64);
2870 IRTemp result = newTemp(Ity_I64);
2871
2872 assign(op1, get_gpr_dw0(r1));
2873 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2874 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2875 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2876 put_gpr_dw0(r1, mkexpr(result));
2877
2878 return "algf";
2879}
2880
2881static HChar *
2882s390_irgen_ALFI(UChar r1, UInt i2)
2883{
2884 IRTemp op1 = newTemp(Ity_I32);
2885 UInt op2;
2886 IRTemp result = newTemp(Ity_I32);
2887
2888 assign(op1, get_gpr_w1(r1));
2889 op2 = i2;
2890 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2891 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2892 mkU32(op2)));
2893 put_gpr_w1(r1, mkexpr(result));
2894
2895 return "alfi";
2896}
2897
2898static HChar *
2899s390_irgen_ALGFI(UChar r1, UInt i2)
2900{
2901 IRTemp op1 = newTemp(Ity_I64);
2902 ULong op2;
2903 IRTemp result = newTemp(Ity_I64);
2904
2905 assign(op1, get_gpr_dw0(r1));
2906 op2 = (ULong)i2;
2907 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2908 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2909 mkU64(op2)));
2910 put_gpr_dw0(r1, mkexpr(result));
2911
2912 return "algfi";
2913}
2914
2915static HChar *
2916s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2917{
2918 IRTemp op2 = newTemp(Ity_I32);
2919 IRTemp op3 = newTemp(Ity_I32);
2920 IRTemp result = newTemp(Ity_I32);
2921
2922 assign(op2, get_gpr_w0(r2));
2923 assign(op3, get_gpr_w0(r3));
2924 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2925 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2926 put_gpr_w0(r1, mkexpr(result));
2927
2928 return "alhhhr";
2929}
2930
2931static HChar *
2932s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2933{
2934 IRTemp op2 = newTemp(Ity_I32);
2935 IRTemp op3 = newTemp(Ity_I32);
2936 IRTemp result = newTemp(Ity_I32);
2937
2938 assign(op2, get_gpr_w0(r2));
2939 assign(op3, get_gpr_w1(r3));
2940 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2941 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2942 put_gpr_w0(r1, mkexpr(result));
2943
2944 return "alhhlr";
2945}
2946
2947static HChar *
2948s390_irgen_ALCR(UChar r1, UChar r2)
2949{
2950 IRTemp op1 = newTemp(Ity_I32);
2951 IRTemp op2 = newTemp(Ity_I32);
2952 IRTemp result = newTemp(Ity_I32);
2953 IRTemp carry_in = newTemp(Ity_I32);
2954
2955 assign(op1, get_gpr_w1(r1));
2956 assign(op2, get_gpr_w1(r2));
2957 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2958 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2959 mkexpr(carry_in)));
2960 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2961 put_gpr_w1(r1, mkexpr(result));
2962
2963 return "alcr";
2964}
2965
2966static HChar *
2967s390_irgen_ALCGR(UChar r1, UChar r2)
2968{
2969 IRTemp op1 = newTemp(Ity_I64);
2970 IRTemp op2 = newTemp(Ity_I64);
2971 IRTemp result = newTemp(Ity_I64);
2972 IRTemp carry_in = newTemp(Ity_I64);
2973
2974 assign(op1, get_gpr_dw0(r1));
2975 assign(op2, get_gpr_dw0(r2));
2976 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2977 mkU8(1))));
2978 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2979 mkexpr(carry_in)));
2980 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2981 put_gpr_dw0(r1, mkexpr(result));
2982
2983 return "alcgr";
2984}
2985
2986static HChar *
2987s390_irgen_ALC(UChar r1, IRTemp op2addr)
2988{
2989 IRTemp op1 = newTemp(Ity_I32);
2990 IRTemp op2 = newTemp(Ity_I32);
2991 IRTemp result = newTemp(Ity_I32);
2992 IRTemp carry_in = newTemp(Ity_I32);
2993
2994 assign(op1, get_gpr_w1(r1));
2995 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2996 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2997 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2998 mkexpr(carry_in)));
2999 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3000 put_gpr_w1(r1, mkexpr(result));
3001
3002 return "alc";
3003}
3004
3005static HChar *
3006s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3007{
3008 IRTemp op1 = newTemp(Ity_I64);
3009 IRTemp op2 = newTemp(Ity_I64);
3010 IRTemp result = newTemp(Ity_I64);
3011 IRTemp carry_in = newTemp(Ity_I64);
3012
3013 assign(op1, get_gpr_dw0(r1));
3014 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3015 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3016 mkU8(1))));
3017 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3018 mkexpr(carry_in)));
3019 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3020 put_gpr_dw0(r1, mkexpr(result));
3021
3022 return "alcg";
3023}
3024
3025static HChar *
3026s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3027{
3028 IRTemp op1 = newTemp(Ity_I32);
3029 UInt op2;
3030 IRTemp result = newTemp(Ity_I32);
3031
3032 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3033 op2 = (UInt)(Int)(Char)i2;
3034 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3035 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3036 mkU32(op2)));
3037 store(mkexpr(op1addr), mkexpr(result));
3038
3039 return "alsi";
3040}
3041
3042static HChar *
3043s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3044{
3045 IRTemp op1 = newTemp(Ity_I64);
3046 ULong op2;
3047 IRTemp result = newTemp(Ity_I64);
3048
3049 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3050 op2 = (ULong)(Long)(Char)i2;
3051 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3052 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3053 mkU64(op2)));
3054 store(mkexpr(op1addr), mkexpr(result));
3055
3056 return "algsi";
3057}
3058
3059static HChar *
3060s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3061{
3062 UInt op2;
3063 IRTemp op3 = newTemp(Ity_I32);
3064 IRTemp result = newTemp(Ity_I32);
3065
3066 op2 = (UInt)(Int)(Short)i2;
3067 assign(op3, get_gpr_w1(r3));
3068 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3069 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3070 op3);
3071 put_gpr_w1(r1, mkexpr(result));
3072
3073 return "alhsik";
3074}
3075
3076static HChar *
3077s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3078{
3079 ULong op2;
3080 IRTemp op3 = newTemp(Ity_I64);
3081 IRTemp result = newTemp(Ity_I64);
3082
3083 op2 = (ULong)(Long)(Short)i2;
3084 assign(op3, get_gpr_dw0(r3));
3085 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3086 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3087 op3);
3088 put_gpr_dw0(r1, mkexpr(result));
3089
3090 return "alghsik";
3091}
3092
3093static HChar *
3094s390_irgen_ALSIH(UChar r1, UInt i2)
3095{
3096 IRTemp op1 = newTemp(Ity_I32);
3097 UInt op2;
3098 IRTemp result = newTemp(Ity_I32);
3099
3100 assign(op1, get_gpr_w0(r1));
3101 op2 = i2;
3102 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3103 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3104 mkU32(op2)));
3105 put_gpr_w0(r1, mkexpr(result));
3106
3107 return "alsih";
3108}
3109
3110static HChar *
3111s390_irgen_ALSIHN(UChar r1, UInt i2)
3112{
3113 IRTemp op1 = newTemp(Ity_I32);
3114 UInt op2;
3115 IRTemp result = newTemp(Ity_I32);
3116
3117 assign(op1, get_gpr_w0(r1));
3118 op2 = i2;
3119 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3120 put_gpr_w0(r1, mkexpr(result));
3121
3122 return "alsihn";
3123}
3124
3125static HChar *
3126s390_irgen_NR(UChar r1, UChar r2)
3127{
3128 IRTemp op1 = newTemp(Ity_I32);
3129 IRTemp op2 = newTemp(Ity_I32);
3130 IRTemp result = newTemp(Ity_I32);
3131
3132 assign(op1, get_gpr_w1(r1));
3133 assign(op2, get_gpr_w1(r2));
3134 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3135 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3136 put_gpr_w1(r1, mkexpr(result));
3137
3138 return "nr";
3139}
3140
3141static HChar *
3142s390_irgen_NGR(UChar r1, UChar r2)
3143{
3144 IRTemp op1 = newTemp(Ity_I64);
3145 IRTemp op2 = newTemp(Ity_I64);
3146 IRTemp result = newTemp(Ity_I64);
3147
3148 assign(op1, get_gpr_dw0(r1));
3149 assign(op2, get_gpr_dw0(r2));
3150 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3151 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3152 put_gpr_dw0(r1, mkexpr(result));
3153
3154 return "ngr";
3155}
3156
3157static HChar *
3158s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3159{
3160 IRTemp op2 = newTemp(Ity_I32);
3161 IRTemp op3 = newTemp(Ity_I32);
3162 IRTemp result = newTemp(Ity_I32);
3163
3164 assign(op2, get_gpr_w1(r2));
3165 assign(op3, get_gpr_w1(r3));
3166 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3167 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3168 put_gpr_w1(r1, mkexpr(result));
3169
3170 return "nrk";
3171}
3172
3173static HChar *
3174s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3175{
3176 IRTemp op2 = newTemp(Ity_I64);
3177 IRTemp op3 = newTemp(Ity_I64);
3178 IRTemp result = newTemp(Ity_I64);
3179
3180 assign(op2, get_gpr_dw0(r2));
3181 assign(op3, get_gpr_dw0(r3));
3182 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3183 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3184 put_gpr_dw0(r1, mkexpr(result));
3185
3186 return "ngrk";
3187}
3188
3189static HChar *
3190s390_irgen_N(UChar r1, IRTemp op2addr)
3191{
3192 IRTemp op1 = newTemp(Ity_I32);
3193 IRTemp op2 = newTemp(Ity_I32);
3194 IRTemp result = newTemp(Ity_I32);
3195
3196 assign(op1, get_gpr_w1(r1));
3197 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3198 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3199 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3200 put_gpr_w1(r1, mkexpr(result));
3201
3202 return "n";
3203}
3204
3205static HChar *
3206s390_irgen_NY(UChar r1, IRTemp op2addr)
3207{
3208 IRTemp op1 = newTemp(Ity_I32);
3209 IRTemp op2 = newTemp(Ity_I32);
3210 IRTemp result = newTemp(Ity_I32);
3211
3212 assign(op1, get_gpr_w1(r1));
3213 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3214 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3215 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3216 put_gpr_w1(r1, mkexpr(result));
3217
3218 return "ny";
3219}
3220
3221static HChar *
3222s390_irgen_NG(UChar r1, IRTemp op2addr)
3223{
3224 IRTemp op1 = newTemp(Ity_I64);
3225 IRTemp op2 = newTemp(Ity_I64);
3226 IRTemp result = newTemp(Ity_I64);
3227
3228 assign(op1, get_gpr_dw0(r1));
3229 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3230 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3231 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3232 put_gpr_dw0(r1, mkexpr(result));
3233
3234 return "ng";
3235}
3236
3237static HChar *
3238s390_irgen_NI(UChar i2, IRTemp op1addr)
3239{
3240 IRTemp op1 = newTemp(Ity_I8);
3241 UChar op2;
3242 IRTemp result = newTemp(Ity_I8);
3243
3244 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3245 op2 = i2;
3246 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3247 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3248 store(mkexpr(op1addr), mkexpr(result));
3249
3250 return "ni";
3251}
3252
3253static HChar *
3254s390_irgen_NIY(UChar i2, IRTemp op1addr)
3255{
3256 IRTemp op1 = newTemp(Ity_I8);
3257 UChar op2;
3258 IRTemp result = newTemp(Ity_I8);
3259
3260 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3261 op2 = i2;
3262 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3263 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3264 store(mkexpr(op1addr), mkexpr(result));
3265
3266 return "niy";
3267}
3268
3269static HChar *
3270s390_irgen_NIHF(UChar r1, UInt i2)
3271{
3272 IRTemp op1 = newTemp(Ity_I32);
3273 UInt op2;
3274 IRTemp result = newTemp(Ity_I32);
3275
3276 assign(op1, get_gpr_w0(r1));
3277 op2 = i2;
3278 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3279 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3280 put_gpr_w0(r1, mkexpr(result));
3281
3282 return "nihf";
3283}
3284
3285static HChar *
3286s390_irgen_NIHH(UChar r1, UShort i2)
3287{
3288 IRTemp op1 = newTemp(Ity_I16);
3289 UShort op2;
3290 IRTemp result = newTemp(Ity_I16);
3291
3292 assign(op1, get_gpr_hw0(r1));
3293 op2 = i2;
3294 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3295 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3296 put_gpr_hw0(r1, mkexpr(result));
3297
3298 return "nihh";
3299}
3300
3301static HChar *
3302s390_irgen_NIHL(UChar r1, UShort i2)
3303{
3304 IRTemp op1 = newTemp(Ity_I16);
3305 UShort op2;
3306 IRTemp result = newTemp(Ity_I16);
3307
3308 assign(op1, get_gpr_hw1(r1));
3309 op2 = i2;
3310 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3311 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3312 put_gpr_hw1(r1, mkexpr(result));
3313
3314 return "nihl";
3315}
3316
3317static HChar *
3318s390_irgen_NILF(UChar r1, UInt i2)
3319{
3320 IRTemp op1 = newTemp(Ity_I32);
3321 UInt op2;
3322 IRTemp result = newTemp(Ity_I32);
3323
3324 assign(op1, get_gpr_w1(r1));
3325 op2 = i2;
3326 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3327 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3328 put_gpr_w1(r1, mkexpr(result));
3329
3330 return "nilf";
3331}
3332
3333static HChar *
3334s390_irgen_NILH(UChar r1, UShort i2)
3335{
3336 IRTemp op1 = newTemp(Ity_I16);
3337 UShort op2;
3338 IRTemp result = newTemp(Ity_I16);
3339
3340 assign(op1, get_gpr_hw2(r1));
3341 op2 = i2;
3342 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3343 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3344 put_gpr_hw2(r1, mkexpr(result));
3345
3346 return "nilh";
3347}
3348
3349static HChar *
3350s390_irgen_NILL(UChar r1, UShort i2)
3351{
3352 IRTemp op1 = newTemp(Ity_I16);
3353 UShort op2;
3354 IRTemp result = newTemp(Ity_I16);
3355
3356 assign(op1, get_gpr_hw3(r1));
3357 op2 = i2;
3358 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3359 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3360 put_gpr_hw3(r1, mkexpr(result));
3361
3362 return "nill";
3363}
3364
3365static HChar *
3366s390_irgen_BASR(UChar r1, UChar r2)
3367{
3368 IRTemp target = newTemp(Ity_I64);
3369
3370 if (r2 == 0) {
3371 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3372 } else {
3373 if (r1 != r2) {
3374 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3375 call_function(get_gpr_dw0(r2));
3376 } else {
3377 assign(target, get_gpr_dw0(r2));
3378 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3379 call_function(mkexpr(target));
3380 }
3381 }
3382
3383 return "basr";
3384}
3385
3386static HChar *
3387s390_irgen_BAS(UChar r1, IRTemp op2addr)
3388{
3389 IRTemp target = newTemp(Ity_I64);
3390
3391 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3392 assign(target, mkexpr(op2addr));
3393 call_function(mkexpr(target));
3394
3395 return "bas";
3396}
3397
3398static HChar *
3399s390_irgen_BCR(UChar r1, UChar r2)
3400{
3401 IRTemp cond = newTemp(Ity_I32);
3402
sewardja52e37e2011-04-28 18:48:06 +00003403 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3404 stmt(IRStmt_MBE(Imbe_Fence));
3405 }
3406
sewardj2019a972011-03-07 16:04:07 +00003407 if ((r2 == 0) || (r1 == 0)) {
3408 } else {
3409 if (r1 == 15) {
3410 return_from_function(get_gpr_dw0(r2));
3411 } else {
3412 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003413 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3414 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003415 }
3416 }
sewardj7ee97522011-05-09 21:45:04 +00003417 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003418 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3419
3420 return "bcr";
3421}
3422
3423static HChar *
3424s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3425{
3426 IRTemp cond = newTemp(Ity_I32);
3427
3428 if (r1 == 0) {
3429 } else {
3430 if (r1 == 15) {
3431 always_goto(mkexpr(op2addr));
3432 } else {
3433 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003434 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3435 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003436 }
3437 }
sewardj7ee97522011-05-09 21:45:04 +00003438 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003439 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3440
3441 return "bc";
3442}
3443
3444static HChar *
3445s390_irgen_BCTR(UChar r1, UChar r2)
3446{
3447 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3448 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003449 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3450 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003451 }
3452
3453 return "bctr";
3454}
3455
3456static HChar *
3457s390_irgen_BCTGR(UChar r1, UChar r2)
3458{
3459 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3460 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003461 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3462 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003463 }
3464
3465 return "bctgr";
3466}
3467
3468static HChar *
3469s390_irgen_BCT(UChar r1, IRTemp op2addr)
3470{
3471 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003472 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3473 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003474
3475 return "bct";
3476}
3477
3478static HChar *
3479s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3480{
3481 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003482 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3483 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003484
3485 return "bctg";
3486}
3487
3488static HChar *
3489s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3490{
3491 IRTemp value = newTemp(Ity_I32);
3492
3493 assign(value, get_gpr_w1(r3 | 1));
3494 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003495 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3496 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003497
3498 return "bxh";
3499}
3500
3501static HChar *
3502s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3503{
3504 IRTemp value = newTemp(Ity_I64);
3505
3506 assign(value, get_gpr_dw0(r3 | 1));
3507 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003508 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3509 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003510
3511 return "bxhg";
3512}
3513
3514static HChar *
3515s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3516{
3517 IRTemp value = newTemp(Ity_I32);
3518
3519 assign(value, get_gpr_w1(r3 | 1));
3520 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003521 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3522 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003523
3524 return "bxle";
3525}
3526
3527static HChar *
3528s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3529{
3530 IRTemp value = newTemp(Ity_I64);
3531
3532 assign(value, get_gpr_dw0(r3 | 1));
3533 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003534 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3535 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003536
3537 return "bxleg";
3538}
3539
3540static HChar *
3541s390_irgen_BRAS(UChar r1, UShort i2)
3542{
3543 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003544 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003545
3546 return "bras";
3547}
3548
3549static HChar *
3550s390_irgen_BRASL(UChar r1, UInt i2)
3551{
3552 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003553 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003554
3555 return "brasl";
3556}
3557
3558static HChar *
3559s390_irgen_BRC(UChar r1, UShort i2)
3560{
3561 IRTemp cond = newTemp(Ity_I32);
3562
3563 if (r1 == 0) {
3564 } else {
3565 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003566 always_goto_and_chase(
3567 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003568 } else {
3569 assign(cond, s390_call_calculate_cond(r1));
3570 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3571 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3572
3573 }
3574 }
sewardj7ee97522011-05-09 21:45:04 +00003575 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003576 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3577
3578 return "brc";
3579}
3580
3581static HChar *
3582s390_irgen_BRCL(UChar r1, UInt i2)
3583{
3584 IRTemp cond = newTemp(Ity_I32);
3585
3586 if (r1 == 0) {
3587 } else {
3588 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003589 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003590 } else {
3591 assign(cond, s390_call_calculate_cond(r1));
3592 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3593 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3594 }
3595 }
sewardj7ee97522011-05-09 21:45:04 +00003596 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003597 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3598
3599 return "brcl";
3600}
3601
3602static HChar *
3603s390_irgen_BRCT(UChar r1, UShort i2)
3604{
3605 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3606 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3607 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3608
3609 return "brct";
3610}
3611
3612static HChar *
3613s390_irgen_BRCTG(UChar r1, UShort i2)
3614{
3615 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3616 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3617 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3618
3619 return "brctg";
3620}
3621
3622static HChar *
3623s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3624{
3625 IRTemp value = newTemp(Ity_I32);
3626
3627 assign(value, get_gpr_w1(r3 | 1));
3628 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3629 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3630 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3631
3632 return "brxh";
3633}
3634
3635static HChar *
3636s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3637{
3638 IRTemp value = newTemp(Ity_I64);
3639
3640 assign(value, get_gpr_dw0(r3 | 1));
3641 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3642 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3643 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3644
3645 return "brxhg";
3646}
3647
3648static HChar *
3649s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3650{
3651 IRTemp value = newTemp(Ity_I32);
3652
3653 assign(value, get_gpr_w1(r3 | 1));
3654 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3655 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3656 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3657
3658 return "brxle";
3659}
3660
3661static HChar *
3662s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3663{
3664 IRTemp value = newTemp(Ity_I64);
3665
3666 assign(value, get_gpr_dw0(r3 | 1));
3667 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3668 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3669 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3670
3671 return "brxlg";
3672}
3673
3674static HChar *
3675s390_irgen_CR(UChar r1, UChar r2)
3676{
3677 IRTemp op1 = newTemp(Ity_I32);
3678 IRTemp op2 = newTemp(Ity_I32);
3679
3680 assign(op1, get_gpr_w1(r1));
3681 assign(op2, get_gpr_w1(r2));
3682 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3683
3684 return "cr";
3685}
3686
3687static HChar *
3688s390_irgen_CGR(UChar r1, UChar r2)
3689{
3690 IRTemp op1 = newTemp(Ity_I64);
3691 IRTemp op2 = newTemp(Ity_I64);
3692
3693 assign(op1, get_gpr_dw0(r1));
3694 assign(op2, get_gpr_dw0(r2));
3695 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3696
3697 return "cgr";
3698}
3699
3700static HChar *
3701s390_irgen_CGFR(UChar r1, UChar r2)
3702{
3703 IRTemp op1 = newTemp(Ity_I64);
3704 IRTemp op2 = newTemp(Ity_I64);
3705
3706 assign(op1, get_gpr_dw0(r1));
3707 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3708 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3709
3710 return "cgfr";
3711}
3712
3713static HChar *
3714s390_irgen_C(UChar r1, IRTemp op2addr)
3715{
3716 IRTemp op1 = newTemp(Ity_I32);
3717 IRTemp op2 = newTemp(Ity_I32);
3718
3719 assign(op1, get_gpr_w1(r1));
3720 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3721 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3722
3723 return "c";
3724}
3725
3726static HChar *
3727s390_irgen_CY(UChar r1, IRTemp op2addr)
3728{
3729 IRTemp op1 = newTemp(Ity_I32);
3730 IRTemp op2 = newTemp(Ity_I32);
3731
3732 assign(op1, get_gpr_w1(r1));
3733 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3734 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3735
3736 return "cy";
3737}
3738
3739static HChar *
3740s390_irgen_CG(UChar r1, IRTemp op2addr)
3741{
3742 IRTemp op1 = newTemp(Ity_I64);
3743 IRTemp op2 = newTemp(Ity_I64);
3744
3745 assign(op1, get_gpr_dw0(r1));
3746 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3747 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3748
3749 return "cg";
3750}
3751
3752static HChar *
3753s390_irgen_CGF(UChar r1, IRTemp op2addr)
3754{
3755 IRTemp op1 = newTemp(Ity_I64);
3756 IRTemp op2 = newTemp(Ity_I64);
3757
3758 assign(op1, get_gpr_dw0(r1));
3759 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3760 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3761
3762 return "cgf";
3763}
3764
3765static HChar *
3766s390_irgen_CFI(UChar r1, UInt i2)
3767{
3768 IRTemp op1 = newTemp(Ity_I32);
3769 Int op2;
3770
3771 assign(op1, get_gpr_w1(r1));
3772 op2 = (Int)i2;
3773 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3774 mkU32((UInt)op2)));
3775
3776 return "cfi";
3777}
3778
3779static HChar *
3780s390_irgen_CGFI(UChar r1, UInt i2)
3781{
3782 IRTemp op1 = newTemp(Ity_I64);
3783 Long op2;
3784
3785 assign(op1, get_gpr_dw0(r1));
3786 op2 = (Long)(Int)i2;
3787 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3788 mkU64((ULong)op2)));
3789
3790 return "cgfi";
3791}
3792
3793static HChar *
3794s390_irgen_CRL(UChar r1, UInt i2)
3795{
3796 IRTemp op1 = newTemp(Ity_I32);
3797 IRTemp op2 = newTemp(Ity_I32);
3798
3799 assign(op1, get_gpr_w1(r1));
3800 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3801 i2 << 1))));
3802 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3803
3804 return "crl";
3805}
3806
3807static HChar *
3808s390_irgen_CGRL(UChar r1, UInt i2)
3809{
3810 IRTemp op1 = newTemp(Ity_I64);
3811 IRTemp op2 = newTemp(Ity_I64);
3812
3813 assign(op1, get_gpr_dw0(r1));
3814 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3815 i2 << 1))));
3816 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3817
3818 return "cgrl";
3819}
3820
3821static HChar *
3822s390_irgen_CGFRL(UChar r1, UInt i2)
3823{
3824 IRTemp op1 = newTemp(Ity_I64);
3825 IRTemp op2 = newTemp(Ity_I64);
3826
3827 assign(op1, get_gpr_dw0(r1));
3828 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3829 ((ULong)(Long)(Int)i2 << 1)))));
3830 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3831
3832 return "cgfrl";
3833}
3834
3835static HChar *
3836s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3837{
3838 IRTemp op1 = newTemp(Ity_I32);
3839 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003840 IRTemp cond = newTemp(Ity_I32);
3841
3842 if (m3 == 0) {
3843 } else {
3844 if (m3 == 14) {
3845 always_goto(mkexpr(op4addr));
3846 } else {
3847 assign(op1, get_gpr_w1(r1));
3848 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003849 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3850 op1, op2));
florianf321da72012-07-21 20:32:57 +00003851 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3852 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003853 }
3854 }
3855
3856 return "crb";
3857}
3858
3859static HChar *
3860s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3861{
3862 IRTemp op1 = newTemp(Ity_I64);
3863 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003864 IRTemp cond = newTemp(Ity_I32);
3865
3866 if (m3 == 0) {
3867 } else {
3868 if (m3 == 14) {
3869 always_goto(mkexpr(op4addr));
3870 } else {
3871 assign(op1, get_gpr_dw0(r1));
3872 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003873 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3874 op1, op2));
florianf321da72012-07-21 20:32:57 +00003875 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3876 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003877 }
3878 }
3879
3880 return "cgrb";
3881}
3882
3883static HChar *
3884s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3885{
3886 IRTemp op1 = newTemp(Ity_I32);
3887 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003888 IRTemp cond = newTemp(Ity_I32);
3889
3890 if (m3 == 0) {
3891 } else {
3892 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003893 always_goto_and_chase(
3894 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003895 } else {
3896 assign(op1, get_gpr_w1(r1));
3897 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003898 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3899 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003900 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3901 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3902
3903 }
3904 }
3905
3906 return "crj";
3907}
3908
3909static HChar *
3910s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3911{
3912 IRTemp op1 = newTemp(Ity_I64);
3913 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003914 IRTemp cond = newTemp(Ity_I32);
3915
3916 if (m3 == 0) {
3917 } else {
3918 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003919 always_goto_and_chase(
3920 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003921 } else {
3922 assign(op1, get_gpr_dw0(r1));
3923 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003924 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3925 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003926 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3927 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3928
3929 }
3930 }
3931
3932 return "cgrj";
3933}
3934
3935static HChar *
3936s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3937{
3938 IRTemp op1 = newTemp(Ity_I32);
3939 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003940 IRTemp cond = newTemp(Ity_I32);
3941
3942 if (m3 == 0) {
3943 } else {
3944 if (m3 == 14) {
3945 always_goto(mkexpr(op4addr));
3946 } else {
3947 assign(op1, get_gpr_w1(r1));
3948 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003949 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3950 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003951 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3952 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003953 }
3954 }
3955
3956 return "cib";
3957}
3958
3959static HChar *
3960s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3961{
3962 IRTemp op1 = newTemp(Ity_I64);
3963 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003964 IRTemp cond = newTemp(Ity_I32);
3965
3966 if (m3 == 0) {
3967 } else {
3968 if (m3 == 14) {
3969 always_goto(mkexpr(op4addr));
3970 } else {
3971 assign(op1, get_gpr_dw0(r1));
3972 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003973 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3974 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003975 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3976 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003977 }
3978 }
3979
3980 return "cgib";
3981}
3982
3983static HChar *
3984s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3985{
3986 IRTemp op1 = newTemp(Ity_I32);
3987 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003988 IRTemp cond = newTemp(Ity_I32);
3989
3990 if (m3 == 0) {
3991 } else {
3992 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003993 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003994 } else {
3995 assign(op1, get_gpr_w1(r1));
3996 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003997 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3998 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003999 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4000 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4001
4002 }
4003 }
4004
4005 return "cij";
4006}
4007
4008static HChar *
4009s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4010{
4011 IRTemp op1 = newTemp(Ity_I64);
4012 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004013 IRTemp cond = newTemp(Ity_I32);
4014
4015 if (m3 == 0) {
4016 } else {
4017 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004018 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004019 } else {
4020 assign(op1, get_gpr_dw0(r1));
4021 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004022 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4023 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004024 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4025 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4026
4027 }
4028 }
4029
4030 return "cgij";
4031}
4032
4033static HChar *
4034s390_irgen_CH(UChar r1, IRTemp op2addr)
4035{
4036 IRTemp op1 = newTemp(Ity_I32);
4037 IRTemp op2 = newTemp(Ity_I32);
4038
4039 assign(op1, get_gpr_w1(r1));
4040 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4041 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4042
4043 return "ch";
4044}
4045
4046static HChar *
4047s390_irgen_CHY(UChar r1, IRTemp op2addr)
4048{
4049 IRTemp op1 = newTemp(Ity_I32);
4050 IRTemp op2 = newTemp(Ity_I32);
4051
4052 assign(op1, get_gpr_w1(r1));
4053 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4054 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4055
4056 return "chy";
4057}
4058
4059static HChar *
4060s390_irgen_CGH(UChar r1, IRTemp op2addr)
4061{
4062 IRTemp op1 = newTemp(Ity_I64);
4063 IRTemp op2 = newTemp(Ity_I64);
4064
4065 assign(op1, get_gpr_dw0(r1));
4066 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4067 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4068
4069 return "cgh";
4070}
4071
4072static HChar *
4073s390_irgen_CHI(UChar r1, UShort i2)
4074{
4075 IRTemp op1 = newTemp(Ity_I32);
4076 Int op2;
4077
4078 assign(op1, get_gpr_w1(r1));
4079 op2 = (Int)(Short)i2;
4080 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4081 mkU32((UInt)op2)));
4082
4083 return "chi";
4084}
4085
4086static HChar *
4087s390_irgen_CGHI(UChar r1, UShort i2)
4088{
4089 IRTemp op1 = newTemp(Ity_I64);
4090 Long op2;
4091
4092 assign(op1, get_gpr_dw0(r1));
4093 op2 = (Long)(Short)i2;
4094 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4095 mkU64((ULong)op2)));
4096
4097 return "cghi";
4098}
4099
4100static HChar *
4101s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4102{
4103 IRTemp op1 = newTemp(Ity_I16);
4104 Short op2;
4105
4106 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4107 op2 = (Short)i2;
4108 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4109 mkU16((UShort)op2)));
4110
4111 return "chhsi";
4112}
4113
4114static HChar *
4115s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4116{
4117 IRTemp op1 = newTemp(Ity_I32);
4118 Int op2;
4119
4120 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4121 op2 = (Int)(Short)i2;
4122 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4123 mkU32((UInt)op2)));
4124
4125 return "chsi";
4126}
4127
4128static HChar *
4129s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4130{
4131 IRTemp op1 = newTemp(Ity_I64);
4132 Long op2;
4133
4134 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4135 op2 = (Long)(Short)i2;
4136 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4137 mkU64((ULong)op2)));
4138
4139 return "cghsi";
4140}
4141
4142static HChar *
4143s390_irgen_CHRL(UChar r1, UInt i2)
4144{
4145 IRTemp op1 = newTemp(Ity_I32);
4146 IRTemp op2 = newTemp(Ity_I32);
4147
4148 assign(op1, get_gpr_w1(r1));
4149 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4150 ((ULong)(Long)(Int)i2 << 1)))));
4151 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4152
4153 return "chrl";
4154}
4155
4156static HChar *
4157s390_irgen_CGHRL(UChar r1, UInt i2)
4158{
4159 IRTemp op1 = newTemp(Ity_I64);
4160 IRTemp op2 = newTemp(Ity_I64);
4161
4162 assign(op1, get_gpr_dw0(r1));
4163 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4164 ((ULong)(Long)(Int)i2 << 1)))));
4165 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4166
4167 return "cghrl";
4168}
4169
4170static HChar *
4171s390_irgen_CHHR(UChar r1, UChar r2)
4172{
4173 IRTemp op1 = newTemp(Ity_I32);
4174 IRTemp op2 = newTemp(Ity_I32);
4175
4176 assign(op1, get_gpr_w0(r1));
4177 assign(op2, get_gpr_w0(r2));
4178 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4179
4180 return "chhr";
4181}
4182
4183static HChar *
4184s390_irgen_CHLR(UChar r1, UChar r2)
4185{
4186 IRTemp op1 = newTemp(Ity_I32);
4187 IRTemp op2 = newTemp(Ity_I32);
4188
4189 assign(op1, get_gpr_w0(r1));
4190 assign(op2, get_gpr_w1(r2));
4191 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4192
4193 return "chlr";
4194}
4195
4196static HChar *
4197s390_irgen_CHF(UChar r1, IRTemp op2addr)
4198{
4199 IRTemp op1 = newTemp(Ity_I32);
4200 IRTemp op2 = newTemp(Ity_I32);
4201
4202 assign(op1, get_gpr_w0(r1));
4203 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4204 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4205
4206 return "chf";
4207}
4208
4209static HChar *
4210s390_irgen_CIH(UChar r1, UInt i2)
4211{
4212 IRTemp op1 = newTemp(Ity_I32);
4213 Int op2;
4214
4215 assign(op1, get_gpr_w0(r1));
4216 op2 = (Int)i2;
4217 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4218 mkU32((UInt)op2)));
4219
4220 return "cih";
4221}
4222
4223static HChar *
4224s390_irgen_CLR(UChar r1, UChar r2)
4225{
4226 IRTemp op1 = newTemp(Ity_I32);
4227 IRTemp op2 = newTemp(Ity_I32);
4228
4229 assign(op1, get_gpr_w1(r1));
4230 assign(op2, get_gpr_w1(r2));
4231 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4232
4233 return "clr";
4234}
4235
4236static HChar *
4237s390_irgen_CLGR(UChar r1, UChar r2)
4238{
4239 IRTemp op1 = newTemp(Ity_I64);
4240 IRTemp op2 = newTemp(Ity_I64);
4241
4242 assign(op1, get_gpr_dw0(r1));
4243 assign(op2, get_gpr_dw0(r2));
4244 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4245
4246 return "clgr";
4247}
4248
4249static HChar *
4250s390_irgen_CLGFR(UChar r1, UChar r2)
4251{
4252 IRTemp op1 = newTemp(Ity_I64);
4253 IRTemp op2 = newTemp(Ity_I64);
4254
4255 assign(op1, get_gpr_dw0(r1));
4256 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4257 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4258
4259 return "clgfr";
4260}
4261
4262static HChar *
4263s390_irgen_CL(UChar r1, IRTemp op2addr)
4264{
4265 IRTemp op1 = newTemp(Ity_I32);
4266 IRTemp op2 = newTemp(Ity_I32);
4267
4268 assign(op1, get_gpr_w1(r1));
4269 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4270 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4271
4272 return "cl";
4273}
4274
4275static HChar *
4276s390_irgen_CLY(UChar r1, IRTemp op2addr)
4277{
4278 IRTemp op1 = newTemp(Ity_I32);
4279 IRTemp op2 = newTemp(Ity_I32);
4280
4281 assign(op1, get_gpr_w1(r1));
4282 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4283 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4284
4285 return "cly";
4286}
4287
4288static HChar *
4289s390_irgen_CLG(UChar r1, IRTemp op2addr)
4290{
4291 IRTemp op1 = newTemp(Ity_I64);
4292 IRTemp op2 = newTemp(Ity_I64);
4293
4294 assign(op1, get_gpr_dw0(r1));
4295 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4296 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4297
4298 return "clg";
4299}
4300
4301static HChar *
4302s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4303{
4304 IRTemp op1 = newTemp(Ity_I64);
4305 IRTemp op2 = newTemp(Ity_I64);
4306
4307 assign(op1, get_gpr_dw0(r1));
4308 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4309 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4310
4311 return "clgf";
4312}
4313
4314static HChar *
4315s390_irgen_CLFI(UChar r1, UInt i2)
4316{
4317 IRTemp op1 = newTemp(Ity_I32);
4318 UInt op2;
4319
4320 assign(op1, get_gpr_w1(r1));
4321 op2 = i2;
4322 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4323 mkU32(op2)));
4324
4325 return "clfi";
4326}
4327
4328static HChar *
4329s390_irgen_CLGFI(UChar r1, UInt i2)
4330{
4331 IRTemp op1 = newTemp(Ity_I64);
4332 ULong op2;
4333
4334 assign(op1, get_gpr_dw0(r1));
4335 op2 = (ULong)i2;
4336 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4337 mkU64(op2)));
4338
4339 return "clgfi";
4340}
4341
4342static HChar *
4343s390_irgen_CLI(UChar i2, IRTemp op1addr)
4344{
4345 IRTemp op1 = newTemp(Ity_I8);
4346 UChar op2;
4347
4348 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4349 op2 = i2;
4350 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4351 mkU8(op2)));
4352
4353 return "cli";
4354}
4355
4356static HChar *
4357s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4358{
4359 IRTemp op1 = newTemp(Ity_I8);
4360 UChar op2;
4361
4362 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4363 op2 = i2;
4364 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4365 mkU8(op2)));
4366
4367 return "cliy";
4368}
4369
4370static HChar *
4371s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4372{
4373 IRTemp op1 = newTemp(Ity_I32);
4374 UInt op2;
4375
4376 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4377 op2 = (UInt)i2;
4378 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4379 mkU32(op2)));
4380
4381 return "clfhsi";
4382}
4383
4384static HChar *
4385s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4386{
4387 IRTemp op1 = newTemp(Ity_I64);
4388 ULong op2;
4389
4390 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4391 op2 = (ULong)i2;
4392 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4393 mkU64(op2)));
4394
4395 return "clghsi";
4396}
4397
4398static HChar *
4399s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4400{
4401 IRTemp op1 = newTemp(Ity_I16);
4402 UShort op2;
4403
4404 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4405 op2 = i2;
4406 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4407 mkU16(op2)));
4408
4409 return "clhhsi";
4410}
4411
4412static HChar *
4413s390_irgen_CLRL(UChar r1, UInt i2)
4414{
4415 IRTemp op1 = newTemp(Ity_I32);
4416 IRTemp op2 = newTemp(Ity_I32);
4417
4418 assign(op1, get_gpr_w1(r1));
4419 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4420 i2 << 1))));
4421 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4422
4423 return "clrl";
4424}
4425
4426static HChar *
4427s390_irgen_CLGRL(UChar r1, UInt i2)
4428{
4429 IRTemp op1 = newTemp(Ity_I64);
4430 IRTemp op2 = newTemp(Ity_I64);
4431
4432 assign(op1, get_gpr_dw0(r1));
4433 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4434 i2 << 1))));
4435 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4436
4437 return "clgrl";
4438}
4439
4440static HChar *
4441s390_irgen_CLGFRL(UChar r1, UInt i2)
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, mkU64(guest_IA_curr_instr +
4448 ((ULong)(Long)(Int)i2 << 1)))));
4449 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4450
4451 return "clgfrl";
4452}
4453
4454static HChar *
4455s390_irgen_CLHRL(UChar r1, UInt i2)
4456{
4457 IRTemp op1 = newTemp(Ity_I32);
4458 IRTemp op2 = newTemp(Ity_I32);
4459
4460 assign(op1, get_gpr_w1(r1));
4461 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4462 ((ULong)(Long)(Int)i2 << 1)))));
4463 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4464
4465 return "clhrl";
4466}
4467
4468static HChar *
4469s390_irgen_CLGHRL(UChar r1, UInt i2)
4470{
4471 IRTemp op1 = newTemp(Ity_I64);
4472 IRTemp op2 = newTemp(Ity_I64);
4473
4474 assign(op1, get_gpr_dw0(r1));
4475 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4476 ((ULong)(Long)(Int)i2 << 1)))));
4477 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4478
4479 return "clghrl";
4480}
4481
4482static HChar *
4483s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4484{
4485 IRTemp op1 = newTemp(Ity_I32);
4486 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004487 IRTemp cond = newTemp(Ity_I32);
4488
4489 if (m3 == 0) {
4490 } else {
4491 if (m3 == 14) {
4492 always_goto(mkexpr(op4addr));
4493 } else {
4494 assign(op1, get_gpr_w1(r1));
4495 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004496 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4497 op1, op2));
florianf321da72012-07-21 20:32:57 +00004498 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4499 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004500 }
4501 }
4502
4503 return "clrb";
4504}
4505
4506static HChar *
4507s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4508{
4509 IRTemp op1 = newTemp(Ity_I64);
4510 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004511 IRTemp cond = newTemp(Ity_I32);
4512
4513 if (m3 == 0) {
4514 } else {
4515 if (m3 == 14) {
4516 always_goto(mkexpr(op4addr));
4517 } else {
4518 assign(op1, get_gpr_dw0(r1));
4519 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004520 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4521 op1, op2));
florianf321da72012-07-21 20:32:57 +00004522 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4523 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004524 }
4525 }
4526
4527 return "clgrb";
4528}
4529
4530static HChar *
4531s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4532{
4533 IRTemp op1 = newTemp(Ity_I32);
4534 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004535 IRTemp cond = newTemp(Ity_I32);
4536
4537 if (m3 == 0) {
4538 } else {
4539 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004540 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004541 } else {
4542 assign(op1, get_gpr_w1(r1));
4543 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004544 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4545 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004546 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4547 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4548
4549 }
4550 }
4551
4552 return "clrj";
4553}
4554
4555static HChar *
4556s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4557{
4558 IRTemp op1 = newTemp(Ity_I64);
4559 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004560 IRTemp cond = newTemp(Ity_I32);
4561
4562 if (m3 == 0) {
4563 } else {
4564 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004565 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004566 } else {
4567 assign(op1, get_gpr_dw0(r1));
4568 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004569 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4570 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004571 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4572 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4573
4574 }
4575 }
4576
4577 return "clgrj";
4578}
4579
4580static HChar *
4581s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4582{
4583 IRTemp op1 = newTemp(Ity_I32);
4584 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004585 IRTemp cond = newTemp(Ity_I32);
4586
4587 if (m3 == 0) {
4588 } else {
4589 if (m3 == 14) {
4590 always_goto(mkexpr(op4addr));
4591 } else {
4592 assign(op1, get_gpr_w1(r1));
4593 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004594 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4595 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004596 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4597 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004598 }
4599 }
4600
4601 return "clib";
4602}
4603
4604static HChar *
4605s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4606{
4607 IRTemp op1 = newTemp(Ity_I64);
4608 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004609 IRTemp cond = newTemp(Ity_I32);
4610
4611 if (m3 == 0) {
4612 } else {
4613 if (m3 == 14) {
4614 always_goto(mkexpr(op4addr));
4615 } else {
4616 assign(op1, get_gpr_dw0(r1));
4617 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004618 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4619 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004620 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4621 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004622 }
4623 }
4624
4625 return "clgib";
4626}
4627
4628static HChar *
4629s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4630{
4631 IRTemp op1 = newTemp(Ity_I32);
4632 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004633 IRTemp cond = newTemp(Ity_I32);
4634
4635 if (m3 == 0) {
4636 } else {
4637 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004638 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004639 } else {
4640 assign(op1, get_gpr_w1(r1));
4641 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004642 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4643 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004644 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4645 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4646
4647 }
4648 }
4649
4650 return "clij";
4651}
4652
4653static HChar *
4654s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4655{
4656 IRTemp op1 = newTemp(Ity_I64);
4657 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004658 IRTemp cond = newTemp(Ity_I32);
4659
4660 if (m3 == 0) {
4661 } else {
4662 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004663 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004664 } else {
4665 assign(op1, get_gpr_dw0(r1));
4666 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004667 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4668 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004669 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4670 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4671
4672 }
4673 }
4674
4675 return "clgij";
4676}
4677
4678static HChar *
4679s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4680{
4681 IRTemp op1 = newTemp(Ity_I32);
4682 IRTemp op2 = newTemp(Ity_I32);
4683 IRTemp b0 = newTemp(Ity_I32);
4684 IRTemp b1 = newTemp(Ity_I32);
4685 IRTemp b2 = newTemp(Ity_I32);
4686 IRTemp b3 = newTemp(Ity_I32);
4687 IRTemp c0 = newTemp(Ity_I32);
4688 IRTemp c1 = newTemp(Ity_I32);
4689 IRTemp c2 = newTemp(Ity_I32);
4690 IRTemp c3 = newTemp(Ity_I32);
4691 UChar n;
4692
4693 n = 0;
4694 if ((r3 & 8) != 0) {
4695 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4696 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4697 n = n + 1;
4698 } else {
4699 assign(b0, mkU32(0));
4700 assign(c0, mkU32(0));
4701 }
4702 if ((r3 & 4) != 0) {
4703 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4704 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4705 mkU64(n)))));
4706 n = n + 1;
4707 } else {
4708 assign(b1, mkU32(0));
4709 assign(c1, mkU32(0));
4710 }
4711 if ((r3 & 2) != 0) {
4712 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4713 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4714 mkU64(n)))));
4715 n = n + 1;
4716 } else {
4717 assign(b2, mkU32(0));
4718 assign(c2, mkU32(0));
4719 }
4720 if ((r3 & 1) != 0) {
4721 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4722 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4723 mkU64(n)))));
4724 n = n + 1;
4725 } else {
4726 assign(b3, mkU32(0));
4727 assign(c3, mkU32(0));
4728 }
4729 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4730 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4731 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4732 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4733 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4734 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4735 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4736
4737 return "clm";
4738}
4739
4740static HChar *
4741s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4742{
4743 IRTemp op1 = newTemp(Ity_I32);
4744 IRTemp op2 = newTemp(Ity_I32);
4745 IRTemp b0 = newTemp(Ity_I32);
4746 IRTemp b1 = newTemp(Ity_I32);
4747 IRTemp b2 = newTemp(Ity_I32);
4748 IRTemp b3 = newTemp(Ity_I32);
4749 IRTemp c0 = newTemp(Ity_I32);
4750 IRTemp c1 = newTemp(Ity_I32);
4751 IRTemp c2 = newTemp(Ity_I32);
4752 IRTemp c3 = newTemp(Ity_I32);
4753 UChar n;
4754
4755 n = 0;
4756 if ((r3 & 8) != 0) {
4757 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4758 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4759 n = n + 1;
4760 } else {
4761 assign(b0, mkU32(0));
4762 assign(c0, mkU32(0));
4763 }
4764 if ((r3 & 4) != 0) {
4765 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4766 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4767 mkU64(n)))));
4768 n = n + 1;
4769 } else {
4770 assign(b1, mkU32(0));
4771 assign(c1, mkU32(0));
4772 }
4773 if ((r3 & 2) != 0) {
4774 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4775 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4776 mkU64(n)))));
4777 n = n + 1;
4778 } else {
4779 assign(b2, mkU32(0));
4780 assign(c2, mkU32(0));
4781 }
4782 if ((r3 & 1) != 0) {
4783 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4784 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4785 mkU64(n)))));
4786 n = n + 1;
4787 } else {
4788 assign(b3, mkU32(0));
4789 assign(c3, mkU32(0));
4790 }
4791 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4792 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4793 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4794 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4795 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4796 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4797 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4798
4799 return "clmy";
4800}
4801
4802static HChar *
4803s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4804{
4805 IRTemp op1 = newTemp(Ity_I32);
4806 IRTemp op2 = newTemp(Ity_I32);
4807 IRTemp b0 = newTemp(Ity_I32);
4808 IRTemp b1 = newTemp(Ity_I32);
4809 IRTemp b2 = newTemp(Ity_I32);
4810 IRTemp b3 = newTemp(Ity_I32);
4811 IRTemp c0 = newTemp(Ity_I32);
4812 IRTemp c1 = newTemp(Ity_I32);
4813 IRTemp c2 = newTemp(Ity_I32);
4814 IRTemp c3 = newTemp(Ity_I32);
4815 UChar n;
4816
4817 n = 0;
4818 if ((r3 & 8) != 0) {
4819 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4820 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4821 n = n + 1;
4822 } else {
4823 assign(b0, mkU32(0));
4824 assign(c0, mkU32(0));
4825 }
4826 if ((r3 & 4) != 0) {
4827 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4828 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4829 mkU64(n)))));
4830 n = n + 1;
4831 } else {
4832 assign(b1, mkU32(0));
4833 assign(c1, mkU32(0));
4834 }
4835 if ((r3 & 2) != 0) {
4836 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4837 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4838 mkU64(n)))));
4839 n = n + 1;
4840 } else {
4841 assign(b2, mkU32(0));
4842 assign(c2, mkU32(0));
4843 }
4844 if ((r3 & 1) != 0) {
4845 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4846 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4847 mkU64(n)))));
4848 n = n + 1;
4849 } else {
4850 assign(b3, mkU32(0));
4851 assign(c3, mkU32(0));
4852 }
4853 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4854 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4855 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4856 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4857 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4858 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4859 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4860
4861 return "clmh";
4862}
4863
4864static HChar *
4865s390_irgen_CLHHR(UChar r1, UChar r2)
4866{
4867 IRTemp op1 = newTemp(Ity_I32);
4868 IRTemp op2 = newTemp(Ity_I32);
4869
4870 assign(op1, get_gpr_w0(r1));
4871 assign(op2, get_gpr_w0(r2));
4872 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4873
4874 return "clhhr";
4875}
4876
4877static HChar *
4878s390_irgen_CLHLR(UChar r1, UChar r2)
4879{
4880 IRTemp op1 = newTemp(Ity_I32);
4881 IRTemp op2 = newTemp(Ity_I32);
4882
4883 assign(op1, get_gpr_w0(r1));
4884 assign(op2, get_gpr_w1(r2));
4885 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4886
4887 return "clhlr";
4888}
4889
4890static HChar *
4891s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4892{
4893 IRTemp op1 = newTemp(Ity_I32);
4894 IRTemp op2 = newTemp(Ity_I32);
4895
4896 assign(op1, get_gpr_w0(r1));
4897 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4898 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4899
4900 return "clhf";
4901}
4902
4903static HChar *
4904s390_irgen_CLIH(UChar r1, UInt i2)
4905{
4906 IRTemp op1 = newTemp(Ity_I32);
4907 UInt op2;
4908
4909 assign(op1, get_gpr_w0(r1));
4910 op2 = i2;
4911 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4912 mkU32(op2)));
4913
4914 return "clih";
4915}
4916
4917static HChar *
4918s390_irgen_CPYA(UChar r1, UChar r2)
4919{
4920 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004921 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004922 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4923
4924 return "cpya";
4925}
4926
4927static HChar *
4928s390_irgen_XR(UChar r1, UChar r2)
4929{
4930 IRTemp op1 = newTemp(Ity_I32);
4931 IRTemp op2 = newTemp(Ity_I32);
4932 IRTemp result = newTemp(Ity_I32);
4933
4934 if (r1 == r2) {
4935 assign(result, mkU32(0));
4936 } else {
4937 assign(op1, get_gpr_w1(r1));
4938 assign(op2, get_gpr_w1(r2));
4939 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4940 }
4941 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4942 put_gpr_w1(r1, mkexpr(result));
4943
4944 return "xr";
4945}
4946
4947static HChar *
4948s390_irgen_XGR(UChar r1, UChar r2)
4949{
4950 IRTemp op1 = newTemp(Ity_I64);
4951 IRTemp op2 = newTemp(Ity_I64);
4952 IRTemp result = newTemp(Ity_I64);
4953
4954 if (r1 == r2) {
4955 assign(result, mkU64(0));
4956 } else {
4957 assign(op1, get_gpr_dw0(r1));
4958 assign(op2, get_gpr_dw0(r2));
4959 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4960 }
4961 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4962 put_gpr_dw0(r1, mkexpr(result));
4963
4964 return "xgr";
4965}
4966
4967static HChar *
4968s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4969{
4970 IRTemp op2 = newTemp(Ity_I32);
4971 IRTemp op3 = newTemp(Ity_I32);
4972 IRTemp result = newTemp(Ity_I32);
4973
4974 assign(op2, get_gpr_w1(r2));
4975 assign(op3, get_gpr_w1(r3));
4976 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4977 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4978 put_gpr_w1(r1, mkexpr(result));
4979
4980 return "xrk";
4981}
4982
4983static HChar *
4984s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4985{
4986 IRTemp op2 = newTemp(Ity_I64);
4987 IRTemp op3 = newTemp(Ity_I64);
4988 IRTemp result = newTemp(Ity_I64);
4989
4990 assign(op2, get_gpr_dw0(r2));
4991 assign(op3, get_gpr_dw0(r3));
4992 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4993 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4994 put_gpr_dw0(r1, mkexpr(result));
4995
4996 return "xgrk";
4997}
4998
4999static HChar *
5000s390_irgen_X(UChar r1, IRTemp op2addr)
5001{
5002 IRTemp op1 = newTemp(Ity_I32);
5003 IRTemp op2 = newTemp(Ity_I32);
5004 IRTemp result = newTemp(Ity_I32);
5005
5006 assign(op1, get_gpr_w1(r1));
5007 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5008 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5009 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5010 put_gpr_w1(r1, mkexpr(result));
5011
5012 return "x";
5013}
5014
5015static HChar *
5016s390_irgen_XY(UChar r1, IRTemp op2addr)
5017{
5018 IRTemp op1 = newTemp(Ity_I32);
5019 IRTemp op2 = newTemp(Ity_I32);
5020 IRTemp result = newTemp(Ity_I32);
5021
5022 assign(op1, get_gpr_w1(r1));
5023 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5024 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5025 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5026 put_gpr_w1(r1, mkexpr(result));
5027
5028 return "xy";
5029}
5030
5031static HChar *
5032s390_irgen_XG(UChar r1, IRTemp op2addr)
5033{
5034 IRTemp op1 = newTemp(Ity_I64);
5035 IRTemp op2 = newTemp(Ity_I64);
5036 IRTemp result = newTemp(Ity_I64);
5037
5038 assign(op1, get_gpr_dw0(r1));
5039 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5040 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5041 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5042 put_gpr_dw0(r1, mkexpr(result));
5043
5044 return "xg";
5045}
5046
5047static HChar *
5048s390_irgen_XI(UChar i2, IRTemp op1addr)
5049{
5050 IRTemp op1 = newTemp(Ity_I8);
5051 UChar op2;
5052 IRTemp result = newTemp(Ity_I8);
5053
5054 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5055 op2 = i2;
5056 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5057 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5058 store(mkexpr(op1addr), mkexpr(result));
5059
5060 return "xi";
5061}
5062
5063static HChar *
5064s390_irgen_XIY(UChar i2, IRTemp op1addr)
5065{
5066 IRTemp op1 = newTemp(Ity_I8);
5067 UChar op2;
5068 IRTemp result = newTemp(Ity_I8);
5069
5070 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5071 op2 = i2;
5072 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5073 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5074 store(mkexpr(op1addr), mkexpr(result));
5075
5076 return "xiy";
5077}
5078
5079static HChar *
5080s390_irgen_XIHF(UChar r1, UInt i2)
5081{
5082 IRTemp op1 = newTemp(Ity_I32);
5083 UInt op2;
5084 IRTemp result = newTemp(Ity_I32);
5085
5086 assign(op1, get_gpr_w0(r1));
5087 op2 = i2;
5088 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5089 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5090 put_gpr_w0(r1, mkexpr(result));
5091
5092 return "xihf";
5093}
5094
5095static HChar *
5096s390_irgen_XILF(UChar r1, UInt i2)
5097{
5098 IRTemp op1 = newTemp(Ity_I32);
5099 UInt op2;
5100 IRTemp result = newTemp(Ity_I32);
5101
5102 assign(op1, get_gpr_w1(r1));
5103 op2 = i2;
5104 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5105 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5106 put_gpr_w1(r1, mkexpr(result));
5107
5108 return "xilf";
5109}
5110
5111static HChar *
5112s390_irgen_EAR(UChar r1, UChar r2)
5113{
5114 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005115 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005116 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5117
5118 return "ear";
5119}
5120
5121static HChar *
5122s390_irgen_IC(UChar r1, IRTemp op2addr)
5123{
5124 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5125
5126 return "ic";
5127}
5128
5129static HChar *
5130s390_irgen_ICY(UChar r1, IRTemp op2addr)
5131{
5132 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5133
5134 return "icy";
5135}
5136
5137static HChar *
5138s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5139{
5140 UChar n;
5141 IRTemp result = newTemp(Ity_I32);
5142 UInt mask;
5143
5144 n = 0;
5145 mask = (UInt)r3;
5146 if ((mask & 8) != 0) {
5147 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5148 n = n + 1;
5149 }
5150 if ((mask & 4) != 0) {
5151 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5152
5153 n = n + 1;
5154 }
5155 if ((mask & 2) != 0) {
5156 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5157
5158 n = n + 1;
5159 }
5160 if ((mask & 1) != 0) {
5161 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5162
5163 n = n + 1;
5164 }
5165 assign(result, get_gpr_w1(r1));
5166 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5167 mkU32(mask)));
5168
5169 return "icm";
5170}
5171
5172static HChar *
5173s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5174{
5175 UChar n;
5176 IRTemp result = newTemp(Ity_I32);
5177 UInt mask;
5178
5179 n = 0;
5180 mask = (UInt)r3;
5181 if ((mask & 8) != 0) {
5182 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5183 n = n + 1;
5184 }
5185 if ((mask & 4) != 0) {
5186 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5187
5188 n = n + 1;
5189 }
5190 if ((mask & 2) != 0) {
5191 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5192
5193 n = n + 1;
5194 }
5195 if ((mask & 1) != 0) {
5196 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5197
5198 n = n + 1;
5199 }
5200 assign(result, get_gpr_w1(r1));
5201 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5202 mkU32(mask)));
5203
5204 return "icmy";
5205}
5206
5207static HChar *
5208s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5209{
5210 UChar n;
5211 IRTemp result = newTemp(Ity_I32);
5212 UInt mask;
5213
5214 n = 0;
5215 mask = (UInt)r3;
5216 if ((mask & 8) != 0) {
5217 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5218 n = n + 1;
5219 }
5220 if ((mask & 4) != 0) {
5221 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5222
5223 n = n + 1;
5224 }
5225 if ((mask & 2) != 0) {
5226 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5227
5228 n = n + 1;
5229 }
5230 if ((mask & 1) != 0) {
5231 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5232
5233 n = n + 1;
5234 }
5235 assign(result, get_gpr_w0(r1));
5236 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5237 mkU32(mask)));
5238
5239 return "icmh";
5240}
5241
5242static HChar *
5243s390_irgen_IIHF(UChar r1, UInt i2)
5244{
5245 put_gpr_w0(r1, mkU32(i2));
5246
5247 return "iihf";
5248}
5249
5250static HChar *
5251s390_irgen_IIHH(UChar r1, UShort i2)
5252{
5253 put_gpr_hw0(r1, mkU16(i2));
5254
5255 return "iihh";
5256}
5257
5258static HChar *
5259s390_irgen_IIHL(UChar r1, UShort i2)
5260{
5261 put_gpr_hw1(r1, mkU16(i2));
5262
5263 return "iihl";
5264}
5265
5266static HChar *
5267s390_irgen_IILF(UChar r1, UInt i2)
5268{
5269 put_gpr_w1(r1, mkU32(i2));
5270
5271 return "iilf";
5272}
5273
5274static HChar *
5275s390_irgen_IILH(UChar r1, UShort i2)
5276{
5277 put_gpr_hw2(r1, mkU16(i2));
5278
5279 return "iilh";
5280}
5281
5282static HChar *
5283s390_irgen_IILL(UChar r1, UShort i2)
5284{
5285 put_gpr_hw3(r1, mkU16(i2));
5286
5287 return "iill";
5288}
5289
5290static HChar *
5291s390_irgen_LR(UChar r1, UChar r2)
5292{
5293 put_gpr_w1(r1, get_gpr_w1(r2));
5294
5295 return "lr";
5296}
5297
5298static HChar *
5299s390_irgen_LGR(UChar r1, UChar r2)
5300{
5301 put_gpr_dw0(r1, get_gpr_dw0(r2));
5302
5303 return "lgr";
5304}
5305
5306static HChar *
5307s390_irgen_LGFR(UChar r1, UChar r2)
5308{
5309 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5310
5311 return "lgfr";
5312}
5313
5314static HChar *
5315s390_irgen_L(UChar r1, IRTemp op2addr)
5316{
5317 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5318
5319 return "l";
5320}
5321
5322static HChar *
5323s390_irgen_LY(UChar r1, IRTemp op2addr)
5324{
5325 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5326
5327 return "ly";
5328}
5329
5330static HChar *
5331s390_irgen_LG(UChar r1, IRTemp op2addr)
5332{
5333 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5334
5335 return "lg";
5336}
5337
5338static HChar *
5339s390_irgen_LGF(UChar r1, IRTemp op2addr)
5340{
5341 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5342
5343 return "lgf";
5344}
5345
5346static HChar *
5347s390_irgen_LGFI(UChar r1, UInt i2)
5348{
5349 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5350
5351 return "lgfi";
5352}
5353
5354static HChar *
5355s390_irgen_LRL(UChar r1, UInt i2)
5356{
5357 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5358 i2 << 1))));
5359
5360 return "lrl";
5361}
5362
5363static HChar *
5364s390_irgen_LGRL(UChar r1, UInt i2)
5365{
5366 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5367 i2 << 1))));
5368
5369 return "lgrl";
5370}
5371
5372static HChar *
5373s390_irgen_LGFRL(UChar r1, UInt i2)
5374{
5375 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5376 ((ULong)(Long)(Int)i2 << 1)))));
5377
5378 return "lgfrl";
5379}
5380
5381static HChar *
5382s390_irgen_LA(UChar r1, IRTemp op2addr)
5383{
5384 put_gpr_dw0(r1, mkexpr(op2addr));
5385
5386 return "la";
5387}
5388
5389static HChar *
5390s390_irgen_LAY(UChar r1, IRTemp op2addr)
5391{
5392 put_gpr_dw0(r1, mkexpr(op2addr));
5393
5394 return "lay";
5395}
5396
5397static HChar *
5398s390_irgen_LAE(UChar r1, IRTemp op2addr)
5399{
5400 put_gpr_dw0(r1, mkexpr(op2addr));
5401
5402 return "lae";
5403}
5404
5405static HChar *
5406s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5407{
5408 put_gpr_dw0(r1, mkexpr(op2addr));
5409
5410 return "laey";
5411}
5412
5413static HChar *
5414s390_irgen_LARL(UChar r1, UInt i2)
5415{
5416 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5417
5418 return "larl";
5419}
5420
5421static HChar *
5422s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5423{
5424 IRTemp op2 = newTemp(Ity_I32);
5425 IRTemp op3 = newTemp(Ity_I32);
5426 IRTemp result = newTemp(Ity_I32);
5427
5428 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5429 assign(op3, get_gpr_w1(r3));
5430 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5431 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5432 store(mkexpr(op2addr), mkexpr(result));
5433 put_gpr_w1(r1, mkexpr(op2));
5434
5435 return "laa";
5436}
5437
5438static HChar *
5439s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5440{
5441 IRTemp op2 = newTemp(Ity_I64);
5442 IRTemp op3 = newTemp(Ity_I64);
5443 IRTemp result = newTemp(Ity_I64);
5444
5445 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5446 assign(op3, get_gpr_dw0(r3));
5447 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5448 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5449 store(mkexpr(op2addr), mkexpr(result));
5450 put_gpr_dw0(r1, mkexpr(op2));
5451
5452 return "laag";
5453}
5454
5455static HChar *
5456s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5457{
5458 IRTemp op2 = newTemp(Ity_I32);
5459 IRTemp op3 = newTemp(Ity_I32);
5460 IRTemp result = newTemp(Ity_I32);
5461
5462 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5463 assign(op3, get_gpr_w1(r3));
5464 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5465 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5466 store(mkexpr(op2addr), mkexpr(result));
5467 put_gpr_w1(r1, mkexpr(op2));
5468
5469 return "laal";
5470}
5471
5472static HChar *
5473s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5474{
5475 IRTemp op2 = newTemp(Ity_I64);
5476 IRTemp op3 = newTemp(Ity_I64);
5477 IRTemp result = newTemp(Ity_I64);
5478
5479 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5480 assign(op3, get_gpr_dw0(r3));
5481 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5482 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5483 store(mkexpr(op2addr), mkexpr(result));
5484 put_gpr_dw0(r1, mkexpr(op2));
5485
5486 return "laalg";
5487}
5488
5489static HChar *
5490s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5491{
5492 IRTemp op2 = newTemp(Ity_I32);
5493 IRTemp op3 = newTemp(Ity_I32);
5494 IRTemp result = newTemp(Ity_I32);
5495
5496 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5497 assign(op3, get_gpr_w1(r3));
5498 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5499 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5500 store(mkexpr(op2addr), mkexpr(result));
5501 put_gpr_w1(r1, mkexpr(op2));
5502
5503 return "lan";
5504}
5505
5506static HChar *
5507s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5508{
5509 IRTemp op2 = newTemp(Ity_I64);
5510 IRTemp op3 = newTemp(Ity_I64);
5511 IRTemp result = newTemp(Ity_I64);
5512
5513 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5514 assign(op3, get_gpr_dw0(r3));
5515 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5516 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5517 store(mkexpr(op2addr), mkexpr(result));
5518 put_gpr_dw0(r1, mkexpr(op2));
5519
5520 return "lang";
5521}
5522
5523static HChar *
5524s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5525{
5526 IRTemp op2 = newTemp(Ity_I32);
5527 IRTemp op3 = newTemp(Ity_I32);
5528 IRTemp result = newTemp(Ity_I32);
5529
5530 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5531 assign(op3, get_gpr_w1(r3));
5532 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5533 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5534 store(mkexpr(op2addr), mkexpr(result));
5535 put_gpr_w1(r1, mkexpr(op2));
5536
5537 return "lax";
5538}
5539
5540static HChar *
5541s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5542{
5543 IRTemp op2 = newTemp(Ity_I64);
5544 IRTemp op3 = newTemp(Ity_I64);
5545 IRTemp result = newTemp(Ity_I64);
5546
5547 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5548 assign(op3, get_gpr_dw0(r3));
5549 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5550 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5551 store(mkexpr(op2addr), mkexpr(result));
5552 put_gpr_dw0(r1, mkexpr(op2));
5553
5554 return "laxg";
5555}
5556
5557static HChar *
5558s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5559{
5560 IRTemp op2 = newTemp(Ity_I32);
5561 IRTemp op3 = newTemp(Ity_I32);
5562 IRTemp result = newTemp(Ity_I32);
5563
5564 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5565 assign(op3, get_gpr_w1(r3));
5566 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5567 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5568 store(mkexpr(op2addr), mkexpr(result));
5569 put_gpr_w1(r1, mkexpr(op2));
5570
5571 return "lao";
5572}
5573
5574static HChar *
5575s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5576{
5577 IRTemp op2 = newTemp(Ity_I64);
5578 IRTemp op3 = newTemp(Ity_I64);
5579 IRTemp result = newTemp(Ity_I64);
5580
5581 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5582 assign(op3, get_gpr_dw0(r3));
5583 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5584 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5585 store(mkexpr(op2addr), mkexpr(result));
5586 put_gpr_dw0(r1, mkexpr(op2));
5587
5588 return "laog";
5589}
5590
5591static HChar *
5592s390_irgen_LTR(UChar r1, UChar r2)
5593{
5594 IRTemp op2 = newTemp(Ity_I32);
5595
5596 assign(op2, get_gpr_w1(r2));
5597 put_gpr_w1(r1, mkexpr(op2));
5598 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5599
5600 return "ltr";
5601}
5602
5603static HChar *
5604s390_irgen_LTGR(UChar r1, UChar r2)
5605{
5606 IRTemp op2 = newTemp(Ity_I64);
5607
5608 assign(op2, get_gpr_dw0(r2));
5609 put_gpr_dw0(r1, mkexpr(op2));
5610 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5611
5612 return "ltgr";
5613}
5614
5615static HChar *
5616s390_irgen_LTGFR(UChar r1, UChar r2)
5617{
5618 IRTemp op2 = newTemp(Ity_I64);
5619
5620 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5621 put_gpr_dw0(r1, mkexpr(op2));
5622 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5623
5624 return "ltgfr";
5625}
5626
5627static HChar *
5628s390_irgen_LT(UChar r1, IRTemp op2addr)
5629{
5630 IRTemp op2 = newTemp(Ity_I32);
5631
5632 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5633 put_gpr_w1(r1, mkexpr(op2));
5634 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5635
5636 return "lt";
5637}
5638
5639static HChar *
5640s390_irgen_LTG(UChar r1, IRTemp op2addr)
5641{
5642 IRTemp op2 = newTemp(Ity_I64);
5643
5644 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5645 put_gpr_dw0(r1, mkexpr(op2));
5646 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5647
5648 return "ltg";
5649}
5650
5651static HChar *
5652s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5653{
5654 IRTemp op2 = newTemp(Ity_I64);
5655
5656 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5657 put_gpr_dw0(r1, mkexpr(op2));
5658 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5659
5660 return "ltgf";
5661}
5662
5663static HChar *
5664s390_irgen_LBR(UChar r1, UChar r2)
5665{
5666 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5667
5668 return "lbr";
5669}
5670
5671static HChar *
5672s390_irgen_LGBR(UChar r1, UChar r2)
5673{
5674 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5675
5676 return "lgbr";
5677}
5678
5679static HChar *
5680s390_irgen_LB(UChar r1, IRTemp op2addr)
5681{
5682 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5683
5684 return "lb";
5685}
5686
5687static HChar *
5688s390_irgen_LGB(UChar r1, IRTemp op2addr)
5689{
5690 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5691
5692 return "lgb";
5693}
5694
5695static HChar *
5696s390_irgen_LBH(UChar r1, IRTemp op2addr)
5697{
5698 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5699
5700 return "lbh";
5701}
5702
5703static HChar *
5704s390_irgen_LCR(UChar r1, UChar r2)
5705{
5706 Int op1;
5707 IRTemp op2 = newTemp(Ity_I32);
5708 IRTemp result = newTemp(Ity_I32);
5709
5710 op1 = 0;
5711 assign(op2, get_gpr_w1(r2));
5712 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5713 put_gpr_w1(r1, mkexpr(result));
5714 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5715 op1)), op2);
5716
5717 return "lcr";
5718}
5719
5720static HChar *
5721s390_irgen_LCGR(UChar r1, UChar r2)
5722{
5723 Long op1;
5724 IRTemp op2 = newTemp(Ity_I64);
5725 IRTemp result = newTemp(Ity_I64);
5726
5727 op1 = 0ULL;
5728 assign(op2, get_gpr_dw0(r2));
5729 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5730 put_gpr_dw0(r1, mkexpr(result));
5731 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5732 op1)), op2);
5733
5734 return "lcgr";
5735}
5736
5737static HChar *
5738s390_irgen_LCGFR(UChar r1, UChar r2)
5739{
5740 Long op1;
5741 IRTemp op2 = newTemp(Ity_I64);
5742 IRTemp result = newTemp(Ity_I64);
5743
5744 op1 = 0ULL;
5745 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5746 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5747 put_gpr_dw0(r1, mkexpr(result));
5748 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5749 op1)), op2);
5750
5751 return "lcgfr";
5752}
5753
5754static HChar *
5755s390_irgen_LHR(UChar r1, UChar r2)
5756{
5757 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5758
5759 return "lhr";
5760}
5761
5762static HChar *
5763s390_irgen_LGHR(UChar r1, UChar r2)
5764{
5765 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5766
5767 return "lghr";
5768}
5769
5770static HChar *
5771s390_irgen_LH(UChar r1, IRTemp op2addr)
5772{
5773 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5774
5775 return "lh";
5776}
5777
5778static HChar *
5779s390_irgen_LHY(UChar r1, IRTemp op2addr)
5780{
5781 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5782
5783 return "lhy";
5784}
5785
5786static HChar *
5787s390_irgen_LGH(UChar r1, IRTemp op2addr)
5788{
5789 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5790
5791 return "lgh";
5792}
5793
5794static HChar *
5795s390_irgen_LHI(UChar r1, UShort i2)
5796{
5797 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5798
5799 return "lhi";
5800}
5801
5802static HChar *
5803s390_irgen_LGHI(UChar r1, UShort i2)
5804{
5805 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5806
5807 return "lghi";
5808}
5809
5810static HChar *
5811s390_irgen_LHRL(UChar r1, UInt i2)
5812{
5813 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5814 ((ULong)(Long)(Int)i2 << 1)))));
5815
5816 return "lhrl";
5817}
5818
5819static HChar *
5820s390_irgen_LGHRL(UChar r1, UInt i2)
5821{
5822 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5823 ((ULong)(Long)(Int)i2 << 1)))));
5824
5825 return "lghrl";
5826}
5827
5828static HChar *
5829s390_irgen_LHH(UChar r1, IRTemp op2addr)
5830{
5831 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5832
5833 return "lhh";
5834}
5835
5836static HChar *
5837s390_irgen_LFH(UChar r1, IRTemp op2addr)
5838{
5839 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5840
5841 return "lfh";
5842}
5843
5844static HChar *
5845s390_irgen_LLGFR(UChar r1, UChar r2)
5846{
5847 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5848
5849 return "llgfr";
5850}
5851
5852static HChar *
5853s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5854{
5855 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5856
5857 return "llgf";
5858}
5859
5860static HChar *
5861s390_irgen_LLGFRL(UChar r1, UInt i2)
5862{
5863 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5864 ((ULong)(Long)(Int)i2 << 1)))));
5865
5866 return "llgfrl";
5867}
5868
5869static HChar *
5870s390_irgen_LLCR(UChar r1, UChar r2)
5871{
5872 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5873
5874 return "llcr";
5875}
5876
5877static HChar *
5878s390_irgen_LLGCR(UChar r1, UChar r2)
5879{
5880 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5881
5882 return "llgcr";
5883}
5884
5885static HChar *
5886s390_irgen_LLC(UChar r1, IRTemp op2addr)
5887{
5888 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5889
5890 return "llc";
5891}
5892
5893static HChar *
5894s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5895{
5896 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5897
5898 return "llgc";
5899}
5900
5901static HChar *
5902s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5903{
5904 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5905
5906 return "llch";
5907}
5908
5909static HChar *
5910s390_irgen_LLHR(UChar r1, UChar r2)
5911{
5912 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5913
5914 return "llhr";
5915}
5916
5917static HChar *
5918s390_irgen_LLGHR(UChar r1, UChar r2)
5919{
5920 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5921
5922 return "llghr";
5923}
5924
5925static HChar *
5926s390_irgen_LLH(UChar r1, IRTemp op2addr)
5927{
5928 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5929
5930 return "llh";
5931}
5932
5933static HChar *
5934s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5935{
5936 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5937
5938 return "llgh";
5939}
5940
5941static HChar *
5942s390_irgen_LLHRL(UChar r1, UInt i2)
5943{
5944 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5945 ((ULong)(Long)(Int)i2 << 1)))));
5946
5947 return "llhrl";
5948}
5949
5950static HChar *
5951s390_irgen_LLGHRL(UChar r1, UInt i2)
5952{
5953 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5954 ((ULong)(Long)(Int)i2 << 1)))));
5955
5956 return "llghrl";
5957}
5958
5959static HChar *
5960s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5961{
5962 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5963
5964 return "llhh";
5965}
5966
5967static HChar *
5968s390_irgen_LLIHF(UChar r1, UInt i2)
5969{
5970 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5971
5972 return "llihf";
5973}
5974
5975static HChar *
5976s390_irgen_LLIHH(UChar r1, UShort i2)
5977{
5978 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5979
5980 return "llihh";
5981}
5982
5983static HChar *
5984s390_irgen_LLIHL(UChar r1, UShort i2)
5985{
5986 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5987
5988 return "llihl";
5989}
5990
5991static HChar *
5992s390_irgen_LLILF(UChar r1, UInt i2)
5993{
5994 put_gpr_dw0(r1, mkU64(i2));
5995
5996 return "llilf";
5997}
5998
5999static HChar *
6000s390_irgen_LLILH(UChar r1, UShort i2)
6001{
6002 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6003
6004 return "llilh";
6005}
6006
6007static HChar *
6008s390_irgen_LLILL(UChar r1, UShort i2)
6009{
6010 put_gpr_dw0(r1, mkU64(i2));
6011
6012 return "llill";
6013}
6014
6015static HChar *
6016s390_irgen_LLGTR(UChar r1, UChar r2)
6017{
6018 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6019 mkU32(2147483647))));
6020
6021 return "llgtr";
6022}
6023
6024static HChar *
6025s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6026{
6027 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6028 mkexpr(op2addr)), mkU32(2147483647))));
6029
6030 return "llgt";
6031}
6032
6033static HChar *
6034s390_irgen_LNR(UChar r1, UChar r2)
6035{
6036 IRTemp op2 = newTemp(Ity_I32);
6037 IRTemp result = newTemp(Ity_I32);
6038
6039 assign(op2, get_gpr_w1(r2));
6040 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6041 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6042 put_gpr_w1(r1, mkexpr(result));
6043 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6044
6045 return "lnr";
6046}
6047
6048static HChar *
6049s390_irgen_LNGR(UChar r1, UChar r2)
6050{
6051 IRTemp op2 = newTemp(Ity_I64);
6052 IRTemp result = newTemp(Ity_I64);
6053
6054 assign(op2, get_gpr_dw0(r2));
6055 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6056 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6057 put_gpr_dw0(r1, mkexpr(result));
6058 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6059
6060 return "lngr";
6061}
6062
6063static HChar *
6064s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6065{
6066 IRTemp op2 = newTemp(Ity_I64);
6067 IRTemp result = newTemp(Ity_I64);
6068
6069 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6070 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6071 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6072 put_gpr_dw0(r1, mkexpr(result));
6073 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6074
6075 return "lngfr";
6076}
6077
6078static HChar *
sewardjd7bde722011-04-05 13:19:33 +00006079s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6080{
florian6820ba52012-07-26 02:01:50 +00006081 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006082 put_gpr_w1(r1, get_gpr_w1(r2));
6083
6084 return "locr";
6085}
6086
6087static HChar *
6088s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6089{
florian6820ba52012-07-26 02:01:50 +00006090 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006091 put_gpr_dw0(r1, get_gpr_dw0(r2));
6092
6093 return "locgr";
6094}
6095
6096static HChar *
6097s390_irgen_LOC(UChar r1, IRTemp op2addr)
6098{
6099 /* condition is checked in format handler */
6100 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6101
6102 return "loc";
6103}
6104
6105static HChar *
6106s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6107{
6108 /* condition is checked in format handler */
6109 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6110
6111 return "locg";
6112}
6113
6114static HChar *
sewardj2019a972011-03-07 16:04:07 +00006115s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6116{
6117 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6118 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6119 ));
6120
6121 return "lpq";
6122}
6123
6124static HChar *
6125s390_irgen_LPR(UChar r1, UChar r2)
6126{
6127 IRTemp op2 = newTemp(Ity_I32);
6128 IRTemp result = newTemp(Ity_I32);
6129
6130 assign(op2, get_gpr_w1(r2));
6131 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6132 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6133 put_gpr_w1(r1, mkexpr(result));
6134 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6135
6136 return "lpr";
6137}
6138
6139static HChar *
6140s390_irgen_LPGR(UChar r1, UChar r2)
6141{
6142 IRTemp op2 = newTemp(Ity_I64);
6143 IRTemp result = newTemp(Ity_I64);
6144
6145 assign(op2, get_gpr_dw0(r2));
6146 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6147 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6148 put_gpr_dw0(r1, mkexpr(result));
6149 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6150
6151 return "lpgr";
6152}
6153
6154static HChar *
6155s390_irgen_LPGFR(UChar r1, UChar r2)
6156{
6157 IRTemp op2 = newTemp(Ity_I64);
6158 IRTemp result = newTemp(Ity_I64);
6159
6160 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6161 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6162 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6163 put_gpr_dw0(r1, mkexpr(result));
6164 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6165
6166 return "lpgfr";
6167}
6168
6169static HChar *
6170s390_irgen_LRVR(UChar r1, UChar r2)
6171{
6172 IRTemp b0 = newTemp(Ity_I8);
6173 IRTemp b1 = newTemp(Ity_I8);
6174 IRTemp b2 = newTemp(Ity_I8);
6175 IRTemp b3 = newTemp(Ity_I8);
6176
6177 assign(b3, get_gpr_b7(r2));
6178 assign(b2, get_gpr_b6(r2));
6179 assign(b1, get_gpr_b5(r2));
6180 assign(b0, get_gpr_b4(r2));
6181 put_gpr_b4(r1, mkexpr(b3));
6182 put_gpr_b5(r1, mkexpr(b2));
6183 put_gpr_b6(r1, mkexpr(b1));
6184 put_gpr_b7(r1, mkexpr(b0));
6185
6186 return "lrvr";
6187}
6188
6189static HChar *
6190s390_irgen_LRVGR(UChar r1, UChar r2)
6191{
6192 IRTemp b0 = newTemp(Ity_I8);
6193 IRTemp b1 = newTemp(Ity_I8);
6194 IRTemp b2 = newTemp(Ity_I8);
6195 IRTemp b3 = newTemp(Ity_I8);
6196 IRTemp b4 = newTemp(Ity_I8);
6197 IRTemp b5 = newTemp(Ity_I8);
6198 IRTemp b6 = newTemp(Ity_I8);
6199 IRTemp b7 = newTemp(Ity_I8);
6200
6201 assign(b7, get_gpr_b7(r2));
6202 assign(b6, get_gpr_b6(r2));
6203 assign(b5, get_gpr_b5(r2));
6204 assign(b4, get_gpr_b4(r2));
6205 assign(b3, get_gpr_b3(r2));
6206 assign(b2, get_gpr_b2(r2));
6207 assign(b1, get_gpr_b1(r2));
6208 assign(b0, get_gpr_b0(r2));
6209 put_gpr_b0(r1, mkexpr(b7));
6210 put_gpr_b1(r1, mkexpr(b6));
6211 put_gpr_b2(r1, mkexpr(b5));
6212 put_gpr_b3(r1, mkexpr(b4));
6213 put_gpr_b4(r1, mkexpr(b3));
6214 put_gpr_b5(r1, mkexpr(b2));
6215 put_gpr_b6(r1, mkexpr(b1));
6216 put_gpr_b7(r1, mkexpr(b0));
6217
6218 return "lrvgr";
6219}
6220
6221static HChar *
6222s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6223{
6224 IRTemp op2 = newTemp(Ity_I16);
6225
6226 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6227 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6228 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6229
6230 return "lrvh";
6231}
6232
6233static HChar *
6234s390_irgen_LRV(UChar r1, IRTemp op2addr)
6235{
6236 IRTemp op2 = newTemp(Ity_I32);
6237
6238 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6239 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6240 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6241 mkU8(8)), mkU32(255))));
6242 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6243 mkU8(16)), mkU32(255))));
6244 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6245 mkU8(24)), mkU32(255))));
6246
6247 return "lrv";
6248}
6249
6250static HChar *
6251s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6252{
6253 IRTemp op2 = newTemp(Ity_I64);
6254
6255 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6256 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6257 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6258 mkU8(8)), mkU64(255))));
6259 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6260 mkU8(16)), mkU64(255))));
6261 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6262 mkU8(24)), mkU64(255))));
6263 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6264 mkU8(32)), mkU64(255))));
6265 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6266 mkU8(40)), mkU64(255))));
6267 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6268 mkU8(48)), mkU64(255))));
6269 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6270 mkU8(56)), mkU64(255))));
6271
6272 return "lrvg";
6273}
6274
6275static HChar *
6276s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6277{
6278 store(mkexpr(op1addr), mkU16(i2));
6279
6280 return "mvhhi";
6281}
6282
6283static HChar *
6284s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6285{
6286 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6287
6288 return "mvhi";
6289}
6290
6291static HChar *
6292s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6293{
6294 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6295
6296 return "mvghi";
6297}
6298
6299static HChar *
6300s390_irgen_MVI(UChar i2, IRTemp op1addr)
6301{
6302 store(mkexpr(op1addr), mkU8(i2));
6303
6304 return "mvi";
6305}
6306
6307static HChar *
6308s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6309{
6310 store(mkexpr(op1addr), mkU8(i2));
6311
6312 return "mviy";
6313}
6314
6315static HChar *
6316s390_irgen_MR(UChar r1, UChar r2)
6317{
6318 IRTemp op1 = newTemp(Ity_I32);
6319 IRTemp op2 = newTemp(Ity_I32);
6320 IRTemp result = newTemp(Ity_I64);
6321
6322 assign(op1, get_gpr_w1(r1 + 1));
6323 assign(op2, get_gpr_w1(r2));
6324 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6325 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6326 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6327
6328 return "mr";
6329}
6330
6331static HChar *
6332s390_irgen_M(UChar r1, IRTemp op2addr)
6333{
6334 IRTemp op1 = newTemp(Ity_I32);
6335 IRTemp op2 = newTemp(Ity_I32);
6336 IRTemp result = newTemp(Ity_I64);
6337
6338 assign(op1, get_gpr_w1(r1 + 1));
6339 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6340 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6341 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6342 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6343
6344 return "m";
6345}
6346
6347static HChar *
6348s390_irgen_MFY(UChar r1, IRTemp op2addr)
6349{
6350 IRTemp op1 = newTemp(Ity_I32);
6351 IRTemp op2 = newTemp(Ity_I32);
6352 IRTemp result = newTemp(Ity_I64);
6353
6354 assign(op1, get_gpr_w1(r1 + 1));
6355 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6356 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6357 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6358 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6359
6360 return "mfy";
6361}
6362
6363static HChar *
6364s390_irgen_MH(UChar r1, IRTemp op2addr)
6365{
6366 IRTemp op1 = newTemp(Ity_I32);
6367 IRTemp op2 = newTemp(Ity_I16);
6368 IRTemp result = newTemp(Ity_I64);
6369
6370 assign(op1, get_gpr_w1(r1));
6371 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6372 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6373 ));
6374 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6375
6376 return "mh";
6377}
6378
6379static HChar *
6380s390_irgen_MHY(UChar r1, IRTemp op2addr)
6381{
6382 IRTemp op1 = newTemp(Ity_I32);
6383 IRTemp op2 = newTemp(Ity_I16);
6384 IRTemp result = newTemp(Ity_I64);
6385
6386 assign(op1, get_gpr_w1(r1));
6387 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6388 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6389 ));
6390 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6391
6392 return "mhy";
6393}
6394
6395static HChar *
6396s390_irgen_MHI(UChar r1, UShort i2)
6397{
6398 IRTemp op1 = newTemp(Ity_I32);
6399 Short op2;
6400 IRTemp result = newTemp(Ity_I64);
6401
6402 assign(op1, get_gpr_w1(r1));
6403 op2 = (Short)i2;
6404 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6405 mkU16((UShort)op2))));
6406 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6407
6408 return "mhi";
6409}
6410
6411static HChar *
6412s390_irgen_MGHI(UChar r1, UShort i2)
6413{
6414 IRTemp op1 = newTemp(Ity_I64);
6415 Short op2;
6416 IRTemp result = newTemp(Ity_I128);
6417
6418 assign(op1, get_gpr_dw0(r1));
6419 op2 = (Short)i2;
6420 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6421 mkU16((UShort)op2))));
6422 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6423
6424 return "mghi";
6425}
6426
6427static HChar *
6428s390_irgen_MLR(UChar r1, UChar r2)
6429{
6430 IRTemp op1 = newTemp(Ity_I32);
6431 IRTemp op2 = newTemp(Ity_I32);
6432 IRTemp result = newTemp(Ity_I64);
6433
6434 assign(op1, get_gpr_w1(r1 + 1));
6435 assign(op2, get_gpr_w1(r2));
6436 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6437 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6438 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6439
6440 return "mlr";
6441}
6442
6443static HChar *
6444s390_irgen_MLGR(UChar r1, UChar r2)
6445{
6446 IRTemp op1 = newTemp(Ity_I64);
6447 IRTemp op2 = newTemp(Ity_I64);
6448 IRTemp result = newTemp(Ity_I128);
6449
6450 assign(op1, get_gpr_dw0(r1 + 1));
6451 assign(op2, get_gpr_dw0(r2));
6452 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6453 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6454 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6455
6456 return "mlgr";
6457}
6458
6459static HChar *
6460s390_irgen_ML(UChar r1, IRTemp op2addr)
6461{
6462 IRTemp op1 = newTemp(Ity_I32);
6463 IRTemp op2 = newTemp(Ity_I32);
6464 IRTemp result = newTemp(Ity_I64);
6465
6466 assign(op1, get_gpr_w1(r1 + 1));
6467 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6468 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6469 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6470 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6471
6472 return "ml";
6473}
6474
6475static HChar *
6476s390_irgen_MLG(UChar r1, IRTemp op2addr)
6477{
6478 IRTemp op1 = newTemp(Ity_I64);
6479 IRTemp op2 = newTemp(Ity_I64);
6480 IRTemp result = newTemp(Ity_I128);
6481
6482 assign(op1, get_gpr_dw0(r1 + 1));
6483 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6484 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6485 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6486 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6487
6488 return "mlg";
6489}
6490
6491static HChar *
6492s390_irgen_MSR(UChar r1, UChar r2)
6493{
6494 IRTemp op1 = newTemp(Ity_I32);
6495 IRTemp op2 = newTemp(Ity_I32);
6496 IRTemp result = newTemp(Ity_I64);
6497
6498 assign(op1, get_gpr_w1(r1));
6499 assign(op2, get_gpr_w1(r2));
6500 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6501 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6502
6503 return "msr";
6504}
6505
6506static HChar *
6507s390_irgen_MSGR(UChar r1, UChar r2)
6508{
6509 IRTemp op1 = newTemp(Ity_I64);
6510 IRTemp op2 = newTemp(Ity_I64);
6511 IRTemp result = newTemp(Ity_I128);
6512
6513 assign(op1, get_gpr_dw0(r1));
6514 assign(op2, get_gpr_dw0(r2));
6515 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6516 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6517
6518 return "msgr";
6519}
6520
6521static HChar *
6522s390_irgen_MSGFR(UChar r1, UChar r2)
6523{
6524 IRTemp op1 = newTemp(Ity_I64);
6525 IRTemp op2 = newTemp(Ity_I32);
6526 IRTemp result = newTemp(Ity_I128);
6527
6528 assign(op1, get_gpr_dw0(r1));
6529 assign(op2, get_gpr_w1(r2));
6530 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6531 ));
6532 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6533
6534 return "msgfr";
6535}
6536
6537static HChar *
6538s390_irgen_MS(UChar r1, IRTemp op2addr)
6539{
6540 IRTemp op1 = newTemp(Ity_I32);
6541 IRTemp op2 = newTemp(Ity_I32);
6542 IRTemp result = newTemp(Ity_I64);
6543
6544 assign(op1, get_gpr_w1(r1));
6545 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6546 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6547 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6548
6549 return "ms";
6550}
6551
6552static HChar *
6553s390_irgen_MSY(UChar r1, IRTemp op2addr)
6554{
6555 IRTemp op1 = newTemp(Ity_I32);
6556 IRTemp op2 = newTemp(Ity_I32);
6557 IRTemp result = newTemp(Ity_I64);
6558
6559 assign(op1, get_gpr_w1(r1));
6560 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6561 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6562 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6563
6564 return "msy";
6565}
6566
6567static HChar *
6568s390_irgen_MSG(UChar r1, IRTemp op2addr)
6569{
6570 IRTemp op1 = newTemp(Ity_I64);
6571 IRTemp op2 = newTemp(Ity_I64);
6572 IRTemp result = newTemp(Ity_I128);
6573
6574 assign(op1, get_gpr_dw0(r1));
6575 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6576 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6577 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6578
6579 return "msg";
6580}
6581
6582static HChar *
6583s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6584{
6585 IRTemp op1 = newTemp(Ity_I64);
6586 IRTemp op2 = newTemp(Ity_I32);
6587 IRTemp result = newTemp(Ity_I128);
6588
6589 assign(op1, get_gpr_dw0(r1));
6590 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6591 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6592 ));
6593 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6594
6595 return "msgf";
6596}
6597
6598static HChar *
6599s390_irgen_MSFI(UChar r1, UInt i2)
6600{
6601 IRTemp op1 = newTemp(Ity_I32);
6602 Int op2;
6603 IRTemp result = newTemp(Ity_I64);
6604
6605 assign(op1, get_gpr_w1(r1));
6606 op2 = (Int)i2;
6607 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6608 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6609
6610 return "msfi";
6611}
6612
6613static HChar *
6614s390_irgen_MSGFI(UChar r1, UInt i2)
6615{
6616 IRTemp op1 = newTemp(Ity_I64);
6617 Int op2;
6618 IRTemp result = newTemp(Ity_I128);
6619
6620 assign(op1, get_gpr_dw0(r1));
6621 op2 = (Int)i2;
6622 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6623 op2))));
6624 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6625
6626 return "msgfi";
6627}
6628
6629static HChar *
6630s390_irgen_OR(UChar r1, UChar r2)
6631{
6632 IRTemp op1 = newTemp(Ity_I32);
6633 IRTemp op2 = newTemp(Ity_I32);
6634 IRTemp result = newTemp(Ity_I32);
6635
6636 assign(op1, get_gpr_w1(r1));
6637 assign(op2, get_gpr_w1(r2));
6638 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6639 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6640 put_gpr_w1(r1, mkexpr(result));
6641
6642 return "or";
6643}
6644
6645static HChar *
6646s390_irgen_OGR(UChar r1, UChar r2)
6647{
6648 IRTemp op1 = newTemp(Ity_I64);
6649 IRTemp op2 = newTemp(Ity_I64);
6650 IRTemp result = newTemp(Ity_I64);
6651
6652 assign(op1, get_gpr_dw0(r1));
6653 assign(op2, get_gpr_dw0(r2));
6654 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6655 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6656 put_gpr_dw0(r1, mkexpr(result));
6657
6658 return "ogr";
6659}
6660
6661static HChar *
6662s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6663{
6664 IRTemp op2 = newTemp(Ity_I32);
6665 IRTemp op3 = newTemp(Ity_I32);
6666 IRTemp result = newTemp(Ity_I32);
6667
6668 assign(op2, get_gpr_w1(r2));
6669 assign(op3, get_gpr_w1(r3));
6670 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6671 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6672 put_gpr_w1(r1, mkexpr(result));
6673
6674 return "ork";
6675}
6676
6677static HChar *
6678s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6679{
6680 IRTemp op2 = newTemp(Ity_I64);
6681 IRTemp op3 = newTemp(Ity_I64);
6682 IRTemp result = newTemp(Ity_I64);
6683
6684 assign(op2, get_gpr_dw0(r2));
6685 assign(op3, get_gpr_dw0(r3));
6686 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6687 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6688 put_gpr_dw0(r1, mkexpr(result));
6689
6690 return "ogrk";
6691}
6692
6693static HChar *
6694s390_irgen_O(UChar r1, IRTemp op2addr)
6695{
6696 IRTemp op1 = newTemp(Ity_I32);
6697 IRTemp op2 = newTemp(Ity_I32);
6698 IRTemp result = newTemp(Ity_I32);
6699
6700 assign(op1, get_gpr_w1(r1));
6701 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6702 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6703 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6704 put_gpr_w1(r1, mkexpr(result));
6705
6706 return "o";
6707}
6708
6709static HChar *
6710s390_irgen_OY(UChar r1, IRTemp op2addr)
6711{
6712 IRTemp op1 = newTemp(Ity_I32);
6713 IRTemp op2 = newTemp(Ity_I32);
6714 IRTemp result = newTemp(Ity_I32);
6715
6716 assign(op1, get_gpr_w1(r1));
6717 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6718 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6719 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6720 put_gpr_w1(r1, mkexpr(result));
6721
6722 return "oy";
6723}
6724
6725static HChar *
6726s390_irgen_OG(UChar r1, IRTemp op2addr)
6727{
6728 IRTemp op1 = newTemp(Ity_I64);
6729 IRTemp op2 = newTemp(Ity_I64);
6730 IRTemp result = newTemp(Ity_I64);
6731
6732 assign(op1, get_gpr_dw0(r1));
6733 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6734 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6735 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6736 put_gpr_dw0(r1, mkexpr(result));
6737
6738 return "og";
6739}
6740
6741static HChar *
6742s390_irgen_OI(UChar i2, IRTemp op1addr)
6743{
6744 IRTemp op1 = newTemp(Ity_I8);
6745 UChar op2;
6746 IRTemp result = newTemp(Ity_I8);
6747
6748 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6749 op2 = i2;
6750 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6751 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6752 store(mkexpr(op1addr), mkexpr(result));
6753
6754 return "oi";
6755}
6756
6757static HChar *
6758s390_irgen_OIY(UChar i2, IRTemp op1addr)
6759{
6760 IRTemp op1 = newTemp(Ity_I8);
6761 UChar op2;
6762 IRTemp result = newTemp(Ity_I8);
6763
6764 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6765 op2 = i2;
6766 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6767 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6768 store(mkexpr(op1addr), mkexpr(result));
6769
6770 return "oiy";
6771}
6772
6773static HChar *
6774s390_irgen_OIHF(UChar r1, UInt i2)
6775{
6776 IRTemp op1 = newTemp(Ity_I32);
6777 UInt op2;
6778 IRTemp result = newTemp(Ity_I32);
6779
6780 assign(op1, get_gpr_w0(r1));
6781 op2 = i2;
6782 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6783 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6784 put_gpr_w0(r1, mkexpr(result));
6785
6786 return "oihf";
6787}
6788
6789static HChar *
6790s390_irgen_OIHH(UChar r1, UShort i2)
6791{
6792 IRTemp op1 = newTemp(Ity_I16);
6793 UShort op2;
6794 IRTemp result = newTemp(Ity_I16);
6795
6796 assign(op1, get_gpr_hw0(r1));
6797 op2 = i2;
6798 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6799 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6800 put_gpr_hw0(r1, mkexpr(result));
6801
6802 return "oihh";
6803}
6804
6805static HChar *
6806s390_irgen_OIHL(UChar r1, UShort i2)
6807{
6808 IRTemp op1 = newTemp(Ity_I16);
6809 UShort op2;
6810 IRTemp result = newTemp(Ity_I16);
6811
6812 assign(op1, get_gpr_hw1(r1));
6813 op2 = i2;
6814 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6815 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6816 put_gpr_hw1(r1, mkexpr(result));
6817
6818 return "oihl";
6819}
6820
6821static HChar *
6822s390_irgen_OILF(UChar r1, UInt i2)
6823{
6824 IRTemp op1 = newTemp(Ity_I32);
6825 UInt op2;
6826 IRTemp result = newTemp(Ity_I32);
6827
6828 assign(op1, get_gpr_w1(r1));
6829 op2 = i2;
6830 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6831 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6832 put_gpr_w1(r1, mkexpr(result));
6833
6834 return "oilf";
6835}
6836
6837static HChar *
6838s390_irgen_OILH(UChar r1, UShort i2)
6839{
6840 IRTemp op1 = newTemp(Ity_I16);
6841 UShort op2;
6842 IRTemp result = newTemp(Ity_I16);
6843
6844 assign(op1, get_gpr_hw2(r1));
6845 op2 = i2;
6846 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6847 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6848 put_gpr_hw2(r1, mkexpr(result));
6849
6850 return "oilh";
6851}
6852
6853static HChar *
6854s390_irgen_OILL(UChar r1, UShort i2)
6855{
6856 IRTemp op1 = newTemp(Ity_I16);
6857 UShort op2;
6858 IRTemp result = newTemp(Ity_I16);
6859
6860 assign(op1, get_gpr_hw3(r1));
6861 op2 = i2;
6862 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6863 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6864 put_gpr_hw3(r1, mkexpr(result));
6865
6866 return "oill";
6867}
6868
6869static HChar *
6870s390_irgen_PFD(void)
6871{
6872
6873 return "pfd";
6874}
6875
6876static HChar *
6877s390_irgen_PFDRL(void)
6878{
6879
6880 return "pfdrl";
6881}
6882
6883static HChar *
6884s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6885{
6886 IRTemp amount = newTemp(Ity_I64);
6887 IRTemp op = newTemp(Ity_I32);
6888
6889 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6890 assign(op, get_gpr_w1(r3));
6891 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6892 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6893 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6894
6895 return "rll";
6896}
6897
6898static HChar *
6899s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6900{
6901 IRTemp amount = newTemp(Ity_I64);
6902 IRTemp op = newTemp(Ity_I64);
6903
6904 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6905 assign(op, get_gpr_dw0(r3));
6906 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6907 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6908 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6909
6910 return "rllg";
6911}
6912
6913static HChar *
6914s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6915{
6916 UChar from;
6917 UChar to;
6918 UChar rot;
6919 UChar t_bit;
6920 ULong mask;
6921 ULong maskc;
6922 IRTemp result = newTemp(Ity_I64);
6923 IRTemp op2 = newTemp(Ity_I64);
6924
6925 from = i3 & 63;
6926 to = i4 & 63;
6927 rot = i5 & 63;
6928 t_bit = i3 & 128;
6929 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6930 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6931 mkU8(64 - rot))));
6932 if (from <= to) {
6933 mask = ~0ULL;
6934 mask = (mask >> from) & (mask << (63 - to));
6935 maskc = ~mask;
6936 } else {
6937 maskc = ~0ULL;
6938 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6939 mask = ~maskc;
6940 }
6941 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6942 ), mkU64(mask)));
6943 if (t_bit == 0) {
6944 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6945 mkU64(maskc)), mkexpr(result)));
6946 }
6947 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6948
6949 return "rnsbg";
6950}
6951
6952static HChar *
6953s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6954{
6955 UChar from;
6956 UChar to;
6957 UChar rot;
6958 UChar t_bit;
6959 ULong mask;
6960 ULong maskc;
6961 IRTemp result = newTemp(Ity_I64);
6962 IRTemp op2 = newTemp(Ity_I64);
6963
6964 from = i3 & 63;
6965 to = i4 & 63;
6966 rot = i5 & 63;
6967 t_bit = i3 & 128;
6968 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6969 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6970 mkU8(64 - rot))));
6971 if (from <= to) {
6972 mask = ~0ULL;
6973 mask = (mask >> from) & (mask << (63 - to));
6974 maskc = ~mask;
6975 } else {
6976 maskc = ~0ULL;
6977 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6978 mask = ~maskc;
6979 }
6980 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6981 ), mkU64(mask)));
6982 if (t_bit == 0) {
6983 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6984 mkU64(maskc)), mkexpr(result)));
6985 }
6986 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6987
6988 return "rxsbg";
6989}
6990
6991static HChar *
6992s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6993{
6994 UChar from;
6995 UChar to;
6996 UChar rot;
6997 UChar t_bit;
6998 ULong mask;
6999 ULong maskc;
7000 IRTemp result = newTemp(Ity_I64);
7001 IRTemp op2 = newTemp(Ity_I64);
7002
7003 from = i3 & 63;
7004 to = i4 & 63;
7005 rot = i5 & 63;
7006 t_bit = i3 & 128;
7007 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7008 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7009 mkU8(64 - rot))));
7010 if (from <= to) {
7011 mask = ~0ULL;
7012 mask = (mask >> from) & (mask << (63 - to));
7013 maskc = ~mask;
7014 } else {
7015 maskc = ~0ULL;
7016 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7017 mask = ~maskc;
7018 }
7019 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7020 ), mkU64(mask)));
7021 if (t_bit == 0) {
7022 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7023 mkU64(maskc)), mkexpr(result)));
7024 }
7025 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7026
7027 return "rosbg";
7028}
7029
7030static HChar *
7031s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7032{
7033 UChar from;
7034 UChar to;
7035 UChar rot;
7036 UChar z_bit;
7037 ULong mask;
7038 ULong maskc;
7039 IRTemp op2 = newTemp(Ity_I64);
7040 IRTemp result = newTemp(Ity_I64);
7041
7042 from = i3 & 63;
7043 to = i4 & 63;
7044 rot = i5 & 63;
7045 z_bit = i4 & 128;
7046 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7047 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7048 mkU8(64 - rot))));
7049 if (from <= to) {
7050 mask = ~0ULL;
7051 mask = (mask >> from) & (mask << (63 - to));
7052 maskc = ~mask;
7053 } else {
7054 maskc = ~0ULL;
7055 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7056 mask = ~maskc;
7057 }
7058 if (z_bit == 0) {
7059 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7060 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7061 } else {
7062 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7063 }
7064 assign(result, get_gpr_dw0(r1));
7065 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7066
7067 return "risbg";
7068}
7069
7070static HChar *
7071s390_irgen_SAR(UChar r1, UChar r2)
7072{
7073 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007074 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007075 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7076
7077 return "sar";
7078}
7079
7080static HChar *
7081s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7082{
7083 IRTemp p1 = newTemp(Ity_I64);
7084 IRTemp p2 = newTemp(Ity_I64);
7085 IRTemp op = newTemp(Ity_I64);
7086 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007087 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007088 IRTemp shift_amount = newTemp(Ity_I64);
7089
7090 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7091 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7092 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7093 ));
7094 sign_mask = 1ULL << 63;
7095 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7096 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007097 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7098 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007099 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7100 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7101 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7102
7103 return "slda";
7104}
7105
7106static HChar *
7107s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7108{
7109 IRTemp p1 = newTemp(Ity_I64);
7110 IRTemp p2 = newTemp(Ity_I64);
7111 IRTemp result = newTemp(Ity_I64);
7112
7113 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7114 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7115 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7116 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7117 mkexpr(op2addr), mkU64(63)))));
7118 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7119 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7120
7121 return "sldl";
7122}
7123
7124static HChar *
7125s390_irgen_SLA(UChar r1, IRTemp op2addr)
7126{
7127 IRTemp uop = newTemp(Ity_I32);
7128 IRTemp result = newTemp(Ity_I32);
7129 UInt sign_mask;
7130 IRTemp shift_amount = newTemp(Ity_I64);
7131 IRTemp op = newTemp(Ity_I32);
7132
7133 assign(op, get_gpr_w1(r1));
7134 assign(uop, get_gpr_w1(r1));
7135 sign_mask = 2147483648U;
7136 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7137 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7138 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7139 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7140 put_gpr_w1(r1, mkexpr(result));
7141 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7142
7143 return "sla";
7144}
7145
7146static HChar *
7147s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7148{
7149 IRTemp uop = newTemp(Ity_I32);
7150 IRTemp result = newTemp(Ity_I32);
7151 UInt sign_mask;
7152 IRTemp shift_amount = newTemp(Ity_I64);
7153 IRTemp op = newTemp(Ity_I32);
7154
7155 assign(op, get_gpr_w1(r3));
7156 assign(uop, get_gpr_w1(r3));
7157 sign_mask = 2147483648U;
7158 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7159 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7160 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7161 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7162 put_gpr_w1(r1, mkexpr(result));
7163 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7164
7165 return "slak";
7166}
7167
7168static HChar *
7169s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7170{
7171 IRTemp uop = newTemp(Ity_I64);
7172 IRTemp result = newTemp(Ity_I64);
7173 ULong sign_mask;
7174 IRTemp shift_amount = newTemp(Ity_I64);
7175 IRTemp op = newTemp(Ity_I64);
7176
7177 assign(op, get_gpr_dw0(r3));
7178 assign(uop, get_gpr_dw0(r3));
7179 sign_mask = 9223372036854775808ULL;
7180 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7181 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7182 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7183 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7184 put_gpr_dw0(r1, mkexpr(result));
7185 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7186
7187 return "slag";
7188}
7189
7190static HChar *
7191s390_irgen_SLL(UChar r1, IRTemp op2addr)
7192{
7193 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7194 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7195
7196 return "sll";
7197}
7198
7199static HChar *
7200s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7201{
7202 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7203 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7204
7205 return "sllk";
7206}
7207
7208static HChar *
7209s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7210{
7211 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7212 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7213
7214 return "sllg";
7215}
7216
7217static HChar *
7218s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7219{
7220 IRTemp p1 = newTemp(Ity_I64);
7221 IRTemp p2 = newTemp(Ity_I64);
7222 IRTemp result = newTemp(Ity_I64);
7223
7224 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7225 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7226 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7227 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7228 mkexpr(op2addr), mkU64(63)))));
7229 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7230 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7231 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7232
7233 return "srda";
7234}
7235
7236static HChar *
7237s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7238{
7239 IRTemp p1 = newTemp(Ity_I64);
7240 IRTemp p2 = newTemp(Ity_I64);
7241 IRTemp result = newTemp(Ity_I64);
7242
7243 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7244 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7245 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7246 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7247 mkexpr(op2addr), mkU64(63)))));
7248 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7249 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7250
7251 return "srdl";
7252}
7253
7254static HChar *
7255s390_irgen_SRA(UChar r1, IRTemp op2addr)
7256{
7257 IRTemp result = newTemp(Ity_I32);
7258 IRTemp op = newTemp(Ity_I32);
7259
7260 assign(op, get_gpr_w1(r1));
7261 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7262 mkexpr(op2addr), mkU64(63)))));
7263 put_gpr_w1(r1, mkexpr(result));
7264 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7265
7266 return "sra";
7267}
7268
7269static HChar *
7270s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7271{
7272 IRTemp result = newTemp(Ity_I32);
7273 IRTemp op = newTemp(Ity_I32);
7274
7275 assign(op, get_gpr_w1(r3));
7276 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7277 mkexpr(op2addr), mkU64(63)))));
7278 put_gpr_w1(r1, mkexpr(result));
7279 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7280
7281 return "srak";
7282}
7283
7284static HChar *
7285s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7286{
7287 IRTemp result = newTemp(Ity_I64);
7288 IRTemp op = newTemp(Ity_I64);
7289
7290 assign(op, get_gpr_dw0(r3));
7291 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7292 mkexpr(op2addr), mkU64(63)))));
7293 put_gpr_dw0(r1, mkexpr(result));
7294 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7295
7296 return "srag";
7297}
7298
7299static HChar *
7300s390_irgen_SRL(UChar r1, IRTemp op2addr)
7301{
7302 IRTemp op = newTemp(Ity_I32);
7303
7304 assign(op, get_gpr_w1(r1));
7305 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7306 mkexpr(op2addr), mkU64(63)))));
7307
7308 return "srl";
7309}
7310
7311static HChar *
7312s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7313{
7314 IRTemp op = newTemp(Ity_I32);
7315
7316 assign(op, get_gpr_w1(r3));
7317 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7318 mkexpr(op2addr), mkU64(63)))));
7319
7320 return "srlk";
7321}
7322
7323static HChar *
7324s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7325{
7326 IRTemp op = newTemp(Ity_I64);
7327
7328 assign(op, get_gpr_dw0(r3));
7329 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7330 mkexpr(op2addr), mkU64(63)))));
7331
7332 return "srlg";
7333}
7334
7335static HChar *
7336s390_irgen_ST(UChar r1, IRTemp op2addr)
7337{
7338 store(mkexpr(op2addr), get_gpr_w1(r1));
7339
7340 return "st";
7341}
7342
7343static HChar *
7344s390_irgen_STY(UChar r1, IRTemp op2addr)
7345{
7346 store(mkexpr(op2addr), get_gpr_w1(r1));
7347
7348 return "sty";
7349}
7350
7351static HChar *
7352s390_irgen_STG(UChar r1, IRTemp op2addr)
7353{
7354 store(mkexpr(op2addr), get_gpr_dw0(r1));
7355
7356 return "stg";
7357}
7358
7359static HChar *
7360s390_irgen_STRL(UChar r1, UInt i2)
7361{
7362 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7363 get_gpr_w1(r1));
7364
7365 return "strl";
7366}
7367
7368static HChar *
7369s390_irgen_STGRL(UChar r1, UInt i2)
7370{
7371 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7372 get_gpr_dw0(r1));
7373
7374 return "stgrl";
7375}
7376
7377static HChar *
7378s390_irgen_STC(UChar r1, IRTemp op2addr)
7379{
7380 store(mkexpr(op2addr), get_gpr_b7(r1));
7381
7382 return "stc";
7383}
7384
7385static HChar *
7386s390_irgen_STCY(UChar r1, IRTemp op2addr)
7387{
7388 store(mkexpr(op2addr), get_gpr_b7(r1));
7389
7390 return "stcy";
7391}
7392
7393static HChar *
7394s390_irgen_STCH(UChar r1, IRTemp op2addr)
7395{
7396 store(mkexpr(op2addr), get_gpr_b3(r1));
7397
7398 return "stch";
7399}
7400
7401static HChar *
7402s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7403{
7404 UChar mask;
7405 UChar n;
7406
7407 mask = (UChar)r3;
7408 n = 0;
7409 if ((mask & 8) != 0) {
7410 store(mkexpr(op2addr), get_gpr_b4(r1));
7411 n = n + 1;
7412 }
7413 if ((mask & 4) != 0) {
7414 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7415 n = n + 1;
7416 }
7417 if ((mask & 2) != 0) {
7418 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7419 n = n + 1;
7420 }
7421 if ((mask & 1) != 0) {
7422 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7423 }
7424
7425 return "stcm";
7426}
7427
7428static HChar *
7429s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7430{
7431 UChar mask;
7432 UChar n;
7433
7434 mask = (UChar)r3;
7435 n = 0;
7436 if ((mask & 8) != 0) {
7437 store(mkexpr(op2addr), get_gpr_b4(r1));
7438 n = n + 1;
7439 }
7440 if ((mask & 4) != 0) {
7441 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7442 n = n + 1;
7443 }
7444 if ((mask & 2) != 0) {
7445 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7446 n = n + 1;
7447 }
7448 if ((mask & 1) != 0) {
7449 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7450 }
7451
7452 return "stcmy";
7453}
7454
7455static HChar *
7456s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7457{
7458 UChar mask;
7459 UChar n;
7460
7461 mask = (UChar)r3;
7462 n = 0;
7463 if ((mask & 8) != 0) {
7464 store(mkexpr(op2addr), get_gpr_b0(r1));
7465 n = n + 1;
7466 }
7467 if ((mask & 4) != 0) {
7468 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7469 n = n + 1;
7470 }
7471 if ((mask & 2) != 0) {
7472 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7473 n = n + 1;
7474 }
7475 if ((mask & 1) != 0) {
7476 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7477 }
7478
7479 return "stcmh";
7480}
7481
7482static HChar *
7483s390_irgen_STH(UChar r1, IRTemp op2addr)
7484{
7485 store(mkexpr(op2addr), get_gpr_hw3(r1));
7486
7487 return "sth";
7488}
7489
7490static HChar *
7491s390_irgen_STHY(UChar r1, IRTemp op2addr)
7492{
7493 store(mkexpr(op2addr), get_gpr_hw3(r1));
7494
7495 return "sthy";
7496}
7497
7498static HChar *
7499s390_irgen_STHRL(UChar r1, UInt i2)
7500{
7501 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7502 get_gpr_hw3(r1));
7503
7504 return "sthrl";
7505}
7506
7507static HChar *
7508s390_irgen_STHH(UChar r1, IRTemp op2addr)
7509{
7510 store(mkexpr(op2addr), get_gpr_hw1(r1));
7511
7512 return "sthh";
7513}
7514
7515static HChar *
7516s390_irgen_STFH(UChar r1, IRTemp op2addr)
7517{
7518 store(mkexpr(op2addr), get_gpr_w0(r1));
7519
7520 return "stfh";
7521}
7522
7523static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007524s390_irgen_STOC(UChar r1, IRTemp op2addr)
7525{
7526 /* condition is checked in format handler */
7527 store(mkexpr(op2addr), get_gpr_w1(r1));
7528
7529 return "stoc";
7530}
7531
7532static HChar *
7533s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7534{
7535 /* condition is checked in format handler */
7536 store(mkexpr(op2addr), get_gpr_dw0(r1));
7537
7538 return "stocg";
7539}
7540
7541static HChar *
sewardj2019a972011-03-07 16:04:07 +00007542s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7543{
7544 store(mkexpr(op2addr), get_gpr_dw0(r1));
7545 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7546
7547 return "stpq";
7548}
7549
7550static HChar *
7551s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7552{
7553 store(mkexpr(op2addr), get_gpr_b7(r1));
7554 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7555
7556 return "strvh";
7557}
7558
7559static HChar *
7560s390_irgen_STRV(UChar r1, IRTemp op2addr)
7561{
7562 store(mkexpr(op2addr), get_gpr_b7(r1));
7563 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7564 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7565 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7566
7567 return "strv";
7568}
7569
7570static HChar *
7571s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7572{
7573 store(mkexpr(op2addr), get_gpr_b7(r1));
7574 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7575 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7576 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7577 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7578 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7579 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7580 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7581
7582 return "strvg";
7583}
7584
7585static HChar *
7586s390_irgen_SR(UChar r1, UChar r2)
7587{
7588 IRTemp op1 = newTemp(Ity_I32);
7589 IRTemp op2 = newTemp(Ity_I32);
7590 IRTemp result = newTemp(Ity_I32);
7591
7592 assign(op1, get_gpr_w1(r1));
7593 assign(op2, get_gpr_w1(r2));
7594 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7595 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7596 put_gpr_w1(r1, mkexpr(result));
7597
7598 return "sr";
7599}
7600
7601static HChar *
7602s390_irgen_SGR(UChar r1, UChar r2)
7603{
7604 IRTemp op1 = newTemp(Ity_I64);
7605 IRTemp op2 = newTemp(Ity_I64);
7606 IRTemp result = newTemp(Ity_I64);
7607
7608 assign(op1, get_gpr_dw0(r1));
7609 assign(op2, get_gpr_dw0(r2));
7610 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7611 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7612 put_gpr_dw0(r1, mkexpr(result));
7613
7614 return "sgr";
7615}
7616
7617static HChar *
7618s390_irgen_SGFR(UChar r1, UChar r2)
7619{
7620 IRTemp op1 = newTemp(Ity_I64);
7621 IRTemp op2 = newTemp(Ity_I64);
7622 IRTemp result = newTemp(Ity_I64);
7623
7624 assign(op1, get_gpr_dw0(r1));
7625 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7626 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7627 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7628 put_gpr_dw0(r1, mkexpr(result));
7629
7630 return "sgfr";
7631}
7632
7633static HChar *
7634s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7635{
7636 IRTemp op2 = newTemp(Ity_I32);
7637 IRTemp op3 = newTemp(Ity_I32);
7638 IRTemp result = newTemp(Ity_I32);
7639
7640 assign(op2, get_gpr_w1(r2));
7641 assign(op3, get_gpr_w1(r3));
7642 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7643 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7644 put_gpr_w1(r1, mkexpr(result));
7645
7646 return "srk";
7647}
7648
7649static HChar *
7650s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7651{
7652 IRTemp op2 = newTemp(Ity_I64);
7653 IRTemp op3 = newTemp(Ity_I64);
7654 IRTemp result = newTemp(Ity_I64);
7655
7656 assign(op2, get_gpr_dw0(r2));
7657 assign(op3, get_gpr_dw0(r3));
7658 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7659 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7660 put_gpr_dw0(r1, mkexpr(result));
7661
7662 return "sgrk";
7663}
7664
7665static HChar *
7666s390_irgen_S(UChar r1, IRTemp op2addr)
7667{
7668 IRTemp op1 = newTemp(Ity_I32);
7669 IRTemp op2 = newTemp(Ity_I32);
7670 IRTemp result = newTemp(Ity_I32);
7671
7672 assign(op1, get_gpr_w1(r1));
7673 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7674 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7675 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7676 put_gpr_w1(r1, mkexpr(result));
7677
7678 return "s";
7679}
7680
7681static HChar *
7682s390_irgen_SY(UChar r1, IRTemp op2addr)
7683{
7684 IRTemp op1 = newTemp(Ity_I32);
7685 IRTemp op2 = newTemp(Ity_I32);
7686 IRTemp result = newTemp(Ity_I32);
7687
7688 assign(op1, get_gpr_w1(r1));
7689 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7690 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7691 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7692 put_gpr_w1(r1, mkexpr(result));
7693
7694 return "sy";
7695}
7696
7697static HChar *
7698s390_irgen_SG(UChar r1, IRTemp op2addr)
7699{
7700 IRTemp op1 = newTemp(Ity_I64);
7701 IRTemp op2 = newTemp(Ity_I64);
7702 IRTemp result = newTemp(Ity_I64);
7703
7704 assign(op1, get_gpr_dw0(r1));
7705 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7706 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7707 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7708 put_gpr_dw0(r1, mkexpr(result));
7709
7710 return "sg";
7711}
7712
7713static HChar *
7714s390_irgen_SGF(UChar r1, IRTemp op2addr)
7715{
7716 IRTemp op1 = newTemp(Ity_I64);
7717 IRTemp op2 = newTemp(Ity_I64);
7718 IRTemp result = newTemp(Ity_I64);
7719
7720 assign(op1, get_gpr_dw0(r1));
7721 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7722 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7723 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7724 put_gpr_dw0(r1, mkexpr(result));
7725
7726 return "sgf";
7727}
7728
7729static HChar *
7730s390_irgen_SH(UChar r1, IRTemp op2addr)
7731{
7732 IRTemp op1 = newTemp(Ity_I32);
7733 IRTemp op2 = newTemp(Ity_I32);
7734 IRTemp result = newTemp(Ity_I32);
7735
7736 assign(op1, get_gpr_w1(r1));
7737 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7738 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7739 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7740 put_gpr_w1(r1, mkexpr(result));
7741
7742 return "sh";
7743}
7744
7745static HChar *
7746s390_irgen_SHY(UChar r1, IRTemp op2addr)
7747{
7748 IRTemp op1 = newTemp(Ity_I32);
7749 IRTemp op2 = newTemp(Ity_I32);
7750 IRTemp result = newTemp(Ity_I32);
7751
7752 assign(op1, get_gpr_w1(r1));
7753 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7754 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7755 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7756 put_gpr_w1(r1, mkexpr(result));
7757
7758 return "shy";
7759}
7760
7761static HChar *
7762s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7763{
7764 IRTemp op2 = newTemp(Ity_I32);
7765 IRTemp op3 = newTemp(Ity_I32);
7766 IRTemp result = newTemp(Ity_I32);
7767
7768 assign(op2, get_gpr_w0(r1));
7769 assign(op3, get_gpr_w0(r2));
7770 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7771 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7772 put_gpr_w0(r1, mkexpr(result));
7773
7774 return "shhhr";
7775}
7776
7777static HChar *
7778s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7779{
7780 IRTemp op2 = newTemp(Ity_I32);
7781 IRTemp op3 = newTemp(Ity_I32);
7782 IRTemp result = newTemp(Ity_I32);
7783
7784 assign(op2, get_gpr_w0(r1));
7785 assign(op3, get_gpr_w1(r2));
7786 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7787 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7788 put_gpr_w0(r1, mkexpr(result));
7789
7790 return "shhlr";
7791}
7792
7793static HChar *
7794s390_irgen_SLR(UChar r1, UChar r2)
7795{
7796 IRTemp op1 = newTemp(Ity_I32);
7797 IRTemp op2 = newTemp(Ity_I32);
7798 IRTemp result = newTemp(Ity_I32);
7799
7800 assign(op1, get_gpr_w1(r1));
7801 assign(op2, get_gpr_w1(r2));
7802 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7803 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7804 put_gpr_w1(r1, mkexpr(result));
7805
7806 return "slr";
7807}
7808
7809static HChar *
7810s390_irgen_SLGR(UChar r1, UChar r2)
7811{
7812 IRTemp op1 = newTemp(Ity_I64);
7813 IRTemp op2 = newTemp(Ity_I64);
7814 IRTemp result = newTemp(Ity_I64);
7815
7816 assign(op1, get_gpr_dw0(r1));
7817 assign(op2, get_gpr_dw0(r2));
7818 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7819 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7820 put_gpr_dw0(r1, mkexpr(result));
7821
7822 return "slgr";
7823}
7824
7825static HChar *
7826s390_irgen_SLGFR(UChar r1, UChar r2)
7827{
7828 IRTemp op1 = newTemp(Ity_I64);
7829 IRTemp op2 = newTemp(Ity_I64);
7830 IRTemp result = newTemp(Ity_I64);
7831
7832 assign(op1, get_gpr_dw0(r1));
7833 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7834 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7835 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7836 put_gpr_dw0(r1, mkexpr(result));
7837
7838 return "slgfr";
7839}
7840
7841static HChar *
7842s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7843{
7844 IRTemp op2 = newTemp(Ity_I32);
7845 IRTemp op3 = newTemp(Ity_I32);
7846 IRTemp result = newTemp(Ity_I32);
7847
7848 assign(op2, get_gpr_w1(r2));
7849 assign(op3, get_gpr_w1(r3));
7850 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7851 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7852 put_gpr_w1(r1, mkexpr(result));
7853
7854 return "slrk";
7855}
7856
7857static HChar *
7858s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7859{
7860 IRTemp op2 = newTemp(Ity_I64);
7861 IRTemp op3 = newTemp(Ity_I64);
7862 IRTemp result = newTemp(Ity_I64);
7863
7864 assign(op2, get_gpr_dw0(r2));
7865 assign(op3, get_gpr_dw0(r3));
7866 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7867 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7868 put_gpr_dw0(r1, mkexpr(result));
7869
7870 return "slgrk";
7871}
7872
7873static HChar *
7874s390_irgen_SL(UChar r1, IRTemp op2addr)
7875{
7876 IRTemp op1 = newTemp(Ity_I32);
7877 IRTemp op2 = newTemp(Ity_I32);
7878 IRTemp result = newTemp(Ity_I32);
7879
7880 assign(op1, get_gpr_w1(r1));
7881 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7882 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7883 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7884 put_gpr_w1(r1, mkexpr(result));
7885
7886 return "sl";
7887}
7888
7889static HChar *
7890s390_irgen_SLY(UChar r1, IRTemp op2addr)
7891{
7892 IRTemp op1 = newTemp(Ity_I32);
7893 IRTemp op2 = newTemp(Ity_I32);
7894 IRTemp result = newTemp(Ity_I32);
7895
7896 assign(op1, get_gpr_w1(r1));
7897 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7898 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7899 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7900 put_gpr_w1(r1, mkexpr(result));
7901
7902 return "sly";
7903}
7904
7905static HChar *
7906s390_irgen_SLG(UChar r1, IRTemp op2addr)
7907{
7908 IRTemp op1 = newTemp(Ity_I64);
7909 IRTemp op2 = newTemp(Ity_I64);
7910 IRTemp result = newTemp(Ity_I64);
7911
7912 assign(op1, get_gpr_dw0(r1));
7913 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7914 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7915 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7916 put_gpr_dw0(r1, mkexpr(result));
7917
7918 return "slg";
7919}
7920
7921static HChar *
7922s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7923{
7924 IRTemp op1 = newTemp(Ity_I64);
7925 IRTemp op2 = newTemp(Ity_I64);
7926 IRTemp result = newTemp(Ity_I64);
7927
7928 assign(op1, get_gpr_dw0(r1));
7929 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7930 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7931 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7932 put_gpr_dw0(r1, mkexpr(result));
7933
7934 return "slgf";
7935}
7936
7937static HChar *
7938s390_irgen_SLFI(UChar r1, UInt i2)
7939{
7940 IRTemp op1 = newTemp(Ity_I32);
7941 UInt op2;
7942 IRTemp result = newTemp(Ity_I32);
7943
7944 assign(op1, get_gpr_w1(r1));
7945 op2 = i2;
7946 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7947 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7948 mkU32(op2)));
7949 put_gpr_w1(r1, mkexpr(result));
7950
7951 return "slfi";
7952}
7953
7954static HChar *
7955s390_irgen_SLGFI(UChar r1, UInt i2)
7956{
7957 IRTemp op1 = newTemp(Ity_I64);
7958 ULong op2;
7959 IRTemp result = newTemp(Ity_I64);
7960
7961 assign(op1, get_gpr_dw0(r1));
7962 op2 = (ULong)i2;
7963 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7964 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7965 mkU64(op2)));
7966 put_gpr_dw0(r1, mkexpr(result));
7967
7968 return "slgfi";
7969}
7970
7971static HChar *
7972s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7973{
7974 IRTemp op2 = newTemp(Ity_I32);
7975 IRTemp op3 = newTemp(Ity_I32);
7976 IRTemp result = newTemp(Ity_I32);
7977
7978 assign(op2, get_gpr_w0(r1));
7979 assign(op3, get_gpr_w0(r2));
7980 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7981 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7982 put_gpr_w0(r1, mkexpr(result));
7983
7984 return "slhhhr";
7985}
7986
7987static HChar *
7988s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7989{
7990 IRTemp op2 = newTemp(Ity_I32);
7991 IRTemp op3 = newTemp(Ity_I32);
7992 IRTemp result = newTemp(Ity_I32);
7993
7994 assign(op2, get_gpr_w0(r1));
7995 assign(op3, get_gpr_w1(r2));
7996 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7997 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7998 put_gpr_w0(r1, mkexpr(result));
7999
8000 return "slhhlr";
8001}
8002
8003static HChar *
8004s390_irgen_SLBR(UChar r1, UChar r2)
8005{
8006 IRTemp op1 = newTemp(Ity_I32);
8007 IRTemp op2 = newTemp(Ity_I32);
8008 IRTemp result = newTemp(Ity_I32);
8009 IRTemp borrow_in = newTemp(Ity_I32);
8010
8011 assign(op1, get_gpr_w1(r1));
8012 assign(op2, get_gpr_w1(r2));
8013 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8014 s390_call_calculate_cc(), mkU8(1))));
8015 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8016 mkexpr(borrow_in)));
8017 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8018 put_gpr_w1(r1, mkexpr(result));
8019
8020 return "slbr";
8021}
8022
8023static HChar *
8024s390_irgen_SLBGR(UChar r1, UChar r2)
8025{
8026 IRTemp op1 = newTemp(Ity_I64);
8027 IRTemp op2 = newTemp(Ity_I64);
8028 IRTemp result = newTemp(Ity_I64);
8029 IRTemp borrow_in = newTemp(Ity_I64);
8030
8031 assign(op1, get_gpr_dw0(r1));
8032 assign(op2, get_gpr_dw0(r2));
8033 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8034 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8035 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8036 mkexpr(borrow_in)));
8037 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8038 put_gpr_dw0(r1, mkexpr(result));
8039
8040 return "slbgr";
8041}
8042
8043static HChar *
8044s390_irgen_SLB(UChar r1, IRTemp op2addr)
8045{
8046 IRTemp op1 = newTemp(Ity_I32);
8047 IRTemp op2 = newTemp(Ity_I32);
8048 IRTemp result = newTemp(Ity_I32);
8049 IRTemp borrow_in = newTemp(Ity_I32);
8050
8051 assign(op1, get_gpr_w1(r1));
8052 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8053 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8054 s390_call_calculate_cc(), mkU8(1))));
8055 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8056 mkexpr(borrow_in)));
8057 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8058 put_gpr_w1(r1, mkexpr(result));
8059
8060 return "slb";
8061}
8062
8063static HChar *
8064s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8065{
8066 IRTemp op1 = newTemp(Ity_I64);
8067 IRTemp op2 = newTemp(Ity_I64);
8068 IRTemp result = newTemp(Ity_I64);
8069 IRTemp borrow_in = newTemp(Ity_I64);
8070
8071 assign(op1, get_gpr_dw0(r1));
8072 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8073 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8074 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8075 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8076 mkexpr(borrow_in)));
8077 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8078 put_gpr_dw0(r1, mkexpr(result));
8079
8080 return "slbg";
8081}
8082
8083static HChar *
8084s390_irgen_SVC(UChar i)
8085{
8086 IRTemp sysno = newTemp(Ity_I64);
8087
8088 if (i != 0) {
8089 assign(sysno, mkU64(i));
8090 } else {
8091 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8092 }
8093 system_call(mkexpr(sysno));
8094
8095 return "svc";
8096}
8097
8098static HChar *
sewardj2019a972011-03-07 16:04:07 +00008099s390_irgen_TM(UChar i2, IRTemp op1addr)
8100{
8101 UChar mask;
8102 IRTemp value = newTemp(Ity_I8);
8103
8104 mask = i2;
8105 assign(value, load(Ity_I8, mkexpr(op1addr)));
8106 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8107 mkU8(mask)));
8108
8109 return "tm";
8110}
8111
8112static HChar *
8113s390_irgen_TMY(UChar i2, IRTemp op1addr)
8114{
8115 UChar mask;
8116 IRTemp value = newTemp(Ity_I8);
8117
8118 mask = i2;
8119 assign(value, load(Ity_I8, mkexpr(op1addr)));
8120 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8121 mkU8(mask)));
8122
8123 return "tmy";
8124}
8125
8126static HChar *
8127s390_irgen_TMHH(UChar r1, UShort i2)
8128{
8129 UShort mask;
8130 IRTemp value = newTemp(Ity_I16);
8131
8132 mask = i2;
8133 assign(value, get_gpr_hw0(r1));
8134 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8135 mkU16(mask)));
8136
8137 return "tmhh";
8138}
8139
8140static HChar *
8141s390_irgen_TMHL(UChar r1, UShort i2)
8142{
8143 UShort mask;
8144 IRTemp value = newTemp(Ity_I16);
8145
8146 mask = i2;
8147 assign(value, get_gpr_hw1(r1));
8148 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8149 mkU16(mask)));
8150
8151 return "tmhl";
8152}
8153
8154static HChar *
8155s390_irgen_TMLH(UChar r1, UShort i2)
8156{
8157 UShort mask;
8158 IRTemp value = newTemp(Ity_I16);
8159
8160 mask = i2;
8161 assign(value, get_gpr_hw2(r1));
8162 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8163 mkU16(mask)));
8164
8165 return "tmlh";
8166}
8167
8168static HChar *
8169s390_irgen_TMLL(UChar r1, UShort i2)
8170{
8171 UShort mask;
8172 IRTemp value = newTemp(Ity_I16);
8173
8174 mask = i2;
8175 assign(value, get_gpr_hw3(r1));
8176 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8177 mkU16(mask)));
8178
8179 return "tmll";
8180}
8181
8182static HChar *
8183s390_irgen_EFPC(UChar r1)
8184{
8185 put_gpr_w1(r1, get_fpc_w0());
8186
8187 return "efpc";
8188}
8189
8190static HChar *
8191s390_irgen_LER(UChar r1, UChar r2)
8192{
8193 put_fpr_w0(r1, get_fpr_w0(r2));
8194
8195 return "ler";
8196}
8197
8198static HChar *
8199s390_irgen_LDR(UChar r1, UChar r2)
8200{
8201 put_fpr_dw0(r1, get_fpr_dw0(r2));
8202
8203 return "ldr";
8204}
8205
8206static HChar *
8207s390_irgen_LXR(UChar r1, UChar r2)
8208{
8209 put_fpr_dw0(r1, get_fpr_dw0(r2));
8210 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8211
8212 return "lxr";
8213}
8214
8215static HChar *
8216s390_irgen_LE(UChar r1, IRTemp op2addr)
8217{
8218 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8219
8220 return "le";
8221}
8222
8223static HChar *
8224s390_irgen_LD(UChar r1, IRTemp op2addr)
8225{
8226 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8227
8228 return "ld";
8229}
8230
8231static HChar *
8232s390_irgen_LEY(UChar r1, IRTemp op2addr)
8233{
8234 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8235
8236 return "ley";
8237}
8238
8239static HChar *
8240s390_irgen_LDY(UChar r1, IRTemp op2addr)
8241{
8242 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8243
8244 return "ldy";
8245}
8246
8247static HChar *
8248s390_irgen_LFPC(IRTemp op2addr)
8249{
8250 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8251
8252 return "lfpc";
8253}
8254
8255static HChar *
8256s390_irgen_LZER(UChar r1)
8257{
8258 put_fpr_w0(r1, mkF32i(0x0));
8259
8260 return "lzer";
8261}
8262
8263static HChar *
8264s390_irgen_LZDR(UChar r1)
8265{
8266 put_fpr_dw0(r1, mkF64i(0x0));
8267
8268 return "lzdr";
8269}
8270
8271static HChar *
8272s390_irgen_LZXR(UChar r1)
8273{
8274 put_fpr_dw0(r1, mkF64i(0x0));
8275 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8276
8277 return "lzxr";
8278}
8279
8280static HChar *
8281s390_irgen_SRNM(IRTemp op2addr)
8282{
florianf0fa1be2012-09-18 20:24:38 +00008283 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008284
florianf0fa1be2012-09-18 20:24:38 +00008285 input_mask = 3;
8286 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008287
florianf0fa1be2012-09-18 20:24:38 +00008288 put_fpc_w0(binop(Iop_Or32,
8289 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8290 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8291 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008292 return "srnm";
8293}
8294
8295static HChar *
florianf0fa1be2012-09-18 20:24:38 +00008296s390_irgen_SRNMB(IRTemp op2addr)
8297{
8298 UInt input_mask, fpc_mask;
8299
8300 input_mask = 7;
8301 fpc_mask = 7;
8302
8303 put_fpc_w0(binop(Iop_Or32,
8304 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8305 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8306 mkU32(input_mask))));
8307 return "srnmb";
8308}
8309
florian81a4bfe2012-09-20 01:25:28 +00008310static void
florianf0fa1be2012-09-18 20:24:38 +00008311s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8312{
8313 if (b2 == 0) { /* This is the typical case */
8314 if (d2 > 3) {
8315 if (s390_host_has_fpext && d2 == 7) {
8316 /* ok */
8317 } else {
8318 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008319 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008320 }
8321 }
8322 }
8323
8324 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8325}
8326
8327
8328static HChar *
sewardj2019a972011-03-07 16:04:07 +00008329s390_irgen_SFPC(UChar r1)
8330{
8331 put_fpc_w0(get_gpr_w1(r1));
8332
8333 return "sfpc";
8334}
8335
8336static HChar *
8337s390_irgen_STE(UChar r1, IRTemp op2addr)
8338{
8339 store(mkexpr(op2addr), get_fpr_w0(r1));
8340
8341 return "ste";
8342}
8343
8344static HChar *
8345s390_irgen_STD(UChar r1, IRTemp op2addr)
8346{
8347 store(mkexpr(op2addr), get_fpr_dw0(r1));
8348
8349 return "std";
8350}
8351
8352static HChar *
8353s390_irgen_STEY(UChar r1, IRTemp op2addr)
8354{
8355 store(mkexpr(op2addr), get_fpr_w0(r1));
8356
8357 return "stey";
8358}
8359
8360static HChar *
8361s390_irgen_STDY(UChar r1, IRTemp op2addr)
8362{
8363 store(mkexpr(op2addr), get_fpr_dw0(r1));
8364
8365 return "stdy";
8366}
8367
8368static HChar *
8369s390_irgen_STFPC(IRTemp op2addr)
8370{
8371 store(mkexpr(op2addr), get_fpc_w0());
8372
8373 return "stfpc";
8374}
8375
8376static HChar *
8377s390_irgen_AEBR(UChar r1, UChar r2)
8378{
8379 IRTemp op1 = newTemp(Ity_F32);
8380 IRTemp op2 = newTemp(Ity_F32);
8381 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008382 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008383
8384 assign(op1, get_fpr_w0(r1));
8385 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008386 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008387 mkexpr(op2)));
8388 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8389 put_fpr_w0(r1, mkexpr(result));
8390
8391 return "aebr";
8392}
8393
8394static HChar *
8395s390_irgen_ADBR(UChar r1, UChar r2)
8396{
8397 IRTemp op1 = newTemp(Ity_F64);
8398 IRTemp op2 = newTemp(Ity_F64);
8399 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008400 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008401
8402 assign(op1, get_fpr_dw0(r1));
8403 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008404 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008405 mkexpr(op2)));
8406 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8407 put_fpr_dw0(r1, mkexpr(result));
8408
8409 return "adbr";
8410}
8411
8412static HChar *
8413s390_irgen_AEB(UChar r1, IRTemp op2addr)
8414{
8415 IRTemp op1 = newTemp(Ity_F32);
8416 IRTemp op2 = newTemp(Ity_F32);
8417 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008418 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008419
8420 assign(op1, get_fpr_w0(r1));
8421 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008422 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008423 mkexpr(op2)));
8424 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8425 put_fpr_w0(r1, mkexpr(result));
8426
8427 return "aeb";
8428}
8429
8430static HChar *
8431s390_irgen_ADB(UChar r1, IRTemp op2addr)
8432{
8433 IRTemp op1 = newTemp(Ity_F64);
8434 IRTemp op2 = newTemp(Ity_F64);
8435 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008436 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008437
8438 assign(op1, get_fpr_dw0(r1));
8439 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008440 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008441 mkexpr(op2)));
8442 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8443 put_fpr_dw0(r1, mkexpr(result));
8444
8445 return "adb";
8446}
8447
8448static HChar *
florian4b8efad2012-09-02 18:07:08 +00008449s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8450 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008451{
florian125e20d2012-10-07 15:42:37 +00008452 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008453 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008454 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008455 }
sewardj2019a972011-03-07 16:04:07 +00008456 IRTemp op2 = newTemp(Ity_I32);
8457
8458 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008459 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008460 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008461
8462 return "cefbr";
8463}
8464
8465static HChar *
florian4b8efad2012-09-02 18:07:08 +00008466s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8467 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008468{
8469 IRTemp op2 = newTemp(Ity_I32);
8470
8471 assign(op2, get_gpr_w1(r2));
8472 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8473
8474 return "cdfbr";
8475}
8476
8477static HChar *
florian4b8efad2012-09-02 18:07:08 +00008478s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8479 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008480{
florian125e20d2012-10-07 15:42:37 +00008481 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008482 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008483 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008484 }
sewardj2019a972011-03-07 16:04:07 +00008485 IRTemp op2 = newTemp(Ity_I64);
8486
8487 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008488 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008489 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008490
8491 return "cegbr";
8492}
8493
8494static HChar *
florian4b8efad2012-09-02 18:07:08 +00008495s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8496 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008497{
florian125e20d2012-10-07 15:42:37 +00008498 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008499 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008500 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008501 }
sewardj2019a972011-03-07 16:04:07 +00008502 IRTemp op2 = newTemp(Ity_I64);
8503
8504 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008505 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008506 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008507
8508 return "cdgbr";
8509}
8510
8511static HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008512s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8513 UChar r1, UChar r2)
8514{
floriane75dafa2012-09-01 17:54:09 +00008515 if (! s390_host_has_fpext) {
8516 emulation_failure(EmFail_S390X_fpext);
8517 } else {
8518 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008519
floriane75dafa2012-09-01 17:54:09 +00008520 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008521 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008522 mkexpr(op2)));
8523 }
florian1c8f7ff2012-09-01 00:12:11 +00008524 return "celfbr";
8525}
8526
8527static HChar *
floriand2129202012-09-01 20:01:39 +00008528s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8529 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008530{
floriane75dafa2012-09-01 17:54:09 +00008531 if (! s390_host_has_fpext) {
8532 emulation_failure(EmFail_S390X_fpext);
8533 } else {
8534 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008535
floriane75dafa2012-09-01 17:54:09 +00008536 assign(op2, get_gpr_w1(r2));
8537 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8538 }
florian1c8f7ff2012-09-01 00:12:11 +00008539 return "cdlfbr";
8540}
8541
8542static HChar *
8543s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8544 UChar r1, UChar r2)
8545{
floriane75dafa2012-09-01 17:54:09 +00008546 if (! s390_host_has_fpext) {
8547 emulation_failure(EmFail_S390X_fpext);
8548 } else {
8549 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008550
floriane75dafa2012-09-01 17:54:09 +00008551 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008552 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008553 mkexpr(op2)));
8554 }
florian1c8f7ff2012-09-01 00:12:11 +00008555 return "celgbr";
8556}
8557
8558static HChar *
8559s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8560 UChar r1, UChar r2)
8561{
floriane75dafa2012-09-01 17:54:09 +00008562 if (! s390_host_has_fpext) {
8563 emulation_failure(EmFail_S390X_fpext);
8564 } else {
8565 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008566
floriane75dafa2012-09-01 17:54:09 +00008567 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008568 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8569 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008570 mkexpr(op2)));
8571 }
florian1c8f7ff2012-09-01 00:12:11 +00008572 return "cdlgbr";
8573}
8574
8575static HChar *
8576s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8577 UChar r1, UChar r2)
8578{
floriane75dafa2012-09-01 17:54:09 +00008579 if (! s390_host_has_fpext) {
8580 emulation_failure(EmFail_S390X_fpext);
8581 } else {
8582 IRTemp op = newTemp(Ity_F32);
8583 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008584 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008585
floriane75dafa2012-09-01 17:54:09 +00008586 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008587 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008588 mkexpr(op)));
8589 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008590 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008591 }
florian1c8f7ff2012-09-01 00:12:11 +00008592 return "clfebr";
8593}
8594
8595static HChar *
8596s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8597 UChar r1, UChar r2)
8598{
floriane75dafa2012-09-01 17:54:09 +00008599 if (! s390_host_has_fpext) {
8600 emulation_failure(EmFail_S390X_fpext);
8601 } else {
8602 IRTemp op = newTemp(Ity_F64);
8603 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008604 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008605
floriane75dafa2012-09-01 17:54:09 +00008606 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008607 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008608 mkexpr(op)));
8609 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008610 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008611 }
florian1c8f7ff2012-09-01 00:12:11 +00008612 return "clfdbr";
8613}
8614
8615static HChar *
8616s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8617 UChar r1, UChar r2)
8618{
floriane75dafa2012-09-01 17:54:09 +00008619 if (! s390_host_has_fpext) {
8620 emulation_failure(EmFail_S390X_fpext);
8621 } else {
8622 IRTemp op = newTemp(Ity_F32);
8623 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008624 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008625
floriane75dafa2012-09-01 17:54:09 +00008626 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008627 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008628 mkexpr(op)));
8629 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008630 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008631 }
florian1c8f7ff2012-09-01 00:12:11 +00008632 return "clgebr";
8633}
8634
8635static HChar *
8636s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8637 UChar r1, UChar r2)
8638{
floriane75dafa2012-09-01 17:54:09 +00008639 if (! s390_host_has_fpext) {
8640 emulation_failure(EmFail_S390X_fpext);
8641 } else {
8642 IRTemp op = newTemp(Ity_F64);
8643 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008644 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008645
floriane75dafa2012-09-01 17:54:09 +00008646 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008647 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008648 mkexpr(op)));
8649 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008650 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008651 }
florian1c8f7ff2012-09-01 00:12:11 +00008652 return "clgdbr";
8653}
8654
8655static HChar *
florian4b8efad2012-09-02 18:07:08 +00008656s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8657 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008658{
8659 IRTemp op = newTemp(Ity_F32);
8660 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008661 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008662
8663 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008664 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008665 mkexpr(op)));
8666 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008667 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008668
8669 return "cfebr";
8670}
8671
8672static HChar *
florian4b8efad2012-09-02 18:07:08 +00008673s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8674 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008675{
8676 IRTemp op = newTemp(Ity_F64);
8677 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008678 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008679
8680 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008681 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008682 mkexpr(op)));
8683 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008684 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008685
8686 return "cfdbr";
8687}
8688
8689static HChar *
florian4b8efad2012-09-02 18:07:08 +00008690s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8691 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008692{
8693 IRTemp op = newTemp(Ity_F32);
8694 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008695 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008696
8697 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008698 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008699 mkexpr(op)));
8700 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008701 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008702
8703 return "cgebr";
8704}
8705
8706static HChar *
florian4b8efad2012-09-02 18:07:08 +00008707s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8708 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008709{
8710 IRTemp op = newTemp(Ity_F64);
8711 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008712 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008713
8714 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008715 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008716 mkexpr(op)));
8717 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008718 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008719
8720 return "cgdbr";
8721}
8722
8723static HChar *
8724s390_irgen_DEBR(UChar r1, UChar r2)
8725{
8726 IRTemp op1 = newTemp(Ity_F32);
8727 IRTemp op2 = newTemp(Ity_F32);
8728 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008729 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008730
8731 assign(op1, get_fpr_w0(r1));
8732 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008733 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008734 mkexpr(op2)));
8735 put_fpr_w0(r1, mkexpr(result));
8736
8737 return "debr";
8738}
8739
8740static HChar *
8741s390_irgen_DDBR(UChar r1, UChar r2)
8742{
8743 IRTemp op1 = newTemp(Ity_F64);
8744 IRTemp op2 = newTemp(Ity_F64);
8745 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008746 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008747
8748 assign(op1, get_fpr_dw0(r1));
8749 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008750 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008751 mkexpr(op2)));
8752 put_fpr_dw0(r1, mkexpr(result));
8753
8754 return "ddbr";
8755}
8756
8757static HChar *
8758s390_irgen_DEB(UChar r1, IRTemp op2addr)
8759{
8760 IRTemp op1 = newTemp(Ity_F32);
8761 IRTemp op2 = newTemp(Ity_F32);
8762 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008763 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008764
8765 assign(op1, get_fpr_w0(r1));
8766 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008767 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008768 mkexpr(op2)));
8769 put_fpr_w0(r1, mkexpr(result));
8770
8771 return "deb";
8772}
8773
8774static HChar *
8775s390_irgen_DDB(UChar r1, IRTemp op2addr)
8776{
8777 IRTemp op1 = newTemp(Ity_F64);
8778 IRTemp op2 = newTemp(Ity_F64);
8779 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008780 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008781
8782 assign(op1, get_fpr_dw0(r1));
8783 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008784 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008785 mkexpr(op2)));
8786 put_fpr_dw0(r1, mkexpr(result));
8787
8788 return "ddb";
8789}
8790
8791static HChar *
8792s390_irgen_LTEBR(UChar r1, UChar r2)
8793{
8794 IRTemp result = newTemp(Ity_F32);
8795
8796 assign(result, get_fpr_w0(r2));
8797 put_fpr_w0(r1, mkexpr(result));
8798 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8799
8800 return "ltebr";
8801}
8802
8803static HChar *
8804s390_irgen_LTDBR(UChar r1, UChar r2)
8805{
8806 IRTemp result = newTemp(Ity_F64);
8807
8808 assign(result, get_fpr_dw0(r2));
8809 put_fpr_dw0(r1, mkexpr(result));
8810 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8811
8812 return "ltdbr";
8813}
8814
8815static HChar *
8816s390_irgen_LCEBR(UChar r1, UChar r2)
8817{
8818 IRTemp result = newTemp(Ity_F32);
8819
8820 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8821 put_fpr_w0(r1, mkexpr(result));
8822 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8823
8824 return "lcebr";
8825}
8826
8827static HChar *
8828s390_irgen_LCDBR(UChar r1, UChar r2)
8829{
8830 IRTemp result = newTemp(Ity_F64);
8831
8832 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8833 put_fpr_dw0(r1, mkexpr(result));
8834 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8835
8836 return "lcdbr";
8837}
8838
8839static HChar *
8840s390_irgen_LDEBR(UChar r1, UChar r2)
8841{
8842 IRTemp op = newTemp(Ity_F32);
8843
8844 assign(op, get_fpr_w0(r2));
8845 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8846
8847 return "ldebr";
8848}
8849
8850static HChar *
8851s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8852{
8853 IRTemp op = newTemp(Ity_F32);
8854
8855 assign(op, load(Ity_F32, mkexpr(op2addr)));
8856 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8857
8858 return "ldeb";
8859}
8860
8861static HChar *
florian4b8efad2012-09-02 18:07:08 +00008862s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8863 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008864{
florian125e20d2012-10-07 15:42:37 +00008865 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00008866 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008867 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00008868 }
sewardj2019a972011-03-07 16:04:07 +00008869 IRTemp op = newTemp(Ity_F64);
8870
8871 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008872 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008873 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008874
8875 return "ledbr";
8876}
8877
8878static HChar *
florian12390202012-11-10 22:34:14 +00008879s390_irgen_LTDTR(UChar r1, UChar r2)
8880{
8881 IRTemp result = newTemp(Ity_D64);
8882
8883 assign(result, get_dpr_dw0(r2));
8884 put_dpr_dw0(r1, mkexpr(result));
8885 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
8886
8887 return "ltdtr";
8888}
8889
8890static HChar *
sewardj2019a972011-03-07 16:04:07 +00008891s390_irgen_MEEBR(UChar r1, UChar r2)
8892{
8893 IRTemp op1 = newTemp(Ity_F32);
8894 IRTemp op2 = newTemp(Ity_F32);
8895 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008896 IRRoundingMode rounding_mode =
8897 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008898
8899 assign(op1, get_fpr_w0(r1));
8900 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008901 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008902 mkexpr(op2)));
8903 put_fpr_w0(r1, mkexpr(result));
8904
8905 return "meebr";
8906}
8907
8908static HChar *
8909s390_irgen_MDBR(UChar r1, UChar r2)
8910{
8911 IRTemp op1 = newTemp(Ity_F64);
8912 IRTemp op2 = newTemp(Ity_F64);
8913 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008914 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008915
8916 assign(op1, get_fpr_dw0(r1));
8917 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008918 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008919 mkexpr(op2)));
8920 put_fpr_dw0(r1, mkexpr(result));
8921
8922 return "mdbr";
8923}
8924
8925static HChar *
8926s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8927{
8928 IRTemp op1 = newTemp(Ity_F32);
8929 IRTemp op2 = newTemp(Ity_F32);
8930 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008931 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008932
8933 assign(op1, get_fpr_w0(r1));
8934 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008935 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008936 mkexpr(op2)));
8937 put_fpr_w0(r1, mkexpr(result));
8938
8939 return "meeb";
8940}
8941
8942static HChar *
8943s390_irgen_MDB(UChar r1, IRTemp op2addr)
8944{
8945 IRTemp op1 = newTemp(Ity_F64);
8946 IRTemp op2 = newTemp(Ity_F64);
8947 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008948 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008949
8950 assign(op1, get_fpr_dw0(r1));
8951 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008952 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008953 mkexpr(op2)));
8954 put_fpr_dw0(r1, mkexpr(result));
8955
8956 return "mdb";
8957}
8958
8959static HChar *
8960s390_irgen_SEBR(UChar r1, UChar r2)
8961{
8962 IRTemp op1 = newTemp(Ity_F32);
8963 IRTemp op2 = newTemp(Ity_F32);
8964 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008965 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008966
8967 assign(op1, get_fpr_w0(r1));
8968 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008969 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008970 mkexpr(op2)));
8971 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8972 put_fpr_w0(r1, mkexpr(result));
8973
8974 return "sebr";
8975}
8976
8977static HChar *
8978s390_irgen_SDBR(UChar r1, UChar r2)
8979{
8980 IRTemp op1 = newTemp(Ity_F64);
8981 IRTemp op2 = newTemp(Ity_F64);
8982 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008983 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008984
8985 assign(op1, get_fpr_dw0(r1));
8986 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008987 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008988 mkexpr(op2)));
8989 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8990 put_fpr_dw0(r1, mkexpr(result));
8991
8992 return "sdbr";
8993}
8994
8995static HChar *
8996s390_irgen_SEB(UChar r1, IRTemp op2addr)
8997{
8998 IRTemp op1 = newTemp(Ity_F32);
8999 IRTemp op2 = newTemp(Ity_F32);
9000 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009001 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009002
9003 assign(op1, get_fpr_w0(r1));
9004 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009005 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009006 mkexpr(op2)));
9007 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9008 put_fpr_w0(r1, mkexpr(result));
9009
9010 return "seb";
9011}
9012
9013static HChar *
9014s390_irgen_SDB(UChar r1, IRTemp op2addr)
9015{
9016 IRTemp op1 = newTemp(Ity_F64);
9017 IRTemp op2 = newTemp(Ity_F64);
9018 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009019 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009020
9021 assign(op1, get_fpr_dw0(r1));
9022 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009023 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009024 mkexpr(op2)));
9025 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9026 put_fpr_dw0(r1, mkexpr(result));
9027
9028 return "sdb";
9029}
9030
florian12390202012-11-10 22:34:14 +00009031static HChar *
9032s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9033{
9034 IRTemp op1 = newTemp(Ity_D64);
9035 IRTemp op2 = newTemp(Ity_D64);
9036 IRTemp result = newTemp(Ity_D64);
9037 IRTemp rounding_mode;
9038
9039 vassert(s390_host_has_dfp);
9040 vassert(m4 == 0 || s390_host_has_fpext);
9041 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9042 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9043 rounding_mode = encode_dfp_rounding_mode(m4);
9044 assign(op1, get_dpr_dw0(r2));
9045 assign(op2, get_dpr_dw0(r3));
9046 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9047 mkexpr(op2)));
9048 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9049 put_dpr_dw0(r1, mkexpr(result));
9050
9051 return (m4 == 0) ? "adtr" : "adtra";
9052}
9053
9054static HChar *
9055s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9056{
9057 IRTemp op1 = newTemp(Ity_D64);
9058 IRTemp op2 = newTemp(Ity_D64);
9059 IRTemp result = newTemp(Ity_D64);
9060 IRTemp rounding_mode;
9061
9062 vassert(s390_host_has_dfp);
9063 vassert(m4 == 0 || s390_host_has_fpext);
9064 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9065 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9066 rounding_mode = encode_dfp_rounding_mode(m4);
9067 assign(op1, get_dpr_dw0(r2));
9068 assign(op2, get_dpr_dw0(r3));
9069 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9070 mkexpr(op2)));
9071 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9072 put_dpr_dw0(r1, mkexpr(result));
9073
9074 return (m4 == 0) ? "ddtr" : "ddtra";
9075}
9076
9077static HChar *
9078s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9079{
9080 IRTemp op1 = newTemp(Ity_D64);
9081 IRTemp op2 = newTemp(Ity_D64);
9082 IRTemp result = newTemp(Ity_D64);
9083 IRTemp rounding_mode;
9084
9085 vassert(s390_host_has_dfp);
9086 vassert(m4 == 0 || s390_host_has_fpext);
9087 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9088 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9089 rounding_mode = encode_dfp_rounding_mode(m4);
9090 assign(op1, get_dpr_dw0(r2));
9091 assign(op2, get_dpr_dw0(r3));
9092 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9093 mkexpr(op2)));
9094 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9095 put_dpr_dw0(r1, mkexpr(result));
9096
9097 return (m4 == 0) ? "mdtr" : "mdtra";
9098}
9099
9100static HChar *
9101s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9102{
9103 IRTemp op1 = newTemp(Ity_D64);
9104 IRTemp op2 = newTemp(Ity_D64);
9105 IRTemp result = newTemp(Ity_D64);
9106 IRTemp rounding_mode;
9107
9108 vassert(s390_host_has_dfp);
9109 vassert(m4 == 0 || s390_host_has_fpext);
9110 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9111 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9112 rounding_mode = encode_dfp_rounding_mode(m4);
9113 assign(op1, get_dpr_dw0(r2));
9114 assign(op2, get_dpr_dw0(r3));
9115 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9116 mkexpr(op2)));
9117 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9118 put_dpr_dw0(r1, mkexpr(result));
9119
9120 return (m4 == 0) ? "sdtr" : "sdtra";
9121}
9122
sewardj2019a972011-03-07 16:04:07 +00009123
9124static HChar *
9125s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9126{
florian79e839e2012-05-05 02:20:30 +00009127 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009128
florian79e839e2012-05-05 02:20:30 +00009129 assign(len, mkU64(length));
9130 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009131
9132 return "clc";
9133}
9134
9135static HChar *
florianb0c9a132011-09-08 15:37:39 +00009136s390_irgen_CLCL(UChar r1, UChar r2)
9137{
9138 IRTemp addr1 = newTemp(Ity_I64);
9139 IRTemp addr2 = newTemp(Ity_I64);
9140 IRTemp addr1_load = newTemp(Ity_I64);
9141 IRTemp addr2_load = newTemp(Ity_I64);
9142 IRTemp len1 = newTemp(Ity_I32);
9143 IRTemp len2 = newTemp(Ity_I32);
9144 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9145 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9146 IRTemp single1 = newTemp(Ity_I8);
9147 IRTemp single2 = newTemp(Ity_I8);
9148 IRTemp pad = newTemp(Ity_I8);
9149
9150 assign(addr1, get_gpr_dw0(r1));
9151 assign(r1p1, get_gpr_w1(r1 + 1));
9152 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9153 assign(addr2, get_gpr_dw0(r2));
9154 assign(r2p1, get_gpr_w1(r2 + 1));
9155 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9156 assign(pad, get_gpr_b4(r2 + 1));
9157
9158 /* len1 == 0 and len2 == 0? Exit */
9159 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009160 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9161 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009162
9163 /* Because mkite evaluates both the then-clause and the else-clause
9164 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9165 may be NULL and loading from there would segfault. So we provide a
9166 valid dummy address in that case. Loading from there does no harm and
9167 the value will be discarded at runtime. */
9168 assign(addr1_load,
9169 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9170 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9171 assign(single1,
9172 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9173 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9174
9175 assign(addr2_load,
9176 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9177 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9178 assign(single2,
9179 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9180 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9181
9182 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9183 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009184 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009185
9186 /* Update len1 and addr1, unless len1 == 0. */
9187 put_gpr_dw0(r1,
9188 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9189 mkexpr(addr1),
9190 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9191
9192 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9193 put_gpr_w1(r1 + 1,
9194 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9195 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9196 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9197
9198 /* Update len2 and addr2, unless len2 == 0. */
9199 put_gpr_dw0(r2,
9200 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9201 mkexpr(addr2),
9202 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9203
9204 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9205 put_gpr_w1(r2 + 1,
9206 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9207 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9208 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9209
florian6820ba52012-07-26 02:01:50 +00009210 iterate();
florianb0c9a132011-09-08 15:37:39 +00009211
9212 return "clcl";
9213}
9214
9215static HChar *
sewardj2019a972011-03-07 16:04:07 +00009216s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9217{
9218 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9219
9220 addr1 = newTemp(Ity_I64);
9221 addr3 = newTemp(Ity_I64);
9222 addr1_load = newTemp(Ity_I64);
9223 addr3_load = newTemp(Ity_I64);
9224 len1 = newTemp(Ity_I64);
9225 len3 = newTemp(Ity_I64);
9226 single1 = newTemp(Ity_I8);
9227 single3 = newTemp(Ity_I8);
9228
9229 assign(addr1, get_gpr_dw0(r1));
9230 assign(len1, get_gpr_dw0(r1 + 1));
9231 assign(addr3, get_gpr_dw0(r3));
9232 assign(len3, get_gpr_dw0(r3 + 1));
9233
9234 /* len1 == 0 and len3 == 0? Exit */
9235 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009236 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9237 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009238
9239 /* A mux requires both ways to be possible. This is a way to prevent clcle
9240 from reading from addr1 if it should read from the pad. Since the pad
9241 has no address, just read from the instruction, we discard that anyway */
9242 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009243 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9244 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009245
9246 /* same for addr3 */
9247 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009248 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9249 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009250
9251 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009252 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9253 unop(Iop_64to8, mkexpr(pad2)),
9254 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009255
9256 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009257 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9258 unop(Iop_64to8, mkexpr(pad2)),
9259 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009260
9261 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9262 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009263 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009264
9265 /* If a length in 0 we must not change this length and the address */
9266 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009267 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9268 mkexpr(addr1),
9269 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009270
9271 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009272 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9273 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009274
9275 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009276 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9277 mkexpr(addr3),
9278 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009279
9280 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009281 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9282 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009283
florian6820ba52012-07-26 02:01:50 +00009284 iterate();
sewardj2019a972011-03-07 16:04:07 +00009285
9286 return "clcle";
9287}
floriana64c2432011-07-16 02:11:50 +00009288
florianb0bf6602012-05-05 00:01:16 +00009289
sewardj2019a972011-03-07 16:04:07 +00009290static void
9291s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9292{
florianb0bf6602012-05-05 00:01:16 +00009293 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9294}
sewardj2019a972011-03-07 16:04:07 +00009295
sewardj2019a972011-03-07 16:04:07 +00009296
florianb0bf6602012-05-05 00:01:16 +00009297static void
9298s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9299{
9300 s390_irgen_xonc(Iop_And8, length, start1, start2);
9301}
sewardj2019a972011-03-07 16:04:07 +00009302
sewardj2019a972011-03-07 16:04:07 +00009303
florianb0bf6602012-05-05 00:01:16 +00009304static void
9305s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9306{
9307 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009308}
9309
9310
9311static void
9312s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9313{
9314 IRTemp current1 = newTemp(Ity_I8);
9315 IRTemp current2 = newTemp(Ity_I8);
9316 IRTemp counter = newTemp(Ity_I64);
9317
9318 assign(counter, get_counter_dw0());
9319 put_counter_dw0(mkU64(0));
9320
9321 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9322 mkexpr(counter))));
9323 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9324 mkexpr(counter))));
9325 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9326 False);
9327
9328 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009329 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009330
9331 /* Check for end of field */
9332 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009333 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009334 put_counter_dw0(mkU64(0));
9335}
9336
9337static void
9338s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9339{
9340 IRTemp counter = newTemp(Ity_I64);
9341
9342 assign(counter, get_counter_dw0());
9343
9344 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9345 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9346
9347 /* Check for end of field */
9348 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009349 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009350 put_counter_dw0(mkU64(0));
9351}
9352
florianf87d4fb2012-05-05 02:55:24 +00009353static void
9354s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9355{
9356 IRTemp op = newTemp(Ity_I8);
9357 IRTemp op1 = newTemp(Ity_I8);
9358 IRTemp result = newTemp(Ity_I64);
9359 IRTemp counter = newTemp(Ity_I64);
9360
9361 assign(counter, get_counter_dw0());
9362
9363 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9364
9365 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9366
9367 assign(op1, load(Ity_I8, mkexpr(result)));
9368 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9369
9370 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009371 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009372 put_counter_dw0(mkU64(0));
9373}
sewardj2019a972011-03-07 16:04:07 +00009374
9375
9376static void
9377s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009378 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9379 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009380{
9381 struct SS {
9382 unsigned int op : 8;
9383 unsigned int l : 8;
9384 unsigned int b1 : 4;
9385 unsigned int d1 : 12;
9386 unsigned int b2 : 4;
9387 unsigned int d2 : 12;
9388 };
9389 union {
9390 struct SS dec;
9391 unsigned long bytes;
9392 } ss;
9393 IRTemp cond;
9394 IRDirty *d;
9395 IRTemp torun;
9396
9397 IRTemp start1 = newTemp(Ity_I64);
9398 IRTemp start2 = newTemp(Ity_I64);
9399 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9400 cond = newTemp(Ity_I1);
9401 torun = newTemp(Ity_I64);
9402
9403 assign(torun, load(Ity_I64, mkexpr(addr2)));
9404 /* Start with a check that the saved code is still correct */
9405 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9406 /* If not, save the new value */
9407 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9408 mkIRExprVec_1(mkexpr(torun)));
9409 d->guard = mkexpr(cond);
9410 stmt(IRStmt_Dirty(d));
9411
9412 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009413 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9414 mkU64(guest_IA_curr_instr)));
9415 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009416 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009417
9418 ss.bytes = last_execute_target;
9419 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9420 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9421 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9422 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9423 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9424 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9425 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009426
sewardj2019a972011-03-07 16:04:07 +00009427 last_execute_target = 0;
9428}
9429
9430static HChar *
9431s390_irgen_EX(UChar r1, IRTemp addr2)
9432{
9433 switch(last_execute_target & 0xff00000000000000ULL) {
9434 case 0:
9435 {
9436 /* no code information yet */
9437 IRDirty *d;
9438
9439 /* so safe the code... */
9440 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9441 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9442 stmt(IRStmt_Dirty(d));
9443 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009444 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9445 mkU64(guest_IA_curr_instr)));
9446 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009447 restart_if(IRExpr_Const(IRConst_U1(True)));
9448
sewardj2019a972011-03-07 16:04:07 +00009449 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009450 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009451 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009452 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009453 break;
9454 }
9455
9456 case 0xd200000000000000ULL:
9457 /* special case MVC */
9458 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9459 return "mvc via ex";
9460
9461 case 0xd500000000000000ULL:
9462 /* special case CLC */
9463 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9464 return "clc via ex";
9465
9466 case 0xd700000000000000ULL:
9467 /* special case XC */
9468 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9469 return "xc via ex";
9470
florianb0bf6602012-05-05 00:01:16 +00009471 case 0xd600000000000000ULL:
9472 /* special case OC */
9473 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9474 return "oc via ex";
9475
9476 case 0xd400000000000000ULL:
9477 /* special case NC */
9478 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9479 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009480
florianf87d4fb2012-05-05 02:55:24 +00009481 case 0xdc00000000000000ULL:
9482 /* special case TR */
9483 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9484 return "tr via ex";
9485
sewardj2019a972011-03-07 16:04:07 +00009486 default:
9487 {
9488 /* everything else will get a self checking prefix that also checks the
9489 register content */
9490 IRDirty *d;
9491 UChar *bytes;
9492 IRTemp cond;
9493 IRTemp orperand;
9494 IRTemp torun;
9495
9496 cond = newTemp(Ity_I1);
9497 orperand = newTemp(Ity_I64);
9498 torun = newTemp(Ity_I64);
9499
9500 if (r1 == 0)
9501 assign(orperand, mkU64(0));
9502 else
9503 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9504 /* This code is going to be translated */
9505 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9506 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9507
9508 /* Start with a check that saved code is still correct */
9509 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9510 mkU64(last_execute_target)));
9511 /* If not, save the new value */
9512 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9513 mkIRExprVec_1(mkexpr(torun)));
9514 d->guard = mkexpr(cond);
9515 stmt(IRStmt_Dirty(d));
9516
9517 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009518 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9519 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009520 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009521
9522 /* Now comes the actual translation */
9523 bytes = (UChar *) &last_execute_target;
9524 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9525 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009526 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009527 vex_printf(" which was executed by\n");
9528 /* dont make useless translations in the next execute */
9529 last_execute_target = 0;
9530 }
9531 }
9532 return "ex";
9533}
9534
9535static HChar *
9536s390_irgen_EXRL(UChar r1, UInt offset)
9537{
9538 IRTemp addr = newTemp(Ity_I64);
9539 /* we might save one round trip because we know the target */
9540 if (!last_execute_target)
9541 last_execute_target = *(ULong *)(HWord)
9542 (guest_IA_curr_instr + offset * 2UL);
9543 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9544 s390_irgen_EX(r1, addr);
9545 return "exrl";
9546}
9547
9548static HChar *
9549s390_irgen_IPM(UChar r1)
9550{
9551 // As long as we dont support SPM, lets just assume 0 as program mask
9552 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9553 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9554
9555 return "ipm";
9556}
9557
9558
9559static HChar *
9560s390_irgen_SRST(UChar r1, UChar r2)
9561{
9562 IRTemp address = newTemp(Ity_I64);
9563 IRTemp next = newTemp(Ity_I64);
9564 IRTemp delim = newTemp(Ity_I8);
9565 IRTemp counter = newTemp(Ity_I64);
9566 IRTemp byte = newTemp(Ity_I8);
9567
9568 assign(address, get_gpr_dw0(r2));
9569 assign(next, get_gpr_dw0(r1));
9570
9571 assign(counter, get_counter_dw0());
9572 put_counter_dw0(mkU64(0));
9573
9574 // start = next? CC=2 and out r1 and r2 unchanged
9575 s390_cc_set(2);
9576 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009577 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009578
9579 assign(byte, load(Ity_I8, mkexpr(address)));
9580 assign(delim, get_gpr_b7(0));
9581
9582 // byte = delim? CC=1, R1=address
9583 s390_cc_set(1);
9584 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009585 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009586
9587 // else: all equal, no end yet, loop
9588 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9589 put_gpr_dw0(r1, mkexpr(next));
9590 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009591
florian6820ba52012-07-26 02:01:50 +00009592 iterate();
sewardj2019a972011-03-07 16:04:07 +00009593
9594 return "srst";
9595}
9596
9597static HChar *
9598s390_irgen_CLST(UChar r1, UChar r2)
9599{
9600 IRTemp address1 = newTemp(Ity_I64);
9601 IRTemp address2 = newTemp(Ity_I64);
9602 IRTemp end = newTemp(Ity_I8);
9603 IRTemp counter = newTemp(Ity_I64);
9604 IRTemp byte1 = newTemp(Ity_I8);
9605 IRTemp byte2 = newTemp(Ity_I8);
9606
9607 assign(address1, get_gpr_dw0(r1));
9608 assign(address2, get_gpr_dw0(r2));
9609 assign(end, get_gpr_b7(0));
9610 assign(counter, get_counter_dw0());
9611 put_counter_dw0(mkU64(0));
9612 assign(byte1, load(Ity_I8, mkexpr(address1)));
9613 assign(byte2, load(Ity_I8, mkexpr(address2)));
9614
9615 // end in both? all equal, reset r1 and r2 to start values
9616 s390_cc_set(0);
9617 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9618 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009619 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9620 binop(Iop_Or8,
9621 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9622 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009623
9624 put_gpr_dw0(r1, mkexpr(address1));
9625 put_gpr_dw0(r2, mkexpr(address2));
9626
9627 // End found in string1
9628 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009629 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009630
9631 // End found in string2
9632 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009633 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009634
9635 // string1 < string2
9636 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009637 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9638 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009639
9640 // string2 < string1
9641 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009642 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9643 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009644
9645 // else: all equal, no end yet, loop
9646 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9647 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9648 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009649
florian6820ba52012-07-26 02:01:50 +00009650 iterate();
sewardj2019a972011-03-07 16:04:07 +00009651
9652 return "clst";
9653}
9654
9655static void
9656s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9657{
9658 UChar reg;
9659 IRTemp addr = newTemp(Ity_I64);
9660
9661 assign(addr, mkexpr(op2addr));
9662 reg = r1;
9663 do {
9664 IRTemp old = addr;
9665
9666 reg %= 16;
9667 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9668 addr = newTemp(Ity_I64);
9669 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9670 reg++;
9671 } while (reg != (r3 + 1));
9672}
9673
9674static HChar *
9675s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9676{
9677 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9678
9679 return "lm";
9680}
9681
9682static HChar *
9683s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9684{
9685 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9686
9687 return "lmy";
9688}
9689
9690static HChar *
9691s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9692{
9693 UChar reg;
9694 IRTemp addr = newTemp(Ity_I64);
9695
9696 assign(addr, mkexpr(op2addr));
9697 reg = r1;
9698 do {
9699 IRTemp old = addr;
9700
9701 reg %= 16;
9702 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9703 addr = newTemp(Ity_I64);
9704 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9705 reg++;
9706 } while (reg != (r3 + 1));
9707
9708 return "lmh";
9709}
9710
9711static HChar *
9712s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9713{
9714 UChar reg;
9715 IRTemp addr = newTemp(Ity_I64);
9716
9717 assign(addr, mkexpr(op2addr));
9718 reg = r1;
9719 do {
9720 IRTemp old = addr;
9721
9722 reg %= 16;
9723 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9724 addr = newTemp(Ity_I64);
9725 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9726 reg++;
9727 } while (reg != (r3 + 1));
9728
9729 return "lmg";
9730}
9731
9732static void
9733s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9734{
9735 UChar reg;
9736 IRTemp addr = newTemp(Ity_I64);
9737
9738 assign(addr, mkexpr(op2addr));
9739 reg = r1;
9740 do {
9741 IRTemp old = addr;
9742
9743 reg %= 16;
9744 store(mkexpr(addr), get_gpr_w1(reg));
9745 addr = newTemp(Ity_I64);
9746 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9747 reg++;
9748 } while( reg != (r3 + 1));
9749}
9750
9751static HChar *
9752s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9753{
9754 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9755
9756 return "stm";
9757}
9758
9759static HChar *
9760s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9761{
9762 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9763
9764 return "stmy";
9765}
9766
9767static HChar *
9768s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9769{
9770 UChar reg;
9771 IRTemp addr = newTemp(Ity_I64);
9772
9773 assign(addr, mkexpr(op2addr));
9774 reg = r1;
9775 do {
9776 IRTemp old = addr;
9777
9778 reg %= 16;
9779 store(mkexpr(addr), get_gpr_w0(reg));
9780 addr = newTemp(Ity_I64);
9781 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9782 reg++;
9783 } while( reg != (r3 + 1));
9784
9785 return "stmh";
9786}
9787
9788static HChar *
9789s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9790{
9791 UChar reg;
9792 IRTemp addr = newTemp(Ity_I64);
9793
9794 assign(addr, mkexpr(op2addr));
9795 reg = r1;
9796 do {
9797 IRTemp old = addr;
9798
9799 reg %= 16;
9800 store(mkexpr(addr), get_gpr_dw0(reg));
9801 addr = newTemp(Ity_I64);
9802 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9803 reg++;
9804 } while( reg != (r3 + 1));
9805
9806 return "stmg";
9807}
9808
9809static void
florianb0bf6602012-05-05 00:01:16 +00009810s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009811{
9812 IRTemp old1 = newTemp(Ity_I8);
9813 IRTemp old2 = newTemp(Ity_I8);
9814 IRTemp new1 = newTemp(Ity_I8);
9815 IRTemp counter = newTemp(Ity_I32);
9816 IRTemp addr1 = newTemp(Ity_I64);
9817
9818 assign(counter, get_counter_w0());
9819
9820 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9821 unop(Iop_32Uto64, mkexpr(counter))));
9822
9823 assign(old1, load(Ity_I8, mkexpr(addr1)));
9824 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9825 unop(Iop_32Uto64,mkexpr(counter)))));
9826 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9827
9828 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009829 if (op == Iop_Xor8) {
9830 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009831 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9832 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009833 } else
9834 store(mkexpr(addr1), mkexpr(new1));
9835 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9836 get_counter_w1()));
9837
9838 /* Check for end of field */
9839 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009840 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009841 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9842 False);
9843 put_counter_dw0(mkU64(0));
9844}
9845
9846static HChar *
9847s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9848{
florianb0bf6602012-05-05 00:01:16 +00009849 IRTemp len = newTemp(Ity_I32);
9850
9851 assign(len, mkU32(length));
9852 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009853
9854 return "xc";
9855}
9856
sewardjb63967e2011-03-24 08:50:04 +00009857static void
9858s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9859{
9860 IRTemp counter = newTemp(Ity_I32);
9861 IRTemp start = newTemp(Ity_I64);
9862 IRTemp addr = newTemp(Ity_I64);
9863
9864 assign(start,
9865 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9866
9867 if (length < 8) {
9868 UInt i;
9869
9870 for (i = 0; i <= length; ++i) {
9871 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9872 }
9873 } else {
9874 assign(counter, get_counter_w0());
9875
9876 assign(addr, binop(Iop_Add64, mkexpr(start),
9877 unop(Iop_32Uto64, mkexpr(counter))));
9878
9879 store(mkexpr(addr), mkU8(0));
9880
9881 /* Check for end of field */
9882 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009883 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009884
9885 /* Reset counter */
9886 put_counter_dw0(mkU64(0));
9887 }
9888
9889 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9890
sewardj7ee97522011-05-09 21:45:04 +00009891 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009892 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9893}
9894
sewardj2019a972011-03-07 16:04:07 +00009895static HChar *
9896s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9897{
florianb0bf6602012-05-05 00:01:16 +00009898 IRTemp len = newTemp(Ity_I32);
9899
9900 assign(len, mkU32(length));
9901 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009902
9903 return "nc";
9904}
9905
9906static HChar *
9907s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9908{
florianb0bf6602012-05-05 00:01:16 +00009909 IRTemp len = newTemp(Ity_I32);
9910
9911 assign(len, mkU32(length));
9912 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009913
9914 return "oc";
9915}
9916
9917
9918static HChar *
9919s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9920{
florian79e839e2012-05-05 02:20:30 +00009921 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009922
florian79e839e2012-05-05 02:20:30 +00009923 assign(len, mkU64(length));
9924 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009925
9926 return "mvc";
9927}
9928
9929static HChar *
florianb0c9a132011-09-08 15:37:39 +00009930s390_irgen_MVCL(UChar r1, UChar r2)
9931{
9932 IRTemp addr1 = newTemp(Ity_I64);
9933 IRTemp addr2 = newTemp(Ity_I64);
9934 IRTemp addr2_load = newTemp(Ity_I64);
9935 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9936 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9937 IRTemp len1 = newTemp(Ity_I32);
9938 IRTemp len2 = newTemp(Ity_I32);
9939 IRTemp pad = newTemp(Ity_I8);
9940 IRTemp single = newTemp(Ity_I8);
9941
9942 assign(addr1, get_gpr_dw0(r1));
9943 assign(r1p1, get_gpr_w1(r1 + 1));
9944 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9945 assign(addr2, get_gpr_dw0(r2));
9946 assign(r2p1, get_gpr_w1(r2 + 1));
9947 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9948 assign(pad, get_gpr_b4(r2 + 1));
9949
9950 /* len1 == 0 ? */
9951 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009952 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009953
9954 /* Check for destructive overlap:
9955 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9956 s390_cc_set(3);
9957 IRTemp cond1 = newTemp(Ity_I32);
9958 assign(cond1, unop(Iop_1Uto32,
9959 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9960 IRTemp cond2 = newTemp(Ity_I32);
9961 assign(cond2, unop(Iop_1Uto32,
9962 binop(Iop_CmpLT64U, mkexpr(addr1),
9963 binop(Iop_Add64, mkexpr(addr2),
9964 unop(Iop_32Uto64, mkexpr(len1))))));
9965 IRTemp cond3 = newTemp(Ity_I32);
9966 assign(cond3, unop(Iop_1Uto32,
9967 binop(Iop_CmpLT64U,
9968 mkexpr(addr1),
9969 binop(Iop_Add64, mkexpr(addr2),
9970 unop(Iop_32Uto64, mkexpr(len2))))));
9971
florian6820ba52012-07-26 02:01:50 +00009972 next_insn_if(binop(Iop_CmpEQ32,
9973 binop(Iop_And32,
9974 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9975 mkexpr(cond3)),
9976 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009977
9978 /* See s390_irgen_CLCL for explanation why we cannot load directly
9979 and need two steps. */
9980 assign(addr2_load,
9981 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9982 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9983 assign(single,
9984 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9985 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9986
9987 store(mkexpr(addr1), mkexpr(single));
9988
9989 /* Update addr1 and len1 */
9990 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9991 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9992
9993 /* Update addr2 and len2 */
9994 put_gpr_dw0(r2,
9995 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9996 mkexpr(addr2),
9997 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9998
9999 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10000 put_gpr_w1(r2 + 1,
10001 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10002 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10003 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10004
10005 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010006 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010007
10008 return "mvcl";
10009}
10010
10011
10012static HChar *
sewardj2019a972011-03-07 16:04:07 +000010013s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10014{
10015 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10016
10017 addr1 = newTemp(Ity_I64);
10018 addr3 = newTemp(Ity_I64);
10019 addr3_load = newTemp(Ity_I64);
10020 len1 = newTemp(Ity_I64);
10021 len3 = newTemp(Ity_I64);
10022 single = newTemp(Ity_I8);
10023
10024 assign(addr1, get_gpr_dw0(r1));
10025 assign(len1, get_gpr_dw0(r1 + 1));
10026 assign(addr3, get_gpr_dw0(r3));
10027 assign(len3, get_gpr_dw0(r3 + 1));
10028
10029 // len1 == 0 ?
10030 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010031 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010032
10033 /* This is a hack to prevent mvcle from reading from addr3 if it
10034 should read from the pad. Since the pad has no address, just
10035 read from the instruction, we discard that anyway */
10036 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010037 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10038 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010039
10040 assign(single,
florian6ad49522011-09-09 02:38:55 +000010041 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10042 unop(Iop_64to8, mkexpr(pad2)),
10043 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010044 store(mkexpr(addr1), mkexpr(single));
10045
10046 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10047
10048 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10049
10050 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010051 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10052 mkexpr(addr3),
10053 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010054
10055 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010056 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10057 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010058
sewardj2019a972011-03-07 16:04:07 +000010059 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010060 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010061
10062 return "mvcle";
10063}
10064
10065static HChar *
10066s390_irgen_MVST(UChar r1, UChar r2)
10067{
10068 IRTemp addr1 = newTemp(Ity_I64);
10069 IRTemp addr2 = newTemp(Ity_I64);
10070 IRTemp end = newTemp(Ity_I8);
10071 IRTemp byte = newTemp(Ity_I8);
10072 IRTemp counter = newTemp(Ity_I64);
10073
10074 assign(addr1, get_gpr_dw0(r1));
10075 assign(addr2, get_gpr_dw0(r2));
10076 assign(counter, get_counter_dw0());
10077 assign(end, get_gpr_b7(0));
10078 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10079 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10080
10081 // We use unlimited as cpu-determined number
10082 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010083 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010084
10085 // and always set cc=1 at the end + update r1
10086 s390_cc_set(1);
10087 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10088 put_counter_dw0(mkU64(0));
10089
10090 return "mvst";
10091}
10092
10093static void
10094s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10095{
10096 IRTemp op1 = newTemp(Ity_I64);
10097 IRTemp result = newTemp(Ity_I64);
10098
10099 assign(op1, binop(Iop_32HLto64,
10100 get_gpr_w1(r1), // high 32 bits
10101 get_gpr_w1(r1 + 1))); // low 32 bits
10102 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10103 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10104 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10105}
10106
10107static void
10108s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10109{
10110 IRTemp op1 = newTemp(Ity_I128);
10111 IRTemp result = newTemp(Ity_I128);
10112
10113 assign(op1, binop(Iop_64HLto128,
10114 get_gpr_dw0(r1), // high 64 bits
10115 get_gpr_dw0(r1 + 1))); // low 64 bits
10116 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10117 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10118 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10119}
10120
10121static void
10122s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10123{
10124 IRTemp op1 = newTemp(Ity_I64);
10125 IRTemp result = newTemp(Ity_I128);
10126
10127 assign(op1, get_gpr_dw0(r1 + 1));
10128 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10129 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10130 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10131}
10132
10133static HChar *
10134s390_irgen_DR(UChar r1, UChar r2)
10135{
10136 IRTemp op2 = newTemp(Ity_I32);
10137
10138 assign(op2, get_gpr_w1(r2));
10139
10140 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10141
10142 return "dr";
10143}
10144
10145static HChar *
10146s390_irgen_D(UChar r1, IRTemp op2addr)
10147{
10148 IRTemp op2 = newTemp(Ity_I32);
10149
10150 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10151
10152 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10153
10154 return "d";
10155}
10156
10157static HChar *
10158s390_irgen_DLR(UChar r1, UChar r2)
10159{
10160 IRTemp op2 = newTemp(Ity_I32);
10161
10162 assign(op2, get_gpr_w1(r2));
10163
10164 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10165
florian7cd1cde2012-08-16 23:57:43 +000010166 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010167}
10168
10169static HChar *
10170s390_irgen_DL(UChar r1, IRTemp op2addr)
10171{
10172 IRTemp op2 = newTemp(Ity_I32);
10173
10174 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10175
10176 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10177
10178 return "dl";
10179}
10180
10181static HChar *
10182s390_irgen_DLG(UChar r1, IRTemp op2addr)
10183{
10184 IRTemp op2 = newTemp(Ity_I64);
10185
10186 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10187
10188 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10189
10190 return "dlg";
10191}
10192
10193static HChar *
10194s390_irgen_DLGR(UChar r1, UChar r2)
10195{
10196 IRTemp op2 = newTemp(Ity_I64);
10197
10198 assign(op2, get_gpr_dw0(r2));
10199
10200 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10201
10202 return "dlgr";
10203}
10204
10205static HChar *
10206s390_irgen_DSGR(UChar r1, UChar r2)
10207{
10208 IRTemp op2 = newTemp(Ity_I64);
10209
10210 assign(op2, get_gpr_dw0(r2));
10211
10212 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10213
10214 return "dsgr";
10215}
10216
10217static HChar *
10218s390_irgen_DSG(UChar r1, IRTemp op2addr)
10219{
10220 IRTemp op2 = newTemp(Ity_I64);
10221
10222 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10223
10224 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10225
10226 return "dsg";
10227}
10228
10229static HChar *
10230s390_irgen_DSGFR(UChar r1, UChar r2)
10231{
10232 IRTemp op2 = newTemp(Ity_I64);
10233
10234 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10235
10236 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10237
10238 return "dsgfr";
10239}
10240
10241static HChar *
10242s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10243{
10244 IRTemp op2 = newTemp(Ity_I64);
10245
10246 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10247
10248 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10249
10250 return "dsgf";
10251}
10252
10253static void
10254s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10255{
10256 UChar reg;
10257 IRTemp addr = newTemp(Ity_I64);
10258
10259 assign(addr, mkexpr(op2addr));
10260 reg = r1;
10261 do {
10262 IRTemp old = addr;
10263
10264 reg %= 16;
10265 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10266 addr = newTemp(Ity_I64);
10267 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10268 reg++;
10269 } while (reg != (r3 + 1));
10270}
10271
10272static HChar *
10273s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10274{
10275 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10276
10277 return "lam";
10278}
10279
10280static HChar *
10281s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10282{
10283 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10284
10285 return "lamy";
10286}
10287
10288static void
10289s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10290{
10291 UChar reg;
10292 IRTemp addr = newTemp(Ity_I64);
10293
10294 assign(addr, mkexpr(op2addr));
10295 reg = r1;
10296 do {
10297 IRTemp old = addr;
10298
10299 reg %= 16;
10300 store(mkexpr(addr), get_ar_w0(reg));
10301 addr = newTemp(Ity_I64);
10302 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10303 reg++;
10304 } while (reg != (r3 + 1));
10305}
10306
10307static HChar *
10308s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10309{
10310 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10311
10312 return "stam";
10313}
10314
10315static HChar *
10316s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10317{
10318 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10319
10320 return "stamy";
10321}
10322
10323
10324/* Implementation for 32-bit compare-and-swap */
10325static void
10326s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10327{
10328 IRCAS *cas;
10329 IRTemp op1 = newTemp(Ity_I32);
10330 IRTemp old_mem = newTemp(Ity_I32);
10331 IRTemp op3 = newTemp(Ity_I32);
10332 IRTemp result = newTemp(Ity_I32);
10333 IRTemp nequal = newTemp(Ity_I1);
10334
10335 assign(op1, get_gpr_w1(r1));
10336 assign(op3, get_gpr_w1(r3));
10337
10338 /* The first and second operands are compared. If they are equal,
10339 the third operand is stored at the second- operand location. */
10340 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10341 Iend_BE, mkexpr(op2addr),
10342 NULL, mkexpr(op1), /* expected value */
10343 NULL, mkexpr(op3) /* new value */);
10344 stmt(IRStmt_CAS(cas));
10345
10346 /* Set CC. Operands compared equal -> 0, else 1. */
10347 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10348 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10349
10350 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10351 Otherwise, store the old_value from memory in r1 and yield. */
10352 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10353 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010354 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010355}
10356
10357static HChar *
10358s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10359{
10360 s390_irgen_cas_32(r1, r3, op2addr);
10361
10362 return "cs";
10363}
10364
10365static HChar *
10366s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10367{
10368 s390_irgen_cas_32(r1, r3, op2addr);
10369
10370 return "csy";
10371}
10372
10373static HChar *
10374s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10375{
10376 IRCAS *cas;
10377 IRTemp op1 = newTemp(Ity_I64);
10378 IRTemp old_mem = newTemp(Ity_I64);
10379 IRTemp op3 = newTemp(Ity_I64);
10380 IRTemp result = newTemp(Ity_I64);
10381 IRTemp nequal = newTemp(Ity_I1);
10382
10383 assign(op1, get_gpr_dw0(r1));
10384 assign(op3, get_gpr_dw0(r3));
10385
10386 /* The first and second operands are compared. If they are equal,
10387 the third operand is stored at the second- operand location. */
10388 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10389 Iend_BE, mkexpr(op2addr),
10390 NULL, mkexpr(op1), /* expected value */
10391 NULL, mkexpr(op3) /* new value */);
10392 stmt(IRStmt_CAS(cas));
10393
10394 /* Set CC. Operands compared equal -> 0, else 1. */
10395 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10396 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10397
10398 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10399 Otherwise, store the old_value from memory in r1 and yield. */
10400 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10401 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010402 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010403
10404 return "csg";
10405}
10406
florian448cbba2012-06-06 02:26:01 +000010407/* Implementation for 32-bit compare-double-and-swap */
10408static void
10409s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10410{
10411 IRCAS *cas;
10412 IRTemp op1_high = newTemp(Ity_I32);
10413 IRTemp op1_low = newTemp(Ity_I32);
10414 IRTemp old_mem_high = newTemp(Ity_I32);
10415 IRTemp old_mem_low = newTemp(Ity_I32);
10416 IRTemp op3_high = newTemp(Ity_I32);
10417 IRTemp op3_low = newTemp(Ity_I32);
10418 IRTemp result = newTemp(Ity_I32);
10419 IRTemp nequal = newTemp(Ity_I1);
10420
10421 assign(op1_high, get_gpr_w1(r1));
10422 assign(op1_low, get_gpr_w1(r1+1));
10423 assign(op3_high, get_gpr_w1(r3));
10424 assign(op3_low, get_gpr_w1(r3+1));
10425
10426 /* The first and second operands are compared. If they are equal,
10427 the third operand is stored at the second-operand location. */
10428 cas = mkIRCAS(old_mem_high, old_mem_low,
10429 Iend_BE, mkexpr(op2addr),
10430 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10431 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10432 stmt(IRStmt_CAS(cas));
10433
10434 /* Set CC. Operands compared equal -> 0, else 1. */
10435 assign(result, unop(Iop_1Uto32,
10436 binop(Iop_CmpNE32,
10437 binop(Iop_Or32,
10438 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10439 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10440 mkU32(0))));
10441
10442 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10443
10444 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10445 Otherwise, store the old_value from memory in r1 and yield. */
10446 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10447 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10448 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010449 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010450}
10451
10452static HChar *
10453s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10454{
10455 s390_irgen_cdas_32(r1, r3, op2addr);
10456
10457 return "cds";
10458}
10459
10460static HChar *
10461s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10462{
10463 s390_irgen_cdas_32(r1, r3, op2addr);
10464
10465 return "cdsy";
10466}
10467
10468static HChar *
10469s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10470{
10471 IRCAS *cas;
10472 IRTemp op1_high = newTemp(Ity_I64);
10473 IRTemp op1_low = newTemp(Ity_I64);
10474 IRTemp old_mem_high = newTemp(Ity_I64);
10475 IRTemp old_mem_low = newTemp(Ity_I64);
10476 IRTemp op3_high = newTemp(Ity_I64);
10477 IRTemp op3_low = newTemp(Ity_I64);
10478 IRTemp result = newTemp(Ity_I64);
10479 IRTemp nequal = newTemp(Ity_I1);
10480
10481 assign(op1_high, get_gpr_dw0(r1));
10482 assign(op1_low, get_gpr_dw0(r1+1));
10483 assign(op3_high, get_gpr_dw0(r3));
10484 assign(op3_low, get_gpr_dw0(r3+1));
10485
10486 /* The first and second operands are compared. If they are equal,
10487 the third operand is stored at the second-operand location. */
10488 cas = mkIRCAS(old_mem_high, old_mem_low,
10489 Iend_BE, mkexpr(op2addr),
10490 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10491 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10492 stmt(IRStmt_CAS(cas));
10493
10494 /* Set CC. Operands compared equal -> 0, else 1. */
10495 assign(result, unop(Iop_1Uto64,
10496 binop(Iop_CmpNE64,
10497 binop(Iop_Or64,
10498 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10499 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10500 mkU64(0))));
10501
10502 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10503
10504 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10505 Otherwise, store the old_value from memory in r1 and yield. */
10506 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10507 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10508 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010509 yield_if(mkexpr(nequal));
10510
florian448cbba2012-06-06 02:26:01 +000010511 return "cdsg";
10512}
10513
sewardj2019a972011-03-07 16:04:07 +000010514
10515/* Binary floating point */
10516
10517static HChar *
10518s390_irgen_AXBR(UChar r1, UChar r2)
10519{
10520 IRTemp op1 = newTemp(Ity_F128);
10521 IRTemp op2 = newTemp(Ity_F128);
10522 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010523 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010524
10525 assign(op1, get_fpr_pair(r1));
10526 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010527 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010528 mkexpr(op2)));
10529 put_fpr_pair(r1, mkexpr(result));
10530
10531 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10532
10533 return "axbr";
10534}
10535
10536/* The result of a Iop_CmdFxx operation is a condition code. It is
10537 encoded using the values defined in type IRCmpFxxResult.
10538 Before we can store the condition code into the guest state (or do
10539 anything else with it for that matter) we need to convert it to
10540 the encoding that s390 uses. This is what this function does.
10541
10542 s390 VEX b6 b2 b0 cc.1 cc.0
10543 0 0x40 EQ 1 0 0 0 0
10544 1 0x01 LT 0 0 1 0 1
10545 2 0x00 GT 0 0 0 1 0
10546 3 0x45 Unordered 1 1 1 1 1
10547
10548 The following bits from the VEX encoding are interesting:
10549 b0, b2, b6 with b0 being the LSB. We observe:
10550
10551 cc.0 = b0;
10552 cc.1 = b2 | (~b0 & ~b6)
10553
10554 with cc being the s390 condition code.
10555*/
10556static IRExpr *
10557convert_vex_fpcc_to_s390(IRTemp vex_cc)
10558{
10559 IRTemp cc0 = newTemp(Ity_I32);
10560 IRTemp cc1 = newTemp(Ity_I32);
10561 IRTemp b0 = newTemp(Ity_I32);
10562 IRTemp b2 = newTemp(Ity_I32);
10563 IRTemp b6 = newTemp(Ity_I32);
10564
10565 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10566 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10567 mkU32(1)));
10568 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10569 mkU32(1)));
10570
10571 assign(cc0, mkexpr(b0));
10572 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10573 binop(Iop_And32,
10574 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10575 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10576 )));
10577
10578 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10579}
10580
10581static HChar *
10582s390_irgen_CEBR(UChar r1, UChar r2)
10583{
10584 IRTemp op1 = newTemp(Ity_F32);
10585 IRTemp op2 = newTemp(Ity_F32);
10586 IRTemp cc_vex = newTemp(Ity_I32);
10587 IRTemp cc_s390 = newTemp(Ity_I32);
10588
10589 assign(op1, get_fpr_w0(r1));
10590 assign(op2, get_fpr_w0(r2));
10591 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10592
10593 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10594 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10595
10596 return "cebr";
10597}
10598
10599static HChar *
10600s390_irgen_CDBR(UChar r1, UChar r2)
10601{
10602 IRTemp op1 = newTemp(Ity_F64);
10603 IRTemp op2 = newTemp(Ity_F64);
10604 IRTemp cc_vex = newTemp(Ity_I32);
10605 IRTemp cc_s390 = newTemp(Ity_I32);
10606
10607 assign(op1, get_fpr_dw0(r1));
10608 assign(op2, get_fpr_dw0(r2));
10609 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10610
10611 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10612 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10613
10614 return "cdbr";
10615}
10616
10617static HChar *
10618s390_irgen_CXBR(UChar r1, UChar r2)
10619{
10620 IRTemp op1 = newTemp(Ity_F128);
10621 IRTemp op2 = newTemp(Ity_F128);
10622 IRTemp cc_vex = newTemp(Ity_I32);
10623 IRTemp cc_s390 = newTemp(Ity_I32);
10624
10625 assign(op1, get_fpr_pair(r1));
10626 assign(op2, get_fpr_pair(r2));
10627 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10628
10629 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10630 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10631
10632 return "cxbr";
10633}
10634
10635static HChar *
10636s390_irgen_CEB(UChar r1, IRTemp op2addr)
10637{
10638 IRTemp op1 = newTemp(Ity_F32);
10639 IRTemp op2 = newTemp(Ity_F32);
10640 IRTemp cc_vex = newTemp(Ity_I32);
10641 IRTemp cc_s390 = newTemp(Ity_I32);
10642
10643 assign(op1, get_fpr_w0(r1));
10644 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10645 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10646
10647 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10648 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10649
10650 return "ceb";
10651}
10652
10653static HChar *
10654s390_irgen_CDB(UChar r1, IRTemp op2addr)
10655{
10656 IRTemp op1 = newTemp(Ity_F64);
10657 IRTemp op2 = newTemp(Ity_F64);
10658 IRTemp cc_vex = newTemp(Ity_I32);
10659 IRTemp cc_s390 = newTemp(Ity_I32);
10660
10661 assign(op1, get_fpr_dw0(r1));
10662 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10663 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10664
10665 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10666 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10667
10668 return "cdb";
10669}
10670
10671static HChar *
florian4b8efad2012-09-02 18:07:08 +000010672s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10673 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010674{
10675 IRTemp op2 = newTemp(Ity_I32);
10676
10677 assign(op2, get_gpr_w1(r2));
10678 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10679
10680 return "cxfbr";
10681}
10682
10683static HChar *
floriand2129202012-09-01 20:01:39 +000010684s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10685 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010686{
floriane75dafa2012-09-01 17:54:09 +000010687 if (! s390_host_has_fpext) {
10688 emulation_failure(EmFail_S390X_fpext);
10689 } else {
10690 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010691
floriane75dafa2012-09-01 17:54:09 +000010692 assign(op2, get_gpr_w1(r2));
10693 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10694 }
florian1c8f7ff2012-09-01 00:12:11 +000010695 return "cxlfbr";
10696}
10697
10698
10699static HChar *
florian4b8efad2012-09-02 18:07:08 +000010700s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10701 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010702{
10703 IRTemp op2 = newTemp(Ity_I64);
10704
10705 assign(op2, get_gpr_dw0(r2));
10706 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10707
10708 return "cxgbr";
10709}
10710
10711static HChar *
floriand2129202012-09-01 20:01:39 +000010712s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10713 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010714{
floriane75dafa2012-09-01 17:54:09 +000010715 if (! s390_host_has_fpext) {
10716 emulation_failure(EmFail_S390X_fpext);
10717 } else {
10718 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010719
floriane75dafa2012-09-01 17:54:09 +000010720 assign(op2, get_gpr_dw0(r2));
10721 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10722 }
florian1c8f7ff2012-09-01 00:12:11 +000010723 return "cxlgbr";
10724}
10725
10726static HChar *
florian4b8efad2012-09-02 18:07:08 +000010727s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10728 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010729{
10730 IRTemp op = newTemp(Ity_F128);
10731 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010732 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010733
10734 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010735 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010736 mkexpr(op)));
10737 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010738 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010739
10740 return "cfxbr";
10741}
10742
10743static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010744s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10745 UChar r1, UChar r2)
10746{
floriane75dafa2012-09-01 17:54:09 +000010747 if (! s390_host_has_fpext) {
10748 emulation_failure(EmFail_S390X_fpext);
10749 } else {
10750 IRTemp op = newTemp(Ity_F128);
10751 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010752 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010753
floriane75dafa2012-09-01 17:54:09 +000010754 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010755 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010756 mkexpr(op)));
10757 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010758 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010759 }
florian1c8f7ff2012-09-01 00:12:11 +000010760 return "clfxbr";
10761}
10762
10763
10764static HChar *
florian4b8efad2012-09-02 18:07:08 +000010765s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10766 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010767{
10768 IRTemp op = newTemp(Ity_F128);
10769 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010770 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010771
10772 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010773 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010774 mkexpr(op)));
10775 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010776 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010777
10778 return "cgxbr";
10779}
10780
10781static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010782s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10783 UChar r1, UChar r2)
10784{
floriane75dafa2012-09-01 17:54:09 +000010785 if (! s390_host_has_fpext) {
10786 emulation_failure(EmFail_S390X_fpext);
10787 } else {
10788 IRTemp op = newTemp(Ity_F128);
10789 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010790 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010791
floriane75dafa2012-09-01 17:54:09 +000010792 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010793 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010794 mkexpr(op)));
10795 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010796 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
10797 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010798 }
florian1c8f7ff2012-09-01 00:12:11 +000010799 return "clgxbr";
10800}
10801
10802static HChar *
sewardj2019a972011-03-07 16:04:07 +000010803s390_irgen_DXBR(UChar r1, UChar r2)
10804{
10805 IRTemp op1 = newTemp(Ity_F128);
10806 IRTemp op2 = newTemp(Ity_F128);
10807 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010808 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010809
10810 assign(op1, get_fpr_pair(r1));
10811 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010812 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010813 mkexpr(op2)));
10814 put_fpr_pair(r1, mkexpr(result));
10815
10816 return "dxbr";
10817}
10818
10819static HChar *
10820s390_irgen_LTXBR(UChar r1, UChar r2)
10821{
10822 IRTemp result = newTemp(Ity_F128);
10823
10824 assign(result, get_fpr_pair(r2));
10825 put_fpr_pair(r1, mkexpr(result));
10826 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10827
10828 return "ltxbr";
10829}
10830
10831static HChar *
10832s390_irgen_LCXBR(UChar r1, UChar r2)
10833{
10834 IRTemp result = newTemp(Ity_F128);
10835
10836 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10837 put_fpr_pair(r1, mkexpr(result));
10838 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10839
10840 return "lcxbr";
10841}
10842
10843static HChar *
10844s390_irgen_LXDBR(UChar r1, UChar r2)
10845{
10846 IRTemp op = newTemp(Ity_F64);
10847
10848 assign(op, get_fpr_dw0(r2));
10849 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10850
10851 return "lxdbr";
10852}
10853
10854static HChar *
10855s390_irgen_LXEBR(UChar r1, UChar r2)
10856{
10857 IRTemp op = newTemp(Ity_F32);
10858
10859 assign(op, get_fpr_w0(r2));
10860 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10861
10862 return "lxebr";
10863}
10864
10865static HChar *
10866s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10867{
10868 IRTemp op = newTemp(Ity_F64);
10869
10870 assign(op, load(Ity_F64, mkexpr(op2addr)));
10871 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10872
10873 return "lxdb";
10874}
10875
10876static HChar *
10877s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10878{
10879 IRTemp op = newTemp(Ity_F32);
10880
10881 assign(op, load(Ity_F32, mkexpr(op2addr)));
10882 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10883
10884 return "lxeb";
10885}
10886
10887static HChar *
10888s390_irgen_LNEBR(UChar r1, UChar r2)
10889{
10890 IRTemp result = newTemp(Ity_F32);
10891
10892 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10893 put_fpr_w0(r1, mkexpr(result));
10894 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10895
10896 return "lnebr";
10897}
10898
10899static HChar *
10900s390_irgen_LNDBR(UChar r1, UChar r2)
10901{
10902 IRTemp result = newTemp(Ity_F64);
10903
10904 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10905 put_fpr_dw0(r1, mkexpr(result));
10906 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10907
10908 return "lndbr";
10909}
10910
10911static HChar *
10912s390_irgen_LNXBR(UChar r1, UChar r2)
10913{
10914 IRTemp result = newTemp(Ity_F128);
10915
10916 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10917 put_fpr_pair(r1, mkexpr(result));
10918 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10919
10920 return "lnxbr";
10921}
10922
10923static HChar *
10924s390_irgen_LPEBR(UChar r1, UChar r2)
10925{
10926 IRTemp result = newTemp(Ity_F32);
10927
10928 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10929 put_fpr_w0(r1, mkexpr(result));
10930 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10931
10932 return "lpebr";
10933}
10934
10935static HChar *
10936s390_irgen_LPDBR(UChar r1, UChar r2)
10937{
10938 IRTemp result = newTemp(Ity_F64);
10939
10940 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10941 put_fpr_dw0(r1, mkexpr(result));
10942 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10943
10944 return "lpdbr";
10945}
10946
10947static HChar *
10948s390_irgen_LPXBR(UChar r1, UChar r2)
10949{
10950 IRTemp result = newTemp(Ity_F128);
10951
10952 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10953 put_fpr_pair(r1, mkexpr(result));
10954 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10955
10956 return "lpxbr";
10957}
10958
10959static HChar *
florian4b8efad2012-09-02 18:07:08 +000010960s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10961 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010962{
florian125e20d2012-10-07 15:42:37 +000010963 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000010964 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000010965 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000010966 }
sewardj2019a972011-03-07 16:04:07 +000010967 IRTemp result = newTemp(Ity_F64);
10968
floriandb4fcaa2012-09-05 19:54:08 +000010969 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010970 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010971 put_fpr_dw0(r1, mkexpr(result));
10972
10973 return "ldxbr";
10974}
10975
10976static HChar *
florian4b8efad2012-09-02 18:07:08 +000010977s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
10978 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010979{
florian125e20d2012-10-07 15:42:37 +000010980 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000010981 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000010982 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000010983 }
sewardj2019a972011-03-07 16:04:07 +000010984 IRTemp result = newTemp(Ity_F32);
10985
floriandb4fcaa2012-09-05 19:54:08 +000010986 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010987 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010988 put_fpr_w0(r1, mkexpr(result));
10989
10990 return "lexbr";
10991}
10992
10993static HChar *
10994s390_irgen_MXBR(UChar r1, UChar r2)
10995{
10996 IRTemp op1 = newTemp(Ity_F128);
10997 IRTemp op2 = newTemp(Ity_F128);
10998 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010999 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011000
11001 assign(op1, get_fpr_pair(r1));
11002 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011003 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011004 mkexpr(op2)));
11005 put_fpr_pair(r1, mkexpr(result));
11006
11007 return "mxbr";
11008}
11009
11010static HChar *
11011s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11012{
florian125e20d2012-10-07 15:42:37 +000011013 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011014
floriandb4fcaa2012-09-05 19:54:08 +000011015 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011016 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011017
11018 return "maebr";
11019}
11020
11021static HChar *
11022s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11023{
florian125e20d2012-10-07 15:42:37 +000011024 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011025
floriandb4fcaa2012-09-05 19:54:08 +000011026 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011027 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011028
11029 return "madbr";
11030}
11031
11032static HChar *
11033s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11034{
11035 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011036 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011037
floriandb4fcaa2012-09-05 19:54:08 +000011038 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011039 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011040
11041 return "maeb";
11042}
11043
11044static HChar *
11045s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11046{
11047 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011048 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011049
floriandb4fcaa2012-09-05 19:54:08 +000011050 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011051 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011052
11053 return "madb";
11054}
11055
11056static HChar *
11057s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11058{
florian125e20d2012-10-07 15:42:37 +000011059 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011060
floriandb4fcaa2012-09-05 19:54:08 +000011061 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011062 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011063
11064 return "msebr";
11065}
11066
11067static HChar *
11068s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11069{
florian125e20d2012-10-07 15:42:37 +000011070 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011071
floriandb4fcaa2012-09-05 19:54:08 +000011072 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011073 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011074
11075 return "msdbr";
11076}
11077
11078static HChar *
11079s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11080{
11081 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011082 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011083
floriandb4fcaa2012-09-05 19:54:08 +000011084 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011085 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011086
11087 return "mseb";
11088}
11089
11090static HChar *
11091s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11092{
11093 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011094 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011095
floriandb4fcaa2012-09-05 19:54:08 +000011096 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011097 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011098
11099 return "msdb";
11100}
11101
11102static HChar *
11103s390_irgen_SQEBR(UChar r1, UChar r2)
11104{
11105 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011106 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011107
floriandb4fcaa2012-09-05 19:54:08 +000011108 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011109 put_fpr_w0(r1, mkexpr(result));
11110
11111 return "sqebr";
11112}
11113
11114static HChar *
11115s390_irgen_SQDBR(UChar r1, UChar r2)
11116{
11117 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011118 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011119
floriandb4fcaa2012-09-05 19:54:08 +000011120 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011121 put_fpr_dw0(r1, mkexpr(result));
11122
11123 return "sqdbr";
11124}
11125
11126static HChar *
11127s390_irgen_SQXBR(UChar r1, UChar r2)
11128{
11129 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011130 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011131
floriandb4fcaa2012-09-05 19:54:08 +000011132 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11133 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011134 put_fpr_pair(r1, mkexpr(result));
11135
11136 return "sqxbr";
11137}
11138
11139static HChar *
11140s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11141{
11142 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011143 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011144
11145 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011146 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011147
11148 return "sqeb";
11149}
11150
11151static HChar *
11152s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11153{
11154 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011155 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011156
11157 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011158 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011159
11160 return "sqdb";
11161}
11162
11163static HChar *
11164s390_irgen_SXBR(UChar r1, UChar r2)
11165{
11166 IRTemp op1 = newTemp(Ity_F128);
11167 IRTemp op2 = newTemp(Ity_F128);
11168 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011169 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011170
11171 assign(op1, get_fpr_pair(r1));
11172 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011173 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011174 mkexpr(op2)));
11175 put_fpr_pair(r1, mkexpr(result));
11176 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11177
11178 return "sxbr";
11179}
11180
11181static HChar *
11182s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11183{
11184 IRTemp value = newTemp(Ity_F32);
11185
11186 assign(value, get_fpr_w0(r1));
11187
11188 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11189
11190 return "tceb";
11191}
11192
11193static HChar *
11194s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11195{
11196 IRTemp value = newTemp(Ity_F64);
11197
11198 assign(value, get_fpr_dw0(r1));
11199
11200 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11201
11202 return "tcdb";
11203}
11204
11205static HChar *
11206s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11207{
11208 IRTemp value = newTemp(Ity_F128);
11209
11210 assign(value, get_fpr_pair(r1));
11211
11212 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11213
11214 return "tcxb";
11215}
11216
11217static HChar *
11218s390_irgen_LCDFR(UChar r1, UChar r2)
11219{
11220 IRTemp result = newTemp(Ity_F64);
11221
11222 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11223 put_fpr_dw0(r1, mkexpr(result));
11224
11225 return "lcdfr";
11226}
11227
11228static HChar *
11229s390_irgen_LNDFR(UChar r1, UChar r2)
11230{
11231 IRTemp result = newTemp(Ity_F64);
11232
11233 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11234 put_fpr_dw0(r1, mkexpr(result));
11235
11236 return "lndfr";
11237}
11238
11239static HChar *
11240s390_irgen_LPDFR(UChar r1, UChar r2)
11241{
11242 IRTemp result = newTemp(Ity_F64);
11243
11244 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11245 put_fpr_dw0(r1, mkexpr(result));
11246
11247 return "lpdfr";
11248}
11249
11250static HChar *
11251s390_irgen_LDGR(UChar r1, UChar r2)
11252{
11253 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11254
11255 return "ldgr";
11256}
11257
11258static HChar *
11259s390_irgen_LGDR(UChar r1, UChar r2)
11260{
11261 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11262
11263 return "lgdr";
11264}
11265
11266
11267static HChar *
11268s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11269{
11270 IRTemp sign = newTemp(Ity_I64);
11271 IRTemp value = newTemp(Ity_I64);
11272
11273 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11274 mkU64(1ULL << 63)));
11275 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11276 mkU64((1ULL << 63) - 1)));
11277 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11278 mkexpr(sign))));
11279
11280 return "cpsdr";
11281}
11282
11283
sewardj2019a972011-03-07 16:04:07 +000011284static IRExpr *
11285s390_call_cvb(IRExpr *in)
11286{
11287 IRExpr **args, *call;
11288
11289 args = mkIRExprVec_1(in);
11290 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11291 "s390_do_cvb", &s390_do_cvb, args);
11292
11293 /* Nothing is excluded from definedness checking. */
11294 call->Iex.CCall.cee->mcx_mask = 0;
11295
11296 return call;
11297}
11298
11299static HChar *
11300s390_irgen_CVB(UChar r1, IRTemp op2addr)
11301{
11302 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11303
11304 return "cvb";
11305}
11306
11307static HChar *
11308s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11309{
11310 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11311
11312 return "cvby";
11313}
11314
11315
sewardj2019a972011-03-07 16:04:07 +000011316static IRExpr *
11317s390_call_cvd(IRExpr *in)
11318{
11319 IRExpr **args, *call;
11320
11321 args = mkIRExprVec_1(in);
11322 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11323 "s390_do_cvd", &s390_do_cvd, args);
11324
11325 /* Nothing is excluded from definedness checking. */
11326 call->Iex.CCall.cee->mcx_mask = 0;
11327
11328 return call;
11329}
11330
11331static HChar *
11332s390_irgen_CVD(UChar r1, IRTemp op2addr)
11333{
florian11b8ee82012-08-06 13:35:33 +000011334 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011335
11336 return "cvd";
11337}
11338
11339static HChar *
11340s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11341{
11342 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11343
11344 return "cvdy";
11345}
11346
11347static HChar *
11348s390_irgen_FLOGR(UChar r1, UChar r2)
11349{
11350 IRTemp input = newTemp(Ity_I64);
11351 IRTemp not_zero = newTemp(Ity_I64);
11352 IRTemp tmpnum = newTemp(Ity_I64);
11353 IRTemp num = newTemp(Ity_I64);
11354 IRTemp shift_amount = newTemp(Ity_I8);
11355
11356 /* We use the "count leading zeroes" operator because the number of
11357 leading zeroes is identical with the bit position of the first '1' bit.
11358 However, that operator does not work when the input value is zero.
11359 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11360 the modified value. If input == 0, then the result is 64. Otherwise,
11361 the result of Clz64 is what we want. */
11362
11363 assign(input, get_gpr_dw0(r2));
11364 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11365 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11366
11367 /* num = (input == 0) ? 64 : tmpnum */
11368 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11369 /* == 0 */ mkU64(64),
11370 /* != 0 */ mkexpr(tmpnum)));
11371
11372 put_gpr_dw0(r1, mkexpr(num));
11373
11374 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11375 is to first shift the input value by NUM + 1 bits to the left which
11376 causes the leftmost '1' bit to disappear. Then we shift logically to
11377 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11378 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11379 the width of the value-to-be-shifted, we need to special case
11380 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11381 For both such INPUT values the result will be 0. */
11382
11383 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11384 mkU64(1))));
11385
11386 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011387 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11388 /* == 0 || == 1*/ mkU64(0),
11389 /* otherwise */
11390 binop(Iop_Shr64,
11391 binop(Iop_Shl64, mkexpr(input),
11392 mkexpr(shift_amount)),
11393 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011394
11395 /* Compare the original value as an unsigned integer with 0. */
11396 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11397 mktemp(Ity_I64, mkU64(0)), False);
11398
11399 return "flogr";
11400}
11401
sewardj1e5fea62011-05-17 16:18:36 +000011402static HChar *
11403s390_irgen_STCK(IRTemp op2addr)
11404{
11405 IRDirty *d;
11406 IRTemp cc = newTemp(Ity_I64);
11407
11408 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11409 &s390x_dirtyhelper_STCK,
11410 mkIRExprVec_1(mkexpr(op2addr)));
11411 d->mFx = Ifx_Write;
11412 d->mAddr = mkexpr(op2addr);
11413 d->mSize = 8;
11414 stmt(IRStmt_Dirty(d));
11415 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11416 mkexpr(cc), mkU64(0), mkU64(0));
11417 return "stck";
11418}
11419
11420static HChar *
11421s390_irgen_STCKF(IRTemp op2addr)
11422{
florianc5c669b2012-08-26 14:32:28 +000011423 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011424 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011425 } else {
11426 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011427
florianc5c669b2012-08-26 14:32:28 +000011428 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11429 &s390x_dirtyhelper_STCKF,
11430 mkIRExprVec_1(mkexpr(op2addr)));
11431 d->mFx = Ifx_Write;
11432 d->mAddr = mkexpr(op2addr);
11433 d->mSize = 8;
11434 stmt(IRStmt_Dirty(d));
11435 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11436 mkexpr(cc), mkU64(0), mkU64(0));
11437 }
sewardj1e5fea62011-05-17 16:18:36 +000011438 return "stckf";
11439}
11440
11441static HChar *
11442s390_irgen_STCKE(IRTemp op2addr)
11443{
11444 IRDirty *d;
11445 IRTemp cc = newTemp(Ity_I64);
11446
11447 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11448 &s390x_dirtyhelper_STCKE,
11449 mkIRExprVec_1(mkexpr(op2addr)));
11450 d->mFx = Ifx_Write;
11451 d->mAddr = mkexpr(op2addr);
11452 d->mSize = 16;
11453 stmt(IRStmt_Dirty(d));
11454 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11455 mkexpr(cc), mkU64(0), mkU64(0));
11456 return "stcke";
11457}
11458
florian933065d2011-07-11 01:48:02 +000011459static HChar *
11460s390_irgen_STFLE(IRTemp op2addr)
11461{
florian4e0083e2012-08-26 03:41:56 +000011462 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011463 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011464 return "stfle";
11465 }
11466
florian933065d2011-07-11 01:48:02 +000011467 IRDirty *d;
11468 IRTemp cc = newTemp(Ity_I64);
11469
11470 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11471 &s390x_dirtyhelper_STFLE,
11472 mkIRExprVec_1(mkexpr(op2addr)));
11473
11474 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11475
sewardjc9069f22012-06-01 16:09:50 +000011476 d->nFxState = 1;
11477 vex_bzero(&d->fxState, sizeof(d->fxState));
11478
florian933065d2011-07-11 01:48:02 +000011479 d->fxState[0].fx = Ifx_Modify; /* read then write */
11480 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11481 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011482
11483 d->mAddr = mkexpr(op2addr);
11484 /* Pretend all double words are written */
11485 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11486 d->mFx = Ifx_Write;
11487
11488 stmt(IRStmt_Dirty(d));
11489
11490 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11491
11492 return "stfle";
11493}
11494
floriana4384a32011-08-11 16:58:45 +000011495static HChar *
11496s390_irgen_CKSM(UChar r1,UChar r2)
11497{
11498 IRTemp addr = newTemp(Ity_I64);
11499 IRTemp op = newTemp(Ity_I32);
11500 IRTemp len = newTemp(Ity_I64);
11501 IRTemp oldval = newTemp(Ity_I32);
11502 IRTemp mask = newTemp(Ity_I32);
11503 IRTemp newop = newTemp(Ity_I32);
11504 IRTemp result = newTemp(Ity_I32);
11505 IRTemp result1 = newTemp(Ity_I32);
11506 IRTemp inc = newTemp(Ity_I64);
11507
11508 assign(oldval, get_gpr_w1(r1));
11509 assign(addr, get_gpr_dw0(r2));
11510 assign(len, get_gpr_dw0(r2+1));
11511
11512 /* Condition code is always zero. */
11513 s390_cc_set(0);
11514
11515 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011516 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011517
11518 /* Assiging the increment variable to adjust address and length
11519 later on. */
11520 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11521 mkexpr(len), mkU64(4)));
11522
11523 /* If length < 4 the final 4-byte 2nd operand value is computed by
11524 appending the remaining bytes to the right with 0. This is done
11525 by AND'ing the 4 bytes loaded from memory with an appropriate
11526 mask. If length >= 4, that mask is simply 0xffffffff. */
11527
11528 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11529 /* Mask computation when len < 4:
11530 0xffffffff << (32 - (len % 4)*8) */
11531 binop(Iop_Shl32, mkU32(0xffffffff),
11532 unop(Iop_32to8,
11533 binop(Iop_Sub32, mkU32(32),
11534 binop(Iop_Shl32,
11535 unop(Iop_64to32,
11536 binop(Iop_And64,
11537 mkexpr(len), mkU64(3))),
11538 mkU8(3))))),
11539 mkU32(0xffffffff)));
11540
11541 assign(op, load(Ity_I32, mkexpr(addr)));
11542 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11543 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11544
11545 /* Checking for carry */
11546 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11547 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11548 mkexpr(result)));
11549
11550 put_gpr_w1(r1, mkexpr(result1));
11551 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11552 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11553
florian6820ba52012-07-26 02:01:50 +000011554 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011555
11556 return "cksm";
11557}
11558
florian9af37692012-01-15 21:01:16 +000011559static HChar *
11560s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11561{
11562 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11563 src_addr = newTemp(Ity_I64);
11564 des_addr = newTemp(Ity_I64);
11565 tab_addr = newTemp(Ity_I64);
11566 test_byte = newTemp(Ity_I8);
11567 src_len = newTemp(Ity_I64);
11568
11569 assign(src_addr, get_gpr_dw0(r2));
11570 assign(des_addr, get_gpr_dw0(r1));
11571 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011572 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011573 assign(test_byte, get_gpr_b7(0));
11574
11575 IRTemp op = newTemp(Ity_I8);
11576 IRTemp op1 = newTemp(Ity_I8);
11577 IRTemp result = newTemp(Ity_I64);
11578
11579 /* End of source string? We're done; proceed to next insn */
11580 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011581 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011582
11583 /* Load character from source string, index translation table and
11584 store translated character in op1. */
11585 assign(op, load(Ity_I8, mkexpr(src_addr)));
11586
11587 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11588 mkexpr(tab_addr)));
11589 assign(op1, load(Ity_I8, mkexpr(result)));
11590
11591 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11592 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011593 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011594 }
11595 store(get_gpr_dw0(r1), mkexpr(op1));
11596
11597 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11598 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11599 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11600
florian6820ba52012-07-26 02:01:50 +000011601 iterate();
florian9af37692012-01-15 21:01:16 +000011602
11603 return "troo";
11604}
11605
florian730448f2012-02-04 17:07:07 +000011606static HChar *
11607s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11608{
11609 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11610 src_addr = newTemp(Ity_I64);
11611 des_addr = newTemp(Ity_I64);
11612 tab_addr = newTemp(Ity_I64);
11613 test_byte = newTemp(Ity_I8);
11614 src_len = newTemp(Ity_I64);
11615
11616 assign(src_addr, get_gpr_dw0(r2));
11617 assign(des_addr, get_gpr_dw0(r1));
11618 assign(tab_addr, get_gpr_dw0(1));
11619 assign(src_len, get_gpr_dw0(r1+1));
11620 assign(test_byte, get_gpr_b7(0));
11621
11622 IRTemp op = newTemp(Ity_I16);
11623 IRTemp op1 = newTemp(Ity_I8);
11624 IRTemp result = newTemp(Ity_I64);
11625
11626 /* End of source string? We're done; proceed to next insn */
11627 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011628 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011629
11630 /* Load character from source string, index translation table and
11631 store translated character in op1. */
11632 assign(op, load(Ity_I16, mkexpr(src_addr)));
11633
11634 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11635 mkexpr(tab_addr)));
11636
11637 assign(op1, load(Ity_I8, mkexpr(result)));
11638
11639 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11640 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011641 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011642 }
11643 store(get_gpr_dw0(r1), mkexpr(op1));
11644
11645 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11646 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11647 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11648
florian6820ba52012-07-26 02:01:50 +000011649 iterate();
florian730448f2012-02-04 17:07:07 +000011650
11651 return "trto";
11652}
11653
11654static HChar *
11655s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11656{
11657 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11658 src_addr = newTemp(Ity_I64);
11659 des_addr = newTemp(Ity_I64);
11660 tab_addr = newTemp(Ity_I64);
11661 test_byte = newTemp(Ity_I16);
11662 src_len = newTemp(Ity_I64);
11663
11664 assign(src_addr, get_gpr_dw0(r2));
11665 assign(des_addr, get_gpr_dw0(r1));
11666 assign(tab_addr, get_gpr_dw0(1));
11667 assign(src_len, get_gpr_dw0(r1+1));
11668 assign(test_byte, get_gpr_hw3(0));
11669
11670 IRTemp op = newTemp(Ity_I8);
11671 IRTemp op1 = newTemp(Ity_I16);
11672 IRTemp result = newTemp(Ity_I64);
11673
11674 /* End of source string? We're done; proceed to next insn */
11675 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011676 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011677
11678 /* Load character from source string, index translation table and
11679 store translated character in op1. */
11680 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11681
11682 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11683 mkexpr(tab_addr)));
11684 assign(op1, load(Ity_I16, mkexpr(result)));
11685
11686 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11687 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011688 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011689 }
11690 store(get_gpr_dw0(r1), mkexpr(op1));
11691
11692 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11693 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11694 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11695
florian6820ba52012-07-26 02:01:50 +000011696 iterate();
florian730448f2012-02-04 17:07:07 +000011697
11698 return "trot";
11699}
11700
11701static HChar *
11702s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11703{
11704 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11705 src_addr = newTemp(Ity_I64);
11706 des_addr = newTemp(Ity_I64);
11707 tab_addr = newTemp(Ity_I64);
11708 test_byte = newTemp(Ity_I16);
11709 src_len = newTemp(Ity_I64);
11710
11711 assign(src_addr, get_gpr_dw0(r2));
11712 assign(des_addr, get_gpr_dw0(r1));
11713 assign(tab_addr, get_gpr_dw0(1));
11714 assign(src_len, get_gpr_dw0(r1+1));
11715 assign(test_byte, get_gpr_hw3(0));
11716
11717 IRTemp op = newTemp(Ity_I16);
11718 IRTemp op1 = newTemp(Ity_I16);
11719 IRTemp result = newTemp(Ity_I64);
11720
11721 /* End of source string? We're done; proceed to next insn */
11722 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011723 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011724
11725 /* Load character from source string, index translation table and
11726 store translated character in op1. */
11727 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11728
11729 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11730 mkexpr(tab_addr)));
11731 assign(op1, load(Ity_I16, mkexpr(result)));
11732
11733 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11734 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011735 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011736 }
11737
11738 store(get_gpr_dw0(r1), mkexpr(op1));
11739
11740 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11741 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11742 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11743
florian6820ba52012-07-26 02:01:50 +000011744 iterate();
florian730448f2012-02-04 17:07:07 +000011745
11746 return "trtt";
11747}
11748
11749static HChar *
11750s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11751{
florianf87d4fb2012-05-05 02:55:24 +000011752 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011753
florianf87d4fb2012-05-05 02:55:24 +000011754 assign(len, mkU64(length));
11755 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011756
11757 return "tr";
11758}
11759
11760static HChar *
11761s390_irgen_TRE(UChar r1,UChar r2)
11762{
11763 IRTemp src_addr, tab_addr, src_len, test_byte;
11764 src_addr = newTemp(Ity_I64);
11765 tab_addr = newTemp(Ity_I64);
11766 src_len = newTemp(Ity_I64);
11767 test_byte = newTemp(Ity_I8);
11768
11769 assign(src_addr, get_gpr_dw0(r1));
11770 assign(src_len, get_gpr_dw0(r1+1));
11771 assign(tab_addr, get_gpr_dw0(r2));
11772 assign(test_byte, get_gpr_b7(0));
11773
11774 IRTemp op = newTemp(Ity_I8);
11775 IRTemp op1 = newTemp(Ity_I8);
11776 IRTemp result = newTemp(Ity_I64);
11777
11778 /* End of source string? We're done; proceed to next insn */
11779 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011780 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011781
11782 /* Load character from source string and compare with test byte */
11783 assign(op, load(Ity_I8, mkexpr(src_addr)));
11784
11785 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011786 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011787
11788 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11789 mkexpr(tab_addr)));
11790
11791 assign(op1, load(Ity_I8, mkexpr(result)));
11792
11793 store(get_gpr_dw0(r1), mkexpr(op1));
11794 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11795 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11796
florian6820ba52012-07-26 02:01:50 +000011797 iterate();
florian730448f2012-02-04 17:07:07 +000011798
11799 return "tre";
11800}
11801
floriana0100c92012-07-20 00:06:35 +000011802static IRExpr *
11803s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11804{
11805 IRExpr **args, *call;
11806 args = mkIRExprVec_2(srcval, low_surrogate);
11807 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11808 "s390_do_cu21", &s390_do_cu21, args);
11809
11810 /* Nothing is excluded from definedness checking. */
11811 call->Iex.CCall.cee->mcx_mask = 0;
11812
11813 return call;
11814}
11815
11816static HChar *
11817s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11818{
11819 IRTemp addr1 = newTemp(Ity_I64);
11820 IRTemp addr2 = newTemp(Ity_I64);
11821 IRTemp len1 = newTemp(Ity_I64);
11822 IRTemp len2 = newTemp(Ity_I64);
11823
11824 assign(addr1, get_gpr_dw0(r1));
11825 assign(addr2, get_gpr_dw0(r2));
11826 assign(len1, get_gpr_dw0(r1 + 1));
11827 assign(len2, get_gpr_dw0(r2 + 1));
11828
11829 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11830 there are less than 2 bytes left, then the 2nd operand is exhausted
11831 and we're done here. cc = 0 */
11832 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011833 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011834
11835 /* There are at least two bytes there. Read them. */
11836 IRTemp srcval = newTemp(Ity_I32);
11837 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11838
11839 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11840 inside the interval [0xd800 - 0xdbff] */
11841 IRTemp is_high_surrogate = newTemp(Ity_I32);
11842 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11843 mkU32(1), mkU32(0));
11844 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11845 mkU32(1), mkU32(0));
11846 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11847
11848 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11849 then the 2nd operand is exhausted and we're done here. cc = 0 */
11850 IRExpr *not_enough_bytes =
11851 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11852
florian6820ba52012-07-26 02:01:50 +000011853 next_insn_if(binop(Iop_CmpEQ32,
11854 binop(Iop_And32, mkexpr(is_high_surrogate),
11855 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011856
11857 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11858 surrogate, read the next two bytes (low surrogate). */
11859 IRTemp low_surrogate = newTemp(Ity_I32);
11860 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11861
11862 assign(low_surrogate,
11863 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11864 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11865 mkU32(0))); // any value is fine; it will not be used
11866
11867 /* Call the helper */
11868 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011869 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11870 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011871
11872 /* Before we can test whether the 1st operand is exhausted we need to
11873 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11874 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11875 IRExpr *invalid_low_surrogate =
11876 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11877
11878 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011879 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011880 }
11881
11882 /* Now test whether the 1st operand is exhausted */
11883 IRTemp num_bytes = newTemp(Ity_I64);
11884 assign(num_bytes, binop(Iop_And64,
11885 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11886 mkU64(0xff)));
11887 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011888 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011889
11890 /* Extract the bytes to be stored at addr1 */
11891 IRTemp data = newTemp(Ity_I64);
11892 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11893
11894 /* To store the bytes construct 4 dirty helper calls. The helper calls
11895 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11896 one of them will be called at runtime. */
11897 int i;
11898 for (i = 1; i <= 4; ++i) {
11899 IRDirty *d;
11900
11901 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11902 &s390x_dirtyhelper_CUxy,
11903 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11904 mkexpr(num_bytes)));
11905 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11906 d->mFx = Ifx_Write;
11907 d->mAddr = mkexpr(addr1);
11908 d->mSize = i;
11909 stmt(IRStmt_Dirty(d));
11910 }
11911
11912 /* Update source address and length */
11913 IRTemp num_src_bytes = newTemp(Ity_I64);
11914 assign(num_src_bytes,
11915 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11916 mkU64(4), mkU64(2)));
11917 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11918 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11919
11920 /* Update destination address and length */
11921 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11922 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11923
florian6820ba52012-07-26 02:01:50 +000011924 iterate();
floriana0100c92012-07-20 00:06:35 +000011925
11926 return "cu21";
11927}
11928
florian2a415a12012-07-21 17:41:36 +000011929static IRExpr *
11930s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11931{
11932 IRExpr **args, *call;
11933 args = mkIRExprVec_2(srcval, low_surrogate);
11934 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11935 "s390_do_cu24", &s390_do_cu24, args);
11936
11937 /* Nothing is excluded from definedness checking. */
11938 call->Iex.CCall.cee->mcx_mask = 0;
11939
11940 return call;
11941}
11942
11943static HChar *
11944s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11945{
11946 IRTemp addr1 = newTemp(Ity_I64);
11947 IRTemp addr2 = newTemp(Ity_I64);
11948 IRTemp len1 = newTemp(Ity_I64);
11949 IRTemp len2 = newTemp(Ity_I64);
11950
11951 assign(addr1, get_gpr_dw0(r1));
11952 assign(addr2, get_gpr_dw0(r2));
11953 assign(len1, get_gpr_dw0(r1 + 1));
11954 assign(len2, get_gpr_dw0(r2 + 1));
11955
11956 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11957 there are less than 2 bytes left, then the 2nd operand is exhausted
11958 and we're done here. cc = 0 */
11959 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011960 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011961
11962 /* There are at least two bytes there. Read them. */
11963 IRTemp srcval = newTemp(Ity_I32);
11964 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11965
11966 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11967 inside the interval [0xd800 - 0xdbff] */
11968 IRTemp is_high_surrogate = newTemp(Ity_I32);
11969 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11970 mkU32(1), mkU32(0));
11971 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11972 mkU32(1), mkU32(0));
11973 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11974
11975 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11976 then the 2nd operand is exhausted and we're done here. cc = 0 */
11977 IRExpr *not_enough_bytes =
11978 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11979
florian6820ba52012-07-26 02:01:50 +000011980 next_insn_if(binop(Iop_CmpEQ32,
11981 binop(Iop_And32, mkexpr(is_high_surrogate),
11982 not_enough_bytes),
11983 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011984
11985 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11986 surrogate, read the next two bytes (low surrogate). */
11987 IRTemp low_surrogate = newTemp(Ity_I32);
11988 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11989
11990 assign(low_surrogate,
11991 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11992 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11993 mkU32(0))); // any value is fine; it will not be used
11994
11995 /* Call the helper */
11996 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011997 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11998 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011999
12000 /* Before we can test whether the 1st operand is exhausted we need to
12001 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12002 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12003 IRExpr *invalid_low_surrogate =
12004 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12005
12006 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012007 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012008 }
12009
12010 /* Now test whether the 1st operand is exhausted */
12011 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012012 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012013
12014 /* Extract the bytes to be stored at addr1 */
12015 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12016
12017 store(mkexpr(addr1), data);
12018
12019 /* Update source address and length */
12020 IRTemp num_src_bytes = newTemp(Ity_I64);
12021 assign(num_src_bytes,
12022 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12023 mkU64(4), mkU64(2)));
12024 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12025 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12026
12027 /* Update destination address and length */
12028 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12029 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12030
florian6820ba52012-07-26 02:01:50 +000012031 iterate();
florian2a415a12012-07-21 17:41:36 +000012032
12033 return "cu24";
12034}
floriana4384a32011-08-11 16:58:45 +000012035
florian956194b2012-07-28 22:18:32 +000012036static IRExpr *
12037s390_call_cu42(IRExpr *srcval)
12038{
12039 IRExpr **args, *call;
12040 args = mkIRExprVec_1(srcval);
12041 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12042 "s390_do_cu42", &s390_do_cu42, args);
12043
12044 /* Nothing is excluded from definedness checking. */
12045 call->Iex.CCall.cee->mcx_mask = 0;
12046
12047 return call;
12048}
12049
12050static HChar *
12051s390_irgen_CU42(UChar r1, UChar r2)
12052{
12053 IRTemp addr1 = newTemp(Ity_I64);
12054 IRTemp addr2 = newTemp(Ity_I64);
12055 IRTemp len1 = newTemp(Ity_I64);
12056 IRTemp len2 = newTemp(Ity_I64);
12057
12058 assign(addr1, get_gpr_dw0(r1));
12059 assign(addr2, get_gpr_dw0(r2));
12060 assign(len1, get_gpr_dw0(r1 + 1));
12061 assign(len2, get_gpr_dw0(r2 + 1));
12062
12063 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12064 there are less than 4 bytes left, then the 2nd operand is exhausted
12065 and we're done here. cc = 0 */
12066 s390_cc_set(0);
12067 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12068
12069 /* Read the 2nd operand. */
12070 IRTemp srcval = newTemp(Ity_I32);
12071 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12072
12073 /* Call the helper */
12074 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012075 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012076
12077 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12078 cc=2 outranks cc=1 (1st operand exhausted) */
12079 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12080
12081 s390_cc_set(2);
12082 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12083
12084 /* Now test whether the 1st operand is exhausted */
12085 IRTemp num_bytes = newTemp(Ity_I64);
12086 assign(num_bytes, binop(Iop_And64,
12087 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12088 mkU64(0xff)));
12089 s390_cc_set(1);
12090 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12091
12092 /* Extract the bytes to be stored at addr1 */
12093 IRTemp data = newTemp(Ity_I64);
12094 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12095
12096 /* To store the bytes construct 2 dirty helper calls. The helper calls
12097 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12098 that only one of them will be called at runtime. */
12099
12100 Int i;
12101 for (i = 2; i <= 4; ++i) {
12102 IRDirty *d;
12103
12104 if (i == 3) continue; // skip this one
12105
12106 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12107 &s390x_dirtyhelper_CUxy,
12108 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12109 mkexpr(num_bytes)));
12110 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12111 d->mFx = Ifx_Write;
12112 d->mAddr = mkexpr(addr1);
12113 d->mSize = i;
12114 stmt(IRStmt_Dirty(d));
12115 }
12116
12117 /* Update source address and length */
12118 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12119 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12120
12121 /* Update destination address and length */
12122 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12123 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12124
12125 iterate();
12126
12127 return "cu42";
12128}
12129
florian6d9b9b22012-08-03 18:35:39 +000012130static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012131s390_call_cu41(IRExpr *srcval)
12132{
12133 IRExpr **args, *call;
12134 args = mkIRExprVec_1(srcval);
12135 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12136 "s390_do_cu41", &s390_do_cu41, args);
12137
12138 /* Nothing is excluded from definedness checking. */
12139 call->Iex.CCall.cee->mcx_mask = 0;
12140
12141 return call;
12142}
12143
12144static HChar *
12145s390_irgen_CU41(UChar r1, UChar r2)
12146{
12147 IRTemp addr1 = newTemp(Ity_I64);
12148 IRTemp addr2 = newTemp(Ity_I64);
12149 IRTemp len1 = newTemp(Ity_I64);
12150 IRTemp len2 = newTemp(Ity_I64);
12151
12152 assign(addr1, get_gpr_dw0(r1));
12153 assign(addr2, get_gpr_dw0(r2));
12154 assign(len1, get_gpr_dw0(r1 + 1));
12155 assign(len2, get_gpr_dw0(r2 + 1));
12156
12157 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12158 there are less than 4 bytes left, then the 2nd operand is exhausted
12159 and we're done here. cc = 0 */
12160 s390_cc_set(0);
12161 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12162
12163 /* Read the 2nd operand. */
12164 IRTemp srcval = newTemp(Ity_I32);
12165 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12166
12167 /* Call the helper */
12168 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012169 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012170
12171 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12172 cc=2 outranks cc=1 (1st operand exhausted) */
12173 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12174
12175 s390_cc_set(2);
12176 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12177
12178 /* Now test whether the 1st operand is exhausted */
12179 IRTemp num_bytes = newTemp(Ity_I64);
12180 assign(num_bytes, binop(Iop_And64,
12181 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12182 mkU64(0xff)));
12183 s390_cc_set(1);
12184 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12185
12186 /* Extract the bytes to be stored at addr1 */
12187 IRTemp data = newTemp(Ity_I64);
12188 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12189
12190 /* To store the bytes construct 4 dirty helper calls. The helper calls
12191 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12192 one of them will be called at runtime. */
12193 int i;
12194 for (i = 1; i <= 4; ++i) {
12195 IRDirty *d;
12196
12197 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12198 &s390x_dirtyhelper_CUxy,
12199 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12200 mkexpr(num_bytes)));
12201 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12202 d->mFx = Ifx_Write;
12203 d->mAddr = mkexpr(addr1);
12204 d->mSize = i;
12205 stmt(IRStmt_Dirty(d));
12206 }
12207
12208 /* Update source address and length */
12209 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12210 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12211
12212 /* Update destination address and length */
12213 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12214 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12215
12216 iterate();
12217
12218 return "cu41";
12219}
12220
12221static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012222s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012223{
12224 IRExpr **args, *call;
12225 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012226 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12227 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012228
12229 /* Nothing is excluded from definedness checking. */
12230 call->Iex.CCall.cee->mcx_mask = 0;
12231
12232 return call;
12233}
12234
12235static IRExpr *
12236s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12237 IRExpr *byte4, IRExpr *stuff)
12238{
12239 IRExpr **args, *call;
12240 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12241 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12242 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12243
12244 /* Nothing is excluded from definedness checking. */
12245 call->Iex.CCall.cee->mcx_mask = 0;
12246
12247 return call;
12248}
12249
florian3f8a96a2012-08-05 02:59:55 +000012250static IRExpr *
12251s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12252 IRExpr *byte4, IRExpr *stuff)
12253{
12254 IRExpr **args, *call;
12255 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12256 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12257 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12258
12259 /* Nothing is excluded from definedness checking. */
12260 call->Iex.CCall.cee->mcx_mask = 0;
12261
12262 return call;
12263}
12264
12265static void
12266s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012267{
12268 IRTemp addr1 = newTemp(Ity_I64);
12269 IRTemp addr2 = newTemp(Ity_I64);
12270 IRTemp len1 = newTemp(Ity_I64);
12271 IRTemp len2 = newTemp(Ity_I64);
12272
12273 assign(addr1, get_gpr_dw0(r1));
12274 assign(addr2, get_gpr_dw0(r2));
12275 assign(len1, get_gpr_dw0(r1 + 1));
12276 assign(len2, get_gpr_dw0(r2 + 1));
12277
12278 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12279
12280 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12281 there is less than 1 byte left, then the 2nd operand is exhausted
12282 and we're done here. cc = 0 */
12283 s390_cc_set(0);
12284 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12285
12286 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012287 IRTemp byte1 = newTemp(Ity_I64);
12288 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012289
12290 /* Call the helper to get number of bytes and invalid byte indicator */
12291 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012292 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012293 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012294
12295 /* Check for invalid 1st byte */
12296 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12297 s390_cc_set(2);
12298 next_insn_if(is_invalid);
12299
12300 /* How many bytes do we have to read? */
12301 IRTemp num_src_bytes = newTemp(Ity_I64);
12302 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12303
12304 /* Now test whether the 2nd operand is exhausted */
12305 s390_cc_set(0);
12306 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12307
12308 /* Read the remaining bytes */
12309 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12310
12311 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12312 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012313 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012314 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12315 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012316 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012317 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12318 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012319 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012320
12321 /* Call the helper to get the converted value and invalid byte indicator.
12322 We can pass at most 5 arguments; therefore some encoding is needed
12323 here */
12324 IRExpr *stuff = binop(Iop_Or64,
12325 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12326 mkU64(extended_checking));
12327 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012328
12329 if (is_cu12) {
12330 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12331 byte4, stuff));
12332 } else {
12333 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12334 byte4, stuff));
12335 }
florian6d9b9b22012-08-03 18:35:39 +000012336
12337 /* Check for invalid character */
12338 s390_cc_set(2);
12339 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12340 next_insn_if(is_invalid);
12341
12342 /* Now test whether the 1st operand is exhausted */
12343 IRTemp num_bytes = newTemp(Ity_I64);
12344 assign(num_bytes, binop(Iop_And64,
12345 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12346 mkU64(0xff)));
12347 s390_cc_set(1);
12348 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12349
12350 /* Extract the bytes to be stored at addr1 */
12351 IRTemp data = newTemp(Ity_I64);
12352 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12353
florian3f8a96a2012-08-05 02:59:55 +000012354 if (is_cu12) {
12355 /* To store the bytes construct 2 dirty helper calls. The helper calls
12356 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12357 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012358
florian3f8a96a2012-08-05 02:59:55 +000012359 Int i;
12360 for (i = 2; i <= 4; ++i) {
12361 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012362
florian3f8a96a2012-08-05 02:59:55 +000012363 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012364
florian3f8a96a2012-08-05 02:59:55 +000012365 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12366 &s390x_dirtyhelper_CUxy,
12367 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12368 mkexpr(num_bytes)));
12369 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12370 d->mFx = Ifx_Write;
12371 d->mAddr = mkexpr(addr1);
12372 d->mSize = i;
12373 stmt(IRStmt_Dirty(d));
12374 }
12375 } else {
12376 // cu14
12377 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012378 }
12379
12380 /* Update source address and length */
12381 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12382 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12383
12384 /* Update destination address and length */
12385 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12386 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12387
12388 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012389}
12390
12391static HChar *
12392s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12393{
12394 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012395
12396 return "cu12";
12397}
12398
florian3f8a96a2012-08-05 02:59:55 +000012399static HChar *
12400s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12401{
12402 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12403
12404 return "cu14";
12405}
12406
florian8c88cb62012-08-26 18:58:13 +000012407static IRExpr *
12408s390_call_ecag(IRExpr *op2addr)
12409{
12410 IRExpr **args, *call;
12411
12412 args = mkIRExprVec_1(op2addr);
12413 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12414 "s390_do_ecag", &s390_do_ecag, args);
12415
12416 /* Nothing is excluded from definedness checking. */
12417 call->Iex.CCall.cee->mcx_mask = 0;
12418
12419 return call;
12420}
12421
12422static HChar *
floriand2129202012-09-01 20:01:39 +000012423s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012424{
12425 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012426 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012427 } else {
12428 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12429 }
12430
12431 return "ecag";
12432}
12433
12434
sewardj2019a972011-03-07 16:04:07 +000012435/*------------------------------------------------------------*/
12436/*--- Build IR for special instructions ---*/
12437/*------------------------------------------------------------*/
12438
florianb4df7682011-07-05 02:09:01 +000012439static void
sewardj2019a972011-03-07 16:04:07 +000012440s390_irgen_client_request(void)
12441{
12442 if (0)
12443 vex_printf("%%R3 = client_request ( %%R2 )\n");
12444
florianf9e1ed72012-04-17 02:41:56 +000012445 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12446 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012447
florianf9e1ed72012-04-17 02:41:56 +000012448 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012449 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012450
12451 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012452}
12453
florianb4df7682011-07-05 02:09:01 +000012454static void
sewardj2019a972011-03-07 16:04:07 +000012455s390_irgen_guest_NRADDR(void)
12456{
12457 if (0)
12458 vex_printf("%%R3 = guest_NRADDR\n");
12459
floriane88b3c92011-07-05 02:48:39 +000012460 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012461}
12462
florianb4df7682011-07-05 02:09:01 +000012463static void
sewardj2019a972011-03-07 16:04:07 +000012464s390_irgen_call_noredir(void)
12465{
florianf9e1ed72012-04-17 02:41:56 +000012466 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12467 + S390_SPECIAL_OP_SIZE;
12468
sewardj2019a972011-03-07 16:04:07 +000012469 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012470 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012471
12472 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012473 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012474
12475 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012476 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012477}
12478
12479/* Force proper alignment for the structures below. */
12480#pragma pack(1)
12481
12482
12483static s390_decode_t
12484s390_decode_2byte_and_irgen(UChar *bytes)
12485{
12486 typedef union {
12487 struct {
12488 unsigned int op : 16;
12489 } E;
12490 struct {
12491 unsigned int op : 8;
12492 unsigned int i : 8;
12493 } I;
12494 struct {
12495 unsigned int op : 8;
12496 unsigned int r1 : 4;
12497 unsigned int r2 : 4;
12498 } RR;
12499 } formats;
12500 union {
12501 formats fmt;
12502 UShort value;
12503 } ovl;
12504
12505 vassert(sizeof(formats) == 2);
12506
12507 ((char *)(&ovl.value))[0] = bytes[0];
12508 ((char *)(&ovl.value))[1] = bytes[1];
12509
12510 switch (ovl.value & 0xffff) {
12511 case 0x0101: /* PR */ goto unimplemented;
12512 case 0x0102: /* UPT */ goto unimplemented;
12513 case 0x0104: /* PTFF */ goto unimplemented;
12514 case 0x0107: /* SCKPF */ goto unimplemented;
12515 case 0x010a: /* PFPO */ goto unimplemented;
12516 case 0x010b: /* TAM */ goto unimplemented;
12517 case 0x010c: /* SAM24 */ goto unimplemented;
12518 case 0x010d: /* SAM31 */ goto unimplemented;
12519 case 0x010e: /* SAM64 */ goto unimplemented;
12520 case 0x01ff: /* TRAP2 */ goto unimplemented;
12521 }
12522
12523 switch ((ovl.value & 0xff00) >> 8) {
12524 case 0x04: /* SPM */ goto unimplemented;
12525 case 0x05: /* BALR */ goto unimplemented;
12526 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12527 goto ok;
12528 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12529 goto ok;
12530 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12531 case 0x0b: /* BSM */ goto unimplemented;
12532 case 0x0c: /* BASSM */ goto unimplemented;
12533 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12534 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012535 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12536 goto ok;
12537 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12538 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012539 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12540 goto ok;
12541 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12542 goto ok;
12543 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12544 goto ok;
12545 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12546 goto ok;
12547 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12548 goto ok;
12549 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12550 goto ok;
12551 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12552 goto ok;
12553 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12554 goto ok;
12555 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12556 goto ok;
12557 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12558 goto ok;
12559 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12560 goto ok;
12561 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12562 goto ok;
12563 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12564 goto ok;
12565 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12566 goto ok;
12567 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12568 goto ok;
12569 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12570 goto ok;
12571 case 0x20: /* LPDR */ goto unimplemented;
12572 case 0x21: /* LNDR */ goto unimplemented;
12573 case 0x22: /* LTDR */ goto unimplemented;
12574 case 0x23: /* LCDR */ goto unimplemented;
12575 case 0x24: /* HDR */ goto unimplemented;
12576 case 0x25: /* LDXR */ goto unimplemented;
12577 case 0x26: /* MXR */ goto unimplemented;
12578 case 0x27: /* MXDR */ goto unimplemented;
12579 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12580 goto ok;
12581 case 0x29: /* CDR */ goto unimplemented;
12582 case 0x2a: /* ADR */ goto unimplemented;
12583 case 0x2b: /* SDR */ goto unimplemented;
12584 case 0x2c: /* MDR */ goto unimplemented;
12585 case 0x2d: /* DDR */ goto unimplemented;
12586 case 0x2e: /* AWR */ goto unimplemented;
12587 case 0x2f: /* SWR */ goto unimplemented;
12588 case 0x30: /* LPER */ goto unimplemented;
12589 case 0x31: /* LNER */ goto unimplemented;
12590 case 0x32: /* LTER */ goto unimplemented;
12591 case 0x33: /* LCER */ goto unimplemented;
12592 case 0x34: /* HER */ goto unimplemented;
12593 case 0x35: /* LEDR */ goto unimplemented;
12594 case 0x36: /* AXR */ goto unimplemented;
12595 case 0x37: /* SXR */ goto unimplemented;
12596 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12597 goto ok;
12598 case 0x39: /* CER */ goto unimplemented;
12599 case 0x3a: /* AER */ goto unimplemented;
12600 case 0x3b: /* SER */ goto unimplemented;
12601 case 0x3c: /* MDER */ goto unimplemented;
12602 case 0x3d: /* DER */ goto unimplemented;
12603 case 0x3e: /* AUR */ goto unimplemented;
12604 case 0x3f: /* SUR */ goto unimplemented;
12605 }
12606
12607 return S390_DECODE_UNKNOWN_INSN;
12608
12609ok:
12610 return S390_DECODE_OK;
12611
12612unimplemented:
12613 return S390_DECODE_UNIMPLEMENTED_INSN;
12614}
12615
12616static s390_decode_t
12617s390_decode_4byte_and_irgen(UChar *bytes)
12618{
12619 typedef union {
12620 struct {
12621 unsigned int op1 : 8;
12622 unsigned int r1 : 4;
12623 unsigned int op2 : 4;
12624 unsigned int i2 : 16;
12625 } RI;
12626 struct {
12627 unsigned int op : 16;
12628 unsigned int : 8;
12629 unsigned int r1 : 4;
12630 unsigned int r2 : 4;
12631 } RRE;
12632 struct {
12633 unsigned int op : 16;
12634 unsigned int r1 : 4;
12635 unsigned int : 4;
12636 unsigned int r3 : 4;
12637 unsigned int r2 : 4;
12638 } RRF;
12639 struct {
12640 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012641 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012642 unsigned int m4 : 4;
12643 unsigned int r1 : 4;
12644 unsigned int r2 : 4;
12645 } RRF2;
12646 struct {
12647 unsigned int op : 16;
12648 unsigned int r3 : 4;
12649 unsigned int : 4;
12650 unsigned int r1 : 4;
12651 unsigned int r2 : 4;
12652 } RRF3;
12653 struct {
12654 unsigned int op : 16;
12655 unsigned int r3 : 4;
12656 unsigned int : 4;
12657 unsigned int r1 : 4;
12658 unsigned int r2 : 4;
12659 } RRR;
12660 struct {
12661 unsigned int op : 16;
12662 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000012663 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000012664 unsigned int r1 : 4;
12665 unsigned int r2 : 4;
12666 } RRF4;
12667 struct {
12668 unsigned int op : 8;
12669 unsigned int r1 : 4;
12670 unsigned int r3 : 4;
12671 unsigned int b2 : 4;
12672 unsigned int d2 : 12;
12673 } RS;
12674 struct {
12675 unsigned int op : 8;
12676 unsigned int r1 : 4;
12677 unsigned int r3 : 4;
12678 unsigned int i2 : 16;
12679 } RSI;
12680 struct {
12681 unsigned int op : 8;
12682 unsigned int r1 : 4;
12683 unsigned int x2 : 4;
12684 unsigned int b2 : 4;
12685 unsigned int d2 : 12;
12686 } RX;
12687 struct {
12688 unsigned int op : 16;
12689 unsigned int b2 : 4;
12690 unsigned int d2 : 12;
12691 } S;
12692 struct {
12693 unsigned int op : 8;
12694 unsigned int i2 : 8;
12695 unsigned int b1 : 4;
12696 unsigned int d1 : 12;
12697 } SI;
12698 } formats;
12699 union {
12700 formats fmt;
12701 UInt value;
12702 } ovl;
12703
12704 vassert(sizeof(formats) == 4);
12705
12706 ((char *)(&ovl.value))[0] = bytes[0];
12707 ((char *)(&ovl.value))[1] = bytes[1];
12708 ((char *)(&ovl.value))[2] = bytes[2];
12709 ((char *)(&ovl.value))[3] = bytes[3];
12710
12711 switch ((ovl.value & 0xff0f0000) >> 16) {
12712 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12713 ovl.fmt.RI.i2); goto ok;
12714 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12715 ovl.fmt.RI.i2); goto ok;
12716 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12717 ovl.fmt.RI.i2); goto ok;
12718 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12719 ovl.fmt.RI.i2); goto ok;
12720 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12721 ovl.fmt.RI.i2); goto ok;
12722 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12723 ovl.fmt.RI.i2); goto ok;
12724 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12725 ovl.fmt.RI.i2); goto ok;
12726 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12727 ovl.fmt.RI.i2); goto ok;
12728 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12729 ovl.fmt.RI.i2); goto ok;
12730 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12731 ovl.fmt.RI.i2); goto ok;
12732 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12733 ovl.fmt.RI.i2); goto ok;
12734 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12735 ovl.fmt.RI.i2); goto ok;
12736 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12737 ovl.fmt.RI.i2); goto ok;
12738 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12739 ovl.fmt.RI.i2); goto ok;
12740 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12741 ovl.fmt.RI.i2); goto ok;
12742 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12743 ovl.fmt.RI.i2); goto ok;
12744 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12745 ovl.fmt.RI.i2); goto ok;
12746 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12747 ovl.fmt.RI.i2); goto ok;
12748 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12749 ovl.fmt.RI.i2); goto ok;
12750 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12751 ovl.fmt.RI.i2); goto ok;
12752 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12753 goto ok;
12754 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12755 ovl.fmt.RI.i2); goto ok;
12756 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12757 ovl.fmt.RI.i2); goto ok;
12758 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12759 ovl.fmt.RI.i2); goto ok;
12760 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12761 goto ok;
12762 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12763 ovl.fmt.RI.i2); goto ok;
12764 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12765 goto ok;
12766 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12767 ovl.fmt.RI.i2); goto ok;
12768 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12769 goto ok;
12770 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12771 ovl.fmt.RI.i2); goto ok;
12772 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12773 goto ok;
12774 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12775 ovl.fmt.RI.i2); goto ok;
12776 }
12777
12778 switch ((ovl.value & 0xffff0000) >> 16) {
12779 case 0x8000: /* SSM */ goto unimplemented;
12780 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012781 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012782 case 0xb202: /* STIDP */ goto unimplemented;
12783 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012784 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12785 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012786 case 0xb206: /* SCKC */ goto unimplemented;
12787 case 0xb207: /* STCKC */ goto unimplemented;
12788 case 0xb208: /* SPT */ goto unimplemented;
12789 case 0xb209: /* STPT */ goto unimplemented;
12790 case 0xb20a: /* SPKA */ goto unimplemented;
12791 case 0xb20b: /* IPK */ goto unimplemented;
12792 case 0xb20d: /* PTLB */ goto unimplemented;
12793 case 0xb210: /* SPX */ goto unimplemented;
12794 case 0xb211: /* STPX */ goto unimplemented;
12795 case 0xb212: /* STAP */ goto unimplemented;
12796 case 0xb214: /* SIE */ goto unimplemented;
12797 case 0xb218: /* PC */ goto unimplemented;
12798 case 0xb219: /* SAC */ goto unimplemented;
12799 case 0xb21a: /* CFC */ goto unimplemented;
12800 case 0xb221: /* IPTE */ goto unimplemented;
12801 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12802 case 0xb223: /* IVSK */ goto unimplemented;
12803 case 0xb224: /* IAC */ goto unimplemented;
12804 case 0xb225: /* SSAR */ goto unimplemented;
12805 case 0xb226: /* EPAR */ goto unimplemented;
12806 case 0xb227: /* ESAR */ goto unimplemented;
12807 case 0xb228: /* PT */ goto unimplemented;
12808 case 0xb229: /* ISKE */ goto unimplemented;
12809 case 0xb22a: /* RRBE */ goto unimplemented;
12810 case 0xb22b: /* SSKE */ goto unimplemented;
12811 case 0xb22c: /* TB */ goto unimplemented;
12812 case 0xb22d: /* DXR */ goto unimplemented;
12813 case 0xb22e: /* PGIN */ goto unimplemented;
12814 case 0xb22f: /* PGOUT */ goto unimplemented;
12815 case 0xb230: /* CSCH */ goto unimplemented;
12816 case 0xb231: /* HSCH */ goto unimplemented;
12817 case 0xb232: /* MSCH */ goto unimplemented;
12818 case 0xb233: /* SSCH */ goto unimplemented;
12819 case 0xb234: /* STSCH */ goto unimplemented;
12820 case 0xb235: /* TSCH */ goto unimplemented;
12821 case 0xb236: /* TPI */ goto unimplemented;
12822 case 0xb237: /* SAL */ goto unimplemented;
12823 case 0xb238: /* RSCH */ goto unimplemented;
12824 case 0xb239: /* STCRW */ goto unimplemented;
12825 case 0xb23a: /* STCPS */ goto unimplemented;
12826 case 0xb23b: /* RCHP */ goto unimplemented;
12827 case 0xb23c: /* SCHM */ goto unimplemented;
12828 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012829 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12830 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012831 case 0xb244: /* SQDR */ goto unimplemented;
12832 case 0xb245: /* SQER */ goto unimplemented;
12833 case 0xb246: /* STURA */ goto unimplemented;
12834 case 0xb247: /* MSTA */ goto unimplemented;
12835 case 0xb248: /* PALB */ goto unimplemented;
12836 case 0xb249: /* EREG */ goto unimplemented;
12837 case 0xb24a: /* ESTA */ goto unimplemented;
12838 case 0xb24b: /* LURA */ goto unimplemented;
12839 case 0xb24c: /* TAR */ goto unimplemented;
12840 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12841 ovl.fmt.RRE.r2); goto ok;
12842 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12843 goto ok;
12844 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12845 goto ok;
12846 case 0xb250: /* CSP */ goto unimplemented;
12847 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12848 ovl.fmt.RRE.r2); goto ok;
12849 case 0xb254: /* MVPG */ goto unimplemented;
12850 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12851 ovl.fmt.RRE.r2); goto ok;
12852 case 0xb257: /* CUSE */ goto unimplemented;
12853 case 0xb258: /* BSG */ goto unimplemented;
12854 case 0xb25a: /* BSA */ goto unimplemented;
12855 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12856 ovl.fmt.RRE.r2); goto ok;
12857 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12858 ovl.fmt.RRE.r2); goto ok;
12859 case 0xb263: /* CMPSC */ goto unimplemented;
12860 case 0xb274: /* SIGA */ goto unimplemented;
12861 case 0xb276: /* XSCH */ goto unimplemented;
12862 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012863 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 +000012864 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012865 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 +000012866 case 0xb27d: /* STSI */ goto unimplemented;
12867 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12868 goto ok;
12869 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12870 goto ok;
12871 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12872 goto ok;
florian730448f2012-02-04 17:07:07 +000012873 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 +000012874 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12875 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12876 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012877 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12878 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12879 goto ok;
florian933065d2011-07-11 01:48:02 +000012880 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12881 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012882 case 0xb2b1: /* STFL */ goto unimplemented;
12883 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000012884 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
12885 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012886 case 0xb2b9: /* SRNMT */ goto unimplemented;
12887 case 0xb2bd: /* LFAS */ goto unimplemented;
12888 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12889 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12890 ovl.fmt.RRE.r2); goto ok;
12891 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12892 ovl.fmt.RRE.r2); goto ok;
12893 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12894 ovl.fmt.RRE.r2); goto ok;
12895 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12896 ovl.fmt.RRE.r2); goto ok;
12897 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12898 ovl.fmt.RRE.r2); goto ok;
12899 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12900 ovl.fmt.RRE.r2); goto ok;
12901 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12902 ovl.fmt.RRE.r2); goto ok;
12903 case 0xb307: /* MXDBR */ goto unimplemented;
12904 case 0xb308: /* KEBR */ goto unimplemented;
12905 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12906 ovl.fmt.RRE.r2); goto ok;
12907 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12908 ovl.fmt.RRE.r2); goto ok;
12909 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12910 ovl.fmt.RRE.r2); goto ok;
12911 case 0xb30c: /* MDEBR */ goto unimplemented;
12912 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12913 ovl.fmt.RRE.r2); goto ok;
12914 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12915 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12916 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12917 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12918 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12919 ovl.fmt.RRE.r2); goto ok;
12920 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12921 ovl.fmt.RRE.r2); goto ok;
12922 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12923 ovl.fmt.RRE.r2); goto ok;
12924 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12925 ovl.fmt.RRE.r2); goto ok;
12926 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12927 ovl.fmt.RRE.r2); goto ok;
12928 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12929 ovl.fmt.RRE.r2); goto ok;
12930 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12931 ovl.fmt.RRE.r2); goto ok;
12932 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12933 ovl.fmt.RRE.r2); goto ok;
12934 case 0xb318: /* KDBR */ goto unimplemented;
12935 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12936 ovl.fmt.RRE.r2); goto ok;
12937 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12938 ovl.fmt.RRE.r2); goto ok;
12939 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12940 ovl.fmt.RRE.r2); goto ok;
12941 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12942 ovl.fmt.RRE.r2); goto ok;
12943 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12944 ovl.fmt.RRE.r2); goto ok;
12945 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12946 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12947 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12948 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12949 case 0xb324: /* LDER */ goto unimplemented;
12950 case 0xb325: /* LXDR */ goto unimplemented;
12951 case 0xb326: /* LXER */ goto unimplemented;
12952 case 0xb32e: /* MAER */ goto unimplemented;
12953 case 0xb32f: /* MSER */ goto unimplemented;
12954 case 0xb336: /* SQXR */ goto unimplemented;
12955 case 0xb337: /* MEER */ goto unimplemented;
12956 case 0xb338: /* MAYLR */ goto unimplemented;
12957 case 0xb339: /* MYLR */ goto unimplemented;
12958 case 0xb33a: /* MAYR */ goto unimplemented;
12959 case 0xb33b: /* MYR */ goto unimplemented;
12960 case 0xb33c: /* MAYHR */ goto unimplemented;
12961 case 0xb33d: /* MYHR */ goto unimplemented;
12962 case 0xb33e: /* MADR */ goto unimplemented;
12963 case 0xb33f: /* MSDR */ goto unimplemented;
12964 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12965 ovl.fmt.RRE.r2); goto ok;
12966 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12967 ovl.fmt.RRE.r2); goto ok;
12968 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12969 ovl.fmt.RRE.r2); goto ok;
12970 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12971 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012972 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
12973 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12974 ovl.fmt.RRF2.r2); goto ok;
12975 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
12976 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12977 ovl.fmt.RRF2.r2); goto ok;
12978 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
12979 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12980 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012981 case 0xb347: /* FIXBR */ goto unimplemented;
12982 case 0xb348: /* KXBR */ goto unimplemented;
12983 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12984 ovl.fmt.RRE.r2); goto ok;
12985 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12986 ovl.fmt.RRE.r2); goto ok;
12987 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12988 ovl.fmt.RRE.r2); goto ok;
12989 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12990 ovl.fmt.RRE.r2); goto ok;
12991 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12992 ovl.fmt.RRE.r2); goto ok;
12993 case 0xb350: /* TBEDR */ goto unimplemented;
12994 case 0xb351: /* TBDR */ goto unimplemented;
12995 case 0xb353: /* DIEBR */ goto unimplemented;
12996 case 0xb357: /* FIEBR */ goto unimplemented;
12997 case 0xb358: /* THDER */ goto unimplemented;
12998 case 0xb359: /* THDR */ goto unimplemented;
12999 case 0xb35b: /* DIDBR */ goto unimplemented;
13000 case 0xb35f: /* FIDBR */ goto unimplemented;
13001 case 0xb360: /* LPXR */ goto unimplemented;
13002 case 0xb361: /* LNXR */ goto unimplemented;
13003 case 0xb362: /* LTXR */ goto unimplemented;
13004 case 0xb363: /* LCXR */ goto unimplemented;
13005 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13006 ovl.fmt.RRE.r2); goto ok;
13007 case 0xb366: /* LEXR */ goto unimplemented;
13008 case 0xb367: /* FIXR */ goto unimplemented;
13009 case 0xb369: /* CXR */ goto unimplemented;
13010 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13011 ovl.fmt.RRE.r2); goto ok;
13012 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13013 ovl.fmt.RRE.r2); goto ok;
13014 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13015 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13016 goto ok;
13017 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13018 ovl.fmt.RRE.r2); goto ok;
13019 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13020 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13021 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13022 case 0xb377: /* FIER */ goto unimplemented;
13023 case 0xb37f: /* FIDR */ goto unimplemented;
13024 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13025 case 0xb385: /* SFASR */ goto unimplemented;
13026 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013027 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13028 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13029 ovl.fmt.RRF2.r2); goto ok;
13030 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13031 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13032 ovl.fmt.RRF2.r2); goto ok;
13033 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13034 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13035 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013036 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13037 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13038 ovl.fmt.RRF2.r2); goto ok;
13039 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13040 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13041 ovl.fmt.RRF2.r2); goto ok;
13042 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13043 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13044 ovl.fmt.RRF2.r2); goto ok;
13045 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13046 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13047 ovl.fmt.RRF2.r2); goto ok;
13048 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13049 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13050 ovl.fmt.RRF2.r2); goto ok;
13051 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13052 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13053 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013054 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13055 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13056 ovl.fmt.RRF2.r2); goto ok;
13057 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13058 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13059 ovl.fmt.RRF2.r2); goto ok;
13060 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13061 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13062 ovl.fmt.RRF2.r2); goto ok;
13063 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13064 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13065 ovl.fmt.RRF2.r2); goto ok;
13066 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13067 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13068 ovl.fmt.RRF2.r2); goto ok;
13069 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13070 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13071 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013072 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13073 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13074 ovl.fmt.RRF2.r2); goto ok;
13075 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13076 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13077 ovl.fmt.RRF2.r2); goto ok;
13078 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13079 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13080 ovl.fmt.RRF2.r2); goto ok;
13081 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13082 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13083 ovl.fmt.RRF2.r2); goto ok;
13084 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13085 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13086 ovl.fmt.RRF2.r2); goto ok;
13087 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13088 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13089 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013090 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13091 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13092 ovl.fmt.RRF2.r2); goto ok;
13093 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13094 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13095 ovl.fmt.RRF2.r2); goto ok;
13096 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13097 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13098 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013099 case 0xb3b4: /* CEFR */ goto unimplemented;
13100 case 0xb3b5: /* CDFR */ goto unimplemented;
13101 case 0xb3b6: /* CXFR */ goto unimplemented;
13102 case 0xb3b8: /* CFER */ goto unimplemented;
13103 case 0xb3b9: /* CFDR */ goto unimplemented;
13104 case 0xb3ba: /* CFXR */ goto unimplemented;
13105 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13106 ovl.fmt.RRE.r2); goto ok;
13107 case 0xb3c4: /* CEGR */ goto unimplemented;
13108 case 0xb3c5: /* CDGR */ goto unimplemented;
13109 case 0xb3c6: /* CXGR */ goto unimplemented;
13110 case 0xb3c8: /* CGER */ goto unimplemented;
13111 case 0xb3c9: /* CGDR */ goto unimplemented;
13112 case 0xb3ca: /* CGXR */ goto unimplemented;
13113 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13114 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013115 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13116 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13117 ovl.fmt.RRF4.r2); goto ok;
13118 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13119 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13120 ovl.fmt.RRF4.r2); goto ok;
13121 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13122 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13123 ovl.fmt.RRF4.r2); goto ok;
13124 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13125 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13126 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013127 case 0xb3d4: /* LDETR */ goto unimplemented;
13128 case 0xb3d5: /* LEDTR */ goto unimplemented;
florian12390202012-11-10 22:34:14 +000013129 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13130 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013131 case 0xb3d7: /* FIDTR */ goto unimplemented;
13132 case 0xb3d8: /* MXTR */ goto unimplemented;
13133 case 0xb3d9: /* DXTR */ goto unimplemented;
13134 case 0xb3da: /* AXTR */ goto unimplemented;
13135 case 0xb3db: /* SXTR */ goto unimplemented;
13136 case 0xb3dc: /* LXDTR */ goto unimplemented;
13137 case 0xb3dd: /* LDXTR */ goto unimplemented;
13138 case 0xb3de: /* LTXTR */ goto unimplemented;
13139 case 0xb3df: /* FIXTR */ goto unimplemented;
13140 case 0xb3e0: /* KDTR */ goto unimplemented;
13141 case 0xb3e1: /* CGDTR */ goto unimplemented;
13142 case 0xb3e2: /* CUDTR */ goto unimplemented;
13143 case 0xb3e3: /* CSDTR */ goto unimplemented;
13144 case 0xb3e4: /* CDTR */ goto unimplemented;
13145 case 0xb3e5: /* EEDTR */ goto unimplemented;
13146 case 0xb3e7: /* ESDTR */ goto unimplemented;
13147 case 0xb3e8: /* KXTR */ goto unimplemented;
13148 case 0xb3e9: /* CGXTR */ goto unimplemented;
13149 case 0xb3ea: /* CUXTR */ goto unimplemented;
13150 case 0xb3eb: /* CSXTR */ goto unimplemented;
13151 case 0xb3ec: /* CXTR */ goto unimplemented;
13152 case 0xb3ed: /* EEXTR */ goto unimplemented;
13153 case 0xb3ef: /* ESXTR */ goto unimplemented;
13154 case 0xb3f1: /* CDGTR */ goto unimplemented;
13155 case 0xb3f2: /* CDUTR */ goto unimplemented;
13156 case 0xb3f3: /* CDSTR */ goto unimplemented;
13157 case 0xb3f4: /* CEDTR */ goto unimplemented;
13158 case 0xb3f5: /* QADTR */ goto unimplemented;
13159 case 0xb3f6: /* IEDTR */ goto unimplemented;
13160 case 0xb3f7: /* RRDTR */ goto unimplemented;
13161 case 0xb3f9: /* CXGTR */ goto unimplemented;
13162 case 0xb3fa: /* CXUTR */ goto unimplemented;
13163 case 0xb3fb: /* CXSTR */ goto unimplemented;
13164 case 0xb3fc: /* CEXTR */ goto unimplemented;
13165 case 0xb3fd: /* QAXTR */ goto unimplemented;
13166 case 0xb3fe: /* IEXTR */ goto unimplemented;
13167 case 0xb3ff: /* RRXTR */ goto unimplemented;
13168 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13169 ovl.fmt.RRE.r2); goto ok;
13170 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13171 ovl.fmt.RRE.r2); goto ok;
13172 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13173 ovl.fmt.RRE.r2); goto ok;
13174 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13175 ovl.fmt.RRE.r2); goto ok;
13176 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13177 ovl.fmt.RRE.r2); goto ok;
13178 case 0xb905: /* LURAG */ goto unimplemented;
13179 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13180 ovl.fmt.RRE.r2); goto ok;
13181 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13182 ovl.fmt.RRE.r2); goto ok;
13183 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13184 ovl.fmt.RRE.r2); goto ok;
13185 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13186 ovl.fmt.RRE.r2); goto ok;
13187 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13188 ovl.fmt.RRE.r2); goto ok;
13189 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13190 ovl.fmt.RRE.r2); goto ok;
13191 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13192 ovl.fmt.RRE.r2); goto ok;
13193 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13194 ovl.fmt.RRE.r2); goto ok;
13195 case 0xb90e: /* EREGG */ goto unimplemented;
13196 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13197 ovl.fmt.RRE.r2); goto ok;
13198 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13199 ovl.fmt.RRE.r2); goto ok;
13200 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13201 ovl.fmt.RRE.r2); goto ok;
13202 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13203 ovl.fmt.RRE.r2); goto ok;
13204 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13205 ovl.fmt.RRE.r2); goto ok;
13206 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13207 ovl.fmt.RRE.r2); goto ok;
13208 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13209 ovl.fmt.RRE.r2); goto ok;
13210 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13211 ovl.fmt.RRE.r2); goto ok;
13212 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13213 ovl.fmt.RRE.r2); goto ok;
13214 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13215 ovl.fmt.RRE.r2); goto ok;
13216 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13217 ovl.fmt.RRE.r2); goto ok;
13218 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13219 ovl.fmt.RRE.r2); goto ok;
13220 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13221 ovl.fmt.RRE.r2); goto ok;
13222 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13223 ovl.fmt.RRE.r2); goto ok;
13224 case 0xb91e: /* KMAC */ goto unimplemented;
13225 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13226 ovl.fmt.RRE.r2); goto ok;
13227 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13228 ovl.fmt.RRE.r2); goto ok;
13229 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13230 ovl.fmt.RRE.r2); goto ok;
13231 case 0xb925: /* STURG */ goto unimplemented;
13232 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13233 ovl.fmt.RRE.r2); goto ok;
13234 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13235 ovl.fmt.RRE.r2); goto ok;
13236 case 0xb928: /* PCKMO */ goto unimplemented;
13237 case 0xb92b: /* KMO */ goto unimplemented;
13238 case 0xb92c: /* PCC */ goto unimplemented;
13239 case 0xb92d: /* KMCTR */ goto unimplemented;
13240 case 0xb92e: /* KM */ goto unimplemented;
13241 case 0xb92f: /* KMC */ goto unimplemented;
13242 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13243 ovl.fmt.RRE.r2); goto ok;
13244 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13245 ovl.fmt.RRE.r2); goto ok;
13246 case 0xb93e: /* KIMD */ goto unimplemented;
13247 case 0xb93f: /* KLMD */ goto unimplemented;
13248 case 0xb941: /* CFDTR */ goto unimplemented;
13249 case 0xb942: /* CLGDTR */ goto unimplemented;
13250 case 0xb943: /* CLFDTR */ goto unimplemented;
13251 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13252 ovl.fmt.RRE.r2); goto ok;
13253 case 0xb949: /* CFXTR */ goto unimplemented;
13254 case 0xb94a: /* CLGXTR */ goto unimplemented;
13255 case 0xb94b: /* CLFXTR */ goto unimplemented;
13256 case 0xb951: /* CDFTR */ goto unimplemented;
13257 case 0xb952: /* CDLGTR */ goto unimplemented;
13258 case 0xb953: /* CDLFTR */ goto unimplemented;
13259 case 0xb959: /* CXFTR */ goto unimplemented;
13260 case 0xb95a: /* CXLGTR */ goto unimplemented;
13261 case 0xb95b: /* CXLFTR */ goto unimplemented;
13262 case 0xb960: /* CGRT */ goto unimplemented;
13263 case 0xb961: /* CLGRT */ goto unimplemented;
13264 case 0xb972: /* CRT */ goto unimplemented;
13265 case 0xb973: /* CLRT */ goto unimplemented;
13266 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13267 ovl.fmt.RRE.r2); goto ok;
13268 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13269 ovl.fmt.RRE.r2); goto ok;
13270 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13271 ovl.fmt.RRE.r2); goto ok;
13272 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13273 ovl.fmt.RRE.r2); goto ok;
13274 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13275 ovl.fmt.RRE.r2); goto ok;
13276 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13277 ovl.fmt.RRE.r2); goto ok;
13278 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13279 ovl.fmt.RRE.r2); goto ok;
13280 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13281 ovl.fmt.RRE.r2); goto ok;
13282 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13283 ovl.fmt.RRE.r2); goto ok;
13284 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13285 ovl.fmt.RRE.r2); goto ok;
13286 case 0xb98a: /* CSPG */ goto unimplemented;
13287 case 0xb98d: /* EPSW */ goto unimplemented;
13288 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013289 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13290 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13291 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13292 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13293 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13294 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013295 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13296 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013297 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13298 ovl.fmt.RRE.r2); goto ok;
13299 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13300 ovl.fmt.RRE.r2); goto ok;
13301 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13302 ovl.fmt.RRE.r2); goto ok;
13303 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13304 ovl.fmt.RRE.r2); goto ok;
13305 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13306 ovl.fmt.RRE.r2); goto ok;
13307 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13308 ovl.fmt.RRE.r2); goto ok;
13309 case 0xb99a: /* EPAIR */ goto unimplemented;
13310 case 0xb99b: /* ESAIR */ goto unimplemented;
13311 case 0xb99d: /* ESEA */ goto unimplemented;
13312 case 0xb99e: /* PTI */ goto unimplemented;
13313 case 0xb99f: /* SSAIR */ goto unimplemented;
13314 case 0xb9a2: /* PTF */ goto unimplemented;
13315 case 0xb9aa: /* LPTEA */ goto unimplemented;
13316 case 0xb9ae: /* RRBM */ goto unimplemented;
13317 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013318 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13319 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13320 goto ok;
florian2a415a12012-07-21 17:41:36 +000013321 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13322 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13323 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013324 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13325 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013326 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13327 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013328 case 0xb9bd: /* TRTRE */ goto unimplemented;
13329 case 0xb9be: /* SRSTU */ goto unimplemented;
13330 case 0xb9bf: /* TRTE */ goto unimplemented;
13331 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13332 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13333 goto ok;
13334 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13335 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13336 goto ok;
13337 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13338 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13339 goto ok;
13340 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13341 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13342 goto ok;
13343 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13344 ovl.fmt.RRE.r2); goto ok;
13345 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13346 ovl.fmt.RRE.r2); goto ok;
13347 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13348 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13349 goto ok;
13350 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13351 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13352 goto ok;
13353 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13354 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13355 goto ok;
13356 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13357 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13358 goto ok;
13359 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13360 ovl.fmt.RRE.r2); goto ok;
13361 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13362 ovl.fmt.RRE.r2); goto ok;
13363 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013364 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13365 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13366 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013367 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13368 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13369 goto ok;
13370 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13371 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13372 goto ok;
13373 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13374 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13375 goto ok;
13376 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13377 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13378 goto ok;
13379 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13380 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13381 goto ok;
13382 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13383 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13384 goto ok;
13385 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13386 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13387 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013388 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13389 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13390 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013391 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13392 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13393 goto ok;
13394 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13395 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13396 goto ok;
13397 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13398 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13399 goto ok;
13400 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13401 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13402 goto ok;
13403 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13404 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13405 goto ok;
13406 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13407 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13408 goto ok;
13409 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13410 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13411 goto ok;
13412 }
13413
13414 switch ((ovl.value & 0xff000000) >> 24) {
13415 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13416 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13417 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13418 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13419 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13420 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13421 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13422 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13423 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13424 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13425 case 0x45: /* BAL */ goto unimplemented;
13426 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13427 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13428 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13429 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13430 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13431 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13432 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13433 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13434 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13435 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13436 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13437 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13438 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13439 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13440 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13441 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13442 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13443 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13444 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13445 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13446 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13447 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13448 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13449 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13450 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13451 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13452 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13453 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13454 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13455 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13456 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13457 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13458 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13459 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13460 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13461 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13462 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13463 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13464 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13465 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13466 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13467 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13468 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13469 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13470 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13471 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13472 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13473 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13474 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13475 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13476 case 0x67: /* MXD */ goto unimplemented;
13477 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13478 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13479 case 0x69: /* CD */ goto unimplemented;
13480 case 0x6a: /* AD */ goto unimplemented;
13481 case 0x6b: /* SD */ goto unimplemented;
13482 case 0x6c: /* MD */ goto unimplemented;
13483 case 0x6d: /* DD */ goto unimplemented;
13484 case 0x6e: /* AW */ goto unimplemented;
13485 case 0x6f: /* SW */ goto unimplemented;
13486 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13487 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13488 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13489 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13490 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13491 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13492 case 0x79: /* CE */ goto unimplemented;
13493 case 0x7a: /* AE */ goto unimplemented;
13494 case 0x7b: /* SE */ goto unimplemented;
13495 case 0x7c: /* MDE */ goto unimplemented;
13496 case 0x7d: /* DE */ goto unimplemented;
13497 case 0x7e: /* AU */ goto unimplemented;
13498 case 0x7f: /* SU */ goto unimplemented;
13499 case 0x83: /* DIAG */ goto unimplemented;
13500 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13501 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13502 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13503 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13504 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13505 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13506 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13507 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13508 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13509 ovl.fmt.RS.d2); goto ok;
13510 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13511 ovl.fmt.RS.d2); goto ok;
13512 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13513 ovl.fmt.RS.d2); goto ok;
13514 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13515 ovl.fmt.RS.d2); goto ok;
13516 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13517 ovl.fmt.RS.d2); goto ok;
13518 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13519 ovl.fmt.RS.d2); goto ok;
13520 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13521 ovl.fmt.RS.d2); goto ok;
13522 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13523 ovl.fmt.RS.d2); goto ok;
13524 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13525 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13526 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13527 ovl.fmt.SI.d1); goto ok;
13528 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13529 ovl.fmt.SI.d1); goto ok;
13530 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13531 ovl.fmt.SI.d1); goto ok;
13532 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13533 ovl.fmt.SI.d1); goto ok;
13534 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13535 ovl.fmt.SI.d1); goto ok;
13536 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13537 ovl.fmt.SI.d1); goto ok;
13538 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13539 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13540 case 0x99: /* TRACE */ goto unimplemented;
13541 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13542 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13543 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13544 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13545 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13546 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13547 goto ok;
13548 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13549 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13550 goto ok;
13551 case 0xac: /* STNSM */ goto unimplemented;
13552 case 0xad: /* STOSM */ goto unimplemented;
13553 case 0xae: /* SIGP */ goto unimplemented;
13554 case 0xaf: /* MC */ goto unimplemented;
13555 case 0xb1: /* LRA */ goto unimplemented;
13556 case 0xb6: /* STCTL */ goto unimplemented;
13557 case 0xb7: /* LCTL */ goto unimplemented;
13558 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13559 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013560 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13561 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013562 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13563 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13564 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13565 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13566 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13567 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13568 }
13569
13570 return S390_DECODE_UNKNOWN_INSN;
13571
13572ok:
13573 return S390_DECODE_OK;
13574
13575unimplemented:
13576 return S390_DECODE_UNIMPLEMENTED_INSN;
13577}
13578
13579static s390_decode_t
13580s390_decode_6byte_and_irgen(UChar *bytes)
13581{
13582 typedef union {
13583 struct {
13584 unsigned int op1 : 8;
13585 unsigned int r1 : 4;
13586 unsigned int r3 : 4;
13587 unsigned int i2 : 16;
13588 unsigned int : 8;
13589 unsigned int op2 : 8;
13590 } RIE;
13591 struct {
13592 unsigned int op1 : 8;
13593 unsigned int r1 : 4;
13594 unsigned int r2 : 4;
13595 unsigned int i3 : 8;
13596 unsigned int i4 : 8;
13597 unsigned int i5 : 8;
13598 unsigned int op2 : 8;
13599 } RIE_RRUUU;
13600 struct {
13601 unsigned int op1 : 8;
13602 unsigned int r1 : 4;
13603 unsigned int : 4;
13604 unsigned int i2 : 16;
13605 unsigned int m3 : 4;
13606 unsigned int : 4;
13607 unsigned int op2 : 8;
13608 } RIEv1;
13609 struct {
13610 unsigned int op1 : 8;
13611 unsigned int r1 : 4;
13612 unsigned int r2 : 4;
13613 unsigned int i4 : 16;
13614 unsigned int m3 : 4;
13615 unsigned int : 4;
13616 unsigned int op2 : 8;
13617 } RIE_RRPU;
13618 struct {
13619 unsigned int op1 : 8;
13620 unsigned int r1 : 4;
13621 unsigned int m3 : 4;
13622 unsigned int i4 : 16;
13623 unsigned int i2 : 8;
13624 unsigned int op2 : 8;
13625 } RIEv3;
13626 struct {
13627 unsigned int op1 : 8;
13628 unsigned int r1 : 4;
13629 unsigned int op2 : 4;
13630 unsigned int i2 : 32;
13631 } RIL;
13632 struct {
13633 unsigned int op1 : 8;
13634 unsigned int r1 : 4;
13635 unsigned int m3 : 4;
13636 unsigned int b4 : 4;
13637 unsigned int d4 : 12;
13638 unsigned int i2 : 8;
13639 unsigned int op2 : 8;
13640 } RIS;
13641 struct {
13642 unsigned int op1 : 8;
13643 unsigned int r1 : 4;
13644 unsigned int r2 : 4;
13645 unsigned int b4 : 4;
13646 unsigned int d4 : 12;
13647 unsigned int m3 : 4;
13648 unsigned int : 4;
13649 unsigned int op2 : 8;
13650 } RRS;
13651 struct {
13652 unsigned int op1 : 8;
13653 unsigned int l1 : 4;
13654 unsigned int : 4;
13655 unsigned int b1 : 4;
13656 unsigned int d1 : 12;
13657 unsigned int : 8;
13658 unsigned int op2 : 8;
13659 } RSL;
13660 struct {
13661 unsigned int op1 : 8;
13662 unsigned int r1 : 4;
13663 unsigned int r3 : 4;
13664 unsigned int b2 : 4;
13665 unsigned int dl2 : 12;
13666 unsigned int dh2 : 8;
13667 unsigned int op2 : 8;
13668 } RSY;
13669 struct {
13670 unsigned int op1 : 8;
13671 unsigned int r1 : 4;
13672 unsigned int x2 : 4;
13673 unsigned int b2 : 4;
13674 unsigned int d2 : 12;
13675 unsigned int : 8;
13676 unsigned int op2 : 8;
13677 } RXE;
13678 struct {
13679 unsigned int op1 : 8;
13680 unsigned int r3 : 4;
13681 unsigned int x2 : 4;
13682 unsigned int b2 : 4;
13683 unsigned int d2 : 12;
13684 unsigned int r1 : 4;
13685 unsigned int : 4;
13686 unsigned int op2 : 8;
13687 } RXF;
13688 struct {
13689 unsigned int op1 : 8;
13690 unsigned int r1 : 4;
13691 unsigned int x2 : 4;
13692 unsigned int b2 : 4;
13693 unsigned int dl2 : 12;
13694 unsigned int dh2 : 8;
13695 unsigned int op2 : 8;
13696 } RXY;
13697 struct {
13698 unsigned int op1 : 8;
13699 unsigned int i2 : 8;
13700 unsigned int b1 : 4;
13701 unsigned int dl1 : 12;
13702 unsigned int dh1 : 8;
13703 unsigned int op2 : 8;
13704 } SIY;
13705 struct {
13706 unsigned int op : 8;
13707 unsigned int l : 8;
13708 unsigned int b1 : 4;
13709 unsigned int d1 : 12;
13710 unsigned int b2 : 4;
13711 unsigned int d2 : 12;
13712 } SS;
13713 struct {
13714 unsigned int op : 8;
13715 unsigned int l1 : 4;
13716 unsigned int l2 : 4;
13717 unsigned int b1 : 4;
13718 unsigned int d1 : 12;
13719 unsigned int b2 : 4;
13720 unsigned int d2 : 12;
13721 } SS_LLRDRD;
13722 struct {
13723 unsigned int op : 8;
13724 unsigned int r1 : 4;
13725 unsigned int r3 : 4;
13726 unsigned int b2 : 4;
13727 unsigned int d2 : 12;
13728 unsigned int b4 : 4;
13729 unsigned int d4 : 12;
13730 } SS_RRRDRD2;
13731 struct {
13732 unsigned int op : 16;
13733 unsigned int b1 : 4;
13734 unsigned int d1 : 12;
13735 unsigned int b2 : 4;
13736 unsigned int d2 : 12;
13737 } SSE;
13738 struct {
13739 unsigned int op1 : 8;
13740 unsigned int r3 : 4;
13741 unsigned int op2 : 4;
13742 unsigned int b1 : 4;
13743 unsigned int d1 : 12;
13744 unsigned int b2 : 4;
13745 unsigned int d2 : 12;
13746 } SSF;
13747 struct {
13748 unsigned int op : 16;
13749 unsigned int b1 : 4;
13750 unsigned int d1 : 12;
13751 unsigned int i2 : 16;
13752 } SIL;
13753 } formats;
13754 union {
13755 formats fmt;
13756 ULong value;
13757 } ovl;
13758
13759 vassert(sizeof(formats) == 6);
13760
13761 ((char *)(&ovl.value))[0] = bytes[0];
13762 ((char *)(&ovl.value))[1] = bytes[1];
13763 ((char *)(&ovl.value))[2] = bytes[2];
13764 ((char *)(&ovl.value))[3] = bytes[3];
13765 ((char *)(&ovl.value))[4] = bytes[4];
13766 ((char *)(&ovl.value))[5] = bytes[5];
13767 ((char *)(&ovl.value))[6] = 0x0;
13768 ((char *)(&ovl.value))[7] = 0x0;
13769
13770 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13771 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13772 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13773 ovl.fmt.RXY.dl2,
13774 ovl.fmt.RXY.dh2); goto ok;
13775 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13776 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13777 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13778 ovl.fmt.RXY.dl2,
13779 ovl.fmt.RXY.dh2); goto ok;
13780 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13781 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13782 ovl.fmt.RXY.dl2,
13783 ovl.fmt.RXY.dh2); goto ok;
13784 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13785 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13786 ovl.fmt.RXY.dl2,
13787 ovl.fmt.RXY.dh2); goto ok;
13788 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13789 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13790 ovl.fmt.RXY.dl2,
13791 ovl.fmt.RXY.dh2); goto ok;
13792 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13793 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13794 ovl.fmt.RXY.dl2,
13795 ovl.fmt.RXY.dh2); goto ok;
13796 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13797 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13798 ovl.fmt.RXY.dl2,
13799 ovl.fmt.RXY.dh2); goto ok;
13800 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13801 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13802 ovl.fmt.RXY.dl2,
13803 ovl.fmt.RXY.dh2); goto ok;
13804 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13805 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13806 ovl.fmt.RXY.dl2,
13807 ovl.fmt.RXY.dh2); goto ok;
13808 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13809 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13810 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13811 ovl.fmt.RXY.dl2,
13812 ovl.fmt.RXY.dh2); goto ok;
13813 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13814 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13815 ovl.fmt.RXY.dl2,
13816 ovl.fmt.RXY.dh2); goto ok;
13817 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13818 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13819 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13820 ovl.fmt.RXY.dl2,
13821 ovl.fmt.RXY.dh2); goto ok;
13822 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13823 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13824 ovl.fmt.RXY.dl2,
13825 ovl.fmt.RXY.dh2); goto ok;
13826 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13827 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13828 ovl.fmt.RXY.dl2,
13829 ovl.fmt.RXY.dh2); goto ok;
13830 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13831 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13832 ovl.fmt.RXY.dl2,
13833 ovl.fmt.RXY.dh2); goto ok;
13834 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13835 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13836 ovl.fmt.RXY.dl2,
13837 ovl.fmt.RXY.dh2); goto ok;
13838 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13839 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13840 ovl.fmt.RXY.dl2,
13841 ovl.fmt.RXY.dh2); goto ok;
13842 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13843 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13844 ovl.fmt.RXY.dl2,
13845 ovl.fmt.RXY.dh2); goto ok;
13846 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13847 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13848 ovl.fmt.RXY.dl2,
13849 ovl.fmt.RXY.dh2); goto ok;
13850 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13851 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13852 ovl.fmt.RXY.dl2,
13853 ovl.fmt.RXY.dh2); goto ok;
13854 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13855 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13856 ovl.fmt.RXY.dl2,
13857 ovl.fmt.RXY.dh2); goto ok;
13858 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13859 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13860 ovl.fmt.RXY.dl2,
13861 ovl.fmt.RXY.dh2); goto ok;
13862 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13863 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13864 ovl.fmt.RXY.dl2,
13865 ovl.fmt.RXY.dh2); goto ok;
13866 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13867 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13868 ovl.fmt.RXY.dl2,
13869 ovl.fmt.RXY.dh2); goto ok;
13870 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13871 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13872 ovl.fmt.RXY.dl2,
13873 ovl.fmt.RXY.dh2); goto ok;
13874 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13875 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13876 ovl.fmt.RXY.dl2,
13877 ovl.fmt.RXY.dh2); goto ok;
13878 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13879 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13880 ovl.fmt.RXY.dl2,
13881 ovl.fmt.RXY.dh2); goto ok;
13882 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13883 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13884 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13885 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13886 ovl.fmt.RXY.dh2); goto ok;
13887 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13888 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13889 ovl.fmt.RXY.dl2,
13890 ovl.fmt.RXY.dh2); goto ok;
13891 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13892 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13893 ovl.fmt.RXY.dl2,
13894 ovl.fmt.RXY.dh2); goto ok;
13895 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13896 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13897 ovl.fmt.RXY.dl2,
13898 ovl.fmt.RXY.dh2); goto ok;
13899 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13900 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13901 ovl.fmt.RXY.dl2,
13902 ovl.fmt.RXY.dh2); goto ok;
13903 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13904 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13905 ovl.fmt.RXY.dl2,
13906 ovl.fmt.RXY.dh2); goto ok;
13907 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13908 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13909 ovl.fmt.RXY.dl2,
13910 ovl.fmt.RXY.dh2); goto ok;
13911 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13912 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13913 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13914 ovl.fmt.RXY.dh2); goto ok;
13915 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13916 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13917 ovl.fmt.RXY.dl2,
13918 ovl.fmt.RXY.dh2); goto ok;
13919 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13920 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13921 ovl.fmt.RXY.dl2,
13922 ovl.fmt.RXY.dh2); goto ok;
13923 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13924 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13925 ovl.fmt.RXY.dl2,
13926 ovl.fmt.RXY.dh2); goto ok;
13927 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13928 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13929 ovl.fmt.RXY.dl2,
13930 ovl.fmt.RXY.dh2); goto ok;
13931 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13932 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13933 ovl.fmt.RXY.dl2,
13934 ovl.fmt.RXY.dh2); goto ok;
13935 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13936 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13937 ovl.fmt.RXY.dl2,
13938 ovl.fmt.RXY.dh2); goto ok;
13939 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13940 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13941 ovl.fmt.RXY.dl2,
13942 ovl.fmt.RXY.dh2); goto ok;
13943 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13944 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13945 ovl.fmt.RXY.dl2,
13946 ovl.fmt.RXY.dh2); goto ok;
13947 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13948 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13949 ovl.fmt.RXY.dl2,
13950 ovl.fmt.RXY.dh2); goto ok;
13951 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13952 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13953 ovl.fmt.RXY.dl2,
13954 ovl.fmt.RXY.dh2); goto ok;
13955 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13956 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13957 ovl.fmt.RXY.dl2,
13958 ovl.fmt.RXY.dh2); goto ok;
13959 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13960 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13961 ovl.fmt.RXY.dl2,
13962 ovl.fmt.RXY.dh2); goto ok;
13963 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13964 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13965 ovl.fmt.RXY.dl2,
13966 ovl.fmt.RXY.dh2); goto ok;
13967 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13968 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13969 ovl.fmt.RXY.dl2,
13970 ovl.fmt.RXY.dh2); goto ok;
13971 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13972 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13973 ovl.fmt.RXY.dl2,
13974 ovl.fmt.RXY.dh2); goto ok;
13975 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13976 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13977 ovl.fmt.RXY.dl2,
13978 ovl.fmt.RXY.dh2); goto ok;
13979 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13980 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13981 ovl.fmt.RXY.dl2,
13982 ovl.fmt.RXY.dh2); goto ok;
13983 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13984 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13985 ovl.fmt.RXY.dl2,
13986 ovl.fmt.RXY.dh2); goto ok;
13987 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13988 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13989 ovl.fmt.RXY.dl2,
13990 ovl.fmt.RXY.dh2); goto ok;
13991 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13992 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13993 ovl.fmt.RXY.dl2,
13994 ovl.fmt.RXY.dh2); goto ok;
13995 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13996 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13997 ovl.fmt.RXY.dl2,
13998 ovl.fmt.RXY.dh2); goto ok;
13999 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14000 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14001 ovl.fmt.RXY.dl2,
14002 ovl.fmt.RXY.dh2); goto ok;
14003 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14004 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14005 ovl.fmt.RXY.dl2,
14006 ovl.fmt.RXY.dh2); goto ok;
14007 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14008 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14009 ovl.fmt.RXY.dl2,
14010 ovl.fmt.RXY.dh2); goto ok;
14011 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14012 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14013 ovl.fmt.RXY.dl2,
14014 ovl.fmt.RXY.dh2); goto ok;
14015 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14016 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14017 ovl.fmt.RXY.dl2,
14018 ovl.fmt.RXY.dh2); goto ok;
14019 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14020 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14021 ovl.fmt.RXY.dl2,
14022 ovl.fmt.RXY.dh2); goto ok;
14023 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14024 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14025 ovl.fmt.RXY.dl2,
14026 ovl.fmt.RXY.dh2); goto ok;
14027 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14028 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14029 ovl.fmt.RXY.dl2,
14030 ovl.fmt.RXY.dh2); goto ok;
14031 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14032 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14033 ovl.fmt.RXY.dl2,
14034 ovl.fmt.RXY.dh2); goto ok;
14035 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14036 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14037 ovl.fmt.RXY.dl2,
14038 ovl.fmt.RXY.dh2); goto ok;
14039 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14040 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14041 ovl.fmt.RXY.dl2,
14042 ovl.fmt.RXY.dh2); goto ok;
14043 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14044 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14045 ovl.fmt.RXY.dl2,
14046 ovl.fmt.RXY.dh2); goto ok;
14047 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14048 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14049 ovl.fmt.RXY.dl2,
14050 ovl.fmt.RXY.dh2); goto ok;
14051 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14052 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14053 ovl.fmt.RXY.dl2,
14054 ovl.fmt.RXY.dh2); goto ok;
14055 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14056 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14057 ovl.fmt.RXY.dl2,
14058 ovl.fmt.RXY.dh2); goto ok;
14059 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14060 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14061 ovl.fmt.RXY.dl2,
14062 ovl.fmt.RXY.dh2); goto ok;
14063 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14064 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14065 ovl.fmt.RXY.dl2,
14066 ovl.fmt.RXY.dh2); goto ok;
14067 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14068 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14069 ovl.fmt.RXY.dl2,
14070 ovl.fmt.RXY.dh2); goto ok;
14071 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14072 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14073 ovl.fmt.RXY.dl2,
14074 ovl.fmt.RXY.dh2); goto ok;
14075 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14076 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14077 ovl.fmt.RXY.dl2,
14078 ovl.fmt.RXY.dh2); goto ok;
14079 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14080 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14081 ovl.fmt.RXY.dl2,
14082 ovl.fmt.RXY.dh2); goto ok;
14083 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14084 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14085 ovl.fmt.RXY.dl2,
14086 ovl.fmt.RXY.dh2); goto ok;
14087 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14088 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14089 ovl.fmt.RXY.dl2,
14090 ovl.fmt.RXY.dh2); goto ok;
14091 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14092 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14093 ovl.fmt.RXY.dl2,
14094 ovl.fmt.RXY.dh2); goto ok;
14095 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14096 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14097 ovl.fmt.RXY.dl2,
14098 ovl.fmt.RXY.dh2); goto ok;
14099 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14100 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14101 ovl.fmt.RXY.dl2,
14102 ovl.fmt.RXY.dh2); goto ok;
14103 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14104 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14105 ovl.fmt.RXY.dl2,
14106 ovl.fmt.RXY.dh2); goto ok;
14107 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14108 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14109 ovl.fmt.RXY.dl2,
14110 ovl.fmt.RXY.dh2); goto ok;
14111 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14112 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14113 ovl.fmt.RXY.dl2,
14114 ovl.fmt.RXY.dh2); goto ok;
14115 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14116 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14117 ovl.fmt.RXY.dl2,
14118 ovl.fmt.RXY.dh2); goto ok;
14119 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14120 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14121 ovl.fmt.RXY.dl2,
14122 ovl.fmt.RXY.dh2); goto ok;
14123 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14124 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14125 ovl.fmt.RXY.dl2,
14126 ovl.fmt.RXY.dh2); goto ok;
14127 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14128 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14129 ovl.fmt.RSY.dl2,
14130 ovl.fmt.RSY.dh2); goto ok;
14131 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14132 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14133 ovl.fmt.RSY.dl2,
14134 ovl.fmt.RSY.dh2); goto ok;
14135 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14136 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14137 ovl.fmt.RSY.dl2,
14138 ovl.fmt.RSY.dh2); goto ok;
14139 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14140 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14141 ovl.fmt.RSY.dl2,
14142 ovl.fmt.RSY.dh2); goto ok;
14143 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14144 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14145 ovl.fmt.RSY.dl2,
14146 ovl.fmt.RSY.dh2); goto ok;
14147 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14148 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14149 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14150 ovl.fmt.RSY.dl2,
14151 ovl.fmt.RSY.dh2); goto ok;
14152 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14153 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14154 ovl.fmt.RSY.dl2,
14155 ovl.fmt.RSY.dh2); goto ok;
14156 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14157 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14158 ovl.fmt.RSY.dl2,
14159 ovl.fmt.RSY.dh2); goto ok;
14160 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14161 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14162 ovl.fmt.RSY.dl2,
14163 ovl.fmt.RSY.dh2); goto ok;
14164 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14165 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14166 ovl.fmt.RSY.dl2,
14167 ovl.fmt.RSY.dh2); goto ok;
14168 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14169 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14170 ovl.fmt.RSY.dl2,
14171 ovl.fmt.RSY.dh2); goto ok;
14172 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14173 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14174 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14175 ovl.fmt.RSY.dl2,
14176 ovl.fmt.RSY.dh2); goto ok;
14177 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14178 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14179 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14180 ovl.fmt.RSY.dh2); goto ok;
14181 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14182 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14183 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14184 ovl.fmt.RSY.dh2); goto ok;
14185 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14186 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14187 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14188 ovl.fmt.RSY.dl2,
14189 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014190 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14191 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14192 ovl.fmt.RSY.dl2,
14193 ovl.fmt.RSY.dh2); goto ok;
14194 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14195 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14196 ovl.fmt.RSY.dl2,
14197 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014198 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14199 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14200 ovl.fmt.RSY.dl2,
14201 ovl.fmt.RSY.dh2); goto ok;
14202 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14203 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14204 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14205 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014206 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14207 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14208 ovl.fmt.RSY.dl2,
14209 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014210 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14211 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14212 ovl.fmt.SIY.dh1); goto ok;
14213 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14214 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14215 ovl.fmt.SIY.dh1); goto ok;
14216 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14217 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14218 ovl.fmt.SIY.dh1); goto ok;
14219 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14220 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14221 ovl.fmt.SIY.dh1); goto ok;
14222 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14223 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14224 ovl.fmt.SIY.dh1); goto ok;
14225 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14226 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14227 ovl.fmt.SIY.dh1); goto ok;
14228 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14229 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14230 ovl.fmt.SIY.dh1); goto ok;
14231 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14232 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14233 ovl.fmt.SIY.dh1); goto ok;
14234 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14235 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14236 ovl.fmt.SIY.dh1); goto ok;
14237 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14238 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14239 ovl.fmt.SIY.dh1); goto ok;
14240 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14241 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14242 ovl.fmt.RSY.dl2,
14243 ovl.fmt.RSY.dh2); goto ok;
14244 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14245 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14246 ovl.fmt.RSY.dl2,
14247 ovl.fmt.RSY.dh2); goto ok;
14248 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14249 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14250 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14251 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14252 ovl.fmt.RSY.dl2,
14253 ovl.fmt.RSY.dh2); goto ok;
14254 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14255 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14256 ovl.fmt.RSY.dl2,
14257 ovl.fmt.RSY.dh2); goto ok;
14258 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14259 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14260 ovl.fmt.RSY.dl2,
14261 ovl.fmt.RSY.dh2); goto ok;
14262 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14263 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14264 ovl.fmt.RSY.dl2,
14265 ovl.fmt.RSY.dh2); goto ok;
14266 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14267 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14268 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14269 ovl.fmt.RSY.dh2); goto ok;
14270 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14271 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14272 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14273 ovl.fmt.RSY.dl2,
14274 ovl.fmt.RSY.dh2); goto ok;
14275 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14276 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14277 ovl.fmt.RSY.dl2,
14278 ovl.fmt.RSY.dh2); goto ok;
14279 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14280 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14281 ovl.fmt.RSY.dl2,
14282 ovl.fmt.RSY.dh2); goto ok;
14283 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14284 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14285 ovl.fmt.RSY.dl2,
14286 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014287 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14288 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14289 ovl.fmt.RSY.dl2,
14290 ovl.fmt.RSY.dh2,
14291 S390_XMNM_LOCG); goto ok;
14292 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14293 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14294 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14295 ovl.fmt.RSY.dh2,
14296 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014297 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14298 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14299 ovl.fmt.RSY.dl2,
14300 ovl.fmt.RSY.dh2); goto ok;
14301 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14302 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14303 ovl.fmt.RSY.dl2,
14304 ovl.fmt.RSY.dh2); goto ok;
14305 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14306 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14307 ovl.fmt.RSY.dl2,
14308 ovl.fmt.RSY.dh2); goto ok;
14309 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14310 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14311 ovl.fmt.RSY.dl2,
14312 ovl.fmt.RSY.dh2); goto ok;
14313 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14314 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14315 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14316 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014317 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14318 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14319 ovl.fmt.RSY.dl2,
14320 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14321 goto ok;
14322 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14323 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14324 ovl.fmt.RSY.dl2,
14325 ovl.fmt.RSY.dh2,
14326 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014327 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14328 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14329 ovl.fmt.RSY.dl2,
14330 ovl.fmt.RSY.dh2); goto ok;
14331 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14332 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14333 ovl.fmt.RSY.dl2,
14334 ovl.fmt.RSY.dh2); goto ok;
14335 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14336 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14337 ovl.fmt.RSY.dl2,
14338 ovl.fmt.RSY.dh2); goto ok;
14339 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14340 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14341 ovl.fmt.RSY.dl2,
14342 ovl.fmt.RSY.dh2); goto ok;
14343 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14344 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14345 ovl.fmt.RSY.dl2,
14346 ovl.fmt.RSY.dh2); goto ok;
14347 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14348 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14349 goto ok;
14350 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14351 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14352 goto ok;
14353 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14354 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14355 ovl.fmt.RIE_RRUUU.r1,
14356 ovl.fmt.RIE_RRUUU.r2,
14357 ovl.fmt.RIE_RRUUU.i3,
14358 ovl.fmt.RIE_RRUUU.i4,
14359 ovl.fmt.RIE_RRUUU.i5);
14360 goto ok;
14361 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14362 ovl.fmt.RIE_RRUUU.r1,
14363 ovl.fmt.RIE_RRUUU.r2,
14364 ovl.fmt.RIE_RRUUU.i3,
14365 ovl.fmt.RIE_RRUUU.i4,
14366 ovl.fmt.RIE_RRUUU.i5);
14367 goto ok;
14368 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14369 ovl.fmt.RIE_RRUUU.r1,
14370 ovl.fmt.RIE_RRUUU.r2,
14371 ovl.fmt.RIE_RRUUU.i3,
14372 ovl.fmt.RIE_RRUUU.i4,
14373 ovl.fmt.RIE_RRUUU.i5);
14374 goto ok;
14375 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14376 ovl.fmt.RIE_RRUUU.r1,
14377 ovl.fmt.RIE_RRUUU.r2,
14378 ovl.fmt.RIE_RRUUU.i3,
14379 ovl.fmt.RIE_RRUUU.i4,
14380 ovl.fmt.RIE_RRUUU.i5);
14381 goto ok;
14382 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14383 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14384 ovl.fmt.RIE_RRPU.r1,
14385 ovl.fmt.RIE_RRPU.r2,
14386 ovl.fmt.RIE_RRPU.i4,
14387 ovl.fmt.RIE_RRPU.m3); goto ok;
14388 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14389 ovl.fmt.RIE_RRPU.r1,
14390 ovl.fmt.RIE_RRPU.r2,
14391 ovl.fmt.RIE_RRPU.i4,
14392 ovl.fmt.RIE_RRPU.m3); goto ok;
14393 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14394 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14395 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14396 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14397 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14398 ovl.fmt.RIE_RRPU.r1,
14399 ovl.fmt.RIE_RRPU.r2,
14400 ovl.fmt.RIE_RRPU.i4,
14401 ovl.fmt.RIE_RRPU.m3); goto ok;
14402 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14403 ovl.fmt.RIE_RRPU.r1,
14404 ovl.fmt.RIE_RRPU.r2,
14405 ovl.fmt.RIE_RRPU.i4,
14406 ovl.fmt.RIE_RRPU.m3); goto ok;
14407 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14408 ovl.fmt.RIEv3.r1,
14409 ovl.fmt.RIEv3.m3,
14410 ovl.fmt.RIEv3.i4,
14411 ovl.fmt.RIEv3.i2); goto ok;
14412 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14413 ovl.fmt.RIEv3.r1,
14414 ovl.fmt.RIEv3.m3,
14415 ovl.fmt.RIEv3.i4,
14416 ovl.fmt.RIEv3.i2); goto ok;
14417 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14418 ovl.fmt.RIEv3.r1,
14419 ovl.fmt.RIEv3.m3,
14420 ovl.fmt.RIEv3.i4,
14421 ovl.fmt.RIEv3.i2); goto ok;
14422 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14423 ovl.fmt.RIEv3.r1,
14424 ovl.fmt.RIEv3.m3,
14425 ovl.fmt.RIEv3.i4,
14426 ovl.fmt.RIEv3.i2); goto ok;
14427 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14428 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14429 goto ok;
14430 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14431 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14432 ovl.fmt.RIE.i2); goto ok;
14433 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14434 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14435 ovl.fmt.RIE.i2); goto ok;
14436 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14437 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14438 ovl.fmt.RIE.i2); goto ok;
14439 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14440 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14441 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14442 goto ok;
14443 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14444 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14445 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14446 goto ok;
14447 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14448 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14449 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14450 goto ok;
14451 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14452 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14453 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14454 goto ok;
14455 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14456 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14457 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14458 ovl.fmt.RIS.i2); goto ok;
14459 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14460 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14461 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14462 ovl.fmt.RIS.i2); goto ok;
14463 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14464 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14465 ovl.fmt.RIS.d4,
14466 ovl.fmt.RIS.i2); goto ok;
14467 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14468 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14469 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14470 ovl.fmt.RIS.i2); goto ok;
14471 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14472 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14473 ovl.fmt.RXE.d2); goto ok;
14474 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14475 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14476 ovl.fmt.RXE.d2); goto ok;
14477 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14478 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14479 ovl.fmt.RXE.d2); goto ok;
14480 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14481 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14482 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14483 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14484 ovl.fmt.RXE.d2); goto ok;
14485 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14486 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14487 ovl.fmt.RXE.d2); goto ok;
14488 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14489 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14490 ovl.fmt.RXE.d2); goto ok;
14491 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14492 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14493 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14494 ovl.fmt.RXE.d2); goto ok;
14495 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14496 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14497 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14498 ovl.fmt.RXF.r1); goto ok;
14499 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14500 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14501 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14502 ovl.fmt.RXF.r1); goto ok;
14503 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14504 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14505 ovl.fmt.RXE.d2); goto ok;
14506 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14507 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14508 ovl.fmt.RXE.d2); goto ok;
14509 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14510 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14511 ovl.fmt.RXE.d2); goto ok;
14512 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14513 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14514 ovl.fmt.RXE.d2); goto ok;
14515 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14516 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14517 ovl.fmt.RXE.d2); goto ok;
14518 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14519 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14520 ovl.fmt.RXE.d2); goto ok;
14521 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14522 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14523 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14524 ovl.fmt.RXE.d2); goto ok;
14525 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14526 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14527 ovl.fmt.RXE.d2); goto ok;
14528 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14529 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14530 ovl.fmt.RXE.d2); goto ok;
14531 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14532 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14533 ovl.fmt.RXE.d2); goto ok;
14534 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14535 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14536 ovl.fmt.RXE.d2); goto ok;
14537 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14538 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14539 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14540 ovl.fmt.RXF.r1); goto ok;
14541 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14542 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14543 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14544 ovl.fmt.RXF.r1); goto ok;
14545 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14546 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14547 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14548 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14549 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14550 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14551 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14552 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14553 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14554 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14555 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14556 case 0xed000000003bULL: /* MY */ goto unimplemented;
14557 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14558 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14559 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14560 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14561 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14562 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14563 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14564 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14565 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14566 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14567 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14568 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14569 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14570 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14571 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14572 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14573 ovl.fmt.RXY.dl2,
14574 ovl.fmt.RXY.dh2); goto ok;
14575 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14576 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14577 ovl.fmt.RXY.dl2,
14578 ovl.fmt.RXY.dh2); goto ok;
14579 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14580 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14581 ovl.fmt.RXY.dl2,
14582 ovl.fmt.RXY.dh2); goto ok;
14583 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14584 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14585 ovl.fmt.RXY.dl2,
14586 ovl.fmt.RXY.dh2); goto ok;
14587 }
14588
14589 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14590 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14591 ovl.fmt.RIL.i2); goto ok;
14592 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14593 ovl.fmt.RIL.i2); goto ok;
14594 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14595 ovl.fmt.RIL.i2); goto ok;
14596 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14597 ovl.fmt.RIL.i2); goto ok;
14598 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14599 ovl.fmt.RIL.i2); goto ok;
14600 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14601 ovl.fmt.RIL.i2); goto ok;
14602 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14603 ovl.fmt.RIL.i2); goto ok;
14604 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14605 ovl.fmt.RIL.i2); goto ok;
14606 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14607 ovl.fmt.RIL.i2); goto ok;
14608 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14609 ovl.fmt.RIL.i2); goto ok;
14610 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14611 ovl.fmt.RIL.i2); goto ok;
14612 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14613 ovl.fmt.RIL.i2); goto ok;
14614 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14615 ovl.fmt.RIL.i2); goto ok;
14616 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14617 ovl.fmt.RIL.i2); goto ok;
14618 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14619 ovl.fmt.RIL.i2); goto ok;
14620 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14621 ovl.fmt.RIL.i2); goto ok;
14622 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14623 ovl.fmt.RIL.i2); goto ok;
14624 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14625 ovl.fmt.RIL.i2); goto ok;
14626 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14627 ovl.fmt.RIL.i2); goto ok;
14628 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14629 ovl.fmt.RIL.i2); goto ok;
14630 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14631 ovl.fmt.RIL.i2); goto ok;
14632 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14633 ovl.fmt.RIL.i2); goto ok;
14634 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14635 ovl.fmt.RIL.i2); goto ok;
14636 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14637 ovl.fmt.RIL.i2); goto ok;
14638 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14639 ovl.fmt.RIL.i2); goto ok;
14640 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14641 ovl.fmt.RIL.i2); goto ok;
14642 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14643 ovl.fmt.RIL.i2); goto ok;
14644 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14645 ovl.fmt.RIL.i2); goto ok;
14646 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14647 ovl.fmt.RIL.i2); goto ok;
14648 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14649 ovl.fmt.RIL.i2); goto ok;
14650 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14651 ovl.fmt.RIL.i2); goto ok;
14652 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14653 ovl.fmt.RIL.i2); goto ok;
14654 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14655 ovl.fmt.RIL.i2); goto ok;
14656 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14657 ovl.fmt.RIL.i2); goto ok;
14658 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14659 ovl.fmt.RIL.i2); goto ok;
14660 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14661 ovl.fmt.RIL.i2); goto ok;
14662 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14663 ovl.fmt.RIL.i2); goto ok;
14664 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14665 ovl.fmt.RIL.i2); goto ok;
14666 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14667 ovl.fmt.RIL.i2); goto ok;
14668 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14669 ovl.fmt.RIL.i2); goto ok;
14670 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14671 ovl.fmt.RIL.i2); goto ok;
14672 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14673 ovl.fmt.RIL.i2); goto ok;
14674 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14675 ovl.fmt.RIL.i2); goto ok;
14676 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14677 ovl.fmt.RIL.i2); goto ok;
14678 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14679 ovl.fmt.RIL.i2); goto ok;
14680 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14681 ovl.fmt.RIL.i2); goto ok;
14682 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14683 ovl.fmt.RIL.i2); goto ok;
14684 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14685 ovl.fmt.RIL.i2); goto ok;
14686 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14687 ovl.fmt.RIL.i2); goto ok;
14688 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14689 case 0xc801ULL: /* ECTG */ goto unimplemented;
14690 case 0xc802ULL: /* CSST */ goto unimplemented;
14691 case 0xc804ULL: /* LPD */ goto unimplemented;
14692 case 0xc805ULL: /* LPDG */ goto unimplemented;
14693 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14694 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14695 ovl.fmt.RIL.i2); goto ok;
14696 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14697 ovl.fmt.RIL.i2); goto ok;
14698 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14699 ovl.fmt.RIL.i2); goto ok;
14700 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14701 ovl.fmt.RIL.i2); goto ok;
14702 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14703 ovl.fmt.RIL.i2); goto ok;
14704 }
14705
14706 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14707 case 0xd0ULL: /* TRTR */ goto unimplemented;
14708 case 0xd1ULL: /* MVN */ goto unimplemented;
14709 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14710 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14711 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14712 case 0xd3ULL: /* MVZ */ goto unimplemented;
14713 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14714 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14715 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14716 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14717 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14718 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14719 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14720 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14721 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014722 case 0xd7ULL:
14723 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14724 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14725 else
14726 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14727 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14728 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14729 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014730 case 0xd9ULL: /* MVCK */ goto unimplemented;
14731 case 0xdaULL: /* MVCP */ goto unimplemented;
14732 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014733 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14734 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14735 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014736 case 0xddULL: /* TRT */ goto unimplemented;
14737 case 0xdeULL: /* ED */ goto unimplemented;
14738 case 0xdfULL: /* EDMK */ goto unimplemented;
14739 case 0xe1ULL: /* PKU */ goto unimplemented;
14740 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14741 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14742 case 0xe9ULL: /* PKA */ goto unimplemented;
14743 case 0xeaULL: /* UNPKA */ goto unimplemented;
14744 case 0xeeULL: /* PLO */ goto unimplemented;
14745 case 0xefULL: /* LMD */ goto unimplemented;
14746 case 0xf0ULL: /* SRP */ goto unimplemented;
14747 case 0xf1ULL: /* MVO */ goto unimplemented;
14748 case 0xf2ULL: /* PACK */ goto unimplemented;
14749 case 0xf3ULL: /* UNPK */ goto unimplemented;
14750 case 0xf8ULL: /* ZAP */ goto unimplemented;
14751 case 0xf9ULL: /* CP */ goto unimplemented;
14752 case 0xfaULL: /* AP */ goto unimplemented;
14753 case 0xfbULL: /* SP */ goto unimplemented;
14754 case 0xfcULL: /* MP */ goto unimplemented;
14755 case 0xfdULL: /* DP */ goto unimplemented;
14756 }
14757
14758 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14759 case 0xe500ULL: /* LASP */ goto unimplemented;
14760 case 0xe501ULL: /* TPROT */ goto unimplemented;
14761 case 0xe502ULL: /* STRAG */ goto unimplemented;
14762 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14763 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14764 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14765 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14766 goto ok;
14767 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14768 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14769 goto ok;
14770 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14771 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14772 goto ok;
14773 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14774 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14775 goto ok;
14776 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14777 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14778 goto ok;
14779 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14780 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14781 goto ok;
14782 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14783 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14784 goto ok;
14785 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14786 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14787 goto ok;
14788 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14789 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14790 goto ok;
14791 }
14792
14793 return S390_DECODE_UNKNOWN_INSN;
14794
14795ok:
14796 return S390_DECODE_OK;
14797
14798unimplemented:
14799 return S390_DECODE_UNIMPLEMENTED_INSN;
14800}
14801
14802/* Handle "special" instructions. */
14803static s390_decode_t
14804s390_decode_special_and_irgen(UChar *bytes)
14805{
14806 s390_decode_t status = S390_DECODE_OK;
14807
14808 /* Got a "Special" instruction preamble. Which one is it? */
14809 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14810 s390_irgen_client_request();
14811 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14812 s390_irgen_guest_NRADDR();
14813 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14814 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014815 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14816 vex_inject_ir(irsb, Iend_BE);
14817
14818 /* Invalidate the current insn. The reason is that the IRop we're
14819 injecting here can change. In which case the translation has to
14820 be redone. For ease of handling, we simply invalidate all the
14821 time. */
14822 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14823 mkU64(guest_IA_curr_instr)));
14824 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14825 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14826 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14827 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14828
14829 put_IA(mkaddr_expr(guest_IA_next_instr));
14830 dis_res->whatNext = Dis_StopHere;
14831 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014832 } else {
14833 /* We don't know what it is. */
14834 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14835 }
14836
14837 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14838
14839 return status;
14840}
14841
14842
14843/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014844static UInt
sewardj2019a972011-03-07 16:04:07 +000014845s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14846{
14847 s390_decode_t status;
14848
14849 dis_res = dres;
14850
14851 /* Spot the 8-byte preamble: 18ff lr r15,r15
14852 1811 lr r1,r1
14853 1822 lr r2,r2
14854 1833 lr r3,r3 */
14855 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14856 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14857 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14858
14859 /* Handle special instruction that follows that preamble. */
14860 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014861
14862 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14863 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14864
14865 status =
14866 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014867 } else {
14868 /* Handle normal instructions. */
14869 switch (insn_length) {
14870 case 2:
14871 status = s390_decode_2byte_and_irgen(bytes);
14872 break;
14873
14874 case 4:
14875 status = s390_decode_4byte_and_irgen(bytes);
14876 break;
14877
14878 case 6:
14879 status = s390_decode_6byte_and_irgen(bytes);
14880 break;
14881
14882 default:
14883 status = S390_DECODE_ERROR;
14884 break;
14885 }
14886 }
florian5fcbba22011-07-27 20:40:22 +000014887 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014888 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14889 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014890 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014891 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014892 }
14893
14894 if (status == S390_DECODE_OK) return insn_length; /* OK */
14895
14896 /* Decoding failed somehow */
14897 vex_printf("vex s390->IR: ");
14898 switch (status) {
14899 case S390_DECODE_UNKNOWN_INSN:
14900 vex_printf("unknown insn: ");
14901 break;
14902
14903 case S390_DECODE_UNIMPLEMENTED_INSN:
14904 vex_printf("unimplemented insn: ");
14905 break;
14906
14907 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14908 vex_printf("unimplemented special insn: ");
14909 break;
14910
14911 default:
14912 case S390_DECODE_ERROR:
14913 vex_printf("decoding error: ");
14914 break;
14915 }
14916
14917 vex_printf("%02x%02x", bytes[0], bytes[1]);
14918 if (insn_length > 2) {
14919 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14920 }
14921 if (insn_length > 4) {
14922 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14923 }
14924 vex_printf("\n");
14925
14926 return 0; /* Failed */
14927}
14928
14929
sewardj2019a972011-03-07 16:04:07 +000014930/* Disassemble a single instruction INSN into IR. */
14931static DisResult
florian420c5012011-07-22 02:12:28 +000014932disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014933{
14934 UChar byte;
14935 UInt insn_length;
14936 DisResult dres;
14937
14938 /* ---------------------------------------------------- */
14939 /* --- Compute instruction length -- */
14940 /* ---------------------------------------------------- */
14941
14942 /* Get the first byte of the insn. */
14943 byte = insn[0];
14944
14945 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14946 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14947 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14948
14949 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14950
14951 /* ---------------------------------------------------- */
14952 /* --- Initialise the DisResult data -- */
14953 /* ---------------------------------------------------- */
14954 dres.whatNext = Dis_Continue;
14955 dres.len = insn_length;
14956 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014957 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014958
floriana99f20e2011-07-17 14:16:41 +000014959 /* fixs390: consider chasing of conditional jumps */
14960
sewardj2019a972011-03-07 16:04:07 +000014961 /* Normal and special instruction handling starts here. */
14962 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14963 /* All decode failures end up here. The decoder has already issued an
14964 error message.
14965 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014966 not been executed, and (is currently) the next to be executed.
14967 The insn address in the guest state needs to be set to
14968 guest_IA_curr_instr, otherwise the complaint will report an
14969 incorrect address. */
14970 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014971
florian8844a632012-04-13 04:04:06 +000014972 dres.whatNext = Dis_StopHere;
14973 dres.jk_StopHere = Ijk_NoDecode;
14974 dres.continueAt = 0;
14975 dres.len = 0;
14976 } else {
14977 /* Decode success */
14978 switch (dres.whatNext) {
14979 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014980 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014981 break;
14982 case Dis_ResteerU:
14983 case Dis_ResteerC:
14984 put_IA(mkaddr_expr(dres.continueAt));
14985 break;
14986 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000014987 if (dres.jk_StopHere == Ijk_EmWarn ||
14988 dres.jk_StopHere == Ijk_EmFail) {
14989 /* We assume here, that emulation warnings are not given for
14990 insns that transfer control. There is no good way to
14991 do that. */
14992 put_IA(mkaddr_expr(guest_IA_next_instr));
14993 }
florian8844a632012-04-13 04:04:06 +000014994 break;
14995 default:
14996 vassert(0);
14997 }
sewardj2019a972011-03-07 16:04:07 +000014998 }
14999
15000 return dres;
15001}
15002
15003
15004/*------------------------------------------------------------*/
15005/*--- Top-level fn ---*/
15006/*------------------------------------------------------------*/
15007
15008/* Disassemble a single instruction into IR. The instruction
15009 is located in host memory at &guest_code[delta]. */
15010
15011DisResult
15012disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015013 Bool (*resteerOkFn)(void *, Addr64),
15014 Bool resteerCisOk,
15015 void *callback_opaque,
15016 UChar *guest_code,
15017 Long delta,
15018 Addr64 guest_IP,
15019 VexArch guest_arch,
15020 VexArchInfo *archinfo,
15021 VexAbiInfo *abiinfo,
15022 Bool host_bigendian)
15023{
15024 vassert(guest_arch == VexArchS390X);
15025
15026 /* The instruction decoder requires a big-endian machine. */
15027 vassert(host_bigendian == True);
15028
15029 /* Set globals (see top of this file) */
15030 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015031 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015032 resteer_fn = resteerOkFn;
15033 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000015034
florian420c5012011-07-22 02:12:28 +000015035 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015036}
15037
15038/*---------------------------------------------------------------*/
15039/*--- end guest_s390_toIR.c ---*/
15040/*---------------------------------------------------------------*/