Adjust ppc set_AV_CR6 computation to help Memcheck instrumentation.
[valgrind.git] / VEX / priv / guest_s390_toIR.c
blob1c4ac390aa168e68f8e5b4c9bf254efc27d02ec5
1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*---------------------------------------------------------------*/
4 /*--- begin guest_s390_toIR.c ---*/
5 /*---------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
11 Copyright IBM Corp. 2010-2017
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.
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.
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.
28 The GNU General Public License is contained in the file COPYING.
31 /* Contributed by Florian Krohm and Christian Borntraeger */
33 /* Translates s390 code to IR. */
35 #include "libvex_basictypes.h"
36 #include "libvex_ir.h"
37 #include "libvex_emnote.h"
38 #include "libvex_s390x_common.h"
39 #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 */
43 #include "s390_disasm.h"
44 #include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45 #include "host_s390_defs.h" /* s390_host_has_xyzzy */
48 /*------------------------------------------------------------*/
49 /*--- Forward declarations ---*/
50 /*------------------------------------------------------------*/
51 static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *);
52 static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
53 static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
56 /*------------------------------------------------------------*/
57 /*--- Globals ---*/
58 /*------------------------------------------------------------*/
60 /* The IRSB* into which we're generating code. */
61 static IRSB *irsb;
63 /* The guest address for the instruction currently being
64 translated. */
65 static Addr64 guest_IA_curr_instr;
67 /* The guest address for the instruction following the current instruction. */
68 static Addr64 guest_IA_next_instr;
70 /* Result of disassembly step. */
71 static DisResult *dis_res;
73 /* Resteer function and callback data */
74 static Bool (*resteer_fn)(void *, Addr);
75 static void *resteer_data;
77 /* Whether to print diagnostics for illegal instructions. */
78 static Bool sigill_diag;
80 /* The last seen execute target instruction */
81 ULong last_execute_target;
83 /* The possible outcomes of a decoding operation */
84 typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_SPECIFICATION_EXCEPTION,
90 S390_DECODE_ERROR
91 } s390_decode_t;
94 /*------------------------------------------------------------*/
95 /*--- Helpers for constructing IR. ---*/
96 /*------------------------------------------------------------*/
98 /* Add a statement to the current irsb. */
99 static __inline__ void
100 stmt(IRStmt *st)
102 addStmtToIRSB(irsb, st);
105 /* Allocate a new temporary of the given type. */
106 static __inline__ IRTemp
107 newTemp(IRType type)
109 vassert(isPlausibleIRType(type));
111 return newIRTemp(irsb->tyenv, type);
114 /* Create an expression node for a temporary */
115 static __inline__ IRExpr *
116 mkexpr(IRTemp tmp)
118 return IRExpr_RdTmp(tmp);
121 /* Generate an expression node for an address. */
122 static __inline__ IRExpr *
123 mkaddr_expr(Addr64 addr)
125 return IRExpr_Const(IRConst_U64(addr));
128 /* Add a statement that assigns to a temporary */
129 static __inline__ void
130 assign(IRTemp dst, IRExpr *expr)
132 stmt(IRStmt_WrTmp(dst, expr));
135 /* Write an address into the guest_IA */
136 static __inline__ void
137 put_IA(IRExpr *address)
139 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
142 /* Create a temporary of the given type and assign the expression to it */
143 static __inline__ IRTemp
144 mktemp(IRType type, IRExpr *expr)
146 IRTemp temp = newTemp(type);
148 assign(temp, expr);
150 return temp;
153 /* Create a unary expression */
154 static __inline__ IRExpr *
155 unop(IROp kind, IRExpr *op)
157 return IRExpr_Unop(kind, op);
160 /* Create a binary expression */
161 static __inline__ IRExpr *
162 binop(IROp kind, IRExpr *op1, IRExpr *op2)
164 return IRExpr_Binop(kind, op1, op2);
167 /* Create a ternary expression */
168 static __inline__ IRExpr *
169 triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
171 return IRExpr_Triop(kind, op1, op2, op3);
174 /* Create a quaternary expression */
175 static __inline__ IRExpr *
176 qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
178 return IRExpr_Qop(kind, op1, op2, op3, op4);
181 /* Create an expression node for an 8-bit integer constant */
182 static __inline__ IRExpr *
183 mkU8(UInt value)
185 vassert(value < 256);
187 return IRExpr_Const(IRConst_U8((UChar)value));
190 /* Create an expression node for a 16-bit integer constant */
191 static __inline__ IRExpr *
192 mkU16(UInt value)
194 vassert(value < 65536);
196 return IRExpr_Const(IRConst_U16((UShort)value));
199 /* Create an expression node for a 32-bit integer constant */
200 static __inline__ IRExpr *
201 mkU32(UInt value)
203 return IRExpr_Const(IRConst_U32(value));
206 /* Create an expression node for a 64-bit integer constant */
207 static __inline__ IRExpr *
208 mkU64(ULong value)
210 return IRExpr_Const(IRConst_U64(value));
213 /* Create an expression node for a 32-bit floating point constant
214 whose value is given by a bit pattern. */
215 static __inline__ IRExpr *
216 mkF32i(UInt value)
218 return IRExpr_Const(IRConst_F32i(value));
221 /* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223 static __inline__ IRExpr *
224 mkF64i(ULong value)
226 return IRExpr_Const(IRConst_F64i(value));
229 /* Little helper function for my sanity. ITE = if-then-else */
230 static IRExpr *
231 mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
233 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
235 return IRExpr_ITE(condition, iftrue, iffalse);
238 /* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
239 static __inline__ void
240 store(IRExpr *addr, IRExpr *data)
242 stmt(IRStmt_Store(Iend_BE, addr, data));
245 /* Create an expression that loads a TYPE sized value from ADDR.
246 This is a big-endian machine. */
247 static __inline__ IRExpr *
248 load(IRType type, IRExpr *addr)
250 return IRExpr_Load(Iend_BE, type, addr);
253 /* Function call */
254 static void
255 call_function(IRExpr *callee_address)
257 put_IA(callee_address);
259 dis_res->whatNext = Dis_StopHere;
260 dis_res->jk_StopHere = Ijk_Call;
263 /* Function call with known target. */
264 static void
265 call_function_and_chase(Addr64 callee_address)
267 if (resteer_fn(resteer_data, callee_address)) {
268 dis_res->whatNext = Dis_ResteerU;
269 dis_res->continueAt = callee_address;
270 } else {
271 put_IA(mkaddr_expr(callee_address));
273 dis_res->whatNext = Dis_StopHere;
274 dis_res->jk_StopHere = Ijk_Call;
278 /* Function return sequence */
279 static void
280 return_from_function(IRExpr *return_address)
282 put_IA(return_address);
284 dis_res->whatNext = Dis_StopHere;
285 dis_res->jk_StopHere = Ijk_Ret;
288 /* A conditional branch whose target is not known at instrumentation time.
290 if (condition) goto computed_target;
292 Needs to be represented as:
294 if (! condition) goto next_instruction;
295 goto computed_target;
297 static void
298 if_condition_goto_computed(IRExpr *condition, IRExpr *target)
300 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
302 condition = unop(Iop_Not1, condition);
304 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
305 S390X_GUEST_OFFSET(guest_IA)));
307 put_IA(target);
309 dis_res->whatNext = Dis_StopHere;
310 dis_res->jk_StopHere = Ijk_Boring;
313 /* A conditional branch whose target is known at instrumentation time. */
314 static void
315 if_condition_goto(IRExpr *condition, Addr64 target)
317 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
319 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
320 S390X_GUEST_OFFSET(guest_IA)));
322 put_IA(mkaddr_expr(guest_IA_next_instr));
324 dis_res->whatNext = Dis_StopHere;
325 dis_res->jk_StopHere = Ijk_Boring;
328 /* An unconditional branch. Target may or may not be known at instrumentation
329 time. */
330 static void
331 always_goto(IRExpr *target)
333 put_IA(target);
335 dis_res->whatNext = Dis_StopHere;
336 dis_res->jk_StopHere = Ijk_Boring;
340 /* An unconditional branch to a known target. */
341 static void
342 always_goto_and_chase(Addr64 target)
344 if (resteer_fn(resteer_data, target)) {
345 /* Follow into the target */
346 dis_res->whatNext = Dis_ResteerU;
347 dis_res->continueAt = target;
348 } else {
349 put_IA(mkaddr_expr(target));
351 dis_res->whatNext = Dis_StopHere;
352 dis_res->jk_StopHere = Ijk_Boring;
356 /* A system call */
357 static void
358 system_call(IRExpr *sysno)
360 /* Store the system call number in the pseudo register. */
361 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
363 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
364 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
365 mkU64(guest_IA_curr_instr)));
367 put_IA(mkaddr_expr(guest_IA_next_instr));
369 /* It's important that all ArchRegs carry their up-to-date value
370 at this point. So we declare an end-of-block here, which
371 forces any TempRegs caching ArchRegs to be flushed. */
372 dis_res->whatNext = Dis_StopHere;
373 dis_res->jk_StopHere = Ijk_Sys_syscall;
376 /* A side exit that branches back to the current insn if CONDITION is
377 true. Does not set DisResult. */
378 static void
379 iterate_if(IRExpr *condition)
381 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
383 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
384 S390X_GUEST_OFFSET(guest_IA)));
387 /* A side exit that branches back to the current insn.
388 Does not set DisResult. */
389 static __inline__ void
390 iterate(void)
392 iterate_if(IRExpr_Const(IRConst_U1(True)));
395 /* A side exit that branches back to the insn immediately following the
396 current insn if CONDITION is true. Does not set DisResult. */
397 static void
398 next_insn_if(IRExpr *condition)
400 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
402 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
403 S390X_GUEST_OFFSET(guest_IA)));
406 /* Convenience function to restart the current insn */
407 static void
408 restart_if(IRExpr *condition)
410 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
412 stmt(IRStmt_Exit(condition, Ijk_InvalICache,
413 IRConst_U64(guest_IA_curr_instr),
414 S390X_GUEST_OFFSET(guest_IA)));
417 /* Convenience function to yield to thread scheduler */
418 static void
419 yield_if(IRExpr *condition)
421 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
422 S390X_GUEST_OFFSET(guest_IA)));
425 /* Convenience macro to yield a specification exception if the given condition
426 is not met. Used to pass this type of decoding error up through the call
427 chain. */
428 #define s390_insn_assert(mnm, cond) \
429 do { \
430 if (!(cond)) { \
431 dis_res->whatNext = Dis_StopHere; \
432 dis_res->jk_StopHere = Ijk_NoDecode; \
433 return (mnm); \
435 } while (0)
437 /* Convenience function to check for a specification exception. */
438 static Bool
439 is_specification_exception(void)
441 return (dis_res->whatNext == Dis_StopHere &&
442 dis_res->jk_StopHere == Ijk_NoDecode);
445 static __inline__ IRExpr *get_fpr_dw0(UInt);
446 static __inline__ void put_fpr_dw0(UInt, IRExpr *);
447 static __inline__ IRExpr *get_dpr_dw0(UInt);
448 static __inline__ void put_dpr_dw0(UInt, IRExpr *);
450 /* Read a floating point register pair and combine their contents into a
451 128-bit value */
452 static IRExpr *
453 get_fpr_pair(UInt archreg)
455 IRExpr *high = get_fpr_dw0(archreg);
456 IRExpr *low = get_fpr_dw0(archreg + 2);
458 return binop(Iop_F64HLtoF128, high, low);
461 /* Write a 128-bit floating point value into a register pair. */
462 static void
463 put_fpr_pair(UInt archreg, IRExpr *expr)
465 IRExpr *high = unop(Iop_F128HItoF64, expr);
466 IRExpr *low = unop(Iop_F128LOtoF64, expr);
468 put_fpr_dw0(archreg, high);
469 put_fpr_dw0(archreg + 2, low);
472 /* Read a floating point register pair cointaining DFP value
473 and combine their contents into a 128-bit value */
475 static IRExpr *
476 get_dpr_pair(UInt archreg)
478 IRExpr *high = get_dpr_dw0(archreg);
479 IRExpr *low = get_dpr_dw0(archreg + 2);
481 return binop(Iop_D64HLtoD128, high, low);
484 /* Write a 128-bit decimal floating point value into a register pair. */
485 static void
486 put_dpr_pair(UInt archreg, IRExpr *expr)
488 IRExpr *high = unop(Iop_D128HItoD64, expr);
489 IRExpr *low = unop(Iop_D128LOtoD64, expr);
491 put_dpr_dw0(archreg, high);
492 put_dpr_dw0(archreg + 2, low);
495 /* Terminate the current IRSB with an emulation failure. */
496 static void
497 emulation_failure_with_expr(IRExpr *emfailure)
499 vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32);
501 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure));
502 dis_res->whatNext = Dis_StopHere;
503 dis_res->jk_StopHere = Ijk_EmFail;
506 static void
507 emulation_failure(VexEmNote fail_kind)
509 emulation_failure_with_expr(mkU32(fail_kind));
512 /* Terminate the current IRSB with an emulation warning. */
513 static void
514 emulation_warning_with_expr(IRExpr *emwarning)
516 vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32);
518 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning));
519 dis_res->whatNext = Dis_StopHere;
520 dis_res->jk_StopHere = Ijk_EmWarn;
523 static void
524 emulation_warning(VexEmNote warn_kind)
526 emulation_warning_with_expr(mkU32(warn_kind));
529 /*------------------------------------------------------------*/
530 /*--- IR Debugging aids. ---*/
531 /*------------------------------------------------------------*/
532 #if 0
534 static ULong
535 s390_do_print(HChar *text, ULong value)
537 vex_printf("%s %llu\n", text, value);
538 return 0;
541 static void
542 s390_print(HChar *text, IRExpr *value)
544 IRDirty *d;
546 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
547 mkIRExprVec_2(mkU64((ULong)text), value));
548 stmt(IRStmt_Dirty(d));
550 #endif
553 /*------------------------------------------------------------*/
554 /*--- Build the flags thunk. ---*/
555 /*------------------------------------------------------------*/
557 /* Completely fill the flags thunk. We're always filling all fields.
558 Apparently, that is better for redundant PUT elimination. */
559 static void
560 s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
562 UInt op_off, dep1_off, dep2_off, ndep_off;
564 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
565 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
566 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
567 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
569 stmt(IRStmt_Put(op_off, op));
570 stmt(IRStmt_Put(dep1_off, dep1));
571 stmt(IRStmt_Put(dep2_off, dep2));
572 stmt(IRStmt_Put(ndep_off, ndep));
576 /* Create an expression for V and widen the result to 64 bit. */
577 static IRExpr *
578 s390_cc_widen(IRTemp v, Bool sign_extend)
580 IRExpr *expr;
582 expr = mkexpr(v);
584 switch (typeOfIRTemp(irsb->tyenv, v)) {
585 case Ity_I64:
586 break;
587 case Ity_I32:
588 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
589 break;
590 case Ity_I16:
591 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
592 break;
593 case Ity_I8:
594 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
595 break;
596 default:
597 vpanic("s390_cc_widen");
600 return expr;
603 static void
604 s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
606 IRExpr *op, *dep1, *dep2, *ndep;
608 op = mkU64(opc);
609 dep1 = s390_cc_widen(d1, sign_extend);
610 dep2 = mkU64(0);
611 ndep = mkU64(0);
613 s390_cc_thunk_fill(op, dep1, dep2, ndep);
617 static void
618 s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
620 IRExpr *op, *dep1, *dep2, *ndep;
622 op = mkU64(opc);
623 dep1 = s390_cc_widen(d1, sign_extend);
624 dep2 = s390_cc_widen(d2, sign_extend);
625 ndep = mkU64(0);
627 s390_cc_thunk_fill(op, dep1, dep2, ndep);
631 /* memcheck believes that the NDEP field in the flags thunk is always
632 defined. But for some flag computations (e.g. add with carry) that is
633 just not true. We therefore need to convey to memcheck that the value
634 of the ndep field does matter and therefore we make the DEP2 field
635 depend on it:
637 DEP2 = original_DEP2 ^ NDEP
639 In s390_calculate_cc we exploit that (a^b)^b == a
640 I.e. we xor the DEP2 value with the NDEP value to recover the
641 original_DEP2 value. */
642 static void
643 s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
645 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
647 op = mkU64(opc);
648 dep1 = s390_cc_widen(d1, sign_extend);
649 dep2 = s390_cc_widen(d2, sign_extend);
650 ndep = s390_cc_widen(nd, sign_extend);
652 dep2x = binop(Iop_Xor64, dep2, ndep);
654 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
658 /* Write one floating point value into the flags thunk */
659 static void
660 s390_cc_thunk_put1f(UInt opc, IRTemp d1)
662 IRExpr *op, *dep1, *dep2, *ndep;
664 /* Make the CC_DEP1 slot appear completely defined.
665 Otherwise, assigning a 32-bit value will cause memcheck
666 to trigger an undefinedness error.
668 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
669 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
670 stmt(IRStmt_Put(dep1_off, mkU64(0)));
672 op = mkU64(opc);
673 dep1 = mkexpr(d1);
674 dep2 = mkU64(0);
675 ndep = mkU64(0);
677 s390_cc_thunk_fill(op, dep1, dep2, ndep);
681 /* Write a floating point value and an integer into the flags thunk. The
682 integer value is zero-extended first. */
683 static void
684 s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
686 IRExpr *op, *dep1, *dep2, *ndep;
688 /* Make the CC_DEP1 slot appear completely defined.
689 Otherwise, assigning a 32-bit value will cause memcheck
690 to trigger an undefinedness error.
692 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
693 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
694 stmt(IRStmt_Put(dep1_off, mkU64(0)));
696 op = mkU64(opc);
697 dep1 = mkexpr(d1);
698 dep2 = s390_cc_widen(d2, False);
699 ndep = mkU64(0);
701 s390_cc_thunk_fill(op, dep1, dep2, ndep);
705 /* Write a 128-bit floating point value into the flags thunk. This is
706 done by splitting the value into two 64-bits values. */
707 static void
708 s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
710 IRExpr *op, *hi, *lo, *ndep;
712 op = mkU64(opc);
713 hi = unop(Iop_F128HItoF64, mkexpr(d1));
714 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
715 ndep = mkU64(0);
717 s390_cc_thunk_fill(op, hi, lo, ndep);
721 /* Write a 128-bit floating point value and an integer into the flags thunk.
722 The integer value is zero-extended first. */
723 static void
724 s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
726 IRExpr *op, *hi, *lo, *lox, *ndep;
728 op = mkU64(opc);
729 hi = unop(Iop_F128HItoF64, mkexpr(d1));
730 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
731 ndep = s390_cc_widen(nd, False);
733 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
735 s390_cc_thunk_fill(op, hi, lox, ndep);
739 /* Write a 128-bit decimal floating point value into the flags thunk.
740 This is done by splitting the value into two 64-bits values. */
741 static void
742 s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
744 IRExpr *op, *hi, *lo, *ndep;
746 op = mkU64(opc);
747 hi = unop(Iop_D128HItoD64, mkexpr(d1));
748 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
749 ndep = mkU64(0);
751 s390_cc_thunk_fill(op, hi, lo, ndep);
755 /* Write a 128-bit decimal floating point value and an integer into the flags
756 thunk. The integer value is zero-extended first. */
757 static void
758 s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
760 IRExpr *op, *hi, *lo, *lox, *ndep;
762 op = mkU64(opc);
763 hi = unop(Iop_D128HItoD64, mkexpr(d1));
764 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
765 ndep = s390_cc_widen(nd, False);
767 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
769 s390_cc_thunk_fill(op, hi, lox, ndep);
772 static void
773 s390_cc_set(IRTemp cc)
775 vassert(typeOfIRTemp(irsb->tyenv, cc) == Ity_I64);
777 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
780 static void
781 s390_cc_set_val(UInt val)
783 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkU64(val), mkU64(0), mkU64(0));
786 /* Build IR to calculate the condition code from flags thunk.
787 Returns an expression of type Ity_I32 */
788 static IRExpr *
789 s390_call_calculate_cc(void)
791 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
793 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
794 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
795 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
796 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
798 args = mkIRExprVec_4(op, dep1, dep2, ndep);
799 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
800 "s390_calculate_cc", &s390_calculate_cc, args);
802 /* Exclude OP and NDEP from definedness checking. We're only
803 interested in DEP1 and DEP2. */
804 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
806 return call;
809 /* Build IR to calculate the internal condition code for a "compare and branch"
810 insn. Returns an expression of type Ity_I32 */
811 static IRExpr *
812 s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
814 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
816 switch (opc) {
817 case S390_CC_OP_SIGNED_COMPARE:
818 dep1 = s390_cc_widen(op1, True);
819 dep2 = s390_cc_widen(op2, True);
820 break;
822 case S390_CC_OP_UNSIGNED_COMPARE:
823 dep1 = s390_cc_widen(op1, False);
824 dep2 = s390_cc_widen(op2, False);
825 break;
827 default:
828 vpanic("s390_call_calculate_icc");
831 mask = mkU64(m);
832 op = mkU64(opc);
834 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
835 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
836 "s390_calculate_cond", &s390_calculate_cond, args);
838 /* Exclude the requested condition, OP and NDEP from definedness
839 checking. We're only interested in DEP1 and DEP2. */
840 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
842 return call;
845 /* Build IR to calculate the condition code from flags thunk.
846 Returns an expression of type Ity_I32 */
847 static IRExpr *
848 s390_call_calculate_cond(UInt m)
850 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
852 mask = mkU64(m);
853 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
854 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
855 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
856 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
858 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
859 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
860 "s390_calculate_cond", &s390_calculate_cond, args);
862 /* Exclude the requested condition, OP and NDEP from definedness
863 checking. We're only interested in DEP1 and DEP2. */
864 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
866 return call;
869 #define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
870 #define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
871 #define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
872 #define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
873 #define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
874 #define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
875 #define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
876 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
877 #define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
878 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
883 /*------------------------------------------------------------*/
884 /*--- Guest register access ---*/
885 /*------------------------------------------------------------*/
888 /*------------------------------------------------------------*/
889 /*--- ar registers ---*/
890 /*------------------------------------------------------------*/
892 /* Return the guest state offset of a ar register. */
893 static UInt
894 ar_offset(UInt archreg)
896 static const UInt offset[16] = {
897 S390X_GUEST_OFFSET(guest_a0),
898 S390X_GUEST_OFFSET(guest_a1),
899 S390X_GUEST_OFFSET(guest_a2),
900 S390X_GUEST_OFFSET(guest_a3),
901 S390X_GUEST_OFFSET(guest_a4),
902 S390X_GUEST_OFFSET(guest_a5),
903 S390X_GUEST_OFFSET(guest_a6),
904 S390X_GUEST_OFFSET(guest_a7),
905 S390X_GUEST_OFFSET(guest_a8),
906 S390X_GUEST_OFFSET(guest_a9),
907 S390X_GUEST_OFFSET(guest_a10),
908 S390X_GUEST_OFFSET(guest_a11),
909 S390X_GUEST_OFFSET(guest_a12),
910 S390X_GUEST_OFFSET(guest_a13),
911 S390X_GUEST_OFFSET(guest_a14),
912 S390X_GUEST_OFFSET(guest_a15),
915 vassert(archreg < 16);
917 return offset[archreg];
921 /* Return the guest state offset of word #0 of a ar register. */
922 static __inline__ UInt
923 ar_w0_offset(UInt archreg)
925 return ar_offset(archreg) + 0;
928 /* Write word #0 of a ar to the guest state. */
929 static __inline__ void
930 put_ar_w0(UInt archreg, IRExpr *expr)
932 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
934 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
937 /* Read word #0 of a ar register. */
938 static __inline__ IRExpr *
939 get_ar_w0(UInt archreg)
941 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
945 /*------------------------------------------------------------*/
946 /*--- fpr registers ---*/
947 /*------------------------------------------------------------*/
949 /* Return the guest state offset of a fpr register.
950 FPRs are maped to first doubleword of VRs.
952 static UInt
953 fpr_offset(UInt archreg)
955 static const UInt offset[16] = {
956 S390X_GUEST_OFFSET(guest_v0),
957 S390X_GUEST_OFFSET(guest_v1),
958 S390X_GUEST_OFFSET(guest_v2),
959 S390X_GUEST_OFFSET(guest_v3),
960 S390X_GUEST_OFFSET(guest_v4),
961 S390X_GUEST_OFFSET(guest_v5),
962 S390X_GUEST_OFFSET(guest_v6),
963 S390X_GUEST_OFFSET(guest_v7),
964 S390X_GUEST_OFFSET(guest_v8),
965 S390X_GUEST_OFFSET(guest_v9),
966 S390X_GUEST_OFFSET(guest_v10),
967 S390X_GUEST_OFFSET(guest_v11),
968 S390X_GUEST_OFFSET(guest_v12),
969 S390X_GUEST_OFFSET(guest_v13),
970 S390X_GUEST_OFFSET(guest_v14),
971 S390X_GUEST_OFFSET(guest_v15),
974 vassert(archreg < 16);
976 return offset[archreg];
980 /* Return the guest state offset of word #0 of a fpr register. */
981 static __inline__ UInt
982 fpr_w0_offset(UInt archreg)
984 return fpr_offset(archreg) + 0;
987 /* Write word #0 of a fpr to the guest state. */
988 static __inline__ void
989 put_fpr_w0(UInt archreg, IRExpr *expr)
991 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
993 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
996 /* Read word #0 of a fpr register. */
997 static __inline__ IRExpr *
998 get_fpr_w0(UInt archreg)
1000 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
1003 /* Return the guest state offset of double word #0 of a fpr register. */
1004 static __inline__ UInt
1005 fpr_dw0_offset(UInt archreg)
1007 return fpr_offset(archreg) + 0;
1010 /* Write double word #0 of a fpr to the guest state. */
1011 static __inline__ void
1012 put_fpr_dw0(UInt archreg, IRExpr *expr)
1014 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
1016 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1019 /* Read double word #0 of a fpr register. */
1020 static __inline__ IRExpr *
1021 get_fpr_dw0(UInt archreg)
1023 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
1026 /* Write word #0 of a dpr to the guest state. */
1027 static __inline__ void
1028 put_dpr_w0(UInt archreg, IRExpr *expr)
1030 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
1032 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1035 /* Read word #0 of a dpr register. */
1036 static __inline__ IRExpr *
1037 get_dpr_w0(UInt archreg)
1039 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1042 /* Write double word #0 of a fpr containg DFP value to the guest state. */
1043 static __inline__ void
1044 put_dpr_dw0(UInt archreg, IRExpr *expr)
1046 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1048 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1051 /* Read double word #0 of a fpr register containing DFP value. */
1052 static __inline__ IRExpr *
1053 get_dpr_dw0(UInt archreg)
1055 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1058 /*------------------------------------------------------------*/
1059 /*--- gpr registers ---*/
1060 /*------------------------------------------------------------*/
1062 /* Return the guest state offset of a gpr register. */
1063 static UInt
1064 gpr_offset(UInt archreg)
1066 static const UInt offset[16] = {
1067 S390X_GUEST_OFFSET(guest_r0),
1068 S390X_GUEST_OFFSET(guest_r1),
1069 S390X_GUEST_OFFSET(guest_r2),
1070 S390X_GUEST_OFFSET(guest_r3),
1071 S390X_GUEST_OFFSET(guest_r4),
1072 S390X_GUEST_OFFSET(guest_r5),
1073 S390X_GUEST_OFFSET(guest_r6),
1074 S390X_GUEST_OFFSET(guest_r7),
1075 S390X_GUEST_OFFSET(guest_r8),
1076 S390X_GUEST_OFFSET(guest_r9),
1077 S390X_GUEST_OFFSET(guest_r10),
1078 S390X_GUEST_OFFSET(guest_r11),
1079 S390X_GUEST_OFFSET(guest_r12),
1080 S390X_GUEST_OFFSET(guest_r13),
1081 S390X_GUEST_OFFSET(guest_r14),
1082 S390X_GUEST_OFFSET(guest_r15),
1085 vassert(archreg < 16);
1087 return offset[archreg];
1091 /* Return the guest state offset of word #0 of a gpr register. */
1092 static __inline__ UInt
1093 gpr_w0_offset(UInt archreg)
1095 return gpr_offset(archreg) + 0;
1098 /* Write an integer right-aligned into a gpr. */
1099 static __inline__ void
1100 put_gpr_int(UInt archreg, IRExpr *expr)
1102 UInt siz = sizeofIRType(typeOfIRExpr(irsb->tyenv, expr));
1104 vassert(siz <= 8);
1105 stmt(IRStmt_Put(gpr_offset(archreg) + 8 - siz, expr));
1108 /* Read an integer of given type from a gpr. */
1109 static __inline__ IRExpr *
1110 get_gpr_int(UInt archreg, IRType ty)
1112 return IRExpr_Get(gpr_offset(archreg) + 8 - sizeofIRType(ty), ty);
1115 /* Write word #0 of a gpr to the guest state. */
1116 static __inline__ void
1117 put_gpr_w0(UInt archreg, IRExpr *expr)
1119 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1121 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1124 /* Read word #0 of a gpr register. */
1125 static __inline__ IRExpr *
1126 get_gpr_w0(UInt archreg)
1128 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1131 /* Return the guest state offset of double word #0 of a gpr register. */
1132 static __inline__ UInt
1133 gpr_dw0_offset(UInt archreg)
1135 return gpr_offset(archreg) + 0;
1138 /* Write double word #0 of a gpr to the guest state. */
1139 static __inline__ void
1140 put_gpr_dw0(UInt archreg, IRExpr *expr)
1142 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1144 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1147 /* Read double word #0 of a gpr register. */
1148 static __inline__ IRExpr *
1149 get_gpr_dw0(UInt archreg)
1151 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1154 /* Return the guest state offset of half word #1 of a gpr register. */
1155 static __inline__ UInt
1156 gpr_hw1_offset(UInt archreg)
1158 return gpr_offset(archreg) + 2;
1161 /* Write half word #1 of a gpr to the guest state. */
1162 static __inline__ void
1163 put_gpr_hw1(UInt archreg, IRExpr *expr)
1165 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1167 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1170 /* Read half word #1 of a gpr register. */
1171 static __inline__ IRExpr *
1172 get_gpr_hw1(UInt archreg)
1174 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1177 /* Return the guest state offset of byte #6 of a gpr register. */
1178 static __inline__ UInt
1179 gpr_b6_offset(UInt archreg)
1181 return gpr_offset(archreg) + 6;
1184 /* Write byte #6 of a gpr to the guest state. */
1185 static __inline__ void
1186 put_gpr_b6(UInt archreg, IRExpr *expr)
1188 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1190 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1193 /* Read byte #6 of a gpr register. */
1194 static __inline__ IRExpr *
1195 get_gpr_b6(UInt archreg)
1197 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1200 /* Return the guest state offset of byte #3 of a gpr register. */
1201 static __inline__ UInt
1202 gpr_b3_offset(UInt archreg)
1204 return gpr_offset(archreg) + 3;
1207 /* Write byte #3 of a gpr to the guest state. */
1208 static __inline__ void
1209 put_gpr_b3(UInt archreg, IRExpr *expr)
1211 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1213 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1216 /* Read byte #3 of a gpr register. */
1217 static __inline__ IRExpr *
1218 get_gpr_b3(UInt archreg)
1220 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1223 /* Return the guest state offset of byte #0 of a gpr register. */
1224 static __inline__ UInt
1225 gpr_b0_offset(UInt archreg)
1227 return gpr_offset(archreg) + 0;
1230 /* Write byte #0 of a gpr to the guest state. */
1231 static __inline__ void
1232 put_gpr_b0(UInt archreg, IRExpr *expr)
1234 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1236 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1239 /* Read byte #0 of a gpr register. */
1240 static __inline__ IRExpr *
1241 get_gpr_b0(UInt archreg)
1243 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1246 /* Return the guest state offset of word #1 of a gpr register. */
1247 static __inline__ UInt
1248 gpr_w1_offset(UInt archreg)
1250 return gpr_offset(archreg) + 4;
1253 /* Write word #1 of a gpr to the guest state. */
1254 static __inline__ void
1255 put_gpr_w1(UInt archreg, IRExpr *expr)
1257 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1259 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1262 /* Read word #1 of a gpr register. */
1263 static __inline__ IRExpr *
1264 get_gpr_w1(UInt archreg)
1266 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1269 /* Return the guest state offset of half word #3 of a gpr register. */
1270 static __inline__ UInt
1271 gpr_hw3_offset(UInt archreg)
1273 return gpr_offset(archreg) + 6;
1276 /* Write half word #3 of a gpr to the guest state. */
1277 static __inline__ void
1278 put_gpr_hw3(UInt archreg, IRExpr *expr)
1280 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1282 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1285 /* Read half word #3 of a gpr register. */
1286 static __inline__ IRExpr *
1287 get_gpr_hw3(UInt archreg)
1289 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1292 /* Return the guest state offset of byte #7 of a gpr register. */
1293 static __inline__ UInt
1294 gpr_b7_offset(UInt archreg)
1296 return gpr_offset(archreg) + 7;
1299 /* Write byte #7 of a gpr to the guest state. */
1300 static __inline__ void
1301 put_gpr_b7(UInt archreg, IRExpr *expr)
1303 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1305 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1308 /* Read byte #7 of a gpr register. */
1309 static __inline__ IRExpr *
1310 get_gpr_b7(UInt archreg)
1312 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1315 /* Return the guest state offset of half word #0 of a gpr register. */
1316 static __inline__ UInt
1317 gpr_hw0_offset(UInt archreg)
1319 return gpr_offset(archreg) + 0;
1322 /* Write half word #0 of a gpr to the guest state. */
1323 static __inline__ void
1324 put_gpr_hw0(UInt archreg, IRExpr *expr)
1326 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1328 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1331 /* Read half word #0 of a gpr register. */
1332 static __inline__ IRExpr *
1333 get_gpr_hw0(UInt archreg)
1335 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1338 /* Return the guest state offset of byte #4 of a gpr register. */
1339 static __inline__ UInt
1340 gpr_b4_offset(UInt archreg)
1342 return gpr_offset(archreg) + 4;
1345 /* Write byte #4 of a gpr to the guest state. */
1346 static __inline__ void
1347 put_gpr_b4(UInt archreg, IRExpr *expr)
1349 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1351 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1354 /* Read byte #4 of a gpr register. */
1355 static __inline__ IRExpr *
1356 get_gpr_b4(UInt archreg)
1358 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1361 /* Return the guest state offset of byte #1 of a gpr register. */
1362 static __inline__ UInt
1363 gpr_b1_offset(UInt archreg)
1365 return gpr_offset(archreg) + 1;
1368 /* Write byte #1 of a gpr to the guest state. */
1369 static __inline__ void
1370 put_gpr_b1(UInt archreg, IRExpr *expr)
1372 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1374 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1377 /* Read byte #1 of a gpr register. */
1378 static __inline__ IRExpr *
1379 get_gpr_b1(UInt archreg)
1381 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1384 /* Return the guest state offset of half word #2 of a gpr register. */
1385 static __inline__ UInt
1386 gpr_hw2_offset(UInt archreg)
1388 return gpr_offset(archreg) + 4;
1391 /* Write half word #2 of a gpr to the guest state. */
1392 static __inline__ void
1393 put_gpr_hw2(UInt archreg, IRExpr *expr)
1395 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1397 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1400 /* Read half word #2 of a gpr register. */
1401 static __inline__ IRExpr *
1402 get_gpr_hw2(UInt archreg)
1404 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1407 /* Return the guest state offset of byte #5 of a gpr register. */
1408 static __inline__ UInt
1409 gpr_b5_offset(UInt archreg)
1411 return gpr_offset(archreg) + 5;
1414 /* Write byte #5 of a gpr to the guest state. */
1415 static __inline__ void
1416 put_gpr_b5(UInt archreg, IRExpr *expr)
1418 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1420 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1423 /* Read byte #5 of a gpr register. */
1424 static __inline__ IRExpr *
1425 get_gpr_b5(UInt archreg)
1427 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1430 /* Return the guest state offset of byte #2 of a gpr register. */
1431 static __inline__ UInt
1432 gpr_b2_offset(UInt archreg)
1434 return gpr_offset(archreg) + 2;
1437 /* Write byte #2 of a gpr to the guest state. */
1438 static __inline__ void
1439 put_gpr_b2(UInt archreg, IRExpr *expr)
1441 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1443 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1446 /* Read byte #2 of a gpr register. */
1447 static __inline__ IRExpr *
1448 get_gpr_b2(UInt archreg)
1450 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1453 /* Return the guest state offset of the counter register. */
1454 static UInt
1455 counter_offset(void)
1457 return S390X_GUEST_OFFSET(guest_counter);
1460 /* Return the guest state offset of double word #0 of the counter register. */
1461 static __inline__ UInt
1462 counter_dw0_offset(void)
1464 return counter_offset() + 0;
1467 /* Write double word #0 of the counter to the guest state. */
1468 static __inline__ void
1469 put_counter_dw0(IRExpr *expr)
1471 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1473 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1476 /* Read double word #0 of the counter register. */
1477 static __inline__ IRExpr *
1478 get_counter_dw0(void)
1480 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1483 /* Return the guest state offset of word #0 of the counter register. */
1484 static __inline__ UInt
1485 counter_w0_offset(void)
1487 return counter_offset() + 0;
1490 /* Return the guest state offset of word #1 of the counter register. */
1491 static __inline__ UInt
1492 counter_w1_offset(void)
1494 return counter_offset() + 4;
1497 /* Write word #0 of the counter to the guest state. */
1498 static __inline__ void
1499 put_counter_w0(IRExpr *expr)
1501 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1503 stmt(IRStmt_Put(counter_w0_offset(), expr));
1506 /* Read word #0 of the counter register. */
1507 static __inline__ IRExpr *
1508 get_counter_w0(void)
1510 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1513 /* Write word #1 of the counter to the guest state. */
1514 static __inline__ void
1515 put_counter_w1(IRExpr *expr)
1517 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1519 stmt(IRStmt_Put(counter_w1_offset(), expr));
1522 /* Read word #1 of the counter register. */
1523 static __inline__ IRExpr *
1524 get_counter_w1(void)
1526 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1529 /* Return the guest state offset of the fpc register. */
1530 static UInt
1531 fpc_offset(void)
1533 return S390X_GUEST_OFFSET(guest_fpc);
1536 /* Return the guest state offset of word #0 of the fpc register. */
1537 static __inline__ UInt
1538 fpc_w0_offset(void)
1540 return fpc_offset() + 0;
1543 /* Write word #0 of the fpc to the guest state. */
1544 static __inline__ void
1545 put_fpc_w0(IRExpr *expr)
1547 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1549 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1552 /* Read word #0 of the fpc register. */
1553 static __inline__ IRExpr *
1554 get_fpc_w0(void)
1556 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1560 /*------------------------------------------------------------*/
1561 /*--- vr registers ---*/
1562 /*------------------------------------------------------------*/
1564 /* Return the guest state offset of a vr register. */
1565 static UInt
1566 vr_offset(const UInt archreg)
1568 static const UInt offset[32] = {
1569 S390X_GUEST_OFFSET(guest_v0),
1570 S390X_GUEST_OFFSET(guest_v1),
1571 S390X_GUEST_OFFSET(guest_v2),
1572 S390X_GUEST_OFFSET(guest_v3),
1573 S390X_GUEST_OFFSET(guest_v4),
1574 S390X_GUEST_OFFSET(guest_v5),
1575 S390X_GUEST_OFFSET(guest_v6),
1576 S390X_GUEST_OFFSET(guest_v7),
1577 S390X_GUEST_OFFSET(guest_v8),
1578 S390X_GUEST_OFFSET(guest_v9),
1579 S390X_GUEST_OFFSET(guest_v10),
1580 S390X_GUEST_OFFSET(guest_v11),
1581 S390X_GUEST_OFFSET(guest_v12),
1582 S390X_GUEST_OFFSET(guest_v13),
1583 S390X_GUEST_OFFSET(guest_v14),
1584 S390X_GUEST_OFFSET(guest_v15),
1585 S390X_GUEST_OFFSET(guest_v16),
1586 S390X_GUEST_OFFSET(guest_v17),
1587 S390X_GUEST_OFFSET(guest_v18),
1588 S390X_GUEST_OFFSET(guest_v19),
1589 S390X_GUEST_OFFSET(guest_v20),
1590 S390X_GUEST_OFFSET(guest_v21),
1591 S390X_GUEST_OFFSET(guest_v22),
1592 S390X_GUEST_OFFSET(guest_v23),
1593 S390X_GUEST_OFFSET(guest_v24),
1594 S390X_GUEST_OFFSET(guest_v25),
1595 S390X_GUEST_OFFSET(guest_v26),
1596 S390X_GUEST_OFFSET(guest_v27),
1597 S390X_GUEST_OFFSET(guest_v28),
1598 S390X_GUEST_OFFSET(guest_v29),
1599 S390X_GUEST_OFFSET(guest_v30),
1600 S390X_GUEST_OFFSET(guest_v31),
1603 vassert(archreg < 32);
1605 return offset[archreg];
1608 /* Return the guest state offset of quadword of a vr register. */
1609 static UInt
1610 vr_qw_offset(const UInt archreg)
1612 return vr_offset(archreg) + 0;
1615 /* Write quadword of a vr to the guest state. */
1616 static void
1617 put_vr_qw(const UInt archreg, IRExpr *expr)
1619 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_V128);
1621 stmt(IRStmt_Put(vr_qw_offset(archreg), expr));
1624 /* Read quadword of a vr register. */
1625 static IRExpr *
1626 get_vr_qw(const UInt archreg)
1628 return IRExpr_Get(vr_qw_offset(archreg), Ity_V128);
1631 /* Return the guest state offset of double word #0 of a gpr register. */
1632 static UInt
1633 vr_dw0_offset(UInt archreg)
1635 return vr_offset(archreg) + 0;
1638 /* Read doubleword #0 of a vr register. */
1639 static IRExpr *
1640 get_vr_dw0(UInt archreg)
1642 return IRExpr_Get(vr_dw0_offset(archreg), Ity_I64);
1645 /* Write double word #0 of a vr to the guest state. */
1646 static void
1647 put_vr_dw0(UInt archreg, IRExpr *expr)
1649 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1651 stmt(IRStmt_Put(vr_dw0_offset(archreg), expr));
1654 /* Return the guest state offset of double word #1 of a gpr register. */
1655 static UInt
1656 vr_dw1_offset(UInt archreg)
1658 return vr_offset(archreg) + 8;
1661 /* Read doubleword #1 of a vr register. */
1662 static IRExpr *
1663 get_vr_dw1(UInt archreg)
1665 return IRExpr_Get(vr_dw1_offset(archreg), Ity_I64);
1668 /* Write double word #0 of a vr to the guest state. */
1669 static void
1670 put_vr_dw1(UInt archreg, IRExpr *expr)
1672 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1674 stmt(IRStmt_Put(vr_dw1_offset(archreg), expr));
1677 /* Return the guest state offset of word #1 of a gpr register. */
1678 static UInt
1679 vr_w1_offset(UInt archreg)
1681 return vr_offset(archreg) + 4;
1684 /* Return the guest state offset of word #3 of a gpr register. */
1685 static UInt
1686 vr_w3_offset(UInt archreg)
1688 return vr_offset(archreg) + 12;
1691 /* Read word #0 of a vr register. */
1692 static IRExpr *
1693 get_vr_w0(UInt archreg)
1695 return IRExpr_Get(vr_dw0_offset(archreg), Ity_I32);
1698 /* Read word #1 of a vr register. */
1699 static IRExpr *
1700 get_vr_w1(UInt archreg)
1702 return IRExpr_Get(vr_w1_offset(archreg), Ity_I32);
1705 /* Read word #2 of a vr register. */
1706 static IRExpr *
1707 get_vr_w2(UInt archreg)
1709 return IRExpr_Get(vr_dw1_offset(archreg), Ity_I32);
1712 /* Read word #3 of a vr register. */
1713 static IRExpr *
1714 get_vr_w3(UInt archreg)
1716 return IRExpr_Get(vr_w3_offset(archreg), Ity_I32);
1719 /* Return the guest state offset of halfword #3 of a gpr register. */
1720 static UInt
1721 vr_hw3_offset(UInt archreg)
1723 return vr_offset(archreg) + 6;
1726 /* Read halfword #3 of a vr register. */
1727 static IRExpr *
1728 get_vr_hw3(UInt archreg)
1730 return IRExpr_Get(vr_hw3_offset(archreg), Ity_I16);
1733 /* Return the guest state offset of halfword #7 of a gpr register. */
1734 static UInt
1735 vr_hw7_offset(UInt archreg)
1737 return vr_offset(archreg) + 14;
1740 /* Read halfword #7 of a vr register. */
1741 static IRExpr *
1742 get_vr_hw7(UInt archreg)
1744 return IRExpr_Get(vr_hw7_offset(archreg), Ity_I16);
1747 /* Return the guest state offset of byte #7 of a vr register. */
1748 static UInt
1749 vr_b7_offset(UInt archreg)
1751 return vr_offset(archreg) + 7;
1754 /* Read byte #7 of a vr register. */
1755 static IRExpr *
1756 get_vr_b7(UInt archreg)
1758 return IRExpr_Get(vr_b7_offset(archreg), Ity_I8);
1761 /* Return the guest state offset of byte #15 of a vr register. */
1762 static UInt
1763 vr_b15_offset(UInt archreg)
1765 return vr_offset(archreg) + 15;
1768 /* Read byte #15 of a vr register. */
1769 static IRExpr *
1770 get_vr_b15(UInt archreg)
1772 return IRExpr_Get(vr_b15_offset(archreg), Ity_I8);
1775 /* Determine IRType by instruction's m3 field */
1776 static IRType
1777 s390_vr_get_type(const UChar m)
1779 static const IRType results[] = {Ity_I8, Ity_I16, Ity_I32, Ity_I64, Ity_V128};
1780 if (m > 4) {
1781 vex_printf("s390_vr_get_type: m=%x\n", m);
1782 vpanic("s390_vr_get_type: reserved m value");
1785 return results[m];
1788 /* Determine if Condition Code Set (CS) flag is set in m field */
1789 #define s390_vr_is_cs_set(m) (((m) & 0x1) != 0)
1791 /* Determine if Zero Search (ZS) flag is set in m field */
1792 #define s390_vr_is_zs_set(m) (((m) & 0b0010) != 0)
1794 /* Check if the "Single-Element-Control" bit is set.
1795 Used in vector FP instructions.
1797 #define s390_vr_is_single_element_control_set(m) (((m) & 0x8) != 0)
1799 /* Generates arg1 < arg2 (or arg1 <= arg2 if allow_equal == True) expression.
1800 Arguments must have V128 type and are treated as unsigned 128-bit numbers.
1802 static IRExpr*
1803 s390_V128_compareLT128x1(IRExpr* arg1, IRExpr* arg2, Bool allow_equal)
1805 /* If high halves are equal
1806 then we compare lower ones
1807 otherwise we compare high halves.
1809 IRExpr* result;
1810 result = mkite(binop(Iop_CmpEQ64,
1811 unop(Iop_V128HIto64, arg1),
1812 unop(Iop_V128HIto64, arg2)
1814 unop(Iop_1Uto64,
1815 binop(allow_equal ? Iop_CmpLE64U : Iop_CmpLT64U,
1816 unop(Iop_V128to64, arg1),
1817 unop(Iop_V128to64, arg2)
1820 unop(Iop_1Uto64,
1821 binop(Iop_CmpLT64U,
1822 unop(Iop_V128HIto64, arg1),
1823 unop(Iop_V128HIto64, arg2)
1828 return result;
1831 /* Generates arg1 == 0 expression.
1832 Argument must have V128 type and is treated as unsigned 128-bit number.
1834 static IRExpr*
1835 s390_V128_isZero(IRExpr* arg)
1837 IRExpr* high_or_low = binop(Iop_Or64,
1838 unop(Iop_V128to64, arg),
1839 unop(Iop_V128HIto64, arg)
1842 return unop(Iop_1Uto64, binop(Iop_CmpEQ64, high_or_low, mkU64(0ULL)));
1845 /* Generate the two's complement for arg.
1846 Arg should be V128.
1848 static IRExpr*
1849 s390_V128_get_complement(IRExpr* arg, IRType type)
1851 IRExpr* notArg = unop(Iop_NotV128, arg);
1852 IRExpr* ones;
1853 IRExpr* result;
1854 switch(type) {
1855 case Ity_I8:
1856 ones = unop(Iop_Dup8x16, mkU8(0x01));
1857 result = binop(Iop_Add8x16, notArg, ones);
1858 break;
1859 case Ity_I16:
1860 ones = unop(Iop_Dup16x8, mkU16(0x0001));
1861 result = binop(Iop_Add16x8, notArg, ones);
1862 break;
1863 case Ity_I32:
1864 ones = unop(Iop_Dup32x4, mkU32(0x00000001));
1865 result = binop(Iop_Add32x4, notArg, ones);
1866 break;
1867 case Ity_I64:
1868 ones = binop(Iop_64HLtoV128, mkU64(0x1ULL), mkU64(0x1ULL));
1869 result = binop(Iop_Add64x2, notArg, ones);
1870 break;
1871 case Ity_V128:
1872 ones = binop(Iop_64HLtoV128, mkU64(0x0ULL), mkU64(0x1ULL));
1873 result = binop(Iop_Add128x1, notArg, ones);
1874 break;
1875 default:
1876 vpanic("s390_V128_get_complement: unknown type");
1879 return result;
1882 /* # Elements are treated as 128-bit unsigned integers
1883 For i = 0; i < elemCount; i++ do:
1884 sum = arg1[i] + arg2[i]
1885 result[i] = carry_out_bit(sum)
1887 return result
1889 static IRExpr*
1890 s390_V128_calculate_carry_out(IRExpr* arg1, IRExpr* arg2, IRType type,
1891 Bool allow_equal)
1893 IRTemp sum = newTemp(Ity_V128);
1894 IRExpr* mask;
1895 IRExpr* comparison;
1896 IRExpr* result;
1897 switch(type){
1898 case Ity_I8:
1899 assign(sum, binop(Iop_Add8x16, arg1, arg2));
1900 mask = unop(Iop_Dup8x16, mkU8(0x1));
1901 comparison = binop(Iop_CmpGT8Ux16, arg1, mkexpr(sum));
1902 if(allow_equal) {
1903 comparison = binop(Iop_OrV128, binop(Iop_CmpEQ8x16, arg1, mkexpr(sum)),
1904 comparison);
1906 result = binop(Iop_AndV128, comparison, mask);
1907 break;
1908 case Ity_I16:
1909 assign(sum, binop(Iop_Add16x8, arg1, arg2));
1910 mask = unop(Iop_Dup16x8, mkU16(0x1));
1911 comparison = binop(Iop_CmpGT16Ux8, arg1, mkexpr(sum));
1912 if(allow_equal) {
1913 comparison = binop(Iop_OrV128, binop(Iop_CmpEQ16x8, arg1, mkexpr(sum)),
1914 comparison);
1916 result = binop(Iop_AndV128, comparison, mask);
1917 break;
1918 case Ity_I32:
1919 assign(sum, binop(Iop_Add32x4, arg1, arg2));
1920 mask = unop(Iop_Dup32x4, mkU32(0x1));
1921 comparison = binop(Iop_CmpGT32Ux4, arg1, mkexpr(sum));
1922 if(allow_equal) {
1923 comparison = binop(Iop_OrV128, binop(Iop_CmpEQ32x4, arg1, mkexpr(sum)),
1924 comparison);
1926 result = binop(Iop_AndV128, comparison, mask);
1927 break;
1928 case Ity_I64:
1929 assign(sum, binop(Iop_Add64x2, arg1, arg2));
1930 mask = binop(Iop_64HLtoV128, mkU64(0x1), mkU64(0x1));
1931 comparison = binop(Iop_CmpGT64Ux2, arg1, mkexpr(sum));
1932 if(allow_equal) {
1933 comparison = binop(Iop_OrV128, binop(Iop_CmpEQ64x2, arg1, mkexpr(sum)),
1934 comparison);
1936 result = binop(Iop_AndV128, comparison, mask);
1937 break;
1938 case Ity_V128:
1939 assign(sum, binop(Iop_Add128x1, arg1, arg2));
1940 comparison = s390_V128_compareLT128x1(mkexpr(sum), arg1, allow_equal);
1941 result = binop(Iop_64HLtoV128, mkU64(0x0), comparison);
1942 break;
1943 default:
1944 ppIRType(type);
1945 vpanic("s390_V128_calculate_carry_out: unknown type");
1948 return result;
1951 /* # elemCount = 1 for now (elements are 128-bit unsigned integers)
1952 For i = 0; i < elemCount; i++ do:
1953 sum = arg1[i] + arg2[i] + arg3[i] & 0x1
1954 result[i] = carry_out_bit(sum)
1956 return result
1958 static IRExpr*
1959 s390_V128_calculate_carry_out_with_carry(IRExpr* arg1, IRExpr* arg2, IRExpr* arg3)
1961 IRTemp sum = newTemp(Ity_V128);
1962 assign(sum, binop(Iop_Add128x1, arg1, arg2));
1964 IRTemp overflow_before = newTemp(Ity_I64);
1965 assign(overflow_before, s390_V128_compareLT128x1(mkexpr(sum), arg1, False));
1967 IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0), mkU64(1));
1968 IRTemp carry_in = newTemp(Ity_V128);
1969 assign(carry_in, binop(Iop_AndV128, arg3, mask));
1971 IRExpr* carry_is_not_zero = unop(Iop_1Uto64,
1972 binop(Iop_CmpNE64,
1973 unop(Iop_V128to64, mkexpr(carry_in)),
1974 mkU64(0ULL)
1978 IRTemp sum_plus_carry = newTemp(Ity_V128);
1979 assign(sum_plus_carry, binop(Iop_Add128x1, mkexpr(sum), mkexpr(carry_in)));
1981 IRExpr* overflow_after = binop(Iop_And64,
1982 carry_is_not_zero,
1983 s390_V128_isZero(mkexpr(sum_plus_carry))
1986 IRExpr* result = binop(Iop_Or64, mkexpr(overflow_before), overflow_after);
1987 result = binop(Iop_64HLtoV128, mkU64(0Ull), result);
1988 return result;
1991 /* Performs "arg1 + arg2 + carry_out_bit(arg1 + arg2)".
1992 Arguments and result are Ity_I32.
1994 static IRTemp
1995 s390_checksum_add(IRExpr* arg1, IRExpr* arg2)
1997 IRTemp sum = newTemp(Ity_I32);
1998 IRTemp res = newTemp(Ity_I32);
2000 assign(sum, binop(Iop_Add32, arg1, arg2));
2001 assign(res,
2002 mkite(binop(Iop_CmpLT32U, mkexpr(sum), arg1),
2003 binop(Iop_Add32, mkexpr(sum), mkU32(1)),
2004 mkexpr(sum))
2007 return res;
2010 /* Return the guest state offset of element with type's size and given index
2011 of a vr register.
2013 static UInt
2014 s390_vr_offset_by_index(UInt archreg,IRType type, UChar index)
2016 switch (type) {
2017 case Ity_I8:
2018 if(index > 15) {
2019 goto invalidIndex;
2021 return vr_offset(archreg) + sizeof(UChar) * index;
2023 case Ity_I16:
2024 if(index > 7) {
2025 goto invalidIndex;
2027 return vr_offset(archreg) + sizeof(UShort) * index;
2029 case Ity_I32:
2030 case Ity_F32:
2031 if(index > 3) {
2032 goto invalidIndex;
2034 return vr_offset(archreg) + sizeof(UInt) * index;
2036 case Ity_I64:
2037 case Ity_F64:
2038 if(index > 1) {
2039 goto invalidIndex;
2041 return vr_offset(archreg) + sizeof(ULong) * index;
2042 case Ity_V128:
2043 if(index == 0) {
2044 return vr_qw_offset(archreg);
2045 } else {
2046 goto invalidIndex;
2048 default:
2049 vpanic("s390_vr_offset_by_index: unknown type");
2052 invalidIndex:
2053 vex_printf("s390_vr_offset_by_index: index = %d ; type = ", index);
2054 ppIRType(type);
2055 vpanic("s390_vr_offset_by_index: invalid index for given type");
2058 /* Write type sized element to indexed part of vr to the guest state. */
2059 static void
2060 put_vr(UInt archreg, IRType type, UChar index, IRExpr *expr)
2062 UInt offset = s390_vr_offset_by_index(archreg, type, index);
2063 vassert(typeOfIRExpr(irsb->tyenv, expr) == type);
2065 stmt(IRStmt_Put(offset, expr));
2068 /* Read type sized part specified by index of a vr register. */
2069 static IRExpr *
2070 get_vr(UInt archreg, IRType type, UChar index)
2072 UInt offset = s390_vr_offset_by_index(archreg, type, index);
2073 return IRExpr_Get(offset, type);
2076 /* Calculates vr index according to instruction's rxb field
2077 and position of vr in instruction.
2078 Index of first argument must be 1 (not zero) */
2079 static UChar
2080 s390_vr_getVRindex(UChar v,UChar argNumber, UChar rxb)
2082 vassert(argNumber > 0 && argNumber <= 4);
2083 vassert(rxb < 16);
2084 return v | (((rxb) << argNumber) & 0b00010000);
2087 static void
2088 s390_vr_fill(UChar v1, IRExpr *o2)
2090 IRType o2type = typeOfIRExpr(irsb->tyenv, o2);
2091 switch (o2type) {
2092 case Ity_I8:
2093 put_vr_qw(v1, unop(Iop_Dup8x16, o2));
2094 break;
2095 case Ity_I16:
2096 put_vr_qw(v1, unop(Iop_Dup16x8, o2));
2097 break;
2098 case Ity_I32:
2099 put_vr_qw(v1, unop(Iop_Dup32x4, o2));
2100 break;
2101 case Ity_I64:
2102 put_vr_qw(v1, binop(Iop_64HLtoV128, o2, o2));
2103 break;
2104 default:
2105 ppIRType(o2type);
2106 vpanic("s390_vr_fill: invalid IRType");
2110 /* Returns Ity_I32 number of bytes till block boundary specified by m */
2111 static IRExpr*
2112 s390_getCountToBlockBoundary(IRTemp op2addr, UChar m)
2114 IRTemp boundary = newTemp(Ity_I32);
2115 IRTemp sixteen = newTemp(Ity_I32);
2116 IRTemp divisionResult = newTemp(Ity_I64);
2117 IRTemp mod_result = newTemp(Ity_I32);
2118 IRTemp output = newTemp(Ity_I32);
2120 switch (m) {
2121 case 0: assign(boundary, mkU32(64)); break;
2122 case 1: assign(boundary, mkU32(128)); break;
2123 case 2: assign(boundary, mkU32(256)); break;
2124 case 3: assign(boundary, mkU32(512)); break;
2125 case 4: assign(boundary, mkU32(1024)); break;
2126 case 5: assign(boundary, mkU32(2048)); break;
2127 case 6: assign(boundary, mkU32(4096)); break;
2128 default:
2129 vex_printf("m = %d\n", m);
2130 vpanic("s390_getCountToBlockBoundary: invalid m");
2132 assign(sixteen, mkU32(16));
2133 assign(divisionResult,
2134 binop(Iop_DivModU64to32, mkexpr(op2addr), mkexpr(boundary)));
2135 assign(mod_result,
2136 binop(Iop_Sub32,mkexpr(boundary),
2137 unop(Iop_64HIto32, mkexpr(divisionResult))));
2139 assign(output,
2140 mkite(binop(Iop_CmpLE32U, mkexpr(sixteen), mkexpr(mod_result)),
2141 mkexpr(sixteen),
2142 mkexpr(mod_result)
2145 return mkexpr(output);
2148 /* Load bytes into v1.
2149 maxIndex specifies max index to load and must be Ity_I32.
2150 If maxIndex >= 15, all 16 bytes are loaded.
2151 All bytes after maxIndex are zeroed. */
2152 static void s390_vr_loadWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex)
2154 IRTemp maxIdx = newTemp(Ity_I32);
2155 IRTemp cappedMax = newTemp(Ity_I64);
2156 IRTemp offset = newTemp(Ity_I64);
2157 IRTemp zeroed = newTemp(Ity_I64);
2158 IRTemp back = newTemp(Ity_I64);
2160 /* Implement the insn with a single 16-byte load, to allow memcheck's
2161 "partial-loads-OK" heuristic to apply. Ensure that a page boundary is
2162 crossed if and only if the real insn would have crossed it as well.
2163 Thus, if the bytes to load are fully contained in an aligned 16-byte
2164 chunk, load the whole 16-byte aligned chunk, and otherwise load 16 bytes
2165 from the unaligned address. Then shift the loaded data left-aligned
2166 into the target vector register. */
2168 assign(maxIdx, maxIndex);
2169 assign(cappedMax, mkite(binop(Iop_CmpLT32U, mkexpr(maxIdx), mkU32(15)),
2170 unop(Iop_32Uto64, mkexpr(maxIdx)), mkU64(15)));
2171 /* 'offset': addr's offset from last 16-byte aligned address
2172 'zeroed': number of bytes to be zeroed in the target vector
2173 'back': how much to subtract from addr before loading 16 bytes */
2174 assign(offset, binop(Iop_And64, mkexpr(addr), mkU64(15)));
2175 assign(zeroed, binop(Iop_Sub64, mkU64(15), mkexpr(cappedMax)));
2176 assign(back, mkite(binop(Iop_CmpLE64U, mkexpr(offset), mkexpr(zeroed)),
2177 mkexpr(offset), mkU64(0)));
2179 /* How much to shift the loaded 16-byte vector to the right, and then to
2180 the left. Since both 'zeroed' and 'back' range from 0 to 15, the shift
2181 amounts range from 0 to 120. */
2182 IRExpr *shrAmount = binop(Iop_Shl64,
2183 binop(Iop_Sub64, mkexpr(zeroed), mkexpr(back)),
2184 mkU8(3));
2185 IRExpr *shlAmount = binop(Iop_Shl64, mkexpr(zeroed), mkU8(3));
2187 put_vr_qw(v1, binop(Iop_ShlV128,
2188 binop(Iop_ShrV128,
2189 load(Ity_V128,
2190 binop(Iop_Sub64, mkexpr(addr), mkexpr(back))),
2191 unop(Iop_64to8, shrAmount)),
2192 unop(Iop_64to8, shlAmount)));
2195 /* Bitwise vCond ? v1 : v2
2196 All args are V128.
2198 static IRExpr*
2199 s390_V128_bitwiseITE(IRExpr* vCond, IRExpr* v1, IRExpr* v2)
2201 IRTemp vc = newTemp(Ity_V128);
2202 assign(vc, vCond);
2203 /* result = (v1 & vCond) | (v2 & ~vCond) */
2204 return binop(Iop_OrV128,
2205 binop(Iop_AndV128, v1, mkexpr(vc)),
2206 binop(Iop_AndV128, v2, unop(Iop_NotV128, mkexpr(vc))));
2209 /*------------------------------------------------------------*/
2210 /*--- Rounding modes ---*/
2211 /*------------------------------------------------------------*/
2213 /* Extract the bfp rounding mode from the guest FPC reg and encode it as an
2214 IRRoundingMode:
2216 rounding mode | s390 | IR
2217 -------------------------
2218 to nearest | 00 | 00
2219 to zero | 01 | 11
2220 to +infinity | 10 | 10
2221 to -infinity | 11 | 01
2223 So: IR = (4 - s390) & 3
2225 static IRExpr *
2226 get_bfp_rounding_mode_from_fpc(void)
2228 IRTemp fpc_bits = newTemp(Ity_I32);
2230 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
2231 Prior to that bits [30:31] contained the bfp rounding mode with
2232 bit 29 being unused and having a value of 0. So we can always
2233 extract the least significant 3 bits. */
2234 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
2236 /* fixs390:
2239 if (! s390_host_has_fpext && rounding_mode > 3) {
2240 emulation warning @ runtime and
2241 set fpc to round nearest
2245 /* For now silently adjust an unsupported rounding mode to "nearest" */
2246 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
2247 mkexpr(fpc_bits),
2248 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
2250 // rm_IR = (4 - rm_s390) & 3;
2251 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
2254 /* Encode the s390 rounding mode as it appears in the m3 field of certain
2255 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
2256 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
2257 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
2258 considers the default rounding mode (4.3.3). */
2259 static IRTemp
2260 encode_bfp_rounding_mode(UChar mode)
2262 IRExpr *rm;
2264 switch (mode) {
2265 case S390_BFP_ROUND_PER_FPC:
2266 rm = get_bfp_rounding_mode_from_fpc();
2267 break;
2268 case S390_BFP_ROUND_NEAREST_AWAY: rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
2269 case S390_BFP_ROUND_PREPARE_SHORT: rm = mkU32(Irrm_PREPARE_SHORTER); break;
2270 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
2271 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
2272 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
2273 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
2274 default:
2275 vpanic("encode_bfp_rounding_mode");
2278 return mktemp(Ity_I32, rm);
2281 /* Extract the DFP rounding mode from the guest FPC reg and encode it as an
2282 IRRoundingMode:
2284 rounding mode | s390 | IR
2285 ------------------------------------------------
2286 to nearest, ties to even | 000 | 000
2287 to zero | 001 | 011
2288 to +infinity | 010 | 010
2289 to -infinity | 011 | 001
2290 to nearest, ties away from 0 | 100 | 100
2291 to nearest, ties toward 0 | 101 | 111
2292 to away from 0 | 110 | 110
2293 to prepare for shorter precision | 111 | 101
2295 So: IR = (s390 ^ ((s390 << 1) & 2))
2297 static IRExpr *
2298 get_dfp_rounding_mode_from_fpc(void)
2300 IRTemp fpc_bits = newTemp(Ity_I32);
2302 /* The dfp rounding mode is stored in bits [25:27].
2303 extract the bits at 25:27 and right shift 4 times. */
2304 assign(fpc_bits, binop(Iop_Shr32,
2305 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
2306 mkU8(4)));
2308 IRExpr *rm_s390 = mkexpr(fpc_bits);
2309 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
2311 return binop(Iop_Xor32, rm_s390,
2312 binop( Iop_And32,
2313 binop(Iop_Shl32, rm_s390, mkU8(1)),
2314 mkU32(2)));
2317 /* Encode the s390 rounding mode as it appears in the m3 field of certain
2318 instructions to VEX's IRRoundingMode. */
2319 static IRTemp
2320 encode_dfp_rounding_mode(UChar mode)
2322 IRExpr *rm;
2324 switch (mode) {
2325 case S390_DFP_ROUND_PER_FPC_0:
2326 case S390_DFP_ROUND_PER_FPC_2:
2327 rm = get_dfp_rounding_mode_from_fpc(); break;
2328 case S390_DFP_ROUND_NEAREST_EVEN_4:
2329 case S390_DFP_ROUND_NEAREST_EVEN_8:
2330 rm = mkU32(Irrm_NEAREST); break;
2331 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
2332 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
2333 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
2334 case S390_DFP_ROUND_PREPARE_SHORT_3:
2335 case S390_DFP_ROUND_PREPARE_SHORT_15:
2336 rm = mkU32(Irrm_PREPARE_SHORTER); break;
2337 case S390_DFP_ROUND_ZERO_5:
2338 case S390_DFP_ROUND_ZERO_9:
2339 rm = mkU32(Irrm_ZERO ); break;
2340 case S390_DFP_ROUND_POSINF_6:
2341 case S390_DFP_ROUND_POSINF_10:
2342 rm = mkU32(Irrm_PosINF); break;
2343 case S390_DFP_ROUND_NEGINF_7:
2344 case S390_DFP_ROUND_NEGINF_11:
2345 rm = mkU32(Irrm_NegINF); break;
2346 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
2347 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
2348 case S390_DFP_ROUND_AWAY_0:
2349 rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
2350 default:
2351 vpanic("encode_dfp_rounding_mode");
2354 return mktemp(Ity_I32, rm);
2358 /*------------------------------------------------------------*/
2359 /*--- Condition code helpers ---*/
2360 /*------------------------------------------------------------*/
2362 /* The result of a Iop_CmpFxx operation is a condition code. It is
2363 encoded using the values defined in type IRCmpFxxResult.
2364 Before we can store the condition code into the guest state (or do
2365 anything else with it for that matter) we need to convert it to
2366 the encoding that s390 uses. This is what this function does.
2368 s390 VEX b6 b2 b0 cc.1 cc.0
2369 0 0x40 EQ 1 0 0 0 0
2370 1 0x01 LT 0 0 1 0 1
2371 2 0x00 GT 0 0 0 1 0
2372 3 0x45 Unordered 1 1 1 1 1
2374 The following bits from the VEX encoding are interesting:
2375 b0, b2, b6 with b0 being the LSB. We observe:
2377 cc.0 = b0;
2378 cc.1 = b2 | (~b0 & ~b6)
2380 with cc being the s390 condition code.
2382 static IRExpr *
2383 convert_vex_bfpcc_to_s390(IRTemp vex_cc)
2385 IRTemp cc0 = newTemp(Ity_I32);
2386 IRTemp cc1 = newTemp(Ity_I32);
2387 IRTemp b0 = newTemp(Ity_I32);
2388 IRTemp b2 = newTemp(Ity_I32);
2389 IRTemp b6 = newTemp(Ity_I32);
2391 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
2392 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
2393 mkU32(1)));
2394 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
2395 mkU32(1)));
2397 assign(cc0, mkexpr(b0));
2398 assign(cc1, binop(Iop_Or32, mkexpr(b2),
2399 binop(Iop_And32,
2400 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
2401 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
2402 )));
2404 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
2408 /* The result of a Iop_CmpDxx operation is a condition code. It is
2409 encoded using the values defined in type IRCmpDxxResult.
2410 Before we can store the condition code into the guest state (or do
2411 anything else with it for that matter) we need to convert it to
2412 the encoding that s390 uses. This is what this function does. */
2413 static IRExpr *
2414 convert_vex_dfpcc_to_s390(IRTemp vex_cc)
2416 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
2417 same. currently. */
2418 return convert_vex_bfpcc_to_s390(vex_cc);
2422 /*------------------------------------------------------------*/
2423 /*--- Build IR for formats ---*/
2424 /*------------------------------------------------------------*/
2425 static void
2426 s390_format_I(const HChar *(*irgen)(UChar i),
2427 UChar i)
2429 const HChar *mnm = irgen(i);
2431 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2432 s390_disasm(ENC2(MNM, UINT), mnm, i);
2435 static void
2436 s390_format_E(const HChar *(*irgen)(void))
2438 const HChar *mnm = irgen();
2440 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2441 s390_disasm(ENC1(MNM), mnm);
2444 static void
2445 s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
2446 UChar r1, UShort i2)
2448 irgen(r1, i2);
2451 static void
2452 s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
2453 UChar r1, UShort i2)
2455 const HChar *mnm = irgen(r1, i2);
2457 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2458 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
2461 static void
2462 s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
2463 UChar r1, UShort i2)
2465 const HChar *mnm = irgen(r1, i2);
2467 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2468 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
2471 static void
2472 s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
2473 UChar r1, UShort i2)
2475 const HChar *mnm = irgen(r1, i2);
2477 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2478 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
2481 static void
2482 s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2483 UChar r1, UChar r3, UShort i2)
2485 const HChar *mnm = irgen(r1, r3, i2);
2487 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2488 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2491 static void
2492 s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2493 UChar r1, UChar r3, UShort i2)
2495 const HChar *mnm = irgen(r1, r3, i2);
2497 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2498 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
2501 static void
2502 s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
2503 UChar i4, UChar i5),
2504 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
2506 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
2508 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2509 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
2510 i5);
2513 static void
2514 s390_format_RIEv1(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3),
2515 UChar r1, UShort i2, UChar m3)
2517 const HChar *mnm = irgen(r1, i2, m3);
2519 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2520 s390_disasm(ENC4(MNM, GPR, UINT, UINT), mnm, r1, i2, m3);
2523 static void
2524 s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
2525 UChar m3),
2526 UChar r1, UChar r2, UShort i4, UChar m3)
2528 const HChar *mnm = irgen(r1, r2, i4, m3);
2530 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2531 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
2532 r2, m3, (Int)(Short)i4);
2535 static void
2536 s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
2537 UChar i2),
2538 UChar r1, UChar m3, UShort i4, UChar i2)
2540 const HChar *mnm = irgen(r1, m3, i4, i2);
2542 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2543 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
2544 r1, i2, m3, (Int)(Short)i4);
2547 static void
2548 s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
2549 UChar i2),
2550 UChar r1, UChar m3, UShort i4, UChar i2)
2552 const HChar *mnm = irgen(r1, m3, i4, i2);
2554 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2555 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
2556 (Int)(Char)i2, m3, (Int)(Short)i4);
2559 static void
2560 s390_format_RIE_RUPIX(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
2561 UChar i2),
2562 UChar r1, UChar m3, UShort i4, UChar i2, Int xmnm_kind)
2564 const HChar *mnm = irgen(r1, m3, i4, i2);
2566 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2567 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), xmnm_kind, mnm, m3, r1,
2568 (Int)(Char)i2, m3, (Int)(Short)i4);
2571 static void
2572 s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
2573 UChar r1, UInt i2)
2575 irgen(r1, i2);
2578 static void
2579 s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
2580 UChar r1, UInt i2)
2582 const HChar *mnm = irgen(r1, i2);
2584 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2585 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
2588 static void
2589 s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
2590 UChar r1, UInt i2)
2592 const HChar *mnm = irgen(r1, i2);
2594 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2595 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
2598 static void
2599 s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
2600 UChar r1, UInt i2)
2602 const HChar *mnm = irgen(r1, i2);
2604 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2605 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
2608 static void
2609 s390_format_RIL_UP(const HChar *(*irgen)(void),
2610 UChar r1, UInt i2)
2612 const HChar *mnm = irgen();
2614 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2615 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
2618 static void
2619 s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
2620 IRTemp op4addr),
2621 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
2623 const HChar *mnm;
2624 IRTemp op4addr = newTemp(Ity_I64);
2626 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2627 mkU64(0)));
2629 mnm = irgen(r1, m3, i2, op4addr);
2631 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2632 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2633 (Int)(Char)i2, m3, d4, 0, b4);
2636 static void
2637 s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
2638 IRTemp op4addr),
2639 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
2641 const HChar *mnm;
2642 IRTemp op4addr = newTemp(Ity_I64);
2644 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2645 mkU64(0)));
2647 mnm = irgen(r1, m3, i2, op4addr);
2649 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2650 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2651 i2, m3, d4, 0, b4);
2654 static void
2655 s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
2656 UChar r1, UChar r2)
2658 irgen(r1, r2);
2661 static void
2662 s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
2663 UChar r1, UChar r2)
2665 const HChar *mnm = irgen(r1, r2);
2667 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2668 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
2671 static void
2672 s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
2673 UChar r1, UChar r2)
2675 const HChar *mnm = irgen(r1, r2);
2677 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2678 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
2681 static void
2682 s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
2683 UChar r1, UChar r2)
2685 irgen(r1, r2);
2688 static void
2689 s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
2690 UChar r1, UChar r2)
2692 const HChar *mnm = irgen(r1, r2);
2694 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2695 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
2698 static void
2699 s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
2700 UChar r1, UChar r2)
2702 const HChar *mnm = irgen(r1, r2);
2704 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2705 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
2708 static void
2709 s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
2710 UChar r1, UChar r2)
2712 const HChar *mnm = irgen(r1, r2);
2714 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2715 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
2718 static void
2719 s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
2720 UChar r1, UChar r2)
2722 const HChar *mnm = irgen(r1, r2);
2724 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2725 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2728 static void
2729 s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
2730 UChar r1)
2732 const HChar *mnm = irgen(r1);
2734 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2735 s390_disasm(ENC2(MNM, GPR), mnm, r1);
2738 static void
2739 s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
2740 UChar r1)
2742 const HChar *mnm = irgen(r1);
2744 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2745 s390_disasm(ENC2(MNM, FPR), mnm, r1);
2748 static void
2749 s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
2750 UChar m3, UChar r1, UChar r2)
2752 const HChar *mnm = irgen(m3, r1, r2);
2754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2755 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
2758 static void
2759 s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
2760 UChar r1, UChar r3, UChar r2)
2762 const HChar *mnm = irgen(r1, r3, r2);
2764 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2765 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2768 static void
2769 s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2770 UChar r3, UChar r1, UChar r2)
2772 const HChar *mnm = irgen(r3, r1, r2);
2774 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2775 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2778 static void
2779 s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2780 UChar r2),
2781 UChar m3, UChar m4, UChar r1, UChar r2)
2783 const HChar *mnm = irgen(m3, m4, r1, r2);
2785 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2786 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2789 static void
2790 s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2791 UChar m4, UChar r1, UChar r2)
2793 const HChar *mnm = irgen(m4, r1, r2);
2795 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2796 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2799 static void
2800 s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2801 UChar r2),
2802 UChar m3, UChar m4, UChar r1, UChar r2)
2804 const HChar *mnm = irgen(m3, m4, r1, r2);
2806 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2807 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2810 static void
2811 s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2812 UChar r2),
2813 UChar m3, UChar m4, UChar r1, UChar r2)
2815 const HChar *mnm = irgen(m3, m4, r1, r2);
2817 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2818 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2822 static void
2823 s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
2824 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2826 irgen(m3, r1, r2);
2828 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2829 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2832 static void
2833 s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
2834 UChar r3, UChar r1, UChar r2)
2836 const HChar *mnm = irgen(r3, r1, r2);
2838 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2839 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2842 static void
2843 s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2844 UChar r3, UChar m4, UChar r1, UChar r2)
2846 const HChar *mnm = irgen(r3, m4, r1, r2);
2848 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2849 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2852 static void
2853 s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2854 UChar r3, UChar m4, UChar r1, UChar r2)
2856 const HChar *mnm = irgen(r3, m4, r1, r2);
2858 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2859 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2862 static void
2863 s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2864 UChar r3, UChar m4, UChar r1, UChar r2)
2866 const HChar *mnm = irgen(r3, m4, r1, r2);
2868 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2869 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2872 static void
2873 s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
2874 UChar r3, UChar r1, UChar r2)
2876 const HChar *mnm = irgen(r3, r1, r2);
2878 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2879 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2882 static void
2883 s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2884 IRTemp op4addr),
2885 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2887 const HChar *mnm;
2888 IRTemp op4addr = newTemp(Ity_I64);
2890 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2891 mkU64(0)));
2893 mnm = irgen(r1, r2, m3, op4addr);
2895 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2896 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2897 r2, m3, d4, 0, b4);
2900 static void
2901 s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2902 UChar r1, UChar b2, UShort d2)
2904 const HChar *mnm;
2905 IRTemp op2addr = newTemp(Ity_I64);
2907 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2908 mkU64(0)));
2910 mnm = irgen(r1, op2addr);
2912 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2913 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2916 static void
2917 s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2918 UChar r1, UChar r3, UChar b2, UShort d2)
2920 const HChar *mnm;
2921 IRTemp op2addr = newTemp(Ity_I64);
2923 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2924 mkU64(0)));
2926 mnm = irgen(r1, r3, op2addr);
2928 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2929 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2932 static void
2933 s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2934 UChar r1, UChar r3, UChar b2, UShort d2)
2936 const HChar *mnm;
2937 IRTemp op2addr = newTemp(Ity_I64);
2939 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2940 mkU64(0)));
2942 mnm = irgen(r1, r3, op2addr);
2944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2945 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2948 static void
2949 s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
2950 UChar r1, UChar r3, UChar b2, UShort d2)
2952 const HChar *mnm;
2953 IRTemp op2addr = newTemp(Ity_I64);
2955 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2956 mkU64(0)));
2958 mnm = irgen(r1, r3, op2addr);
2960 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2961 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2964 static void
2965 s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2966 UChar r1, UChar r3, UShort i2)
2968 const HChar *mnm = irgen(r1, r3, i2);
2970 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2971 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2974 static void
2975 s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2976 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2978 const HChar *mnm;
2979 IRTemp op2addr = newTemp(Ity_I64);
2980 IRTemp d2 = newTemp(Ity_I64);
2982 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2983 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2984 mkU64(0)));
2986 mnm = irgen(r1, r3, op2addr);
2988 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2989 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2992 static void
2993 s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
2994 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2996 const HChar *mnm;
2997 IRTemp op2addr = newTemp(Ity_I64);
2998 IRTemp d2 = newTemp(Ity_I64);
3000 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3001 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3002 mkU64(0)));
3004 mnm = irgen(r1, r3, op2addr);
3006 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3007 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
3010 static void
3011 s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
3012 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3014 const HChar *mnm;
3015 IRTemp op2addr = newTemp(Ity_I64);
3016 IRTemp d2 = newTemp(Ity_I64);
3018 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3019 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3020 mkU64(0)));
3022 mnm = irgen(r1, r3, op2addr);
3024 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3025 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
3028 static void
3029 s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3030 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
3031 Int xmnm_kind)
3033 IRTemp op2addr = newTemp(Ity_I64);
3034 IRTemp d2 = newTemp(Ity_I64);
3036 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
3038 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3039 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3040 mkU64(0)));
3042 irgen(r1, op2addr);
3044 vassert(dis_res->whatNext == Dis_Continue);
3046 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3047 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
3050 static void
3051 s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
3052 IRTemp op2addr),
3053 UChar r1, UChar x2, UChar b2, UShort d2)
3055 IRTemp op2addr = newTemp(Ity_I64);
3057 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3058 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3059 mkU64(0)));
3061 irgen(r1, x2, b2, d2, op2addr);
3064 static void
3065 s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3066 UChar r1, UChar x2, UChar b2, UShort d2)
3068 const HChar *mnm;
3069 IRTemp op2addr = newTemp(Ity_I64);
3071 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3072 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3073 mkU64(0)));
3075 mnm = irgen(r1, op2addr);
3077 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3078 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
3081 static void
3082 s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3083 UChar r1, UChar x2, UChar b2, UShort d2)
3085 const HChar *mnm;
3086 IRTemp op2addr = newTemp(Ity_I64);
3088 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3089 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3090 mkU64(0)));
3092 mnm = irgen(r1, op2addr);
3094 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3095 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
3098 static void
3099 s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3100 UChar r1, UChar x2, UChar b2, UShort d2)
3102 const HChar *mnm;
3103 IRTemp op2addr = newTemp(Ity_I64);
3105 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3106 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3107 mkU64(0)));
3109 mnm = irgen(r1, op2addr);
3111 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3112 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
3115 static void
3116 s390_format_RXE_RRRDR(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar m3),
3117 UChar r1, UChar x2, UChar b2, UShort d2, UChar m3)
3119 const HChar *mnm;
3120 IRTemp op2addr = newTemp(Ity_I64);
3122 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3123 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3124 mkU64(0)));
3126 mnm = irgen(r1, op2addr, m3);
3128 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3129 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
3132 static void
3133 s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
3134 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
3136 const HChar *mnm;
3137 IRTemp op2addr = newTemp(Ity_I64);
3139 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3140 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3141 mkU64(0)));
3143 mnm = irgen(r3, op2addr, r1);
3145 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3146 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
3149 static void
3150 s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3151 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3153 const HChar *mnm;
3154 IRTemp op2addr = newTemp(Ity_I64);
3155 IRTemp d2 = newTemp(Ity_I64);
3157 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3158 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
3159 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3160 mkU64(0)));
3162 mnm = irgen(r1, op2addr);
3164 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3165 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
3168 static void
3169 s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3170 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3172 const HChar *mnm;
3173 IRTemp op2addr = newTemp(Ity_I64);
3174 IRTemp d2 = newTemp(Ity_I64);
3176 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3177 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
3178 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3179 mkU64(0)));
3181 mnm = irgen(r1, op2addr);
3183 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3184 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
3187 static void
3188 s390_format_RXY_URRD(const HChar *(*irgen)(void),
3189 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3191 const HChar *mnm;
3192 IRTemp op2addr = newTemp(Ity_I64);
3193 IRTemp d2 = newTemp(Ity_I64);
3195 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3196 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
3197 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3198 mkU64(0)));
3200 mnm = irgen();
3202 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3203 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
3206 static void
3207 s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
3208 UChar b2, UShort d2)
3210 const HChar *mnm;
3211 IRTemp op2addr = newTemp(Ity_I64);
3213 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3214 mkU64(0)));
3216 mnm = irgen(op2addr);
3218 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3219 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
3222 static void
3223 s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
3224 UChar i2, UChar b1, UShort d1)
3226 const HChar *mnm;
3227 IRTemp op1addr = newTemp(Ity_I64);
3229 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3230 mkU64(0)));
3232 mnm = irgen(i2, op1addr);
3234 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3235 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
3238 static void
3239 s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
3240 UChar i2, UChar b1, UShort dl1, UChar dh1)
3242 const HChar *mnm;
3243 IRTemp op1addr = newTemp(Ity_I64);
3244 IRTemp d1 = newTemp(Ity_I64);
3246 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
3247 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
3248 mkU64(0)));
3250 mnm = irgen(i2, op1addr);
3252 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3253 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
3256 static void
3257 s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
3258 UChar i2, UChar b1, UShort dl1, UChar dh1)
3260 const HChar *mnm;
3261 IRTemp op1addr = newTemp(Ity_I64);
3262 IRTemp d1 = newTemp(Ity_I64);
3264 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
3265 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
3266 mkU64(0)));
3268 mnm = irgen(i2, op1addr);
3270 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3271 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
3274 static void
3275 s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
3276 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
3278 const HChar *mnm;
3279 IRTemp op1addr = newTemp(Ity_I64);
3280 IRTemp op2addr = newTemp(Ity_I64);
3282 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3283 mkU64(0)));
3284 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3285 mkU64(0)));
3287 mnm = irgen(l, op1addr, op2addr);
3289 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3290 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
3293 static void
3294 s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
3295 UChar b1, UShort d1, UShort i2)
3297 const HChar *mnm;
3298 IRTemp op1addr = newTemp(Ity_I64);
3300 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3301 mkU64(0)));
3303 mnm = irgen(i2, op1addr);
3305 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3306 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
3309 static void
3310 s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
3311 UChar b1, UShort d1, UShort i2)
3313 const HChar *mnm;
3314 IRTemp op1addr = newTemp(Ity_I64);
3316 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3317 mkU64(0)));
3319 mnm = irgen(i2, op1addr);
3321 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3322 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
3325 static void
3326 s390_format_VRX_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr),
3327 UChar v1, UChar x2, UChar b2, UShort d2, UChar rxb)
3329 const HChar *mnm;
3330 IRTemp op2addr = newTemp(Ity_I64);
3332 if (! s390_host_has_vx) {
3333 emulation_failure(EmFail_S390X_vx);
3334 return;
3337 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3338 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3339 mkU64(0)));
3341 v1 = s390_vr_getVRindex(v1, 1, rxb);
3342 mnm = irgen(v1, op2addr);
3344 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3345 s390_disasm(ENC3(MNM, VR, UDXB), mnm, v1, d2, x2, b2);
3349 static void
3350 s390_format_VRX_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3),
3351 UChar v1, UChar x2, UChar b2, UShort d2, UChar m3, UChar rxb)
3353 const HChar *mnm;
3354 IRTemp op2addr = newTemp(Ity_I64);
3356 if (! s390_host_has_vx) {
3357 emulation_failure(EmFail_S390X_vx);
3358 return;
3361 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3362 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3363 mkU64(0)));
3365 v1 = s390_vr_getVRindex(v1, 1, rxb);
3366 mnm = irgen(v1, op2addr, m3);
3368 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3369 s390_disasm(ENC3(MNM, VR, UDXB), mnm, v1, d2, x2, b2);
3373 static void
3374 s390_format_VRR_VV(const HChar *(*irgen)(UChar v1, UChar v2),
3375 UChar v1, UChar v2, UChar rxb)
3377 const HChar *mnm;
3379 if (! s390_host_has_vx) {
3380 emulation_failure(EmFail_S390X_vx);
3381 return;
3384 v1 = s390_vr_getVRindex(v1, 1, rxb);
3385 v2 = s390_vr_getVRindex(v2, 2, rxb);
3386 mnm = irgen(v1, v2);
3388 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3389 s390_disasm(ENC3(MNM, VR, VR), mnm, v1, v2);
3393 static void
3394 s390_format_VRR_VVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3),
3395 UChar v1, UChar v2, UChar v3, UChar rxb)
3397 const HChar *mnm;
3399 if (! s390_host_has_vx) {
3400 emulation_failure(EmFail_S390X_vx);
3401 return;
3404 v1 = s390_vr_getVRindex(v1, 1, rxb);
3405 v2 = s390_vr_getVRindex(v2, 2, rxb);
3406 v3 = s390_vr_getVRindex(v3, 3, rxb);
3407 mnm = irgen(v1, v2, v3);
3409 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3410 s390_disasm(ENC4(MNM, VR, VR, VR), mnm, v1, v2, v3);
3414 static void
3415 s390_format_VRR_VVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4),
3416 UChar v1, UChar v2, UChar v3, UChar m4, UChar rxb)
3418 const HChar *mnm;
3420 if (! s390_host_has_vx) {
3421 emulation_failure(EmFail_S390X_vx);
3422 return;
3425 v1 = s390_vr_getVRindex(v1, 1, rxb);
3426 v2 = s390_vr_getVRindex(v2, 2, rxb);
3427 v3 = s390_vr_getVRindex(v3, 3, rxb);
3428 mnm = irgen(v1, v2, v3, m4);
3430 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3431 s390_disasm(ENC5(MNM, VR, VR, VR, UINT), mnm, v1, v2, v3, m4);
3435 static void
3436 s390_format_VRR_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5),
3437 UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar rxb)
3439 const HChar *mnm;
3441 if (! s390_host_has_vx) {
3442 emulation_failure(EmFail_S390X_vx);
3443 return;
3446 v1 = s390_vr_getVRindex(v1, 1, rxb);
3447 v2 = s390_vr_getVRindex(v2, 2, rxb);
3448 v3 = s390_vr_getVRindex(v3, 3, rxb);
3449 mnm = irgen(v1, v2, v3, m4, m5);
3451 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3452 s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, m4, m5);
3456 static void
3457 s390_format_VRR_VVVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar v4),
3458 UChar v1, UChar v2, UChar v3, UChar v4, UChar rxb)
3460 const HChar *mnm;
3462 if (! s390_host_has_vx) {
3463 emulation_failure(EmFail_S390X_vx);
3464 return;
3467 v1 = s390_vr_getVRindex(v1, 1, rxb);
3468 v2 = s390_vr_getVRindex(v2, 2, rxb);
3469 v3 = s390_vr_getVRindex(v3, 3, rxb);
3470 v4 = s390_vr_getVRindex(v4, 4, rxb);
3471 mnm = irgen(v1, v2, v3, v4);
3473 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3474 s390_disasm(ENC5(MNM, VR, VR, VR, VR), mnm, v1, v2, v3, v4);
3478 static void
3479 s390_format_VRR_VRR(const HChar *(*irgen)(UChar v1, UChar r2, UChar r3),
3480 UChar v1, UChar r2, UChar r3, UChar rxb)
3482 const HChar *mnm;
3484 if (! s390_host_has_vx) {
3485 emulation_failure(EmFail_S390X_vx);
3486 return;
3489 v1 = s390_vr_getVRindex(v1, 1, rxb);
3490 mnm = irgen(v1, r2, r3);
3492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3493 s390_disasm(ENC4(MNM, VR, GPR, GPR), mnm, v1, r2, r3);
3497 static void
3498 s390_format_VRR_VVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3),
3499 UChar v1, UChar v2, UChar m3, UChar rxb)
3501 const HChar *mnm;
3503 if (! s390_host_has_vx) {
3504 emulation_failure(EmFail_S390X_vx);
3505 return;
3508 v1 = s390_vr_getVRindex(v1, 1, rxb);
3509 v2 = s390_vr_getVRindex(v2, 2, rxb);
3510 mnm = irgen(v1, v2, m3);
3512 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3513 s390_disasm(ENC4(MNM, VR, VR, UINT), mnm, v1, v2, m3);
3517 static void
3518 s390_format_VRI_VIM(const HChar *(*irgen)(UChar v1, UShort i2, UChar m3),
3519 UChar v1, UShort i2, UChar m3, UChar rxb)
3521 const HChar *mnm;
3523 if (! s390_host_has_vx) {
3524 emulation_failure(EmFail_S390X_vx);
3525 return;
3528 v1 = s390_vr_getVRindex(v1, 1, rxb);
3529 mnm = irgen(v1, i2, m3);
3531 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3532 s390_disasm(ENC4(MNM, VR, UINT, UINT), mnm, v1, i2, m3);
3536 static void
3537 s390_format_VRI_VVIM(const HChar *(*irgen)(UChar v1, UChar v3, UShort i2, UChar m4),
3538 UChar v1, UChar v3, UShort i2, UChar m4, UChar rxb)
3540 const HChar *mnm;
3542 if (! s390_host_has_vx) {
3543 emulation_failure(EmFail_S390X_vx);
3544 return;
3547 v1 = s390_vr_getVRindex(v1, 1, rxb);
3548 v3 = s390_vr_getVRindex(v3, 2, rxb);
3549 mnm = irgen(v1, v3, i2, m4);
3551 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3552 s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v3, i2, m4);
3555 static void
3556 s390_format_VRI_VVIMM(const HChar *(*irgen)(UChar v1, UChar v2, UShort i3,
3557 UChar m4, UChar m5),
3558 UChar v1, UChar v2, UShort i3, UChar m4, UChar m5,
3559 UChar rxb)
3561 const HChar *mnm;
3563 if (!s390_host_has_vx) {
3564 emulation_failure(EmFail_S390X_vx);
3565 return;
3568 v1 = s390_vr_getVRindex(v1, 1, rxb);
3569 v2 = s390_vr_getVRindex(v2, 2, rxb);
3570 mnm = irgen(v1, v2, i3, m4, m5);
3572 if (vex_traceflags & VEX_TRACE_FE)
3573 s390_disasm(ENC6(MNM, VR, VR, UINT, UINT, UINT), mnm, v1, v2, i3, m4, m5);
3576 static void
3577 s390_format_VRS_RRDVM(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar v3,
3578 UChar m4), UChar r1, UChar b2, UShort d2, UChar v3,
3579 UChar m4, UChar rxb)
3581 const HChar *mnm;
3582 IRTemp op2addr = newTemp(Ity_I64);
3584 if (! s390_host_has_vx) {
3585 emulation_failure(EmFail_S390X_vx);
3586 return;
3589 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3590 mkU64(0)));
3592 v3 = s390_vr_getVRindex(v3, 2, rxb);
3593 mnm = irgen(r1, op2addr, v3, m4);
3595 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3596 s390_disasm(ENC5(MNM, GPR, UDXB, VR, UINT), mnm, r1, d2, 0, b2, v3, m4);
3600 static void
3601 s390_format_VRS_VRDVM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3,
3602 UChar m4), UChar v1, UChar b2, UShort d2, UChar v3,
3603 UChar m4, UChar rxb)
3605 const HChar *mnm;
3606 IRTemp op2addr = newTemp(Ity_I64);
3608 if (! s390_host_has_vx) {
3609 emulation_failure(EmFail_S390X_vx);
3610 return;
3613 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3614 mkU64(0)));
3616 v1 = s390_vr_getVRindex(v1, 1, rxb);
3617 v3 = s390_vr_getVRindex(v3, 2, rxb);
3618 mnm = irgen(v1, op2addr, v3, m4);
3620 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3621 s390_disasm(ENC5(MNM, VR, UDXB, VR, UINT), mnm, v1, d2, 0, b2, v3, m4);
3625 static void
3626 s390_format_VRS_VRDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3),
3627 UChar v1, UChar b2, UShort d2, UChar v3, UChar rxb)
3629 const HChar *mnm;
3630 IRTemp op2addr = newTemp(Ity_I64);
3632 if (! s390_host_has_vx) {
3633 emulation_failure(EmFail_S390X_vx);
3634 return;
3637 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3638 mkU64(0)));
3640 v1 = s390_vr_getVRindex(v1, 1, rxb);
3641 v3 = s390_vr_getVRindex(v3, 2, rxb);
3642 mnm = irgen(v1, op2addr, v3);
3644 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3645 s390_disasm(ENC4(MNM, VR, UDXB, VR), mnm, v1, d2, 0, b2, v3);
3649 static void
3650 s390_format_VRS_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3,
3651 UChar m4),
3652 UChar v1, UChar b2, UShort d2, UChar r3, UChar m4, UChar rxb)
3654 const HChar *mnm;
3655 IRTemp op2addr = newTemp(Ity_I64);
3657 if (! s390_host_has_vx) {
3658 emulation_failure(EmFail_S390X_vx);
3659 return;
3662 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3663 mkU64(0)));
3665 v1 = s390_vr_getVRindex(v1, 1, rxb);
3666 mnm = irgen(v1, op2addr, r3, m4);
3668 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3669 s390_disasm(ENC5(MNM, VR, GPR, UDXB, UINT), mnm, v1, r3, d2, 0, b2, m4);
3673 static void
3674 s390_format_VRS_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3),
3675 UChar v1, UChar b2, UShort d2, UChar r3, UChar rxb)
3677 const HChar *mnm;
3678 IRTemp op2addr = newTemp(Ity_I64);
3680 if (! s390_host_has_vx) {
3681 emulation_failure(EmFail_S390X_vx);
3682 return;
3685 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3686 mkU64(0)));
3688 v1 = s390_vr_getVRindex(v1, 1, rxb);
3689 mnm = irgen(v1, op2addr, r3);
3691 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3692 s390_disasm(ENC4(MNM, VR, GPR, UDXB), mnm, v1, r3, d2, 0, b2);
3696 static void
3697 s390_format_VRV_VVRDMT(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3),
3698 UChar v1, UChar v2, UChar b2, UShort d2, UChar m3, UChar rxb,
3699 IRType type)
3701 const HChar *mnm;
3702 IRTemp op2addr = newTemp(Ity_I64);
3704 if (! s390_host_has_vx) {
3705 emulation_failure(EmFail_S390X_vx);
3706 return;
3709 v1 = s390_vr_getVRindex(v1, 1, rxb);
3710 v2 = s390_vr_getVRindex(v2, 2, rxb);
3712 vassert(type == Ity_I32 || type == Ity_I64);
3713 IRExpr *x2;
3714 if(type == Ity_I32) {
3715 x2 = unop(Iop_32Uto64, get_vr(v2, type, m3));
3716 } else {
3717 x2 = get_vr(v2, type, m3);
3720 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3721 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2));
3723 mnm = irgen(v1, op2addr, m3);
3725 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3726 s390_disasm(ENC4(MNM, VR, UDVB, UINT), mnm, v1, d2, v2, b2, m3);
3730 static void
3731 s390_format_VRR_VVVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3732 UChar v4, UChar m5, UChar m6),
3733 UChar v1, UChar v2, UChar v3, UChar v4, UChar m5,
3734 UChar m6, UChar rxb)
3736 const HChar *mnm;
3738 if (! s390_host_has_vx) {
3739 emulation_failure(EmFail_S390X_vx);
3740 return;
3743 v1 = s390_vr_getVRindex(v1, 1, rxb);
3744 v2 = s390_vr_getVRindex(v2, 2, rxb);
3745 v3 = s390_vr_getVRindex(v3, 3, rxb);
3746 v4 = s390_vr_getVRindex(v4, 4, rxb);
3747 mnm = irgen(v1, v2, v3, v4, m5, m6);
3749 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3750 s390_disasm(ENC7(MNM, VR, VR, VR, VR, UINT, UINT),
3751 mnm, v1, v2, v3, v4, m5, m6);
3755 static void
3756 s390_format_VRR_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3,
3757 UChar m5),
3758 UChar v1, UChar v2, UChar m3, UChar m5, UChar rxb)
3760 const HChar *mnm;
3762 if (! s390_host_has_vx) {
3763 emulation_failure(EmFail_S390X_vx);
3764 return;
3767 v1 = s390_vr_getVRindex(v1, 1, rxb);
3768 v2 = s390_vr_getVRindex(v2, 2, rxb);
3769 mnm = irgen(v1, v2, m3, m5);
3771 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3772 s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v2, m3, m5);
3776 static void
3777 s390_format_VRId_VVVIM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3778 UChar i4, UChar m5),
3779 UChar v1, UChar v2, UChar v3, UChar i4, UChar m5,
3780 UChar rxb)
3782 const HChar *mnm;
3784 if (! s390_host_has_vx) {
3785 emulation_failure(EmFail_S390X_vx);
3786 return;
3789 v1 = s390_vr_getVRindex(v1, 1, rxb);
3790 v2 = s390_vr_getVRindex(v2, 2, rxb);
3791 v3 = s390_vr_getVRindex(v3, 3, rxb);
3792 mnm = irgen(v1, v2, v3, i4, m5);
3794 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3795 s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, i4, m5);
3799 static void
3800 s390_format_VRId_VVVI(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3801 UChar i4),
3802 UChar v1, UChar v2, UChar v3, UChar i4, UChar rxb)
3804 const HChar *mnm;
3806 if (! s390_host_has_vx) {
3807 emulation_failure(EmFail_S390X_vx);
3808 return;
3811 v1 = s390_vr_getVRindex(v1, 1, rxb);
3812 v2 = s390_vr_getVRindex(v2, 2, rxb);
3813 v3 = s390_vr_getVRindex(v3, 3, rxb);
3814 mnm = irgen(v1, v2, v3, i4);
3816 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3817 s390_disasm(ENC5(MNM, VR, VR, VR, UINT), mnm, v1, v2, v3, i4);
3821 static void
3822 s390_format_VRRd_VVVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3823 UChar v4, UChar m5),
3824 UChar v1, UChar v2, UChar v3, UChar v4, UChar m5,
3825 UChar rxb)
3827 const HChar *mnm;
3829 if (! s390_host_has_vx) {
3830 emulation_failure(EmFail_S390X_vx);
3831 return;
3834 v1 = s390_vr_getVRindex(v1, 1, rxb);
3835 v2 = s390_vr_getVRindex(v2, 2, rxb);
3836 v3 = s390_vr_getVRindex(v3, 3, rxb);
3837 v4 = s390_vr_getVRindex(v4, 4, rxb);
3838 mnm = irgen(v1, v2, v3, v4, m5);
3840 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3841 s390_disasm(ENC6(MNM, VR, VR, VR, VR, UINT), mnm, v1, v2, v3, v4, m5);
3845 static void
3846 s390_format_VRRa_VVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3,
3847 UChar m4, UChar m5),
3848 UChar v1, UChar v2, UChar m3, UChar m4, UChar m5,
3849 UChar rxb)
3851 const HChar *mnm;
3853 if (!s390_host_has_vx) {
3854 emulation_failure(EmFail_S390X_vx);
3855 return;
3858 v1 = s390_vr_getVRindex(v1, 1, rxb);
3859 v2 = s390_vr_getVRindex(v2, 2, rxb);
3860 mnm = irgen(v1, v2, m3, m4, m5);
3862 if (vex_traceflags & VEX_TRACE_FE)
3863 s390_disasm(ENC6(MNM, VR, VR, UINT, UINT, UINT), mnm, v1, v2, m3, m4, m5);
3866 static void
3867 s390_format_VRRa_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3868 UChar m4, UChar m5),
3869 UChar v1, UChar v2, UChar v3, UChar m4, UChar m5,
3870 UChar rxb)
3872 const HChar *mnm;
3874 if (!s390_host_has_vx) {
3875 emulation_failure(EmFail_S390X_vx);
3876 return;
3879 v1 = s390_vr_getVRindex(v1, 1, rxb);
3880 v2 = s390_vr_getVRindex(v2, 2, rxb);
3881 v3 = s390_vr_getVRindex(v3, 3, rxb);
3882 mnm = irgen(v1, v2, v3, m4, m5);
3884 if (vex_traceflags & VEX_TRACE_FE)
3885 s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, m4, m5);
3888 static void
3889 s390_format_VRRa_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3,
3890 UChar m4),
3891 UChar v1, UChar v2, UChar m3, UChar m4, UChar rxb)
3893 const HChar *mnm;
3895 if (!s390_host_has_vx) {
3896 emulation_failure(EmFail_S390X_vx);
3897 return;
3900 v1 = s390_vr_getVRindex(v1, 1, rxb);
3901 v2 = s390_vr_getVRindex(v2, 2, rxb);
3902 mnm = irgen(v1, v2, m3, m4);
3904 if (vex_traceflags & VEX_TRACE_FE)
3905 s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v2, m3, m4);
3908 static void
3909 s390_format_VRRa_VVVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3910 UChar m4, UChar m5, UChar m6),
3911 UChar v1, UChar v2, UChar v3, UChar m4, UChar m5,
3912 UChar m6, UChar rxb)
3914 const HChar *mnm;
3916 if (!s390_host_has_vx) {
3917 emulation_failure(EmFail_S390X_vx);
3918 return;
3921 v1 = s390_vr_getVRindex(v1, 1, rxb);
3922 v2 = s390_vr_getVRindex(v2, 2, rxb);
3923 v3 = s390_vr_getVRindex(v3, 3, rxb);
3924 mnm = irgen(v1, v2, v3, m4, m5, m6);
3926 if (vex_traceflags & VEX_TRACE_FE)
3927 s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT),
3928 mnm, v1, v2, v3, m4, m5, m6);
3931 /*------------------------------------------------------------*/
3932 /*--- Build IR for opcodes ---*/
3933 /*------------------------------------------------------------*/
3935 static const HChar *
3936 s390_irgen_AR(UChar r1, UChar r2)
3938 IRTemp op1 = newTemp(Ity_I32);
3939 IRTemp op2 = newTemp(Ity_I32);
3940 IRTemp result = newTemp(Ity_I32);
3942 assign(op1, get_gpr_w1(r1));
3943 assign(op2, get_gpr_w1(r2));
3944 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3945 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
3946 put_gpr_w1(r1, mkexpr(result));
3948 return "ar";
3951 static const HChar *
3952 s390_irgen_AGR(UChar r1, UChar r2)
3954 IRTemp op1 = newTemp(Ity_I64);
3955 IRTemp op2 = newTemp(Ity_I64);
3956 IRTemp result = newTemp(Ity_I64);
3958 assign(op1, get_gpr_dw0(r1));
3959 assign(op2, get_gpr_dw0(r2));
3960 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3961 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
3962 put_gpr_dw0(r1, mkexpr(result));
3964 return "agr";
3967 static const HChar *
3968 s390_irgen_AGFR(UChar r1, UChar r2)
3970 IRTemp op1 = newTemp(Ity_I64);
3971 IRTemp op2 = newTemp(Ity_I64);
3972 IRTemp result = newTemp(Ity_I64);
3974 assign(op1, get_gpr_dw0(r1));
3975 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3976 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3977 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
3978 put_gpr_dw0(r1, mkexpr(result));
3980 return "agfr";
3983 static const HChar *
3984 s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
3986 IRTemp op2 = newTemp(Ity_I32);
3987 IRTemp op3 = newTemp(Ity_I32);
3988 IRTemp result = newTemp(Ity_I32);
3990 assign(op2, get_gpr_w1(r2));
3991 assign(op3, get_gpr_w1(r3));
3992 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3993 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
3994 put_gpr_w1(r1, mkexpr(result));
3996 return "ark";
3999 static const HChar *
4000 s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
4002 IRTemp op2 = newTemp(Ity_I64);
4003 IRTemp op3 = newTemp(Ity_I64);
4004 IRTemp result = newTemp(Ity_I64);
4006 assign(op2, get_gpr_dw0(r2));
4007 assign(op3, get_gpr_dw0(r3));
4008 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
4009 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
4010 put_gpr_dw0(r1, mkexpr(result));
4012 return "agrk";
4015 static const HChar *
4016 s390_irgen_A(UChar r1, IRTemp op2addr)
4018 IRTemp op1 = newTemp(Ity_I32);
4019 IRTemp op2 = newTemp(Ity_I32);
4020 IRTemp result = newTemp(Ity_I32);
4022 assign(op1, get_gpr_w1(r1));
4023 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4024 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4025 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4026 put_gpr_w1(r1, mkexpr(result));
4028 return "a";
4031 static const HChar *
4032 s390_irgen_AY(UChar r1, IRTemp op2addr)
4034 IRTemp op1 = newTemp(Ity_I32);
4035 IRTemp op2 = newTemp(Ity_I32);
4036 IRTemp result = newTemp(Ity_I32);
4038 assign(op1, get_gpr_w1(r1));
4039 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4040 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4041 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4042 put_gpr_w1(r1, mkexpr(result));
4044 return "ay";
4047 static const HChar *
4048 s390_irgen_AG(UChar r1, IRTemp op2addr)
4050 IRTemp op1 = newTemp(Ity_I64);
4051 IRTemp op2 = newTemp(Ity_I64);
4052 IRTemp result = newTemp(Ity_I64);
4054 assign(op1, get_gpr_dw0(r1));
4055 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4056 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4057 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4058 put_gpr_dw0(r1, mkexpr(result));
4060 return "ag";
4063 static const HChar *
4064 s390_irgen_AGF(UChar r1, IRTemp op2addr)
4066 IRTemp op1 = newTemp(Ity_I64);
4067 IRTemp op2 = newTemp(Ity_I64);
4068 IRTemp result = newTemp(Ity_I64);
4070 assign(op1, get_gpr_dw0(r1));
4071 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
4072 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4073 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4074 put_gpr_dw0(r1, mkexpr(result));
4076 return "agf";
4079 static const HChar *
4080 s390_irgen_AFI(UChar r1, UInt i2)
4082 IRTemp op1 = newTemp(Ity_I32);
4083 Int op2;
4084 IRTemp result = newTemp(Ity_I32);
4086 assign(op1, get_gpr_w1(r1));
4087 op2 = (Int)i2;
4088 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4089 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4090 mkU32((UInt)op2)));
4091 put_gpr_w1(r1, mkexpr(result));
4093 return "afi";
4096 static const HChar *
4097 s390_irgen_AGFI(UChar r1, UInt i2)
4099 IRTemp op1 = newTemp(Ity_I64);
4100 Long op2;
4101 IRTemp result = newTemp(Ity_I64);
4103 assign(op1, get_gpr_dw0(r1));
4104 op2 = (Long)(Int)i2;
4105 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
4106 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
4107 mkU64((ULong)op2)));
4108 put_gpr_dw0(r1, mkexpr(result));
4110 return "agfi";
4113 static const HChar *
4114 s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
4116 Int op2;
4117 IRTemp op3 = newTemp(Ity_I32);
4118 IRTemp result = newTemp(Ity_I32);
4120 op2 = (Int)(Short)i2;
4121 assign(op3, get_gpr_w1(r3));
4122 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
4123 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
4124 op2)), op3);
4125 put_gpr_w1(r1, mkexpr(result));
4127 return "ahik";
4130 static const HChar *
4131 s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
4133 Long op2;
4134 IRTemp op3 = newTemp(Ity_I64);
4135 IRTemp result = newTemp(Ity_I64);
4137 op2 = (Long)(Short)i2;
4138 assign(op3, get_gpr_dw0(r3));
4139 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
4140 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
4141 op2)), op3);
4142 put_gpr_dw0(r1, mkexpr(result));
4144 return "aghik";
4147 static const HChar *
4148 s390_irgen_ASI(UChar i2, IRTemp op1addr)
4150 IRTemp op1 = newTemp(Ity_I32);
4151 Int op2;
4152 IRTemp result = newTemp(Ity_I32);
4154 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4155 op2 = (Int)(Char)i2;
4156 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4157 store(mkexpr(op1addr), mkexpr(result));
4158 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4159 mkU32((UInt)op2)));
4161 return "asi";
4164 static const HChar *
4165 s390_irgen_AGSI(UChar i2, IRTemp op1addr)
4167 IRTemp op1 = newTemp(Ity_I64);
4168 Long op2;
4169 IRTemp result = newTemp(Ity_I64);
4171 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4172 op2 = (Long)(Char)i2;
4173 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
4174 store(mkexpr(op1addr), mkexpr(result));
4175 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
4176 mkU64((ULong)op2)));
4178 return "agsi";
4181 static const HChar *
4182 s390_irgen_AH(UChar r1, IRTemp op2addr)
4184 IRTemp op1 = newTemp(Ity_I32);
4185 IRTemp op2 = newTemp(Ity_I32);
4186 IRTemp result = newTemp(Ity_I32);
4188 assign(op1, get_gpr_w1(r1));
4189 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4190 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4191 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4192 put_gpr_w1(r1, mkexpr(result));
4194 return "ah";
4197 static const HChar *
4198 s390_irgen_AHY(UChar r1, IRTemp op2addr)
4200 IRTemp op1 = newTemp(Ity_I32);
4201 IRTemp op2 = newTemp(Ity_I32);
4202 IRTemp result = newTemp(Ity_I32);
4204 assign(op1, get_gpr_w1(r1));
4205 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4206 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4207 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4208 put_gpr_w1(r1, mkexpr(result));
4210 return "ahy";
4213 static const HChar *
4214 s390_irgen_AHI(UChar r1, UShort i2)
4216 IRTemp op1 = newTemp(Ity_I32);
4217 Int op2;
4218 IRTemp result = newTemp(Ity_I32);
4220 assign(op1, get_gpr_w1(r1));
4221 op2 = (Int)(Short)i2;
4222 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4223 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4224 mkU32((UInt)op2)));
4225 put_gpr_w1(r1, mkexpr(result));
4227 return "ahi";
4230 static const HChar *
4231 s390_irgen_AGHI(UChar r1, UShort i2)
4233 IRTemp op1 = newTemp(Ity_I64);
4234 Long op2;
4235 IRTemp result = newTemp(Ity_I64);
4237 assign(op1, get_gpr_dw0(r1));
4238 op2 = (Long)(Short)i2;
4239 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
4240 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
4241 mkU64((ULong)op2)));
4242 put_gpr_dw0(r1, mkexpr(result));
4244 return "aghi";
4247 static const HChar *
4248 s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
4250 IRTemp op2 = newTemp(Ity_I32);
4251 IRTemp op3 = newTemp(Ity_I32);
4252 IRTemp result = newTemp(Ity_I32);
4254 assign(op2, get_gpr_w0(r2));
4255 assign(op3, get_gpr_w0(r3));
4256 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4257 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
4258 put_gpr_w0(r1, mkexpr(result));
4260 return "ahhhr";
4263 static const HChar *
4264 s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
4266 IRTemp op2 = newTemp(Ity_I32);
4267 IRTemp op3 = newTemp(Ity_I32);
4268 IRTemp result = newTemp(Ity_I32);
4270 assign(op2, get_gpr_w0(r2));
4271 assign(op3, get_gpr_w1(r3));
4272 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4273 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
4274 put_gpr_w0(r1, mkexpr(result));
4276 return "ahhlr";
4279 static const HChar *
4280 s390_irgen_AIH(UChar r1, UInt i2)
4282 IRTemp op1 = newTemp(Ity_I32);
4283 Int op2;
4284 IRTemp result = newTemp(Ity_I32);
4286 assign(op1, get_gpr_w0(r1));
4287 op2 = (Int)i2;
4288 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4289 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4290 mkU32((UInt)op2)));
4291 put_gpr_w0(r1, mkexpr(result));
4293 return "aih";
4296 static const HChar *
4297 s390_irgen_ALR(UChar r1, UChar r2)
4299 IRTemp op1 = newTemp(Ity_I32);
4300 IRTemp op2 = newTemp(Ity_I32);
4301 IRTemp result = newTemp(Ity_I32);
4303 assign(op1, get_gpr_w1(r1));
4304 assign(op2, get_gpr_w1(r2));
4305 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4306 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
4307 put_gpr_w1(r1, mkexpr(result));
4309 return "alr";
4312 static const HChar *
4313 s390_irgen_ALGR(UChar r1, UChar r2)
4315 IRTemp op1 = newTemp(Ity_I64);
4316 IRTemp op2 = newTemp(Ity_I64);
4317 IRTemp result = newTemp(Ity_I64);
4319 assign(op1, get_gpr_dw0(r1));
4320 assign(op2, get_gpr_dw0(r2));
4321 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4322 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4323 put_gpr_dw0(r1, mkexpr(result));
4325 return "algr";
4328 static const HChar *
4329 s390_irgen_ALGFR(UChar r1, UChar r2)
4331 IRTemp op1 = newTemp(Ity_I64);
4332 IRTemp op2 = newTemp(Ity_I64);
4333 IRTemp result = newTemp(Ity_I64);
4335 assign(op1, get_gpr_dw0(r1));
4336 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4337 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4338 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4339 put_gpr_dw0(r1, mkexpr(result));
4341 return "algfr";
4344 static const HChar *
4345 s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
4347 IRTemp op2 = newTemp(Ity_I32);
4348 IRTemp op3 = newTemp(Ity_I32);
4349 IRTemp result = newTemp(Ity_I32);
4351 assign(op2, get_gpr_w1(r2));
4352 assign(op3, get_gpr_w1(r3));
4353 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4354 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
4355 put_gpr_w1(r1, mkexpr(result));
4357 return "alrk";
4360 static const HChar *
4361 s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
4363 IRTemp op2 = newTemp(Ity_I64);
4364 IRTemp op3 = newTemp(Ity_I64);
4365 IRTemp result = newTemp(Ity_I64);
4367 assign(op2, get_gpr_dw0(r2));
4368 assign(op3, get_gpr_dw0(r3));
4369 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
4370 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
4371 put_gpr_dw0(r1, mkexpr(result));
4373 return "algrk";
4376 static const HChar *
4377 s390_irgen_AL(UChar r1, IRTemp op2addr)
4379 IRTemp op1 = newTemp(Ity_I32);
4380 IRTemp op2 = newTemp(Ity_I32);
4381 IRTemp result = newTemp(Ity_I32);
4383 assign(op1, get_gpr_w1(r1));
4384 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4385 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4386 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
4387 put_gpr_w1(r1, mkexpr(result));
4389 return "al";
4392 static const HChar *
4393 s390_irgen_ALY(UChar r1, IRTemp op2addr)
4395 IRTemp op1 = newTemp(Ity_I32);
4396 IRTemp op2 = newTemp(Ity_I32);
4397 IRTemp result = newTemp(Ity_I32);
4399 assign(op1, get_gpr_w1(r1));
4400 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4401 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4402 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
4403 put_gpr_w1(r1, mkexpr(result));
4405 return "aly";
4408 static const HChar *
4409 s390_irgen_ALG(UChar r1, IRTemp op2addr)
4411 IRTemp op1 = newTemp(Ity_I64);
4412 IRTemp op2 = newTemp(Ity_I64);
4413 IRTemp result = newTemp(Ity_I64);
4415 assign(op1, get_gpr_dw0(r1));
4416 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4417 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4418 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4419 put_gpr_dw0(r1, mkexpr(result));
4421 return "alg";
4424 static const HChar *
4425 s390_irgen_ALGF(UChar r1, IRTemp op2addr)
4427 IRTemp op1 = newTemp(Ity_I64);
4428 IRTemp op2 = newTemp(Ity_I64);
4429 IRTemp result = newTemp(Ity_I64);
4431 assign(op1, get_gpr_dw0(r1));
4432 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4433 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4434 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4435 put_gpr_dw0(r1, mkexpr(result));
4437 return "algf";
4440 static const HChar *
4441 s390_irgen_ALFI(UChar r1, UInt i2)
4443 IRTemp op1 = newTemp(Ity_I32);
4444 UInt op2;
4445 IRTemp result = newTemp(Ity_I32);
4447 assign(op1, get_gpr_w1(r1));
4448 op2 = i2;
4449 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
4450 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
4451 mkU32(op2)));
4452 put_gpr_w1(r1, mkexpr(result));
4454 return "alfi";
4457 static const HChar *
4458 s390_irgen_ALGFI(UChar r1, UInt i2)
4460 IRTemp op1 = newTemp(Ity_I64);
4461 ULong op2;
4462 IRTemp result = newTemp(Ity_I64);
4464 assign(op1, get_gpr_dw0(r1));
4465 op2 = (ULong)i2;
4466 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
4467 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
4468 mkU64(op2)));
4469 put_gpr_dw0(r1, mkexpr(result));
4471 return "algfi";
4474 static const HChar *
4475 s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
4477 IRTemp op2 = newTemp(Ity_I32);
4478 IRTemp op3 = newTemp(Ity_I32);
4479 IRTemp result = newTemp(Ity_I32);
4481 assign(op2, get_gpr_w0(r2));
4482 assign(op3, get_gpr_w0(r3));
4483 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4484 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
4485 put_gpr_w0(r1, mkexpr(result));
4487 return "alhhhr";
4490 static const HChar *
4491 s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
4493 IRTemp op2 = newTemp(Ity_I32);
4494 IRTemp op3 = newTemp(Ity_I32);
4495 IRTemp result = newTemp(Ity_I32);
4497 assign(op2, get_gpr_w0(r2));
4498 assign(op3, get_gpr_w1(r3));
4499 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4500 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
4501 put_gpr_w0(r1, mkexpr(result));
4503 return "alhhlr";
4506 static const HChar *
4507 s390_irgen_ALCR(UChar r1, UChar r2)
4509 IRTemp op1 = newTemp(Ity_I32);
4510 IRTemp op2 = newTemp(Ity_I32);
4511 IRTemp result = newTemp(Ity_I32);
4512 IRTemp carry_in = newTemp(Ity_I32);
4514 assign(op1, get_gpr_w1(r1));
4515 assign(op2, get_gpr_w1(r2));
4516 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
4517 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
4518 mkexpr(carry_in)));
4519 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
4520 put_gpr_w1(r1, mkexpr(result));
4522 return "alcr";
4525 static const HChar *
4526 s390_irgen_ALCGR(UChar r1, UChar r2)
4528 IRTemp op1 = newTemp(Ity_I64);
4529 IRTemp op2 = newTemp(Ity_I64);
4530 IRTemp result = newTemp(Ity_I64);
4531 IRTemp carry_in = newTemp(Ity_I64);
4533 assign(op1, get_gpr_dw0(r1));
4534 assign(op2, get_gpr_dw0(r2));
4535 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
4536 mkU8(1))));
4537 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
4538 mkexpr(carry_in)));
4539 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
4540 put_gpr_dw0(r1, mkexpr(result));
4542 return "alcgr";
4545 static const HChar *
4546 s390_irgen_ALC(UChar r1, IRTemp op2addr)
4548 IRTemp op1 = newTemp(Ity_I32);
4549 IRTemp op2 = newTemp(Ity_I32);
4550 IRTemp result = newTemp(Ity_I32);
4551 IRTemp carry_in = newTemp(Ity_I32);
4553 assign(op1, get_gpr_w1(r1));
4554 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4555 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
4556 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
4557 mkexpr(carry_in)));
4558 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
4559 put_gpr_w1(r1, mkexpr(result));
4561 return "alc";
4564 static const HChar *
4565 s390_irgen_ALCG(UChar r1, IRTemp op2addr)
4567 IRTemp op1 = newTemp(Ity_I64);
4568 IRTemp op2 = newTemp(Ity_I64);
4569 IRTemp result = newTemp(Ity_I64);
4570 IRTemp carry_in = newTemp(Ity_I64);
4572 assign(op1, get_gpr_dw0(r1));
4573 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4574 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
4575 mkU8(1))));
4576 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
4577 mkexpr(carry_in)));
4578 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
4579 put_gpr_dw0(r1, mkexpr(result));
4581 return "alcg";
4584 static const HChar *
4585 s390_irgen_ALSI(UChar i2, IRTemp op1addr)
4587 IRTemp op1 = newTemp(Ity_I32);
4588 UInt op2;
4589 IRTemp result = newTemp(Ity_I32);
4591 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4592 op2 = (UInt)(Int)(Char)i2;
4593 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
4594 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
4595 mkU32(op2)));
4596 store(mkexpr(op1addr), mkexpr(result));
4598 return "alsi";
4601 static const HChar *
4602 s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
4604 IRTemp op1 = newTemp(Ity_I64);
4605 ULong op2;
4606 IRTemp result = newTemp(Ity_I64);
4608 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4609 op2 = (ULong)(Long)(Char)i2;
4610 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
4611 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
4612 mkU64(op2)));
4613 store(mkexpr(op1addr), mkexpr(result));
4615 return "algsi";
4618 static const HChar *
4619 s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
4621 UInt op2;
4622 IRTemp op3 = newTemp(Ity_I32);
4623 IRTemp result = newTemp(Ity_I32);
4625 op2 = (UInt)(Int)(Short)i2;
4626 assign(op3, get_gpr_w1(r3));
4627 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
4628 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
4629 op3);
4630 put_gpr_w1(r1, mkexpr(result));
4632 return "alhsik";
4635 static const HChar *
4636 s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
4638 ULong op2;
4639 IRTemp op3 = newTemp(Ity_I64);
4640 IRTemp result = newTemp(Ity_I64);
4642 op2 = (ULong)(Long)(Short)i2;
4643 assign(op3, get_gpr_dw0(r3));
4644 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
4645 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
4646 op3);
4647 put_gpr_dw0(r1, mkexpr(result));
4649 return "alghsik";
4652 static const HChar *
4653 s390_irgen_ALSIH(UChar r1, UInt i2)
4655 IRTemp op1 = newTemp(Ity_I32);
4656 UInt op2;
4657 IRTemp result = newTemp(Ity_I32);
4659 assign(op1, get_gpr_w0(r1));
4660 op2 = i2;
4661 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
4662 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
4663 mkU32(op2)));
4664 put_gpr_w0(r1, mkexpr(result));
4666 return "alsih";
4669 static const HChar *
4670 s390_irgen_ALSIHN(UChar r1, UInt i2)
4672 IRTemp op1 = newTemp(Ity_I32);
4673 UInt op2;
4674 IRTemp result = newTemp(Ity_I32);
4676 assign(op1, get_gpr_w0(r1));
4677 op2 = i2;
4678 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
4679 put_gpr_w0(r1, mkexpr(result));
4681 return "alsihn";
4684 static const HChar *
4685 s390_irgen_NR(UChar r1, UChar r2)
4687 IRTemp op1 = newTemp(Ity_I32);
4688 IRTemp op2 = newTemp(Ity_I32);
4689 IRTemp result = newTemp(Ity_I32);
4691 assign(op1, get_gpr_w1(r1));
4692 assign(op2, get_gpr_w1(r2));
4693 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
4694 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4695 put_gpr_w1(r1, mkexpr(result));
4697 return "nr";
4700 static const HChar *
4701 s390_irgen_NGR(UChar r1, UChar r2)
4703 IRTemp op1 = newTemp(Ity_I64);
4704 IRTemp op2 = newTemp(Ity_I64);
4705 IRTemp result = newTemp(Ity_I64);
4707 assign(op1, get_gpr_dw0(r1));
4708 assign(op2, get_gpr_dw0(r2));
4709 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
4710 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4711 put_gpr_dw0(r1, mkexpr(result));
4713 return "ngr";
4716 static const HChar *
4717 s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
4719 IRTemp op2 = newTemp(Ity_I32);
4720 IRTemp op3 = newTemp(Ity_I32);
4721 IRTemp result = newTemp(Ity_I32);
4723 assign(op2, get_gpr_w1(r2));
4724 assign(op3, get_gpr_w1(r3));
4725 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
4726 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4727 put_gpr_w1(r1, mkexpr(result));
4729 return "nrk";
4732 static const HChar *
4733 s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
4735 IRTemp op2 = newTemp(Ity_I64);
4736 IRTemp op3 = newTemp(Ity_I64);
4737 IRTemp result = newTemp(Ity_I64);
4739 assign(op2, get_gpr_dw0(r2));
4740 assign(op3, get_gpr_dw0(r3));
4741 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
4742 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4743 put_gpr_dw0(r1, mkexpr(result));
4745 return "ngrk";
4748 static const HChar *
4749 s390_irgen_N(UChar r1, IRTemp op2addr)
4751 IRTemp op1 = newTemp(Ity_I32);
4752 IRTemp op2 = newTemp(Ity_I32);
4753 IRTemp result = newTemp(Ity_I32);
4755 assign(op1, get_gpr_w1(r1));
4756 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4757 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
4758 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4759 put_gpr_w1(r1, mkexpr(result));
4761 return "n";
4764 static const HChar *
4765 s390_irgen_NY(UChar r1, IRTemp op2addr)
4767 IRTemp op1 = newTemp(Ity_I32);
4768 IRTemp op2 = newTemp(Ity_I32);
4769 IRTemp result = newTemp(Ity_I32);
4771 assign(op1, get_gpr_w1(r1));
4772 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4773 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
4774 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4775 put_gpr_w1(r1, mkexpr(result));
4777 return "ny";
4780 static const HChar *
4781 s390_irgen_NG(UChar r1, IRTemp op2addr)
4783 IRTemp op1 = newTemp(Ity_I64);
4784 IRTemp op2 = newTemp(Ity_I64);
4785 IRTemp result = newTemp(Ity_I64);
4787 assign(op1, get_gpr_dw0(r1));
4788 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4789 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
4790 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4791 put_gpr_dw0(r1, mkexpr(result));
4793 return "ng";
4796 static const HChar *
4797 s390_irgen_NI(UChar i2, IRTemp op1addr)
4799 IRTemp op1 = newTemp(Ity_I8);
4800 UChar op2;
4801 IRTemp result = newTemp(Ity_I8);
4803 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4804 op2 = i2;
4805 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
4806 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4807 store(mkexpr(op1addr), mkexpr(result));
4809 return "ni";
4812 static const HChar *
4813 s390_irgen_NIY(UChar i2, IRTemp op1addr)
4815 IRTemp op1 = newTemp(Ity_I8);
4816 UChar op2;
4817 IRTemp result = newTemp(Ity_I8);
4819 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4820 op2 = i2;
4821 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
4822 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4823 store(mkexpr(op1addr), mkexpr(result));
4825 return "niy";
4828 static const HChar *
4829 s390_irgen_NIHF(UChar r1, UInt i2)
4831 IRTemp op1 = newTemp(Ity_I32);
4832 UInt op2;
4833 IRTemp result = newTemp(Ity_I32);
4835 assign(op1, get_gpr_w0(r1));
4836 op2 = i2;
4837 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
4838 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4839 put_gpr_w0(r1, mkexpr(result));
4841 return "nihf";
4844 static const HChar *
4845 s390_irgen_NIHH(UChar r1, UShort i2)
4847 IRTemp op1 = newTemp(Ity_I16);
4848 UShort op2;
4849 IRTemp result = newTemp(Ity_I16);
4851 assign(op1, get_gpr_hw0(r1));
4852 op2 = i2;
4853 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
4854 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4855 put_gpr_hw0(r1, mkexpr(result));
4857 return "nihh";
4860 static const HChar *
4861 s390_irgen_NIHL(UChar r1, UShort i2)
4863 IRTemp op1 = newTemp(Ity_I16);
4864 UShort op2;
4865 IRTemp result = newTemp(Ity_I16);
4867 assign(op1, get_gpr_hw1(r1));
4868 op2 = i2;
4869 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
4870 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4871 put_gpr_hw1(r1, mkexpr(result));
4873 return "nihl";
4876 static const HChar *
4877 s390_irgen_NILF(UChar r1, UInt i2)
4879 IRTemp op1 = newTemp(Ity_I32);
4880 UInt op2;
4881 IRTemp result = newTemp(Ity_I32);
4883 assign(op1, get_gpr_w1(r1));
4884 op2 = i2;
4885 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
4886 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4887 put_gpr_w1(r1, mkexpr(result));
4889 return "nilf";
4892 static const HChar *
4893 s390_irgen_NILH(UChar r1, UShort i2)
4895 IRTemp op1 = newTemp(Ity_I16);
4896 UShort op2;
4897 IRTemp result = newTemp(Ity_I16);
4899 assign(op1, get_gpr_hw2(r1));
4900 op2 = i2;
4901 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
4902 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4903 put_gpr_hw2(r1, mkexpr(result));
4905 return "nilh";
4908 static const HChar *
4909 s390_irgen_NILL(UChar r1, UShort i2)
4911 IRTemp op1 = newTemp(Ity_I16);
4912 UShort op2;
4913 IRTemp result = newTemp(Ity_I16);
4915 assign(op1, get_gpr_hw3(r1));
4916 op2 = i2;
4917 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
4918 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4919 put_gpr_hw3(r1, mkexpr(result));
4921 return "nill";
4924 static const HChar *
4925 s390_irgen_BASR(UChar r1, UChar r2)
4927 IRTemp target = newTemp(Ity_I64);
4929 if (r2 == 0) {
4930 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
4931 } else {
4932 if (r1 != r2) {
4933 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
4934 call_function(get_gpr_dw0(r2));
4935 } else {
4936 assign(target, get_gpr_dw0(r2));
4937 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
4938 call_function(mkexpr(target));
4942 return "basr";
4945 static const HChar *
4946 s390_irgen_BAS(UChar r1, IRTemp op2addr)
4948 IRTemp target = newTemp(Ity_I64);
4950 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
4951 assign(target, mkexpr(op2addr));
4952 call_function(mkexpr(target));
4954 return "bas";
4957 static const HChar *
4958 s390_irgen_BCR(UChar r1, UChar r2)
4960 IRTemp cond = newTemp(Ity_I32);
4962 if (r2 == 0 && (r1 >= 14)) { /* serialization */
4963 stmt(IRStmt_MBE(Imbe_Fence));
4966 if ((r2 == 0) || (r1 == 0)) {
4967 } else {
4968 if (r1 == 15) {
4969 return_from_function(get_gpr_dw0(r2));
4970 } else {
4971 assign(cond, s390_call_calculate_cond(r1));
4972 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4973 get_gpr_dw0(r2));
4976 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4977 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
4979 return "bcr";
4982 static const HChar *
4983 s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
4985 IRTemp cond = newTemp(Ity_I32);
4987 if (r1 == 0) {
4988 } else {
4989 if (r1 == 15) {
4990 always_goto(mkexpr(op2addr));
4991 } else {
4992 assign(cond, s390_call_calculate_cond(r1));
4993 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4994 mkexpr(op2addr));
4997 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4998 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
5000 return "bc";
5003 static const HChar *
5004 s390_irgen_BCTR(UChar r1, UChar r2)
5006 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
5007 if (r2 != 0) {
5008 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
5009 get_gpr_dw0(r2));
5012 return "bctr";
5015 static const HChar *
5016 s390_irgen_BCTGR(UChar r1, UChar r2)
5018 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
5019 if (r2 != 0) {
5020 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
5021 get_gpr_dw0(r2));
5024 return "bctgr";
5027 static const HChar *
5028 s390_irgen_BCT(UChar r1, IRTemp op2addr)
5030 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
5031 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
5032 mkexpr(op2addr));
5034 return "bct";
5037 static const HChar *
5038 s390_irgen_BCTG(UChar r1, IRTemp op2addr)
5040 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
5041 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
5042 mkexpr(op2addr));
5044 return "bctg";
5047 static const HChar *
5048 s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
5050 IRTemp value = newTemp(Ity_I32);
5052 assign(value, get_gpr_w1(r3 | 1));
5053 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5054 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
5055 get_gpr_w1(r1)), mkexpr(op2addr));
5057 return "bxh";
5060 static const HChar *
5061 s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
5063 IRTemp value = newTemp(Ity_I64);
5065 assign(value, get_gpr_dw0(r3 | 1));
5066 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5067 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
5068 get_gpr_dw0(r1)), mkexpr(op2addr));
5070 return "bxhg";
5073 static const HChar *
5074 s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
5076 IRTemp value = newTemp(Ity_I32);
5078 assign(value, get_gpr_w1(r3 | 1));
5079 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5080 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
5081 mkexpr(value)), mkexpr(op2addr));
5083 return "bxle";
5086 static const HChar *
5087 s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
5089 IRTemp value = newTemp(Ity_I64);
5091 assign(value, get_gpr_dw0(r3 | 1));
5092 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5093 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
5094 mkexpr(value)), mkexpr(op2addr));
5096 return "bxleg";
5099 static const HChar *
5100 s390_irgen_BRAS(UChar r1, UShort i2)
5102 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
5103 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5105 return "bras";
5108 static const HChar *
5109 s390_irgen_BRASL(UChar r1, UInt i2)
5111 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
5112 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
5114 return "brasl";
5117 static const HChar *
5118 s390_irgen_BRC(UChar r1, UShort i2)
5120 IRTemp cond = newTemp(Ity_I32);
5122 if (r1 == 0) {
5123 } else {
5124 if (r1 == 15) {
5125 always_goto_and_chase(
5126 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5127 } else {
5128 assign(cond, s390_call_calculate_cond(r1));
5129 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5130 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5134 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5135 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
5137 return "brc";
5140 static const HChar *
5141 s390_irgen_BRCL(UChar r1, UInt i2)
5143 IRTemp cond = newTemp(Ity_I32);
5145 if (r1 == 0) {
5146 } else {
5147 if (r1 == 15) {
5148 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
5149 } else {
5150 assign(cond, s390_call_calculate_cond(r1));
5151 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5152 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
5155 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5156 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
5158 return "brcl";
5161 static const HChar *
5162 s390_irgen_BRCT(UChar r1, UShort i2)
5164 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
5165 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
5166 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5168 return "brct";
5171 static const HChar *
5172 s390_irgen_BRCTH(UChar r1, UInt i2)
5174 put_gpr_w0(r1, binop(Iop_Sub32, get_gpr_w0(r1), mkU32(1)));
5175 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w0(r1), mkU32(0)),
5176 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5178 return "brcth";
5181 static const HChar *
5182 s390_irgen_BRCTG(UChar r1, UShort i2)
5184 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
5185 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
5186 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5188 return "brctg";
5191 static const HChar *
5192 s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
5194 IRTemp value = newTemp(Ity_I32);
5196 assign(value, get_gpr_w1(r3 | 1));
5197 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5198 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
5199 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5201 return "brxh";
5204 static const HChar *
5205 s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
5207 IRTemp value = newTemp(Ity_I64);
5209 assign(value, get_gpr_dw0(r3 | 1));
5210 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5211 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
5212 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5214 return "brxhg";
5217 static const HChar *
5218 s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
5220 IRTemp value = newTemp(Ity_I32);
5222 assign(value, get_gpr_w1(r3 | 1));
5223 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5224 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
5225 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5227 return "brxle";
5230 static const HChar *
5231 s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
5233 IRTemp value = newTemp(Ity_I64);
5235 assign(value, get_gpr_dw0(r3 | 1));
5236 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5237 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
5238 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5240 return "brxlg";
5243 static const HChar *
5244 s390_irgen_CR(UChar r1, UChar r2)
5246 IRTemp op1 = newTemp(Ity_I32);
5247 IRTemp op2 = newTemp(Ity_I32);
5249 assign(op1, get_gpr_w1(r1));
5250 assign(op2, get_gpr_w1(r2));
5251 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5253 return "cr";
5256 static const HChar *
5257 s390_irgen_CGR(UChar r1, UChar r2)
5259 IRTemp op1 = newTemp(Ity_I64);
5260 IRTemp op2 = newTemp(Ity_I64);
5262 assign(op1, get_gpr_dw0(r1));
5263 assign(op2, get_gpr_dw0(r2));
5264 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5266 return "cgr";
5269 static const HChar *
5270 s390_irgen_CGFR(UChar r1, UChar r2)
5272 IRTemp op1 = newTemp(Ity_I64);
5273 IRTemp op2 = newTemp(Ity_I64);
5275 assign(op1, get_gpr_dw0(r1));
5276 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5277 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5279 return "cgfr";
5282 static const HChar *
5283 s390_irgen_C(UChar r1, IRTemp op2addr)
5285 IRTemp op1 = newTemp(Ity_I32);
5286 IRTemp op2 = newTemp(Ity_I32);
5288 assign(op1, get_gpr_w1(r1));
5289 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5290 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5292 return "c";
5295 static const HChar *
5296 s390_irgen_CY(UChar r1, IRTemp op2addr)
5298 IRTemp op1 = newTemp(Ity_I32);
5299 IRTemp op2 = newTemp(Ity_I32);
5301 assign(op1, get_gpr_w1(r1));
5302 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5303 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5305 return "cy";
5308 static const HChar *
5309 s390_irgen_CG(UChar r1, IRTemp op2addr)
5311 IRTemp op1 = newTemp(Ity_I64);
5312 IRTemp op2 = newTemp(Ity_I64);
5314 assign(op1, get_gpr_dw0(r1));
5315 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5316 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5318 return "cg";
5321 static const HChar *
5322 s390_irgen_CGF(UChar r1, IRTemp op2addr)
5324 IRTemp op1 = newTemp(Ity_I64);
5325 IRTemp op2 = newTemp(Ity_I64);
5327 assign(op1, get_gpr_dw0(r1));
5328 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5329 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5331 return "cgf";
5334 static const HChar *
5335 s390_irgen_CFI(UChar r1, UInt i2)
5337 IRTemp op1 = newTemp(Ity_I32);
5338 Int op2;
5340 assign(op1, get_gpr_w1(r1));
5341 op2 = (Int)i2;
5342 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
5343 mkU32((UInt)op2)));
5345 return "cfi";
5348 static const HChar *
5349 s390_irgen_CGFI(UChar r1, UInt i2)
5351 IRTemp op1 = newTemp(Ity_I64);
5352 Long op2;
5354 assign(op1, get_gpr_dw0(r1));
5355 op2 = (Long)(Int)i2;
5356 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
5357 mkU64((ULong)op2)));
5359 return "cgfi";
5362 static const HChar *
5363 s390_irgen_CRL(UChar r1, UInt i2)
5365 IRTemp op1 = newTemp(Ity_I32);
5366 IRTemp op2 = newTemp(Ity_I32);
5368 assign(op1, get_gpr_w1(r1));
5369 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5370 i2 << 1))));
5371 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5373 return "crl";
5376 static const HChar *
5377 s390_irgen_CGRL(UChar r1, UInt i2)
5379 IRTemp op1 = newTemp(Ity_I64);
5380 IRTemp op2 = newTemp(Ity_I64);
5382 assign(op1, get_gpr_dw0(r1));
5383 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5384 i2 << 1))));
5385 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5387 return "cgrl";
5390 static const HChar *
5391 s390_irgen_CGFRL(UChar r1, UInt i2)
5393 IRTemp op1 = newTemp(Ity_I64);
5394 IRTemp op2 = newTemp(Ity_I64);
5396 assign(op1, get_gpr_dw0(r1));
5397 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5398 ((ULong)(Long)(Int)i2 << 1)))));
5399 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5401 return "cgfrl";
5404 static const HChar *
5405 s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
5407 IRTemp op1 = newTemp(Ity_I32);
5408 IRTemp op2 = newTemp(Ity_I32);
5409 IRTemp cond = newTemp(Ity_I32);
5411 if (m3 == 0) {
5412 } else {
5413 if (m3 == 14) {
5414 always_goto(mkexpr(op4addr));
5415 } else {
5416 assign(op1, get_gpr_w1(r1));
5417 assign(op2, get_gpr_w1(r2));
5418 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5419 op1, op2));
5420 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
5421 mkU32(0)), mkexpr(op4addr));
5425 return "crb";
5428 static const HChar *
5429 s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
5431 IRTemp op1 = newTemp(Ity_I64);
5432 IRTemp op2 = newTemp(Ity_I64);
5433 IRTemp cond = newTemp(Ity_I32);
5435 if (m3 == 0) {
5436 } else {
5437 if (m3 == 14) {
5438 always_goto(mkexpr(op4addr));
5439 } else {
5440 assign(op1, get_gpr_dw0(r1));
5441 assign(op2, get_gpr_dw0(r2));
5442 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5443 op1, op2));
5444 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
5445 mkU32(0)), mkexpr(op4addr));
5449 return "cgrb";
5452 static const HChar *
5453 s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
5455 IRTemp op1 = newTemp(Ity_I32);
5456 IRTemp op2 = newTemp(Ity_I32);
5457 IRTemp cond = newTemp(Ity_I32);
5459 if (m3 == 0) {
5460 } else {
5461 if (m3 == 14) {
5462 always_goto_and_chase(
5463 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5464 } else {
5465 assign(op1, get_gpr_w1(r1));
5466 assign(op2, get_gpr_w1(r2));
5467 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5468 op1, op2));
5469 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5470 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5475 return "crj";
5478 static const HChar *
5479 s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
5481 IRTemp op1 = newTemp(Ity_I64);
5482 IRTemp op2 = newTemp(Ity_I64);
5483 IRTemp cond = newTemp(Ity_I32);
5485 if (m3 == 0) {
5486 } else {
5487 if (m3 == 14) {
5488 always_goto_and_chase(
5489 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5490 } else {
5491 assign(op1, get_gpr_dw0(r1));
5492 assign(op2, get_gpr_dw0(r2));
5493 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5494 op1, op2));
5495 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5496 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5501 return "cgrj";
5504 static const HChar *
5505 s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
5507 IRTemp op1 = newTemp(Ity_I32);
5508 Int op2;
5509 IRTemp cond = newTemp(Ity_I32);
5511 if (m3 == 0) {
5512 } else {
5513 if (m3 == 14) {
5514 always_goto(mkexpr(op4addr));
5515 } else {
5516 assign(op1, get_gpr_w1(r1));
5517 op2 = (Int)(Char)i2;
5518 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
5519 mktemp(Ity_I32, mkU32((UInt)op2))));
5520 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5521 mkexpr(op4addr));
5525 return "cib";
5528 static const HChar *
5529 s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
5531 IRTemp op1 = newTemp(Ity_I64);
5532 Long op2;
5533 IRTemp cond = newTemp(Ity_I32);
5535 if (m3 == 0) {
5536 } else {
5537 if (m3 == 14) {
5538 always_goto(mkexpr(op4addr));
5539 } else {
5540 assign(op1, get_gpr_dw0(r1));
5541 op2 = (Long)(Char)i2;
5542 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
5543 mktemp(Ity_I64, mkU64((ULong)op2))));
5544 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5545 mkexpr(op4addr));
5549 return "cgib";
5552 static const HChar *
5553 s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
5555 IRTemp op1 = newTemp(Ity_I32);
5556 Int op2;
5557 IRTemp cond = newTemp(Ity_I32);
5559 if (m3 == 0) {
5560 } else {
5561 if (m3 == 14) {
5562 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5563 } else {
5564 assign(op1, get_gpr_w1(r1));
5565 op2 = (Int)(Char)i2;
5566 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
5567 mktemp(Ity_I32, mkU32((UInt)op2))));
5568 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5569 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5574 return "cij";
5577 static const HChar *
5578 s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
5580 IRTemp op1 = newTemp(Ity_I64);
5581 Long op2;
5582 IRTemp cond = newTemp(Ity_I32);
5584 if (m3 == 0) {
5585 } else {
5586 if (m3 == 14) {
5587 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5588 } else {
5589 assign(op1, get_gpr_dw0(r1));
5590 op2 = (Long)(Char)i2;
5591 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
5592 mktemp(Ity_I64, mkU64((ULong)op2))));
5593 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5594 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5599 return "cgij";
5602 static const HChar *
5603 s390_irgen_CH(UChar r1, IRTemp op2addr)
5605 IRTemp op1 = newTemp(Ity_I32);
5606 IRTemp op2 = newTemp(Ity_I32);
5608 assign(op1, get_gpr_w1(r1));
5609 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5610 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5612 return "ch";
5615 static const HChar *
5616 s390_irgen_CHY(UChar r1, IRTemp op2addr)
5618 IRTemp op1 = newTemp(Ity_I32);
5619 IRTemp op2 = newTemp(Ity_I32);
5621 assign(op1, get_gpr_w1(r1));
5622 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5623 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5625 return "chy";
5628 static const HChar *
5629 s390_irgen_CGH(UChar r1, IRTemp op2addr)
5631 IRTemp op1 = newTemp(Ity_I64);
5632 IRTemp op2 = newTemp(Ity_I64);
5634 assign(op1, get_gpr_dw0(r1));
5635 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5636 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5638 return "cgh";
5641 static const HChar *
5642 s390_irgen_CHI(UChar r1, UShort i2)
5644 IRTemp op1 = newTemp(Ity_I32);
5645 Int op2;
5647 assign(op1, get_gpr_w1(r1));
5648 op2 = (Int)(Short)i2;
5649 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
5650 mkU32((UInt)op2)));
5652 return "chi";
5655 static const HChar *
5656 s390_irgen_CGHI(UChar r1, UShort i2)
5658 IRTemp op1 = newTemp(Ity_I64);
5659 Long op2;
5661 assign(op1, get_gpr_dw0(r1));
5662 op2 = (Long)(Short)i2;
5663 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
5664 mkU64((ULong)op2)));
5666 return "cghi";
5669 static const HChar *
5670 s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
5672 IRTemp op1 = newTemp(Ity_I16);
5673 Short op2;
5675 assign(op1, load(Ity_I16, mkexpr(op1addr)));
5676 op2 = (Short)i2;
5677 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
5678 mkU16((UShort)op2)));
5680 return "chhsi";
5683 static const HChar *
5684 s390_irgen_CHSI(UShort i2, IRTemp op1addr)
5686 IRTemp op1 = newTemp(Ity_I32);
5687 Int op2;
5689 assign(op1, load(Ity_I32, mkexpr(op1addr)));
5690 op2 = (Int)(Short)i2;
5691 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
5692 mkU32((UInt)op2)));
5694 return "chsi";
5697 static const HChar *
5698 s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
5700 IRTemp op1 = newTemp(Ity_I64);
5701 Long op2;
5703 assign(op1, load(Ity_I64, mkexpr(op1addr)));
5704 op2 = (Long)(Short)i2;
5705 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
5706 mkU64((ULong)op2)));
5708 return "cghsi";
5711 static const HChar *
5712 s390_irgen_CHRL(UChar r1, UInt i2)
5714 IRTemp op1 = newTemp(Ity_I32);
5715 IRTemp op2 = newTemp(Ity_I32);
5717 assign(op1, get_gpr_w1(r1));
5718 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5719 ((ULong)(Long)(Int)i2 << 1)))));
5720 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5722 return "chrl";
5725 static const HChar *
5726 s390_irgen_CGHRL(UChar r1, UInt i2)
5728 IRTemp op1 = newTemp(Ity_I64);
5729 IRTemp op2 = newTemp(Ity_I64);
5731 assign(op1, get_gpr_dw0(r1));
5732 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5733 ((ULong)(Long)(Int)i2 << 1)))));
5734 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5736 return "cghrl";
5739 static const HChar *
5740 s390_irgen_CHHR(UChar r1, UChar r2)
5742 IRTemp op1 = newTemp(Ity_I32);
5743 IRTemp op2 = newTemp(Ity_I32);
5745 assign(op1, get_gpr_w0(r1));
5746 assign(op2, get_gpr_w0(r2));
5747 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5749 return "chhr";
5752 static const HChar *
5753 s390_irgen_CHLR(UChar r1, UChar r2)
5755 IRTemp op1 = newTemp(Ity_I32);
5756 IRTemp op2 = newTemp(Ity_I32);
5758 assign(op1, get_gpr_w0(r1));
5759 assign(op2, get_gpr_w1(r2));
5760 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5762 return "chlr";
5765 static const HChar *
5766 s390_irgen_CHF(UChar r1, IRTemp op2addr)
5768 IRTemp op1 = newTemp(Ity_I32);
5769 IRTemp op2 = newTemp(Ity_I32);
5771 assign(op1, get_gpr_w0(r1));
5772 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5773 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5775 return "chf";
5778 static const HChar *
5779 s390_irgen_CIH(UChar r1, UInt i2)
5781 IRTemp op1 = newTemp(Ity_I32);
5782 Int op2;
5784 assign(op1, get_gpr_w0(r1));
5785 op2 = (Int)i2;
5786 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
5787 mkU32((UInt)op2)));
5789 return "cih";
5792 static const HChar *
5793 s390_irgen_CLR(UChar r1, UChar r2)
5795 IRTemp op1 = newTemp(Ity_I32);
5796 IRTemp op2 = newTemp(Ity_I32);
5798 assign(op1, get_gpr_w1(r1));
5799 assign(op2, get_gpr_w1(r2));
5800 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5802 return "clr";
5805 static const HChar *
5806 s390_irgen_CLGR(UChar r1, UChar r2)
5808 IRTemp op1 = newTemp(Ity_I64);
5809 IRTemp op2 = newTemp(Ity_I64);
5811 assign(op1, get_gpr_dw0(r1));
5812 assign(op2, get_gpr_dw0(r2));
5813 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5815 return "clgr";
5818 static const HChar *
5819 s390_irgen_CLGFR(UChar r1, UChar r2)
5821 IRTemp op1 = newTemp(Ity_I64);
5822 IRTemp op2 = newTemp(Ity_I64);
5824 assign(op1, get_gpr_dw0(r1));
5825 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
5826 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5828 return "clgfr";
5831 static const HChar *
5832 s390_irgen_CL(UChar r1, IRTemp op2addr)
5834 IRTemp op1 = newTemp(Ity_I32);
5835 IRTemp op2 = newTemp(Ity_I32);
5837 assign(op1, get_gpr_w1(r1));
5838 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5839 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5841 return "cl";
5844 static const HChar *
5845 s390_irgen_CLY(UChar r1, IRTemp op2addr)
5847 IRTemp op1 = newTemp(Ity_I32);
5848 IRTemp op2 = newTemp(Ity_I32);
5850 assign(op1, get_gpr_w1(r1));
5851 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5852 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5854 return "cly";
5857 static const HChar *
5858 s390_irgen_CLG(UChar r1, IRTemp op2addr)
5860 IRTemp op1 = newTemp(Ity_I64);
5861 IRTemp op2 = newTemp(Ity_I64);
5863 assign(op1, get_gpr_dw0(r1));
5864 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5865 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5867 return "clg";
5870 static const HChar *
5871 s390_irgen_CLGF(UChar r1, IRTemp op2addr)
5873 IRTemp op1 = newTemp(Ity_I64);
5874 IRTemp op2 = newTemp(Ity_I64);
5876 assign(op1, get_gpr_dw0(r1));
5877 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5878 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5880 return "clgf";
5883 static const HChar *
5884 s390_irgen_CLFI(UChar r1, UInt i2)
5886 IRTemp op1 = newTemp(Ity_I32);
5887 UInt op2;
5889 assign(op1, get_gpr_w1(r1));
5890 op2 = i2;
5891 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5892 mkU32(op2)));
5894 return "clfi";
5897 static const HChar *
5898 s390_irgen_CLGFI(UChar r1, UInt i2)
5900 IRTemp op1 = newTemp(Ity_I64);
5901 ULong op2;
5903 assign(op1, get_gpr_dw0(r1));
5904 op2 = (ULong)i2;
5905 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
5906 mkU64(op2)));
5908 return "clgfi";
5911 static const HChar *
5912 s390_irgen_CLI(UChar i2, IRTemp op1addr)
5914 IRTemp op1 = newTemp(Ity_I8);
5915 UChar op2;
5917 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5918 op2 = i2;
5919 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
5920 mkU8(op2)));
5922 return "cli";
5925 static const HChar *
5926 s390_irgen_CLIY(UChar i2, IRTemp op1addr)
5928 IRTemp op1 = newTemp(Ity_I8);
5929 UChar op2;
5931 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5932 op2 = i2;
5933 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
5934 mkU8(op2)));
5936 return "cliy";
5939 static const HChar *
5940 s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
5942 IRTemp op1 = newTemp(Ity_I32);
5943 UInt op2;
5945 assign(op1, load(Ity_I32, mkexpr(op1addr)));
5946 op2 = (UInt)i2;
5947 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5948 mkU32(op2)));
5950 return "clfhsi";
5953 static const HChar *
5954 s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
5956 IRTemp op1 = newTemp(Ity_I64);
5957 ULong op2;
5959 assign(op1, load(Ity_I64, mkexpr(op1addr)));
5960 op2 = (ULong)i2;
5961 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
5962 mkU64(op2)));
5964 return "clghsi";
5967 static const HChar *
5968 s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
5970 IRTemp op1 = newTemp(Ity_I16);
5971 UShort op2;
5973 assign(op1, load(Ity_I16, mkexpr(op1addr)));
5974 op2 = i2;
5975 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
5976 mkU16(op2)));
5978 return "clhhsi";
5981 static const HChar *
5982 s390_irgen_CLRL(UChar r1, UInt i2)
5984 IRTemp op1 = newTemp(Ity_I32);
5985 IRTemp op2 = newTemp(Ity_I32);
5987 assign(op1, get_gpr_w1(r1));
5988 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5989 i2 << 1))));
5990 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5992 return "clrl";
5995 static const HChar *
5996 s390_irgen_CLGRL(UChar r1, UInt i2)
5998 IRTemp op1 = newTemp(Ity_I64);
5999 IRTemp op2 = newTemp(Ity_I64);
6001 assign(op1, get_gpr_dw0(r1));
6002 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
6003 i2 << 1))));
6004 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6006 return "clgrl";
6009 static const HChar *
6010 s390_irgen_CLGFRL(UChar r1, UInt i2)
6012 IRTemp op1 = newTemp(Ity_I64);
6013 IRTemp op2 = newTemp(Ity_I64);
6015 assign(op1, get_gpr_dw0(r1));
6016 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6017 ((ULong)(Long)(Int)i2 << 1)))));
6018 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6020 return "clgfrl";
6023 static const HChar *
6024 s390_irgen_CLHRL(UChar r1, UInt i2)
6026 IRTemp op1 = newTemp(Ity_I32);
6027 IRTemp op2 = newTemp(Ity_I32);
6029 assign(op1, get_gpr_w1(r1));
6030 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6031 ((ULong)(Long)(Int)i2 << 1)))));
6032 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6034 return "clhrl";
6037 static const HChar *
6038 s390_irgen_CLGHRL(UChar r1, UInt i2)
6040 IRTemp op1 = newTemp(Ity_I64);
6041 IRTemp op2 = newTemp(Ity_I64);
6043 assign(op1, get_gpr_dw0(r1));
6044 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6045 ((ULong)(Long)(Int)i2 << 1)))));
6046 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6048 return "clghrl";
6051 static const HChar *
6052 s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
6054 IRTemp op1 = newTemp(Ity_I32);
6055 IRTemp op2 = newTemp(Ity_I32);
6056 IRTemp cond = newTemp(Ity_I32);
6058 if (m3 == 0) {
6059 } else {
6060 if (m3 == 14) {
6061 always_goto(mkexpr(op4addr));
6062 } else {
6063 assign(op1, get_gpr_w1(r1));
6064 assign(op2, get_gpr_w1(r2));
6065 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6066 op1, op2));
6067 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6068 mkexpr(op4addr));
6072 return "clrb";
6075 static const HChar *
6076 s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
6078 IRTemp op1 = newTemp(Ity_I64);
6079 IRTemp op2 = newTemp(Ity_I64);
6080 IRTemp cond = newTemp(Ity_I32);
6082 if (m3 == 0) {
6083 } else {
6084 if (m3 == 14) {
6085 always_goto(mkexpr(op4addr));
6086 } else {
6087 assign(op1, get_gpr_dw0(r1));
6088 assign(op2, get_gpr_dw0(r2));
6089 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6090 op1, op2));
6091 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6092 mkexpr(op4addr));
6096 return "clgrb";
6099 /* Raise the appropriate signal for a compare-and-trap-instruction data
6100 exception if the condition is true. */
6101 static void
6102 s390_trap_on_condition(IRExpr *cond)
6104 stmt(IRStmt_Exit(cond, Ijk_SigFPE, IRConst_U64(guest_IA_next_instr),
6105 S390X_GUEST_OFFSET(guest_IA)));
6108 /* Handle the various flavors of compare (logical) and trap. */
6109 static void
6110 s390_irgen_CxRT(UChar m3, UChar r1, UChar r2, IRType type, UInt opc)
6112 IRExpr *cond;
6114 if (m3 == 0) {
6115 /* Trap never (NOP) */
6116 return;
6117 } else if (m3 == 14) {
6118 /* Trap always */
6119 cond = IRExpr_Const(IRConst_U1 (True));
6120 } else {
6121 IRTemp op1 = newTemp(type);
6122 IRTemp op2 = newTemp(type);
6124 assign(op1, get_gpr_int(r1, type));
6125 assign(op2, get_gpr_int(r2, type));
6126 cond = binop(Iop_CmpNE32,
6127 s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0));
6129 s390_trap_on_condition(cond);
6132 static const HChar *
6133 s390_irgen_CGRT(UChar m3, UChar r1, UChar r2)
6135 s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_SIGNED_COMPARE);
6136 return "cgrt";
6139 static const HChar *
6140 s390_irgen_CRT(UChar m3, UChar r1, UChar r2)
6142 s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_SIGNED_COMPARE);
6143 return "crt";
6146 static const HChar *
6147 s390_irgen_CLGRT(UChar m3, UChar r1, UChar r2)
6149 s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE);
6150 return "clgrt";
6153 static const HChar *
6154 s390_irgen_CLRT(UChar m3, UChar r1, UChar r2)
6156 s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE);
6157 return "clrt";
6160 /* Handle the various flavors of compare (logical) immediate and trap. */
6161 static void
6162 s390_irgen_CxIT(UChar m3, UChar r1, UShort i2, IRType type, UInt opc)
6164 IRExpr *cond;
6166 if (m3 == 0) {
6167 /* Trap never (NOP) */
6168 return;
6169 } else if (m3 == 14) {
6170 /* Trap always */
6171 cond = IRExpr_Const(IRConst_U1 (True));
6172 } else {
6173 IRTemp op1 = newTemp(type);
6174 IRTemp op2 = newTemp(type);
6176 assign(op1, get_gpr_int(r1, type));
6177 if (opc == S390_CC_OP_SIGNED_COMPARE) {
6178 assign(op2, type == Ity_I64 ?
6179 mkU64((ULong)(Short)i2) : mkU32((UInt)(Short)i2));
6180 } else {
6181 assign(op2, type == Ity_I64 ?
6182 mkU64((ULong)i2) : mkU32((UInt)i2));
6184 cond = binop(Iop_CmpNE32,
6185 s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0));
6187 s390_trap_on_condition(cond);
6190 static const HChar *
6191 s390_irgen_CGIT(UChar r1, UShort i2, UChar m3)
6193 s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_SIGNED_COMPARE);
6194 return "cgit";
6197 static const HChar *
6198 s390_irgen_CIT(UChar r1, UShort i2, UChar m3)
6200 s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_SIGNED_COMPARE);
6201 return "cit";
6204 static const HChar *
6205 s390_irgen_CLGIT(UChar r1, UShort i2, UChar m3)
6207 s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE);
6208 return "clgit";
6211 static const HChar *
6212 s390_irgen_CLFIT(UChar r1, UShort i2, UChar m3)
6214 s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE);
6215 return "clfit";
6218 /* Handle the variants of compare logical and trap with memory operand. */
6219 static void
6220 s390_irgen_CLxT(UChar r1, UChar m3, IRTemp op2addr, IRType type, UInt opc)
6222 IRExpr *cond;
6224 if (m3 == 0) {
6225 /* Trap never (NOP) */
6226 return;
6227 } else if (m3 == 14) {
6228 /* Trap always */
6229 cond = IRExpr_Const(IRConst_U1 (True));
6230 } else {
6231 IRTemp op1 = newTemp(type);
6232 IRTemp op2 = newTemp(type);
6234 assign(op1, get_gpr_int(r1, type));
6235 assign(op2, load(type, mkexpr(op2addr)));
6236 cond = binop(Iop_CmpNE32,
6237 s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0));
6239 s390_trap_on_condition(cond);
6242 static const HChar *
6243 s390_irgen_CLT(UChar r1, UChar m3, IRTemp op2addr)
6245 s390_irgen_CLxT(r1, m3, op2addr, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE);
6246 return "clt";
6249 static const HChar *
6250 s390_irgen_CLGT(UChar r1, UChar m3, IRTemp op2addr)
6252 s390_irgen_CLxT(r1, m3, op2addr, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE);
6253 return "clgt";
6256 static const HChar *
6257 s390_irgen_LAT(UChar r1, IRTemp op2addr)
6259 IRTemp val = newTemp(Ity_I32);
6260 assign(val, load(Ity_I32, mkexpr(op2addr)));
6261 put_gpr_w1(r1, mkexpr(val));
6262 s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0)));
6263 return "lat";
6266 static const HChar *
6267 s390_irgen_LGAT(UChar r1, IRTemp op2addr)
6269 IRTemp val = newTemp(Ity_I64);
6270 assign(val, load(Ity_I64, mkexpr(op2addr)));
6271 put_gpr_dw0(r1, mkexpr(val));
6272 s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0)));
6273 return "lgat";
6276 static const HChar *
6277 s390_irgen_LFHAT(UChar r1, IRTemp op2addr)
6279 IRTemp val = newTemp(Ity_I32);
6280 assign(val, load(Ity_I32, mkexpr(op2addr)));
6281 put_gpr_w0(r1, mkexpr(val));
6282 s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0)));
6283 return "lfhat";
6286 static const HChar *
6287 s390_irgen_LLGFAT(UChar r1, IRTemp op2addr)
6289 IRTemp val = newTemp(Ity_I64);
6290 assign(val, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6291 put_gpr_dw0(r1, mkexpr(val));
6292 s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0)));
6293 return "llgfat";
6296 static const HChar *
6297 s390_irgen_LLGTAT(UChar r1, IRTemp op2addr)
6299 IRTemp val = newTemp(Ity_I64);
6300 assign(val, binop(Iop_And64, mkU64(0x7fffffff),
6301 unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))));
6302 put_gpr_dw0(r1, mkexpr(val));
6303 s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0)));
6304 return "llgtat";
6307 static const HChar *
6308 s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
6310 IRTemp op1 = newTemp(Ity_I32);
6311 IRTemp op2 = newTemp(Ity_I32);
6312 IRTemp cond = newTemp(Ity_I32);
6314 if (m3 == 0) {
6315 } else {
6316 if (m3 == 14) {
6317 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6318 } else {
6319 assign(op1, get_gpr_w1(r1));
6320 assign(op2, get_gpr_w1(r2));
6321 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6322 op1, op2));
6323 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6324 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6329 return "clrj";
6332 static const HChar *
6333 s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
6335 IRTemp op1 = newTemp(Ity_I64);
6336 IRTemp op2 = newTemp(Ity_I64);
6337 IRTemp cond = newTemp(Ity_I32);
6339 if (m3 == 0) {
6340 } else {
6341 if (m3 == 14) {
6342 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6343 } else {
6344 assign(op1, get_gpr_dw0(r1));
6345 assign(op2, get_gpr_dw0(r2));
6346 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6347 op1, op2));
6348 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6349 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6354 return "clgrj";
6357 static const HChar *
6358 s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
6360 IRTemp op1 = newTemp(Ity_I32);
6361 UInt op2;
6362 IRTemp cond = newTemp(Ity_I32);
6364 if (m3 == 0) {
6365 } else {
6366 if (m3 == 14) {
6367 always_goto(mkexpr(op4addr));
6368 } else {
6369 assign(op1, get_gpr_w1(r1));
6370 op2 = (UInt)i2;
6371 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6372 mktemp(Ity_I32, mkU32(op2))));
6373 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6374 mkexpr(op4addr));
6378 return "clib";
6381 static const HChar *
6382 s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
6384 IRTemp op1 = newTemp(Ity_I64);
6385 ULong op2;
6386 IRTemp cond = newTemp(Ity_I32);
6388 if (m3 == 0) {
6389 } else {
6390 if (m3 == 14) {
6391 always_goto(mkexpr(op4addr));
6392 } else {
6393 assign(op1, get_gpr_dw0(r1));
6394 op2 = (ULong)i2;
6395 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6396 mktemp(Ity_I64, mkU64(op2))));
6397 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6398 mkexpr(op4addr));
6402 return "clgib";
6405 static const HChar *
6406 s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
6408 IRTemp op1 = newTemp(Ity_I32);
6409 UInt op2;
6410 IRTemp cond = newTemp(Ity_I32);
6412 if (m3 == 0) {
6413 } else {
6414 if (m3 == 14) {
6415 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6416 } else {
6417 assign(op1, get_gpr_w1(r1));
6418 op2 = (UInt)i2;
6419 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6420 mktemp(Ity_I32, mkU32(op2))));
6421 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6422 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6427 return "clij";
6430 static const HChar *
6431 s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
6433 IRTemp op1 = newTemp(Ity_I64);
6434 ULong op2;
6435 IRTemp cond = newTemp(Ity_I32);
6437 if (m3 == 0) {
6438 } else {
6439 if (m3 == 14) {
6440 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6441 } else {
6442 assign(op1, get_gpr_dw0(r1));
6443 op2 = (ULong)i2;
6444 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6445 mktemp(Ity_I64, mkU64(op2))));
6446 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6447 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6452 return "clgij";
6455 static const HChar *
6456 s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
6458 IRTemp op1 = newTemp(Ity_I32);
6459 IRTemp op2 = newTemp(Ity_I32);
6460 IRTemp b0 = newTemp(Ity_I32);
6461 IRTemp b1 = newTemp(Ity_I32);
6462 IRTemp b2 = newTemp(Ity_I32);
6463 IRTemp b3 = newTemp(Ity_I32);
6464 IRTemp c0 = newTemp(Ity_I32);
6465 IRTemp c1 = newTemp(Ity_I32);
6466 IRTemp c2 = newTemp(Ity_I32);
6467 IRTemp c3 = newTemp(Ity_I32);
6468 UChar n;
6470 n = 0;
6471 if ((r3 & 8) != 0) {
6472 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
6473 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6474 n = n + 1;
6475 } else {
6476 assign(b0, mkU32(0));
6477 assign(c0, mkU32(0));
6479 if ((r3 & 4) != 0) {
6480 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
6481 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6482 mkU64(n)))));
6483 n = n + 1;
6484 } else {
6485 assign(b1, mkU32(0));
6486 assign(c1, mkU32(0));
6488 if ((r3 & 2) != 0) {
6489 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
6490 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6491 mkU64(n)))));
6492 n = n + 1;
6493 } else {
6494 assign(b2, mkU32(0));
6495 assign(c2, mkU32(0));
6497 if ((r3 & 1) != 0) {
6498 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
6499 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6500 mkU64(n)))));
6501 n = n + 1;
6502 } else {
6503 assign(b3, mkU32(0));
6504 assign(c3, mkU32(0));
6506 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6507 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
6508 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
6509 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6510 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
6511 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
6512 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6514 return "clm";
6517 static const HChar *
6518 s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
6520 IRTemp op1 = newTemp(Ity_I32);
6521 IRTemp op2 = newTemp(Ity_I32);
6522 IRTemp b0 = newTemp(Ity_I32);
6523 IRTemp b1 = newTemp(Ity_I32);
6524 IRTemp b2 = newTemp(Ity_I32);
6525 IRTemp b3 = newTemp(Ity_I32);
6526 IRTemp c0 = newTemp(Ity_I32);
6527 IRTemp c1 = newTemp(Ity_I32);
6528 IRTemp c2 = newTemp(Ity_I32);
6529 IRTemp c3 = newTemp(Ity_I32);
6530 UChar n;
6532 n = 0;
6533 if ((r3 & 8) != 0) {
6534 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
6535 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6536 n = n + 1;
6537 } else {
6538 assign(b0, mkU32(0));
6539 assign(c0, mkU32(0));
6541 if ((r3 & 4) != 0) {
6542 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
6543 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6544 mkU64(n)))));
6545 n = n + 1;
6546 } else {
6547 assign(b1, mkU32(0));
6548 assign(c1, mkU32(0));
6550 if ((r3 & 2) != 0) {
6551 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
6552 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6553 mkU64(n)))));
6554 n = n + 1;
6555 } else {
6556 assign(b2, mkU32(0));
6557 assign(c2, mkU32(0));
6559 if ((r3 & 1) != 0) {
6560 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
6561 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6562 mkU64(n)))));
6563 n = n + 1;
6564 } else {
6565 assign(b3, mkU32(0));
6566 assign(c3, mkU32(0));
6568 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6569 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
6570 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
6571 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6572 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
6573 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
6574 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6576 return "clmy";
6579 static const HChar *
6580 s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
6582 IRTemp op1 = newTemp(Ity_I32);
6583 IRTemp op2 = newTemp(Ity_I32);
6584 IRTemp b0 = newTemp(Ity_I32);
6585 IRTemp b1 = newTemp(Ity_I32);
6586 IRTemp b2 = newTemp(Ity_I32);
6587 IRTemp b3 = newTemp(Ity_I32);
6588 IRTemp c0 = newTemp(Ity_I32);
6589 IRTemp c1 = newTemp(Ity_I32);
6590 IRTemp c2 = newTemp(Ity_I32);
6591 IRTemp c3 = newTemp(Ity_I32);
6592 UChar n;
6594 n = 0;
6595 if ((r3 & 8) != 0) {
6596 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
6597 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6598 n = n + 1;
6599 } else {
6600 assign(b0, mkU32(0));
6601 assign(c0, mkU32(0));
6603 if ((r3 & 4) != 0) {
6604 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
6605 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6606 mkU64(n)))));
6607 n = n + 1;
6608 } else {
6609 assign(b1, mkU32(0));
6610 assign(c1, mkU32(0));
6612 if ((r3 & 2) != 0) {
6613 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
6614 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6615 mkU64(n)))));
6616 n = n + 1;
6617 } else {
6618 assign(b2, mkU32(0));
6619 assign(c2, mkU32(0));
6621 if ((r3 & 1) != 0) {
6622 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
6623 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6624 mkU64(n)))));
6625 n = n + 1;
6626 } else {
6627 assign(b3, mkU32(0));
6628 assign(c3, mkU32(0));
6630 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6631 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
6632 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
6633 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6634 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
6635 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
6636 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6638 return "clmh";
6641 static const HChar *
6642 s390_irgen_CLHHR(UChar r1, UChar r2)
6644 IRTemp op1 = newTemp(Ity_I32);
6645 IRTemp op2 = newTemp(Ity_I32);
6647 assign(op1, get_gpr_w0(r1));
6648 assign(op2, get_gpr_w0(r2));
6649 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6651 return "clhhr";
6654 static const HChar *
6655 s390_irgen_CLHLR(UChar r1, UChar r2)
6657 IRTemp op1 = newTemp(Ity_I32);
6658 IRTemp op2 = newTemp(Ity_I32);
6660 assign(op1, get_gpr_w0(r1));
6661 assign(op2, get_gpr_w1(r2));
6662 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6664 return "clhlr";
6667 static const HChar *
6668 s390_irgen_CLHF(UChar r1, IRTemp op2addr)
6670 IRTemp op1 = newTemp(Ity_I32);
6671 IRTemp op2 = newTemp(Ity_I32);
6673 assign(op1, get_gpr_w0(r1));
6674 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6675 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6677 return "clhf";
6680 static const HChar *
6681 s390_irgen_CLIH(UChar r1, UInt i2)
6683 IRTemp op1 = newTemp(Ity_I32);
6684 UInt op2;
6686 assign(op1, get_gpr_w0(r1));
6687 op2 = i2;
6688 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
6689 mkU32(op2)));
6691 return "clih";
6694 static const HChar *
6695 s390_irgen_CPYA(UChar r1, UChar r2)
6697 put_ar_w0(r1, get_ar_w0(r2));
6698 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
6699 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
6701 return "cpya";
6704 static const HChar *
6705 s390_irgen_XR(UChar r1, UChar r2)
6707 IRTemp op1 = newTemp(Ity_I32);
6708 IRTemp op2 = newTemp(Ity_I32);
6709 IRTemp result = newTemp(Ity_I32);
6711 if (r1 == r2) {
6712 assign(result, mkU32(0));
6713 } else {
6714 assign(op1, get_gpr_w1(r1));
6715 assign(op2, get_gpr_w1(r2));
6716 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
6718 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6719 put_gpr_w1(r1, mkexpr(result));
6721 return "xr";
6724 static const HChar *
6725 s390_irgen_XGR(UChar r1, UChar r2)
6727 IRTemp op1 = newTemp(Ity_I64);
6728 IRTemp op2 = newTemp(Ity_I64);
6729 IRTemp result = newTemp(Ity_I64);
6731 if (r1 == r2) {
6732 assign(result, mkU64(0));
6733 } else {
6734 assign(op1, get_gpr_dw0(r1));
6735 assign(op2, get_gpr_dw0(r2));
6736 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
6738 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6739 put_gpr_dw0(r1, mkexpr(result));
6741 return "xgr";
6744 static const HChar *
6745 s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
6747 IRTemp op2 = newTemp(Ity_I32);
6748 IRTemp op3 = newTemp(Ity_I32);
6749 IRTemp result = newTemp(Ity_I32);
6751 assign(op2, get_gpr_w1(r2));
6752 assign(op3, get_gpr_w1(r3));
6753 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
6754 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6755 put_gpr_w1(r1, mkexpr(result));
6757 return "xrk";
6760 static const HChar *
6761 s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
6763 IRTemp op2 = newTemp(Ity_I64);
6764 IRTemp op3 = newTemp(Ity_I64);
6765 IRTemp result = newTemp(Ity_I64);
6767 assign(op2, get_gpr_dw0(r2));
6768 assign(op3, get_gpr_dw0(r3));
6769 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
6770 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6771 put_gpr_dw0(r1, mkexpr(result));
6773 return "xgrk";
6776 static const HChar *
6777 s390_irgen_X(UChar r1, IRTemp op2addr)
6779 IRTemp op1 = newTemp(Ity_I32);
6780 IRTemp op2 = newTemp(Ity_I32);
6781 IRTemp result = newTemp(Ity_I32);
6783 assign(op1, get_gpr_w1(r1));
6784 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6785 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
6786 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6787 put_gpr_w1(r1, mkexpr(result));
6789 return "x";
6792 static const HChar *
6793 s390_irgen_XY(UChar r1, IRTemp op2addr)
6795 IRTemp op1 = newTemp(Ity_I32);
6796 IRTemp op2 = newTemp(Ity_I32);
6797 IRTemp result = newTemp(Ity_I32);
6799 assign(op1, get_gpr_w1(r1));
6800 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6801 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
6802 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6803 put_gpr_w1(r1, mkexpr(result));
6805 return "xy";
6808 static const HChar *
6809 s390_irgen_XG(UChar r1, IRTemp op2addr)
6811 IRTemp op1 = newTemp(Ity_I64);
6812 IRTemp op2 = newTemp(Ity_I64);
6813 IRTemp result = newTemp(Ity_I64);
6815 assign(op1, get_gpr_dw0(r1));
6816 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6817 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
6818 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6819 put_gpr_dw0(r1, mkexpr(result));
6821 return "xg";
6824 static const HChar *
6825 s390_irgen_XI(UChar i2, IRTemp op1addr)
6827 IRTemp op1 = newTemp(Ity_I8);
6828 UChar op2;
6829 IRTemp result = newTemp(Ity_I8);
6831 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6832 op2 = i2;
6833 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
6834 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6835 store(mkexpr(op1addr), mkexpr(result));
6837 return "xi";
6840 static const HChar *
6841 s390_irgen_XIY(UChar i2, IRTemp op1addr)
6843 IRTemp op1 = newTemp(Ity_I8);
6844 UChar op2;
6845 IRTemp result = newTemp(Ity_I8);
6847 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6848 op2 = i2;
6849 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
6850 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6851 store(mkexpr(op1addr), mkexpr(result));
6853 return "xiy";
6856 static const HChar *
6857 s390_irgen_XIHF(UChar r1, UInt i2)
6859 IRTemp op1 = newTemp(Ity_I32);
6860 UInt op2;
6861 IRTemp result = newTemp(Ity_I32);
6863 assign(op1, get_gpr_w0(r1));
6864 op2 = i2;
6865 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
6866 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6867 put_gpr_w0(r1, mkexpr(result));
6869 return "xihf";
6872 static const HChar *
6873 s390_irgen_XILF(UChar r1, UInt i2)
6875 IRTemp op1 = newTemp(Ity_I32);
6876 UInt op2;
6877 IRTemp result = newTemp(Ity_I32);
6879 assign(op1, get_gpr_w1(r1));
6880 op2 = i2;
6881 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
6882 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6883 put_gpr_w1(r1, mkexpr(result));
6885 return "xilf";
6888 static const HChar *
6889 s390_irgen_EAR(UChar r1, UChar r2)
6891 put_gpr_w1(r1, get_ar_w0(r2));
6892 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
6893 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
6895 return "ear";
6898 static const HChar *
6899 s390_irgen_IC(UChar r1, IRTemp op2addr)
6901 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
6903 return "ic";
6906 static const HChar *
6907 s390_irgen_ICY(UChar r1, IRTemp op2addr)
6909 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
6911 return "icy";
6914 static const HChar *
6915 s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
6917 UChar n;
6918 IRTemp result = newTemp(Ity_I32);
6919 UInt mask;
6921 n = 0;
6922 mask = (UInt)r3;
6923 if ((mask & 8) != 0) {
6924 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
6925 n = n + 1;
6927 if ((mask & 4) != 0) {
6928 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
6930 n = n + 1;
6932 if ((mask & 2) != 0) {
6933 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
6935 n = n + 1;
6937 if ((mask & 1) != 0) {
6938 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
6940 n = n + 1;
6942 assign(result, get_gpr_w1(r1));
6943 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
6944 mkU32(mask)));
6946 return "icm";
6949 static const HChar *
6950 s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
6952 UChar n;
6953 IRTemp result = newTemp(Ity_I32);
6954 UInt mask;
6956 n = 0;
6957 mask = (UInt)r3;
6958 if ((mask & 8) != 0) {
6959 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
6960 n = n + 1;
6962 if ((mask & 4) != 0) {
6963 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
6965 n = n + 1;
6967 if ((mask & 2) != 0) {
6968 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
6970 n = n + 1;
6972 if ((mask & 1) != 0) {
6973 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
6975 n = n + 1;
6977 assign(result, get_gpr_w1(r1));
6978 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
6979 mkU32(mask)));
6981 return "icmy";
6984 static const HChar *
6985 s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
6987 UChar n;
6988 IRTemp result = newTemp(Ity_I32);
6989 UInt mask;
6991 n = 0;
6992 mask = (UInt)r3;
6993 if ((mask & 8) != 0) {
6994 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
6995 n = n + 1;
6997 if ((mask & 4) != 0) {
6998 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7000 n = n + 1;
7002 if ((mask & 2) != 0) {
7003 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7005 n = n + 1;
7007 if ((mask & 1) != 0) {
7008 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7010 n = n + 1;
7012 assign(result, get_gpr_w0(r1));
7013 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
7014 mkU32(mask)));
7016 return "icmh";
7019 static const HChar *
7020 s390_irgen_IIHF(UChar r1, UInt i2)
7022 put_gpr_w0(r1, mkU32(i2));
7024 return "iihf";
7027 static const HChar *
7028 s390_irgen_IIHH(UChar r1, UShort i2)
7030 put_gpr_hw0(r1, mkU16(i2));
7032 return "iihh";
7035 static const HChar *
7036 s390_irgen_IIHL(UChar r1, UShort i2)
7038 put_gpr_hw1(r1, mkU16(i2));
7040 return "iihl";
7043 static const HChar *
7044 s390_irgen_IILF(UChar r1, UInt i2)
7046 put_gpr_w1(r1, mkU32(i2));
7048 return "iilf";
7051 static const HChar *
7052 s390_irgen_IILH(UChar r1, UShort i2)
7054 put_gpr_hw2(r1, mkU16(i2));
7056 return "iilh";
7059 static const HChar *
7060 s390_irgen_IILL(UChar r1, UShort i2)
7062 put_gpr_hw3(r1, mkU16(i2));
7064 return "iill";
7067 static const HChar *
7068 s390_irgen_LR(UChar r1, UChar r2)
7070 put_gpr_w1(r1, get_gpr_w1(r2));
7072 return "lr";
7075 static const HChar *
7076 s390_irgen_LGR(UChar r1, UChar r2)
7078 put_gpr_dw0(r1, get_gpr_dw0(r2));
7080 return "lgr";
7083 static const HChar *
7084 s390_irgen_LGFR(UChar r1, UChar r2)
7086 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
7088 return "lgfr";
7091 static const HChar *
7092 s390_irgen_L(UChar r1, IRTemp op2addr)
7094 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
7096 return "l";
7099 static const HChar *
7100 s390_irgen_LY(UChar r1, IRTemp op2addr)
7102 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
7104 return "ly";
7107 static const HChar *
7108 s390_irgen_LG(UChar r1, IRTemp op2addr)
7110 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
7112 return "lg";
7115 static const HChar *
7116 s390_irgen_LGF(UChar r1, IRTemp op2addr)
7118 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7120 return "lgf";
7123 static const HChar *
7124 s390_irgen_LGFI(UChar r1, UInt i2)
7126 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
7128 return "lgfi";
7131 static const HChar *
7132 s390_irgen_LRL(UChar r1, UInt i2)
7134 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
7135 i2 << 1))));
7137 return "lrl";
7140 static const HChar *
7141 s390_irgen_LGRL(UChar r1, UInt i2)
7143 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
7144 i2 << 1))));
7146 return "lgrl";
7149 static const HChar *
7150 s390_irgen_LGFRL(UChar r1, UInt i2)
7152 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
7153 ((ULong)(Long)(Int)i2 << 1)))));
7155 return "lgfrl";
7158 static const HChar *
7159 s390_irgen_LA(UChar r1, IRTemp op2addr)
7161 put_gpr_dw0(r1, mkexpr(op2addr));
7163 return "la";
7166 static const HChar *
7167 s390_irgen_LAY(UChar r1, IRTemp op2addr)
7169 put_gpr_dw0(r1, mkexpr(op2addr));
7171 return "lay";
7174 static const HChar *
7175 s390_irgen_LAE(UChar r1, IRTemp op2addr)
7177 put_gpr_dw0(r1, mkexpr(op2addr));
7179 return "lae";
7182 static const HChar *
7183 s390_irgen_LAEY(UChar r1, IRTemp op2addr)
7185 put_gpr_dw0(r1, mkexpr(op2addr));
7187 return "laey";
7190 static const HChar *
7191 s390_irgen_LARL(UChar r1, UInt i2)
7193 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
7195 return "larl";
7198 /* The IR representation of LAA and friends is an approximation of what
7199 happens natively. Essentially a loop containing a compare-and-swap is
7200 constructed which will iterate until the CAS succeeds. As a consequence,
7201 instrumenters may see more memory accesses than happen natively. See also
7202 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
7203 static void
7204 s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
7206 IRCAS *cas;
7207 IRTemp old_mem = newTemp(Ity_I32);
7208 IRTemp op2 = newTemp(Ity_I32);
7209 IRTemp op3 = newTemp(Ity_I32);
7210 IRTemp result = newTemp(Ity_I32);
7212 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7213 assign(op3, get_gpr_w1(r3));
7214 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
7216 /* Place the addition of second operand and third operand at the
7217 second-operand location everytime */
7218 cas = mkIRCAS(IRTemp_INVALID, old_mem,
7219 Iend_BE, mkexpr(op2addr),
7220 NULL, mkexpr(op2), /* expected value */
7221 NULL, mkexpr(result) /* new value */);
7222 stmt(IRStmt_CAS(cas));
7224 /* Set CC according to 32-bit addition */
7225 if (is_signed) {
7226 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
7227 } else {
7228 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
7231 /* If old_mem contains the expected value, then the CAS succeeded.
7232 Otherwise, it did not */
7233 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
7234 put_gpr_w1(r1, mkexpr(old_mem));
7237 static void
7238 s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
7240 IRCAS *cas;
7241 IRTemp old_mem = newTemp(Ity_I64);
7242 IRTemp op2 = newTemp(Ity_I64);
7243 IRTemp op3 = newTemp(Ity_I64);
7244 IRTemp result = newTemp(Ity_I64);
7246 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7247 assign(op3, get_gpr_dw0(r3));
7248 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
7250 /* Place the addition of second operand and third operand at the
7251 second-operand location everytime */
7252 cas = mkIRCAS(IRTemp_INVALID, old_mem,
7253 Iend_BE, mkexpr(op2addr),
7254 NULL, mkexpr(op2), /* expected value */
7255 NULL, mkexpr(result) /* new value */);
7256 stmt(IRStmt_CAS(cas));
7258 /* Set CC according to 64-bit addition */
7259 if (is_signed) {
7260 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
7261 } else {
7262 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
7265 /* If old_mem contains the expected value, then the CAS succeeded.
7266 Otherwise, it did not */
7267 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
7268 put_gpr_dw0(r1, mkexpr(old_mem));
7271 static void
7272 s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
7274 IRCAS *cas;
7275 IRTemp old_mem = newTemp(Ity_I32);
7276 IRTemp op2 = newTemp(Ity_I32);
7277 IRTemp op3 = newTemp(Ity_I32);
7278 IRTemp result = newTemp(Ity_I32);
7280 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7281 assign(op3, get_gpr_w1(r3));
7282 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
7284 /* Place the addition of second operand and third operand at the
7285 second-operand location everytime */
7286 cas = mkIRCAS(IRTemp_INVALID, old_mem,
7287 Iend_BE, mkexpr(op2addr),
7288 NULL, mkexpr(op2), /* expected value */
7289 NULL, mkexpr(result) /* new value */);
7290 stmt(IRStmt_CAS(cas));
7292 /* Set CC according to bitwise operation */
7293 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7295 /* If old_mem contains the expected value, then the CAS succeeded.
7296 Otherwise, it did not */
7297 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
7298 put_gpr_w1(r1, mkexpr(old_mem));
7301 static void
7302 s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
7304 IRCAS *cas;
7305 IRTemp old_mem = newTemp(Ity_I64);
7306 IRTemp op2 = newTemp(Ity_I64);
7307 IRTemp op3 = newTemp(Ity_I64);
7308 IRTemp result = newTemp(Ity_I64);
7310 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7311 assign(op3, get_gpr_dw0(r3));
7312 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
7314 /* Place the addition of second operand and third operand at the
7315 second-operand location everytime */
7316 cas = mkIRCAS(IRTemp_INVALID, old_mem,
7317 Iend_BE, mkexpr(op2addr),
7318 NULL, mkexpr(op2), /* expected value */
7319 NULL, mkexpr(result) /* new value */);
7320 stmt(IRStmt_CAS(cas));
7322 /* Set CC according to bitwise operation */
7323 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7325 /* If old_mem contains the expected value, then the CAS succeeded.
7326 Otherwise, it did not */
7327 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
7328 put_gpr_dw0(r1, mkexpr(old_mem));
7331 static const HChar *
7332 s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
7334 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
7336 return "laa";
7339 static const HChar *
7340 s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
7342 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
7344 return "laag";
7347 static const HChar *
7348 s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
7350 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
7352 return "laal";
7355 static const HChar *
7356 s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
7358 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
7360 return "laalg";
7363 static const HChar *
7364 s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
7366 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
7368 return "lan";
7371 static const HChar *
7372 s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
7374 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
7376 return "lang";
7379 static const HChar *
7380 s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
7382 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
7384 return "lax";
7387 static const HChar *
7388 s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
7390 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
7392 return "laxg";
7395 static const HChar *
7396 s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
7398 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
7400 return "lao";
7403 static const HChar *
7404 s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
7406 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
7408 return "laog";
7411 static const HChar *
7412 s390_irgen_LTR(UChar r1, UChar r2)
7414 IRTemp op2 = newTemp(Ity_I32);
7416 assign(op2, get_gpr_w1(r2));
7417 put_gpr_w1(r1, mkexpr(op2));
7418 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7420 return "ltr";
7423 static const HChar *
7424 s390_irgen_LTGR(UChar r1, UChar r2)
7426 IRTemp op2 = newTemp(Ity_I64);
7428 assign(op2, get_gpr_dw0(r2));
7429 put_gpr_dw0(r1, mkexpr(op2));
7430 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7432 return "ltgr";
7435 static const HChar *
7436 s390_irgen_LTGFR(UChar r1, UChar r2)
7438 IRTemp op2 = newTemp(Ity_I64);
7440 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7441 put_gpr_dw0(r1, mkexpr(op2));
7442 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7444 return "ltgfr";
7447 static const HChar *
7448 s390_irgen_LT(UChar r1, IRTemp op2addr)
7450 IRTemp op2 = newTemp(Ity_I32);
7452 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7453 put_gpr_w1(r1, mkexpr(op2));
7454 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7456 return "lt";
7459 static const HChar *
7460 s390_irgen_LTG(UChar r1, IRTemp op2addr)
7462 IRTemp op2 = newTemp(Ity_I64);
7464 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7465 put_gpr_dw0(r1, mkexpr(op2));
7466 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7468 return "ltg";
7471 static const HChar *
7472 s390_irgen_LTGF(UChar r1, IRTemp op2addr)
7474 IRTemp op2 = newTemp(Ity_I64);
7476 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7477 put_gpr_dw0(r1, mkexpr(op2));
7478 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7480 return "ltgf";
7483 static const HChar *
7484 s390_irgen_LBR(UChar r1, UChar r2)
7486 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
7488 return "lbr";
7491 static const HChar *
7492 s390_irgen_LGBR(UChar r1, UChar r2)
7494 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
7496 return "lgbr";
7499 static const HChar *
7500 s390_irgen_LB(UChar r1, IRTemp op2addr)
7502 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
7504 return "lb";
7507 static const HChar *
7508 s390_irgen_LGB(UChar r1, IRTemp op2addr)
7510 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
7512 return "lgb";
7515 static const HChar *
7516 s390_irgen_LBH(UChar r1, IRTemp op2addr)
7518 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
7520 return "lbh";
7523 static const HChar *
7524 s390_irgen_LCR(UChar r1, UChar r2)
7526 Int op1;
7527 IRTemp op2 = newTemp(Ity_I32);
7528 IRTemp result = newTemp(Ity_I32);
7530 op1 = 0;
7531 assign(op2, get_gpr_w1(r2));
7532 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
7533 put_gpr_w1(r1, mkexpr(result));
7534 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
7535 op1)), op2);
7537 return "lcr";
7540 static const HChar *
7541 s390_irgen_LCGR(UChar r1, UChar r2)
7543 Long op1;
7544 IRTemp op2 = newTemp(Ity_I64);
7545 IRTemp result = newTemp(Ity_I64);
7547 op1 = 0ULL;
7548 assign(op2, get_gpr_dw0(r2));
7549 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
7550 put_gpr_dw0(r1, mkexpr(result));
7551 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
7552 op1)), op2);
7554 return "lcgr";
7557 static const HChar *
7558 s390_irgen_LCGFR(UChar r1, UChar r2)
7560 Long op1;
7561 IRTemp op2 = newTemp(Ity_I64);
7562 IRTemp result = newTemp(Ity_I64);
7564 op1 = 0ULL;
7565 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7566 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
7567 put_gpr_dw0(r1, mkexpr(result));
7568 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
7569 op1)), op2);
7571 return "lcgfr";
7574 static const HChar *
7575 s390_irgen_LHR(UChar r1, UChar r2)
7577 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
7579 return "lhr";
7582 static const HChar *
7583 s390_irgen_LGHR(UChar r1, UChar r2)
7585 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
7587 return "lghr";
7590 static const HChar *
7591 s390_irgen_LH(UChar r1, IRTemp op2addr)
7593 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7595 return "lh";
7598 static const HChar *
7599 s390_irgen_LHY(UChar r1, IRTemp op2addr)
7601 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7603 return "lhy";
7606 static const HChar *
7607 s390_irgen_LGH(UChar r1, IRTemp op2addr)
7609 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
7611 return "lgh";
7614 static const HChar *
7615 s390_irgen_LHI(UChar r1, UShort i2)
7617 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
7619 return "lhi";
7622 static const HChar *
7623 s390_irgen_LGHI(UChar r1, UShort i2)
7625 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
7627 return "lghi";
7630 static const HChar *
7631 s390_irgen_LHRL(UChar r1, UInt i2)
7633 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
7634 ((ULong)(Long)(Int)i2 << 1)))));
7636 return "lhrl";
7639 static const HChar *
7640 s390_irgen_LGHRL(UChar r1, UInt i2)
7642 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
7643 ((ULong)(Long)(Int)i2 << 1)))));
7645 return "lghrl";
7648 static const HChar *
7649 s390_irgen_LHH(UChar r1, IRTemp op2addr)
7651 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7653 return "lhh";
7656 static const HChar *
7657 s390_irgen_LFH(UChar r1, IRTemp op2addr)
7659 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
7661 return "lfh";
7664 static const HChar *
7665 s390_irgen_LLGFR(UChar r1, UChar r2)
7667 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
7669 return "llgfr";
7672 static const HChar *
7673 s390_irgen_LLGF(UChar r1, IRTemp op2addr)
7675 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7677 return "llgf";
7680 static const HChar *
7681 s390_irgen_LLGFRL(UChar r1, UInt i2)
7683 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
7684 ((ULong)(Long)(Int)i2 << 1)))));
7686 return "llgfrl";
7689 static const HChar *
7690 s390_irgen_LLCR(UChar r1, UChar r2)
7692 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
7694 return "llcr";
7697 static const HChar *
7698 s390_irgen_LLGCR(UChar r1, UChar r2)
7700 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
7702 return "llgcr";
7705 static const HChar *
7706 s390_irgen_LLC(UChar r1, IRTemp op2addr)
7708 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
7710 return "llc";
7713 static const HChar *
7714 s390_irgen_LLGC(UChar r1, IRTemp op2addr)
7716 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
7718 return "llgc";
7721 static const HChar *
7722 s390_irgen_LLCH(UChar r1, IRTemp op2addr)
7724 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
7726 return "llch";
7729 static const HChar *
7730 s390_irgen_LLHR(UChar r1, UChar r2)
7732 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
7734 return "llhr";
7737 static const HChar *
7738 s390_irgen_LLGHR(UChar r1, UChar r2)
7740 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
7742 return "llghr";
7745 static const HChar *
7746 s390_irgen_LLH(UChar r1, IRTemp op2addr)
7748 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
7750 return "llh";
7753 static const HChar *
7754 s390_irgen_LLGH(UChar r1, IRTemp op2addr)
7756 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
7758 return "llgh";
7761 static const HChar *
7762 s390_irgen_LLHRL(UChar r1, UInt i2)
7764 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
7765 ((ULong)(Long)(Int)i2 << 1)))));
7767 return "llhrl";
7770 static const HChar *
7771 s390_irgen_LLGHRL(UChar r1, UInt i2)
7773 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
7774 ((ULong)(Long)(Int)i2 << 1)))));
7776 return "llghrl";
7779 static const HChar *
7780 s390_irgen_LLHH(UChar r1, IRTemp op2addr)
7782 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
7784 return "llhh";
7787 static const HChar *
7788 s390_irgen_LLIHF(UChar r1, UInt i2)
7790 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
7792 return "llihf";
7795 static const HChar *
7796 s390_irgen_LLIHH(UChar r1, UShort i2)
7798 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
7800 return "llihh";
7803 static const HChar *
7804 s390_irgen_LLIHL(UChar r1, UShort i2)
7806 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
7808 return "llihl";
7811 static const HChar *
7812 s390_irgen_LLILF(UChar r1, UInt i2)
7814 put_gpr_dw0(r1, mkU64(i2));
7816 return "llilf";
7819 static const HChar *
7820 s390_irgen_LLILH(UChar r1, UShort i2)
7822 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
7824 return "llilh";
7827 static const HChar *
7828 s390_irgen_LLILL(UChar r1, UShort i2)
7830 put_gpr_dw0(r1, mkU64(i2));
7832 return "llill";
7835 static const HChar *
7836 s390_irgen_LLGTR(UChar r1, UChar r2)
7838 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
7839 mkU32(2147483647))));
7841 return "llgtr";
7844 static const HChar *
7845 s390_irgen_LLGT(UChar r1, IRTemp op2addr)
7847 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
7848 mkexpr(op2addr)), mkU32(2147483647))));
7850 return "llgt";
7853 static const HChar *
7854 s390_irgen_LNR(UChar r1, UChar r2)
7856 IRTemp op2 = newTemp(Ity_I32);
7857 IRTemp result = newTemp(Ity_I32);
7859 assign(op2, get_gpr_w1(r2));
7860 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
7861 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
7862 put_gpr_w1(r1, mkexpr(result));
7863 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
7865 return "lnr";
7868 static const HChar *
7869 s390_irgen_LNGR(UChar r1, UChar r2)
7871 IRTemp op2 = newTemp(Ity_I64);
7872 IRTemp result = newTemp(Ity_I64);
7874 assign(op2, get_gpr_dw0(r2));
7875 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
7876 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
7877 put_gpr_dw0(r1, mkexpr(result));
7878 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
7880 return "lngr";
7883 static const HChar *
7884 s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
7886 IRTemp op2 = newTemp(Ity_I64);
7887 IRTemp result = newTemp(Ity_I64);
7889 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
7890 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
7891 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
7892 put_gpr_dw0(r1, mkexpr(result));
7893 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
7895 return "lngfr";
7898 static const HChar *
7899 s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
7901 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
7902 put_gpr_w1(r1, get_gpr_w1(r2));
7904 return "locr";
7907 static const HChar *
7908 s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
7910 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
7911 put_gpr_dw0(r1, get_gpr_dw0(r2));
7913 return "locgr";
7916 static const HChar *
7917 s390_irgen_LOC(UChar r1, IRTemp op2addr)
7919 /* condition is checked in format handler */
7920 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
7922 return "loc";
7925 static const HChar *
7926 s390_irgen_LOCG(UChar r1, IRTemp op2addr)
7928 /* condition is checked in format handler */
7929 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
7931 return "locg";
7934 static const HChar *
7935 s390_irgen_LPQ(UChar r1, IRTemp op2addr)
7937 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
7938 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
7941 return "lpq";
7944 static const HChar *
7945 s390_irgen_LPR(UChar r1, UChar r2)
7947 IRTemp op2 = newTemp(Ity_I32);
7948 IRTemp result = newTemp(Ity_I32);
7950 assign(op2, get_gpr_w1(r2));
7951 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
7952 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
7953 put_gpr_w1(r1, mkexpr(result));
7954 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
7956 return "lpr";
7959 static const HChar *
7960 s390_irgen_LPGR(UChar r1, UChar r2)
7962 IRTemp op2 = newTemp(Ity_I64);
7963 IRTemp result = newTemp(Ity_I64);
7965 assign(op2, get_gpr_dw0(r2));
7966 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
7967 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
7968 put_gpr_dw0(r1, mkexpr(result));
7969 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
7971 return "lpgr";
7974 static const HChar *
7975 s390_irgen_LPGFR(UChar r1, UChar r2)
7977 IRTemp op2 = newTemp(Ity_I64);
7978 IRTemp result = newTemp(Ity_I64);
7980 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7981 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
7982 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
7983 put_gpr_dw0(r1, mkexpr(result));
7984 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
7986 return "lpgfr";
7989 static const HChar *
7990 s390_irgen_LRVR(UChar r1, UChar r2)
7992 IRTemp b0 = newTemp(Ity_I8);
7993 IRTemp b1 = newTemp(Ity_I8);
7994 IRTemp b2 = newTemp(Ity_I8);
7995 IRTemp b3 = newTemp(Ity_I8);
7997 assign(b3, get_gpr_b7(r2));
7998 assign(b2, get_gpr_b6(r2));
7999 assign(b1, get_gpr_b5(r2));
8000 assign(b0, get_gpr_b4(r2));
8001 put_gpr_b4(r1, mkexpr(b3));
8002 put_gpr_b5(r1, mkexpr(b2));
8003 put_gpr_b6(r1, mkexpr(b1));
8004 put_gpr_b7(r1, mkexpr(b0));
8006 return "lrvr";
8009 static const HChar *
8010 s390_irgen_LRVGR(UChar r1, UChar r2)
8012 IRTemp b0 = newTemp(Ity_I8);
8013 IRTemp b1 = newTemp(Ity_I8);
8014 IRTemp b2 = newTemp(Ity_I8);
8015 IRTemp b3 = newTemp(Ity_I8);
8016 IRTemp b4 = newTemp(Ity_I8);
8017 IRTemp b5 = newTemp(Ity_I8);
8018 IRTemp b6 = newTemp(Ity_I8);
8019 IRTemp b7 = newTemp(Ity_I8);
8021 assign(b7, get_gpr_b7(r2));
8022 assign(b6, get_gpr_b6(r2));
8023 assign(b5, get_gpr_b5(r2));
8024 assign(b4, get_gpr_b4(r2));
8025 assign(b3, get_gpr_b3(r2));
8026 assign(b2, get_gpr_b2(r2));
8027 assign(b1, get_gpr_b1(r2));
8028 assign(b0, get_gpr_b0(r2));
8029 put_gpr_b0(r1, mkexpr(b7));
8030 put_gpr_b1(r1, mkexpr(b6));
8031 put_gpr_b2(r1, mkexpr(b5));
8032 put_gpr_b3(r1, mkexpr(b4));
8033 put_gpr_b4(r1, mkexpr(b3));
8034 put_gpr_b5(r1, mkexpr(b2));
8035 put_gpr_b6(r1, mkexpr(b1));
8036 put_gpr_b7(r1, mkexpr(b0));
8038 return "lrvgr";
8041 static const HChar *
8042 s390_irgen_LRVH(UChar r1, IRTemp op2addr)
8044 IRTemp op2 = newTemp(Ity_I16);
8046 assign(op2, load(Ity_I16, mkexpr(op2addr)));
8047 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
8048 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
8050 return "lrvh";
8053 static const HChar *
8054 s390_irgen_LRV(UChar r1, IRTemp op2addr)
8056 IRTemp op2 = newTemp(Ity_I32);
8058 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8059 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
8060 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
8061 mkU8(8)), mkU32(255))));
8062 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
8063 mkU8(16)), mkU32(255))));
8064 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
8065 mkU8(24)), mkU32(255))));
8067 return "lrv";
8070 static const HChar *
8071 s390_irgen_LRVG(UChar r1, IRTemp op2addr)
8073 IRTemp op2 = newTemp(Ity_I64);
8075 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8076 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
8077 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8078 mkU8(8)), mkU64(255))));
8079 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8080 mkU8(16)), mkU64(255))));
8081 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8082 mkU8(24)), mkU64(255))));
8083 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8084 mkU8(32)), mkU64(255))));
8085 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8086 mkU8(40)), mkU64(255))));
8087 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8088 mkU8(48)), mkU64(255))));
8089 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8090 mkU8(56)), mkU64(255))));
8092 return "lrvg";
8095 static const HChar *
8096 s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
8098 store(mkexpr(op1addr), mkU16(i2));
8100 return "mvhhi";
8103 static const HChar *
8104 s390_irgen_MVHI(UShort i2, IRTemp op1addr)
8106 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
8108 return "mvhi";
8111 static const HChar *
8112 s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
8114 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
8116 return "mvghi";
8119 static const HChar *
8120 s390_irgen_MVI(UChar i2, IRTemp op1addr)
8122 store(mkexpr(op1addr), mkU8(i2));
8124 return "mvi";
8127 static const HChar *
8128 s390_irgen_MVIY(UChar i2, IRTemp op1addr)
8130 store(mkexpr(op1addr), mkU8(i2));
8132 return "mviy";
8135 static const HChar *
8136 s390_irgen_MR(UChar r1, UChar r2)
8138 IRTemp op1 = newTemp(Ity_I32);
8139 IRTemp op2 = newTemp(Ity_I32);
8140 IRTemp result = newTemp(Ity_I64);
8142 assign(op1, get_gpr_w1(r1 + 1));
8143 assign(op2, get_gpr_w1(r2));
8144 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8145 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8146 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8148 return "mr";
8151 static const HChar *
8152 s390_irgen_M(UChar r1, IRTemp op2addr)
8154 IRTemp op1 = newTemp(Ity_I32);
8155 IRTemp op2 = newTemp(Ity_I32);
8156 IRTemp result = newTemp(Ity_I64);
8158 assign(op1, get_gpr_w1(r1 + 1));
8159 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8160 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8161 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8162 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8164 return "m";
8167 static const HChar *
8168 s390_irgen_MFY(UChar r1, IRTemp op2addr)
8170 IRTemp op1 = newTemp(Ity_I32);
8171 IRTemp op2 = newTemp(Ity_I32);
8172 IRTemp result = newTemp(Ity_I64);
8174 assign(op1, get_gpr_w1(r1 + 1));
8175 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8176 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8177 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8178 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8180 return "mfy";
8183 static const HChar *
8184 s390_irgen_MH(UChar r1, IRTemp op2addr)
8186 IRTemp op1 = newTemp(Ity_I32);
8187 IRTemp op2 = newTemp(Ity_I16);
8188 IRTemp result = newTemp(Ity_I64);
8190 assign(op1, get_gpr_w1(r1));
8191 assign(op2, load(Ity_I16, mkexpr(op2addr)));
8192 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
8194 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8196 return "mh";
8199 static const HChar *
8200 s390_irgen_MHY(UChar r1, IRTemp op2addr)
8202 IRTemp op1 = newTemp(Ity_I32);
8203 IRTemp op2 = newTemp(Ity_I16);
8204 IRTemp result = newTemp(Ity_I64);
8206 assign(op1, get_gpr_w1(r1));
8207 assign(op2, load(Ity_I16, mkexpr(op2addr)));
8208 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
8210 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8212 return "mhy";
8215 static const HChar *
8216 s390_irgen_MHI(UChar r1, UShort i2)
8218 IRTemp op1 = newTemp(Ity_I32);
8219 Short op2;
8220 IRTemp result = newTemp(Ity_I64);
8222 assign(op1, get_gpr_w1(r1));
8223 op2 = (Short)i2;
8224 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
8225 mkU16((UShort)op2))));
8226 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8228 return "mhi";
8231 static const HChar *
8232 s390_irgen_MGHI(UChar r1, UShort i2)
8234 IRTemp op1 = newTemp(Ity_I64);
8235 Short op2;
8236 IRTemp result = newTemp(Ity_I128);
8238 assign(op1, get_gpr_dw0(r1));
8239 op2 = (Short)i2;
8240 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
8241 mkU16((UShort)op2))));
8242 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8244 return "mghi";
8247 static const HChar *
8248 s390_irgen_MLR(UChar r1, UChar r2)
8250 IRTemp op1 = newTemp(Ity_I32);
8251 IRTemp op2 = newTemp(Ity_I32);
8252 IRTemp result = newTemp(Ity_I64);
8254 assign(op1, get_gpr_w1(r1 + 1));
8255 assign(op2, get_gpr_w1(r2));
8256 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
8257 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8258 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8260 return "mlr";
8263 static const HChar *
8264 s390_irgen_MLGR(UChar r1, UChar r2)
8266 IRTemp op1 = newTemp(Ity_I64);
8267 IRTemp op2 = newTemp(Ity_I64);
8268 IRTemp result = newTemp(Ity_I128);
8270 assign(op1, get_gpr_dw0(r1 + 1));
8271 assign(op2, get_gpr_dw0(r2));
8272 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
8273 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8274 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8276 return "mlgr";
8279 static const HChar *
8280 s390_irgen_ML(UChar r1, IRTemp op2addr)
8282 IRTemp op1 = newTemp(Ity_I32);
8283 IRTemp op2 = newTemp(Ity_I32);
8284 IRTemp result = newTemp(Ity_I64);
8286 assign(op1, get_gpr_w1(r1 + 1));
8287 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8288 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
8289 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8290 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8292 return "ml";
8295 static const HChar *
8296 s390_irgen_MLG(UChar r1, IRTemp op2addr)
8298 IRTemp op1 = newTemp(Ity_I64);
8299 IRTemp op2 = newTemp(Ity_I64);
8300 IRTemp result = newTemp(Ity_I128);
8302 assign(op1, get_gpr_dw0(r1 + 1));
8303 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8304 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
8305 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8306 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8308 return "mlg";
8311 static const HChar *
8312 s390_irgen_MSR(UChar r1, UChar r2)
8314 IRTemp op1 = newTemp(Ity_I32);
8315 IRTemp op2 = newTemp(Ity_I32);
8316 IRTemp result = newTemp(Ity_I64);
8318 assign(op1, get_gpr_w1(r1));
8319 assign(op2, get_gpr_w1(r2));
8320 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8321 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8323 return "msr";
8326 static const HChar *
8327 s390_irgen_MSGR(UChar r1, UChar r2)
8329 IRTemp op1 = newTemp(Ity_I64);
8330 IRTemp op2 = newTemp(Ity_I64);
8331 IRTemp result = newTemp(Ity_I128);
8333 assign(op1, get_gpr_dw0(r1));
8334 assign(op2, get_gpr_dw0(r2));
8335 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8336 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8338 return "msgr";
8341 static const HChar *
8342 s390_irgen_MSGFR(UChar r1, UChar r2)
8344 IRTemp op1 = newTemp(Ity_I64);
8345 IRTemp op2 = newTemp(Ity_I32);
8346 IRTemp result = newTemp(Ity_I128);
8348 assign(op1, get_gpr_dw0(r1));
8349 assign(op2, get_gpr_w1(r2));
8350 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
8352 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8354 return "msgfr";
8357 static const HChar *
8358 s390_irgen_MS(UChar r1, IRTemp op2addr)
8360 IRTemp op1 = newTemp(Ity_I32);
8361 IRTemp op2 = newTemp(Ity_I32);
8362 IRTemp result = newTemp(Ity_I64);
8364 assign(op1, get_gpr_w1(r1));
8365 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8366 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8367 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8369 return "ms";
8372 static const HChar *
8373 s390_irgen_MSY(UChar r1, IRTemp op2addr)
8375 IRTemp op1 = newTemp(Ity_I32);
8376 IRTemp op2 = newTemp(Ity_I32);
8377 IRTemp result = newTemp(Ity_I64);
8379 assign(op1, get_gpr_w1(r1));
8380 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8381 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8382 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8384 return "msy";
8387 static const HChar *
8388 s390_irgen_MSG(UChar r1, IRTemp op2addr)
8390 IRTemp op1 = newTemp(Ity_I64);
8391 IRTemp op2 = newTemp(Ity_I64);
8392 IRTemp result = newTemp(Ity_I128);
8394 assign(op1, get_gpr_dw0(r1));
8395 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8396 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8397 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8399 return "msg";
8402 static const HChar *
8403 s390_irgen_MSGF(UChar r1, IRTemp op2addr)
8405 IRTemp op1 = newTemp(Ity_I64);
8406 IRTemp op2 = newTemp(Ity_I32);
8407 IRTemp result = newTemp(Ity_I128);
8409 assign(op1, get_gpr_dw0(r1));
8410 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8411 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
8413 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8415 return "msgf";
8418 static const HChar *
8419 s390_irgen_MSFI(UChar r1, UInt i2)
8421 IRTemp op1 = newTemp(Ity_I32);
8422 Int op2;
8423 IRTemp result = newTemp(Ity_I64);
8425 assign(op1, get_gpr_w1(r1));
8426 op2 = (Int)i2;
8427 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
8428 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8430 return "msfi";
8433 static const HChar *
8434 s390_irgen_MSGFI(UChar r1, UInt i2)
8436 IRTemp op1 = newTemp(Ity_I64);
8437 Int op2;
8438 IRTemp result = newTemp(Ity_I128);
8440 assign(op1, get_gpr_dw0(r1));
8441 op2 = (Int)i2;
8442 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
8443 op2))));
8444 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8446 return "msgfi";
8449 static const HChar *
8450 s390_irgen_OR(UChar r1, UChar r2)
8452 IRTemp op1 = newTemp(Ity_I32);
8453 IRTemp op2 = newTemp(Ity_I32);
8454 IRTemp result = newTemp(Ity_I32);
8456 assign(op1, get_gpr_w1(r1));
8457 assign(op2, get_gpr_w1(r2));
8458 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
8459 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8460 put_gpr_w1(r1, mkexpr(result));
8462 return "or";
8465 static const HChar *
8466 s390_irgen_OGR(UChar r1, UChar r2)
8468 IRTemp op1 = newTemp(Ity_I64);
8469 IRTemp op2 = newTemp(Ity_I64);
8470 IRTemp result = newTemp(Ity_I64);
8472 assign(op1, get_gpr_dw0(r1));
8473 assign(op2, get_gpr_dw0(r2));
8474 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
8475 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8476 put_gpr_dw0(r1, mkexpr(result));
8478 return "ogr";
8481 static const HChar *
8482 s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
8484 IRTemp op2 = newTemp(Ity_I32);
8485 IRTemp op3 = newTemp(Ity_I32);
8486 IRTemp result = newTemp(Ity_I32);
8488 assign(op2, get_gpr_w1(r2));
8489 assign(op3, get_gpr_w1(r3));
8490 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
8491 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8492 put_gpr_w1(r1, mkexpr(result));
8494 return "ork";
8497 static const HChar *
8498 s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
8500 IRTemp op2 = newTemp(Ity_I64);
8501 IRTemp op3 = newTemp(Ity_I64);
8502 IRTemp result = newTemp(Ity_I64);
8504 assign(op2, get_gpr_dw0(r2));
8505 assign(op3, get_gpr_dw0(r3));
8506 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
8507 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8508 put_gpr_dw0(r1, mkexpr(result));
8510 return "ogrk";
8513 static const HChar *
8514 s390_irgen_O(UChar r1, IRTemp op2addr)
8516 IRTemp op1 = newTemp(Ity_I32);
8517 IRTemp op2 = newTemp(Ity_I32);
8518 IRTemp result = newTemp(Ity_I32);
8520 assign(op1, get_gpr_w1(r1));
8521 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8522 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
8523 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8524 put_gpr_w1(r1, mkexpr(result));
8526 return "o";
8529 static const HChar *
8530 s390_irgen_OY(UChar r1, IRTemp op2addr)
8532 IRTemp op1 = newTemp(Ity_I32);
8533 IRTemp op2 = newTemp(Ity_I32);
8534 IRTemp result = newTemp(Ity_I32);
8536 assign(op1, get_gpr_w1(r1));
8537 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8538 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
8539 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8540 put_gpr_w1(r1, mkexpr(result));
8542 return "oy";
8545 static const HChar *
8546 s390_irgen_OG(UChar r1, IRTemp op2addr)
8548 IRTemp op1 = newTemp(Ity_I64);
8549 IRTemp op2 = newTemp(Ity_I64);
8550 IRTemp result = newTemp(Ity_I64);
8552 assign(op1, get_gpr_dw0(r1));
8553 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8554 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
8555 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8556 put_gpr_dw0(r1, mkexpr(result));
8558 return "og";
8561 static const HChar *
8562 s390_irgen_OI(UChar i2, IRTemp op1addr)
8564 IRTemp op1 = newTemp(Ity_I8);
8565 UChar op2;
8566 IRTemp result = newTemp(Ity_I8);
8568 assign(op1, load(Ity_I8, mkexpr(op1addr)));
8569 op2 = i2;
8570 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
8571 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8572 store(mkexpr(op1addr), mkexpr(result));
8574 return "oi";
8577 static const HChar *
8578 s390_irgen_OIY(UChar i2, IRTemp op1addr)
8580 IRTemp op1 = newTemp(Ity_I8);
8581 UChar op2;
8582 IRTemp result = newTemp(Ity_I8);
8584 assign(op1, load(Ity_I8, mkexpr(op1addr)));
8585 op2 = i2;
8586 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
8587 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8588 store(mkexpr(op1addr), mkexpr(result));
8590 return "oiy";
8593 static const HChar *
8594 s390_irgen_OIHF(UChar r1, UInt i2)
8596 IRTemp op1 = newTemp(Ity_I32);
8597 UInt op2;
8598 IRTemp result = newTemp(Ity_I32);
8600 assign(op1, get_gpr_w0(r1));
8601 op2 = i2;
8602 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
8603 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8604 put_gpr_w0(r1, mkexpr(result));
8606 return "oihf";
8609 static const HChar *
8610 s390_irgen_OIHH(UChar r1, UShort i2)
8612 IRTemp op1 = newTemp(Ity_I16);
8613 UShort op2;
8614 IRTemp result = newTemp(Ity_I16);
8616 assign(op1, get_gpr_hw0(r1));
8617 op2 = i2;
8618 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
8619 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8620 put_gpr_hw0(r1, mkexpr(result));
8622 return "oihh";
8625 static const HChar *
8626 s390_irgen_OIHL(UChar r1, UShort i2)
8628 IRTemp op1 = newTemp(Ity_I16);
8629 UShort op2;
8630 IRTemp result = newTemp(Ity_I16);
8632 assign(op1, get_gpr_hw1(r1));
8633 op2 = i2;
8634 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
8635 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8636 put_gpr_hw1(r1, mkexpr(result));
8638 return "oihl";
8641 static const HChar *
8642 s390_irgen_OILF(UChar r1, UInt i2)
8644 IRTemp op1 = newTemp(Ity_I32);
8645 UInt op2;
8646 IRTemp result = newTemp(Ity_I32);
8648 assign(op1, get_gpr_w1(r1));
8649 op2 = i2;
8650 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
8651 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8652 put_gpr_w1(r1, mkexpr(result));
8654 return "oilf";
8657 static const HChar *
8658 s390_irgen_OILH(UChar r1, UShort i2)
8660 IRTemp op1 = newTemp(Ity_I16);
8661 UShort op2;
8662 IRTemp result = newTemp(Ity_I16);
8664 assign(op1, get_gpr_hw2(r1));
8665 op2 = i2;
8666 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
8667 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8668 put_gpr_hw2(r1, mkexpr(result));
8670 return "oilh";
8673 static const HChar *
8674 s390_irgen_OILL(UChar r1, UShort i2)
8676 IRTemp op1 = newTemp(Ity_I16);
8677 UShort op2;
8678 IRTemp result = newTemp(Ity_I16);
8680 assign(op1, get_gpr_hw3(r1));
8681 op2 = i2;
8682 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
8683 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8684 put_gpr_hw3(r1, mkexpr(result));
8686 return "oill";
8689 static const HChar *
8690 s390_irgen_PFD(void)
8693 return "pfd";
8696 static const HChar *
8697 s390_irgen_PFDRL(void)
8700 return "pfdrl";
8703 static IRExpr *
8704 get_rounding_mode_from_gr0(void)
8706 IRTemp rm_bits = newTemp(Ity_I32);
8707 IRExpr *s390rm;
8708 IRExpr *irrm;
8710 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
8711 when PFPO insn is called. So, extract the bits at [60:63] */
8712 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
8713 s390rm = mkexpr(rm_bits);
8714 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
8715 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
8716 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
8717 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
8718 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
8719 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
8720 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
8721 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
8722 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
8723 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
8724 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
8725 mkexpr(encode_dfp_rounding_mode(
8726 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
8727 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
8728 mkexpr(encode_dfp_rounding_mode(
8729 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
8730 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
8731 mkexpr(encode_dfp_rounding_mode(
8732 S390_DFP_ROUND_AWAY_0)),
8733 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
8734 mkexpr(encode_dfp_rounding_mode(
8735 S390_DFP_ROUND_PREPARE_SHORT_15)),
8736 /* if rounding mode is 0 or invalid (2-7)
8737 set S390_DFP_ROUND_PER_FPC_0 */
8738 mkexpr(encode_dfp_rounding_mode(
8739 S390_DFP_ROUND_PER_FPC_0)))))))))));
8741 return irrm;
8744 static IRExpr *
8745 s390_call_pfpo_helper(IRExpr *gr0)
8747 IRExpr **args, *call;
8749 args = mkIRExprVec_1(gr0);
8750 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
8751 "s390_do_pfpo", &s390_do_pfpo, args);
8752 /* Nothing is excluded from definedness checking. */
8753 call->Iex.CCall.cee->mcx_mask = 0;
8755 return call;
8758 static const HChar *
8759 s390_irgen_PFPO(void)
8761 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
8762 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
8763 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
8764 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
8765 IRTemp src1 = newTemp(Ity_F32);
8766 IRTemp dst1 = newTemp(Ity_D32);
8767 IRTemp src2 = newTemp(Ity_F32);
8768 IRTemp dst2 = newTemp(Ity_D64);
8769 IRTemp src3 = newTemp(Ity_F32);
8770 IRTemp dst3 = newTemp(Ity_D128);
8771 IRTemp src4 = newTemp(Ity_F64);
8772 IRTemp dst4 = newTemp(Ity_D32);
8773 IRTemp src5 = newTemp(Ity_F64);
8774 IRTemp dst5 = newTemp(Ity_D64);
8775 IRTemp src6 = newTemp(Ity_F64);
8776 IRTemp dst6 = newTemp(Ity_D128);
8777 IRTemp src7 = newTemp(Ity_F128);
8778 IRTemp dst7 = newTemp(Ity_D32);
8779 IRTemp src8 = newTemp(Ity_F128);
8780 IRTemp dst8 = newTemp(Ity_D64);
8781 IRTemp src9 = newTemp(Ity_F128);
8782 IRTemp dst9 = newTemp(Ity_D128);
8783 IRTemp src10 = newTemp(Ity_D32);
8784 IRTemp dst10 = newTemp(Ity_F32);
8785 IRTemp src11 = newTemp(Ity_D32);
8786 IRTemp dst11 = newTemp(Ity_F64);
8787 IRTemp src12 = newTemp(Ity_D32);
8788 IRTemp dst12 = newTemp(Ity_F128);
8789 IRTemp src13 = newTemp(Ity_D64);
8790 IRTemp dst13 = newTemp(Ity_F32);
8791 IRTemp src14 = newTemp(Ity_D64);
8792 IRTemp dst14 = newTemp(Ity_F64);
8793 IRTemp src15 = newTemp(Ity_D64);
8794 IRTemp dst15 = newTemp(Ity_F128);
8795 IRTemp src16 = newTemp(Ity_D128);
8796 IRTemp dst16 = newTemp(Ity_F32);
8797 IRTemp src17 = newTemp(Ity_D128);
8798 IRTemp dst17 = newTemp(Ity_F64);
8799 IRTemp src18 = newTemp(Ity_D128);
8800 IRTemp dst18 = newTemp(Ity_F128);
8801 IRExpr *irrm;
8803 if (! s390_host_has_pfpo) {
8804 emulation_failure(EmFail_S390X_pfpo);
8805 goto done;
8808 assign(gr0, get_gpr_w1(0));
8809 /* get function code */
8810 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
8811 mkU32(0x7fffff)));
8812 /* get validity test bit */
8813 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
8814 mkU32(0x1)));
8815 irrm = get_rounding_mode_from_gr0();
8817 /* test_bit is 1 */
8818 assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
8819 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
8821 /* Return code set in GR1 is usually 0. Non-zero value is set only
8822 when exceptions are raised. See Programming Notes point 5 in the
8823 instrcution description of pfpo in POP. Since valgrind does not
8824 model exception, it might be safe to just set 0 to GR 1. */
8825 put_gpr_w1(1, mkU32(0x0));
8826 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
8828 /* Check validity of function code in GR 0 */
8829 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
8830 emulation_failure_with_expr(mkexpr(ef));
8832 stmt(
8833 IRStmt_Exit(
8834 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
8835 Ijk_EmFail,
8836 IRConst_U64(guest_IA_next_instr),
8837 S390X_GUEST_OFFSET(guest_IA)
8841 /* F32 -> D32 */
8842 /* get source from FPR 4,6 - already set in src1 */
8843 assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
8844 put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
8845 put_gpr_w1(1, mkU32(0x0));
8846 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
8847 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
8849 /* F32 -> D64 */
8850 assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
8851 assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
8852 put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
8853 put_gpr_w1(1, mkU32(0x0));
8854 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
8855 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
8857 /* F32 -> D128 */
8858 assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
8859 assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
8860 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
8861 put_gpr_w1(1, mkU32(0x0));
8862 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
8863 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
8865 /* F64 -> D32 */
8866 assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
8867 assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
8868 put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
8869 put_gpr_w1(1, mkU32(0x0));
8870 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
8871 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
8873 /* F64 -> D64 */
8874 assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
8875 assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
8876 put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
8877 put_gpr_w1(1, mkU32(0x0));
8878 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
8879 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
8881 /* F64 -> D128 */
8882 assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
8883 assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
8884 put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
8885 put_gpr_w1(1, mkU32(0x0));
8886 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
8887 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
8889 /* F128 -> D32 */
8890 assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
8891 assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
8892 put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
8893 put_gpr_w1(1, mkU32(0x0));
8894 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
8895 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
8897 /* F128 -> D64 */
8898 assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
8899 assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
8900 put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
8901 put_gpr_w1(1, mkU32(0x0));
8902 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
8903 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
8905 /* F128 -> D128 */
8906 assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
8907 assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
8908 put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
8909 put_gpr_w1(1, mkU32(0x0));
8910 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
8911 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
8913 /* D32 -> F32 */
8914 assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
8915 assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
8916 put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
8917 put_gpr_w1(1, mkU32(0x0));
8918 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
8919 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
8921 /* D32 -> F64 */
8922 assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
8923 assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
8924 put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
8925 put_gpr_w1(1, mkU32(0x0));
8926 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
8927 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
8929 /* D32 -> F128 */
8930 assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
8931 assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
8932 put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
8933 put_gpr_w1(1, mkU32(0x0));
8934 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
8935 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
8937 /* D64 -> F32 */
8938 assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
8939 assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
8940 put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
8941 put_gpr_w1(1, mkU32(0x0));
8942 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
8943 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
8945 /* D64 -> F64 */
8946 assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
8947 assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
8948 put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
8949 put_gpr_w1(1, mkU32(0x0));
8950 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
8951 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
8953 /* D64 -> F128 */
8954 assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
8955 assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
8956 put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
8957 put_gpr_w1(1, mkU32(0x0));
8958 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
8959 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
8961 /* D128 -> F32 */
8962 assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
8963 assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
8964 put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
8965 put_gpr_w1(1, mkU32(0x0));
8966 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
8967 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
8969 /* D128 -> F64 */
8970 assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
8971 assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
8972 put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
8973 put_gpr_w1(1, mkU32(0x0));
8974 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
8975 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
8977 /* D128 -> F128 */
8978 assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
8979 assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
8980 put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
8981 put_gpr_w1(1, mkU32(0x0));
8982 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
8983 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
8985 done:
8986 return "pfpo";
8989 static const HChar *
8990 s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
8992 IRTemp amount = newTemp(Ity_I64);
8993 IRTemp op = newTemp(Ity_I32);
8995 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
8996 assign(op, get_gpr_w1(r3));
8997 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
8998 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
8999 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
9001 return "rll";
9004 static const HChar *
9005 s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
9007 IRTemp amount = newTemp(Ity_I64);
9008 IRTemp op = newTemp(Ity_I64);
9010 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9011 assign(op, get_gpr_dw0(r3));
9012 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
9013 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
9014 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
9016 return "rllg";
9019 static const HChar *
9020 s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9022 UChar from;
9023 UChar to;
9024 UChar rot;
9025 UChar t_bit;
9026 ULong mask;
9027 ULong maskc;
9028 IRTemp result = newTemp(Ity_I64);
9029 IRTemp op2 = newTemp(Ity_I64);
9031 from = i3 & 63;
9032 to = i4 & 63;
9033 rot = i5 & 63;
9034 t_bit = i3 & 128;
9035 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9036 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9037 mkU8(64 - rot))));
9038 if (from <= to) {
9039 mask = ~0ULL;
9040 mask = (mask >> from) & (mask << (63 - to));
9041 maskc = ~mask;
9042 } else {
9043 maskc = ~0ULL;
9044 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9045 mask = ~maskc;
9047 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
9048 ), mkU64(mask)));
9049 if (t_bit == 0) {
9050 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9051 mkU64(maskc)), mkexpr(result)));
9053 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9055 return "rnsbg";
9058 static const HChar *
9059 s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9061 UChar from;
9062 UChar to;
9063 UChar rot;
9064 UChar t_bit;
9065 ULong mask;
9066 ULong maskc;
9067 IRTemp result = newTemp(Ity_I64);
9068 IRTemp op2 = newTemp(Ity_I64);
9070 from = i3 & 63;
9071 to = i4 & 63;
9072 rot = i5 & 63;
9073 t_bit = i3 & 128;
9074 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9075 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9076 mkU8(64 - rot))));
9077 if (from <= to) {
9078 mask = ~0ULL;
9079 mask = (mask >> from) & (mask << (63 - to));
9080 maskc = ~mask;
9081 } else {
9082 maskc = ~0ULL;
9083 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9084 mask = ~maskc;
9086 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
9087 ), mkU64(mask)));
9088 if (t_bit == 0) {
9089 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9090 mkU64(maskc)), mkexpr(result)));
9092 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9094 return "rxsbg";
9097 static const HChar *
9098 s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9100 UChar from;
9101 UChar to;
9102 UChar rot;
9103 UChar t_bit;
9104 ULong mask;
9105 ULong maskc;
9106 IRTemp result = newTemp(Ity_I64);
9107 IRTemp op2 = newTemp(Ity_I64);
9109 from = i3 & 63;
9110 to = i4 & 63;
9111 rot = i5 & 63;
9112 t_bit = i3 & 128;
9113 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9114 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9115 mkU8(64 - rot))));
9116 if (from <= to) {
9117 mask = ~0ULL;
9118 mask = (mask >> from) & (mask << (63 - to));
9119 maskc = ~mask;
9120 } else {
9121 maskc = ~0ULL;
9122 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9123 mask = ~maskc;
9125 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
9126 ), mkU64(mask)));
9127 if (t_bit == 0) {
9128 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9129 mkU64(maskc)), mkexpr(result)));
9131 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9133 return "rosbg";
9136 static const HChar *
9137 s390_irgen_RISBGx(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
9138 Bool set_cc)
9140 UChar from;
9141 UChar to;
9142 UChar rot;
9143 UChar z_bit;
9144 ULong mask;
9145 ULong maskc;
9146 IRTemp op2 = newTemp(Ity_I64);
9147 IRTemp result = newTemp(Ity_I64);
9149 from = i3 & 63;
9150 to = i4 & 63;
9151 rot = i5 & 63;
9152 z_bit = i4 & 128;
9153 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9154 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9155 mkU8(64 - rot))));
9156 if (from <= to) {
9157 mask = ~0ULL;
9158 mask = (mask >> from) & (mask << (63 - to));
9159 maskc = ~mask;
9160 } else {
9161 maskc = ~0ULL;
9162 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9163 mask = ~maskc;
9165 if (z_bit == 0) {
9166 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9167 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
9168 } else {
9169 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
9171 assign(result, get_gpr_dw0(r1));
9172 if (set_cc) {
9173 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9174 return "risbg";
9177 return "risbgn";
9180 static const HChar *
9181 s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9183 return s390_irgen_RISBGx(r1, r2, i3, i4, i5, True);
9186 static const HChar *
9187 s390_irgen_RISBGN(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9189 return s390_irgen_RISBGx(r1, r2, i3, i4, i5, False);
9192 static IRExpr *
9193 s390_irgen_RISBxG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
9194 Bool high)
9196 UChar from;
9197 UChar to;
9198 UChar rot;
9199 UChar z_bit;
9200 UInt mask;
9201 UInt maskc;
9202 IRTemp op2 = newTemp(Ity_I32);
9204 from = i3 & 31;
9205 to = i4 & 31;
9206 rot = i5 & 63;
9207 z_bit = i4 & 128;
9208 if (rot == 0) {
9209 assign(op2, high ? get_gpr_w0(r2) : get_gpr_w1(r2));
9210 } else if (rot == 32) {
9211 assign(op2, high ? get_gpr_w1(r2) : get_gpr_w0(r2));
9212 } else {
9213 assign(op2,
9214 unop(high ? Iop_64HIto32 : Iop_64to32,
9215 binop(Iop_Or64,
9216 binop(Iop_Shl64, get_gpr_dw0(r2), mkU8(rot)),
9217 binop(Iop_Shr64, get_gpr_dw0(r2), mkU8(64 - rot)))));
9219 if (from <= to) {
9220 mask = ~0U;
9221 mask = (mask >> from) & (mask << (31 - to));
9222 maskc = ~mask;
9223 } else {
9224 maskc = ~0U;
9225 maskc = (maskc >> (to + 1)) & (maskc << (32 - from));
9226 mask = ~maskc;
9228 if (z_bit) {
9229 return binop(Iop_And32, mkexpr(op2), mkU32(mask));
9231 return binop(Iop_Or32,
9232 binop(Iop_And32, high ? get_gpr_w0(r1) : get_gpr_w1(r1),
9233 mkU32(maskc)),
9234 binop(Iop_And32, mkexpr(op2), mkU32(mask)));
9237 static const HChar *
9238 s390_irgen_RISBHG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9240 put_gpr_w0(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, True));
9241 return "risbhg";
9244 static const HChar *
9245 s390_irgen_RISBLG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9247 put_gpr_w1(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, False));
9248 return "risblg";
9251 static const HChar *
9252 s390_irgen_SAR(UChar r1, UChar r2)
9254 put_ar_w0(r1, get_gpr_w1(r2));
9255 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
9256 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
9258 return "sar";
9261 static const HChar *
9262 s390_irgen_SLDA(UChar r1, IRTemp op2addr)
9264 IRTemp p1 = newTemp(Ity_I64);
9265 IRTemp p2 = newTemp(Ity_I64);
9266 IRTemp op = newTemp(Ity_I64);
9267 IRTemp result = newTemp(Ity_I64);
9268 ULong sign_mask;
9269 IRTemp shift_amount = newTemp(Ity_I64);
9271 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9272 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9273 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
9275 sign_mask = 1ULL << 63;
9276 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9277 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
9278 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
9279 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
9280 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9281 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9282 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
9284 return "slda";
9287 static const HChar *
9288 s390_irgen_SLDL(UChar r1, IRTemp op2addr)
9290 IRTemp p1 = newTemp(Ity_I64);
9291 IRTemp p2 = newTemp(Ity_I64);
9292 IRTemp result = newTemp(Ity_I64);
9294 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9295 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9296 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
9297 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
9298 mkexpr(op2addr), mkU64(63)))));
9299 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9300 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9302 return "sldl";
9305 static const HChar *
9306 s390_irgen_SLA(UChar r1, IRTemp op2addr)
9308 IRTemp uop = newTemp(Ity_I32);
9309 IRTemp result = newTemp(Ity_I32);
9310 UInt sign_mask;
9311 IRTemp shift_amount = newTemp(Ity_I64);
9312 IRTemp op = newTemp(Ity_I32);
9314 assign(op, get_gpr_w1(r1));
9315 assign(uop, get_gpr_w1(r1));
9316 sign_mask = 2147483648U;
9317 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9318 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
9319 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
9320 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
9321 put_gpr_w1(r1, mkexpr(result));
9322 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
9324 return "sla";
9327 static const HChar *
9328 s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
9330 IRTemp uop = newTemp(Ity_I32);
9331 IRTemp result = newTemp(Ity_I32);
9332 UInt sign_mask;
9333 IRTemp shift_amount = newTemp(Ity_I64);
9334 IRTemp op = newTemp(Ity_I32);
9336 assign(op, get_gpr_w1(r3));
9337 assign(uop, get_gpr_w1(r3));
9338 sign_mask = 2147483648U;
9339 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9340 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
9341 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
9342 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
9343 put_gpr_w1(r1, mkexpr(result));
9344 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
9346 return "slak";
9349 static const HChar *
9350 s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
9352 IRTemp uop = newTemp(Ity_I64);
9353 IRTemp result = newTemp(Ity_I64);
9354 ULong sign_mask;
9355 IRTemp shift_amount = newTemp(Ity_I64);
9356 IRTemp op = newTemp(Ity_I64);
9358 assign(op, get_gpr_dw0(r3));
9359 assign(uop, get_gpr_dw0(r3));
9360 sign_mask = 9223372036854775808ULL;
9361 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9362 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
9363 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
9364 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
9365 put_gpr_dw0(r1, mkexpr(result));
9366 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
9368 return "slag";
9371 static const HChar *
9372 s390_irgen_SLL(UChar r1, IRTemp op2addr)
9374 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
9375 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9377 return "sll";
9380 static const HChar *
9381 s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
9383 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
9384 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9386 return "sllk";
9389 static const HChar *
9390 s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
9392 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
9393 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9395 return "sllg";
9398 static const HChar *
9399 s390_irgen_SRDA(UChar r1, IRTemp op2addr)
9401 IRTemp p1 = newTemp(Ity_I64);
9402 IRTemp p2 = newTemp(Ity_I64);
9403 IRTemp result = newTemp(Ity_I64);
9405 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9406 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9407 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
9408 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
9409 mkexpr(op2addr), mkU64(63)))));
9410 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9411 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9412 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9414 return "srda";
9417 static const HChar *
9418 s390_irgen_SRDL(UChar r1, IRTemp op2addr)
9420 IRTemp p1 = newTemp(Ity_I64);
9421 IRTemp p2 = newTemp(Ity_I64);
9422 IRTemp result = newTemp(Ity_I64);
9424 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9425 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9426 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
9427 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
9428 mkexpr(op2addr), mkU64(63)))));
9429 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9430 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9432 return "srdl";
9435 static const HChar *
9436 s390_irgen_SRA(UChar r1, IRTemp op2addr)
9438 IRTemp result = newTemp(Ity_I32);
9439 IRTemp op = newTemp(Ity_I32);
9441 assign(op, get_gpr_w1(r1));
9442 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9443 mkexpr(op2addr), mkU64(63)))));
9444 put_gpr_w1(r1, mkexpr(result));
9445 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9447 return "sra";
9450 static const HChar *
9451 s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
9453 IRTemp result = newTemp(Ity_I32);
9454 IRTemp op = newTemp(Ity_I32);
9456 assign(op, get_gpr_w1(r3));
9457 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9458 mkexpr(op2addr), mkU64(63)))));
9459 put_gpr_w1(r1, mkexpr(result));
9460 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9462 return "srak";
9465 static const HChar *
9466 s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
9468 IRTemp result = newTemp(Ity_I64);
9469 IRTemp op = newTemp(Ity_I64);
9471 assign(op, get_gpr_dw0(r3));
9472 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9473 mkexpr(op2addr), mkU64(63)))));
9474 put_gpr_dw0(r1, mkexpr(result));
9475 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9477 return "srag";
9480 static const HChar *
9481 s390_irgen_SRL(UChar r1, IRTemp op2addr)
9483 IRTemp op = newTemp(Ity_I32);
9485 assign(op, get_gpr_w1(r1));
9486 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9487 mkexpr(op2addr), mkU64(63)))));
9489 return "srl";
9492 static const HChar *
9493 s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
9495 IRTemp op = newTemp(Ity_I32);
9497 assign(op, get_gpr_w1(r3));
9498 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9499 mkexpr(op2addr), mkU64(63)))));
9501 return "srlk";
9504 static const HChar *
9505 s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
9507 IRTemp op = newTemp(Ity_I64);
9509 assign(op, get_gpr_dw0(r3));
9510 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9511 mkexpr(op2addr), mkU64(63)))));
9513 return "srlg";
9516 static const HChar *
9517 s390_irgen_ST(UChar r1, IRTemp op2addr)
9519 store(mkexpr(op2addr), get_gpr_w1(r1));
9521 return "st";
9524 static const HChar *
9525 s390_irgen_STY(UChar r1, IRTemp op2addr)
9527 store(mkexpr(op2addr), get_gpr_w1(r1));
9529 return "sty";
9532 static const HChar *
9533 s390_irgen_STG(UChar r1, IRTemp op2addr)
9535 store(mkexpr(op2addr), get_gpr_dw0(r1));
9537 return "stg";
9540 static const HChar *
9541 s390_irgen_STRL(UChar r1, UInt i2)
9543 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
9544 get_gpr_w1(r1));
9546 return "strl";
9549 static const HChar *
9550 s390_irgen_STGRL(UChar r1, UInt i2)
9552 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
9553 get_gpr_dw0(r1));
9555 return "stgrl";
9558 static const HChar *
9559 s390_irgen_STC(UChar r1, IRTemp op2addr)
9561 store(mkexpr(op2addr), get_gpr_b7(r1));
9563 return "stc";
9566 static const HChar *
9567 s390_irgen_STCY(UChar r1, IRTemp op2addr)
9569 store(mkexpr(op2addr), get_gpr_b7(r1));
9571 return "stcy";
9574 static const HChar *
9575 s390_irgen_STCH(UChar r1, IRTemp op2addr)
9577 store(mkexpr(op2addr), get_gpr_b3(r1));
9579 return "stch";
9582 static const HChar *
9583 s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
9585 UChar mask;
9586 UChar n;
9588 mask = (UChar)r3;
9589 n = 0;
9590 if ((mask & 8) != 0) {
9591 store(mkexpr(op2addr), get_gpr_b4(r1));
9592 n = n + 1;
9594 if ((mask & 4) != 0) {
9595 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
9596 n = n + 1;
9598 if ((mask & 2) != 0) {
9599 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
9600 n = n + 1;
9602 if ((mask & 1) != 0) {
9603 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
9606 return "stcm";
9609 static const HChar *
9610 s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
9612 UChar mask;
9613 UChar n;
9615 mask = (UChar)r3;
9616 n = 0;
9617 if ((mask & 8) != 0) {
9618 store(mkexpr(op2addr), get_gpr_b4(r1));
9619 n = n + 1;
9621 if ((mask & 4) != 0) {
9622 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
9623 n = n + 1;
9625 if ((mask & 2) != 0) {
9626 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
9627 n = n + 1;
9629 if ((mask & 1) != 0) {
9630 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
9633 return "stcmy";
9636 static const HChar *
9637 s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
9639 UChar mask;
9640 UChar n;
9642 mask = (UChar)r3;
9643 n = 0;
9644 if ((mask & 8) != 0) {
9645 store(mkexpr(op2addr), get_gpr_b0(r1));
9646 n = n + 1;
9648 if ((mask & 4) != 0) {
9649 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
9650 n = n + 1;
9652 if ((mask & 2) != 0) {
9653 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
9654 n = n + 1;
9656 if ((mask & 1) != 0) {
9657 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
9660 return "stcmh";
9663 static const HChar *
9664 s390_irgen_STH(UChar r1, IRTemp op2addr)
9666 store(mkexpr(op2addr), get_gpr_hw3(r1));
9668 return "sth";
9671 static const HChar *
9672 s390_irgen_STHY(UChar r1, IRTemp op2addr)
9674 store(mkexpr(op2addr), get_gpr_hw3(r1));
9676 return "sthy";
9679 static const HChar *
9680 s390_irgen_STHRL(UChar r1, UInt i2)
9682 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
9683 get_gpr_hw3(r1));
9685 return "sthrl";
9688 static const HChar *
9689 s390_irgen_STHH(UChar r1, IRTemp op2addr)
9691 store(mkexpr(op2addr), get_gpr_hw1(r1));
9693 return "sthh";
9696 static const HChar *
9697 s390_irgen_STFH(UChar r1, IRTemp op2addr)
9699 store(mkexpr(op2addr), get_gpr_w0(r1));
9701 return "stfh";
9704 static const HChar *
9705 s390_irgen_STOC(UChar r1, IRTemp op2addr)
9707 /* condition is checked in format handler */
9708 store(mkexpr(op2addr), get_gpr_w1(r1));
9710 return "stoc";
9713 static const HChar *
9714 s390_irgen_STOCG(UChar r1, IRTemp op2addr)
9716 /* condition is checked in format handler */
9717 store(mkexpr(op2addr), get_gpr_dw0(r1));
9719 return "stocg";
9722 static const HChar *
9723 s390_irgen_STPQ(UChar r1, IRTemp op2addr)
9725 store(mkexpr(op2addr), get_gpr_dw0(r1));
9726 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
9728 return "stpq";
9731 static const HChar *
9732 s390_irgen_STRVH(UChar r1, IRTemp op2addr)
9734 store(mkexpr(op2addr), get_gpr_b7(r1));
9735 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
9737 return "strvh";
9740 static const HChar *
9741 s390_irgen_STRV(UChar r1, IRTemp op2addr)
9743 store(mkexpr(op2addr), get_gpr_b7(r1));
9744 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
9745 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
9746 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
9748 return "strv";
9751 static const HChar *
9752 s390_irgen_STRVG(UChar r1, IRTemp op2addr)
9754 store(mkexpr(op2addr), get_gpr_b7(r1));
9755 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
9756 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
9757 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
9758 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
9759 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
9760 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
9761 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
9763 return "strvg";
9766 static const HChar *
9767 s390_irgen_SR(UChar r1, UChar r2)
9769 IRTemp op1 = newTemp(Ity_I32);
9770 IRTemp op2 = newTemp(Ity_I32);
9771 IRTemp result = newTemp(Ity_I32);
9773 assign(op1, get_gpr_w1(r1));
9774 assign(op2, get_gpr_w1(r2));
9775 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
9776 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
9777 put_gpr_w1(r1, mkexpr(result));
9779 return "sr";
9782 static const HChar *
9783 s390_irgen_SGR(UChar r1, UChar r2)
9785 IRTemp op1 = newTemp(Ity_I64);
9786 IRTemp op2 = newTemp(Ity_I64);
9787 IRTemp result = newTemp(Ity_I64);
9789 assign(op1, get_gpr_dw0(r1));
9790 assign(op2, get_gpr_dw0(r2));
9791 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
9792 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
9793 put_gpr_dw0(r1, mkexpr(result));
9795 return "sgr";
9798 static const HChar *
9799 s390_irgen_SGFR(UChar r1, UChar r2)
9801 IRTemp op1 = newTemp(Ity_I64);
9802 IRTemp op2 = newTemp(Ity_I64);
9803 IRTemp result = newTemp(Ity_I64);
9805 assign(op1, get_gpr_dw0(r1));
9806 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9807 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
9808 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
9809 put_gpr_dw0(r1, mkexpr(result));
9811 return "sgfr";
9814 static const HChar *
9815 s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
9817 IRTemp op2 = newTemp(Ity_I32);
9818 IRTemp op3 = newTemp(Ity_I32);
9819 IRTemp result = newTemp(Ity_I32);
9821 assign(op2, get_gpr_w1(r2));
9822 assign(op3, get_gpr_w1(r3));
9823 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
9824 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
9825 put_gpr_w1(r1, mkexpr(result));
9827 return "srk";
9830 static const HChar *
9831 s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
9833 IRTemp op2 = newTemp(Ity_I64);
9834 IRTemp op3 = newTemp(Ity_I64);
9835 IRTemp result = newTemp(Ity_I64);
9837 assign(op2, get_gpr_dw0(r2));
9838 assign(op3, get_gpr_dw0(r3));
9839 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
9840 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
9841 put_gpr_dw0(r1, mkexpr(result));
9843 return "sgrk";
9846 static const HChar *
9847 s390_irgen_S(UChar r1, IRTemp op2addr)
9849 IRTemp op1 = newTemp(Ity_I32);
9850 IRTemp op2 = newTemp(Ity_I32);
9851 IRTemp result = newTemp(Ity_I32);
9853 assign(op1, get_gpr_w1(r1));
9854 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9855 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
9856 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
9857 put_gpr_w1(r1, mkexpr(result));
9859 return "s";
9862 static const HChar *
9863 s390_irgen_SY(UChar r1, IRTemp op2addr)
9865 IRTemp op1 = newTemp(Ity_I32);
9866 IRTemp op2 = newTemp(Ity_I32);
9867 IRTemp result = newTemp(Ity_I32);
9869 assign(op1, get_gpr_w1(r1));
9870 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9871 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
9872 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
9873 put_gpr_w1(r1, mkexpr(result));
9875 return "sy";
9878 static const HChar *
9879 s390_irgen_SG(UChar r1, IRTemp op2addr)
9881 IRTemp op1 = newTemp(Ity_I64);
9882 IRTemp op2 = newTemp(Ity_I64);
9883 IRTemp result = newTemp(Ity_I64);
9885 assign(op1, get_gpr_dw0(r1));
9886 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9887 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
9888 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
9889 put_gpr_dw0(r1, mkexpr(result));
9891 return "sg";
9894 static const HChar *
9895 s390_irgen_SGF(UChar r1, IRTemp op2addr)
9897 IRTemp op1 = newTemp(Ity_I64);
9898 IRTemp op2 = newTemp(Ity_I64);
9899 IRTemp result = newTemp(Ity_I64);
9901 assign(op1, get_gpr_dw0(r1));
9902 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9903 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
9904 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
9905 put_gpr_dw0(r1, mkexpr(result));
9907 return "sgf";
9910 static const HChar *
9911 s390_irgen_SH(UChar r1, IRTemp op2addr)
9913 IRTemp op1 = newTemp(Ity_I32);
9914 IRTemp op2 = newTemp(Ity_I32);
9915 IRTemp result = newTemp(Ity_I32);
9917 assign(op1, get_gpr_w1(r1));
9918 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
9919 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
9920 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
9921 put_gpr_w1(r1, mkexpr(result));
9923 return "sh";
9926 static const HChar *
9927 s390_irgen_SHY(UChar r1, IRTemp op2addr)
9929 IRTemp op1 = newTemp(Ity_I32);
9930 IRTemp op2 = newTemp(Ity_I32);
9931 IRTemp result = newTemp(Ity_I32);
9933 assign(op1, get_gpr_w1(r1));
9934 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
9935 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
9936 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
9937 put_gpr_w1(r1, mkexpr(result));
9939 return "shy";
9942 static const HChar *
9943 s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
9945 IRTemp op2 = newTemp(Ity_I32);
9946 IRTemp op3 = newTemp(Ity_I32);
9947 IRTemp result = newTemp(Ity_I32);
9949 assign(op2, get_gpr_w0(r1));
9950 assign(op3, get_gpr_w0(r2));
9951 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
9952 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
9953 put_gpr_w0(r1, mkexpr(result));
9955 return "shhhr";
9958 static const HChar *
9959 s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
9961 IRTemp op2 = newTemp(Ity_I32);
9962 IRTemp op3 = newTemp(Ity_I32);
9963 IRTemp result = newTemp(Ity_I32);
9965 assign(op2, get_gpr_w0(r1));
9966 assign(op3, get_gpr_w1(r2));
9967 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
9968 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
9969 put_gpr_w0(r1, mkexpr(result));
9971 return "shhlr";
9974 static const HChar *
9975 s390_irgen_SLR(UChar r1, UChar r2)
9977 IRTemp op1 = newTemp(Ity_I32);
9978 IRTemp op2 = newTemp(Ity_I32);
9979 IRTemp result = newTemp(Ity_I32);
9981 assign(op1, get_gpr_w1(r1));
9982 assign(op2, get_gpr_w1(r2));
9983 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
9984 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
9985 put_gpr_w1(r1, mkexpr(result));
9987 return "slr";
9990 static const HChar *
9991 s390_irgen_SLGR(UChar r1, UChar r2)
9993 IRTemp op1 = newTemp(Ity_I64);
9994 IRTemp op2 = newTemp(Ity_I64);
9995 IRTemp result = newTemp(Ity_I64);
9997 assign(op1, get_gpr_dw0(r1));
9998 assign(op2, get_gpr_dw0(r2));
9999 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10000 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10001 put_gpr_dw0(r1, mkexpr(result));
10003 return "slgr";
10006 static const HChar *
10007 s390_irgen_SLGFR(UChar r1, UChar r2)
10009 IRTemp op1 = newTemp(Ity_I64);
10010 IRTemp op2 = newTemp(Ity_I64);
10011 IRTemp result = newTemp(Ity_I64);
10013 assign(op1, get_gpr_dw0(r1));
10014 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
10015 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10016 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10017 put_gpr_dw0(r1, mkexpr(result));
10019 return "slgfr";
10022 static const HChar *
10023 s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
10025 IRTemp op2 = newTemp(Ity_I32);
10026 IRTemp op3 = newTemp(Ity_I32);
10027 IRTemp result = newTemp(Ity_I32);
10029 assign(op2, get_gpr_w1(r2));
10030 assign(op3, get_gpr_w1(r3));
10031 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10032 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
10033 put_gpr_w1(r1, mkexpr(result));
10035 return "slrk";
10038 static const HChar *
10039 s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
10041 IRTemp op2 = newTemp(Ity_I64);
10042 IRTemp op3 = newTemp(Ity_I64);
10043 IRTemp result = newTemp(Ity_I64);
10045 assign(op2, get_gpr_dw0(r2));
10046 assign(op3, get_gpr_dw0(r3));
10047 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
10048 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
10049 put_gpr_dw0(r1, mkexpr(result));
10051 return "slgrk";
10054 static const HChar *
10055 s390_irgen_SL(UChar r1, IRTemp op2addr)
10057 IRTemp op1 = newTemp(Ity_I32);
10058 IRTemp op2 = newTemp(Ity_I32);
10059 IRTemp result = newTemp(Ity_I32);
10061 assign(op1, get_gpr_w1(r1));
10062 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10063 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10064 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
10065 put_gpr_w1(r1, mkexpr(result));
10067 return "sl";
10070 static const HChar *
10071 s390_irgen_SLY(UChar r1, IRTemp op2addr)
10073 IRTemp op1 = newTemp(Ity_I32);
10074 IRTemp op2 = newTemp(Ity_I32);
10075 IRTemp result = newTemp(Ity_I32);
10077 assign(op1, get_gpr_w1(r1));
10078 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10079 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10080 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
10081 put_gpr_w1(r1, mkexpr(result));
10083 return "sly";
10086 static const HChar *
10087 s390_irgen_SLG(UChar r1, IRTemp op2addr)
10089 IRTemp op1 = newTemp(Ity_I64);
10090 IRTemp op2 = newTemp(Ity_I64);
10091 IRTemp result = newTemp(Ity_I64);
10093 assign(op1, get_gpr_dw0(r1));
10094 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10095 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10096 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10097 put_gpr_dw0(r1, mkexpr(result));
10099 return "slg";
10102 static const HChar *
10103 s390_irgen_SLGF(UChar r1, IRTemp op2addr)
10105 IRTemp op1 = newTemp(Ity_I64);
10106 IRTemp op2 = newTemp(Ity_I64);
10107 IRTemp result = newTemp(Ity_I64);
10109 assign(op1, get_gpr_dw0(r1));
10110 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
10111 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10112 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10113 put_gpr_dw0(r1, mkexpr(result));
10115 return "slgf";
10118 static const HChar *
10119 s390_irgen_SLFI(UChar r1, UInt i2)
10121 IRTemp op1 = newTemp(Ity_I32);
10122 UInt op2;
10123 IRTemp result = newTemp(Ity_I32);
10125 assign(op1, get_gpr_w1(r1));
10126 op2 = i2;
10127 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
10128 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
10129 mkU32(op2)));
10130 put_gpr_w1(r1, mkexpr(result));
10132 return "slfi";
10135 static const HChar *
10136 s390_irgen_SLGFI(UChar r1, UInt i2)
10138 IRTemp op1 = newTemp(Ity_I64);
10139 ULong op2;
10140 IRTemp result = newTemp(Ity_I64);
10142 assign(op1, get_gpr_dw0(r1));
10143 op2 = (ULong)i2;
10144 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
10145 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
10146 mkU64(op2)));
10147 put_gpr_dw0(r1, mkexpr(result));
10149 return "slgfi";
10152 static const HChar *
10153 s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10155 IRTemp op2 = newTemp(Ity_I32);
10156 IRTemp op3 = newTemp(Ity_I32);
10157 IRTemp result = newTemp(Ity_I32);
10159 assign(op2, get_gpr_w0(r1));
10160 assign(op3, get_gpr_w0(r2));
10161 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10162 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
10163 put_gpr_w0(r1, mkexpr(result));
10165 return "slhhhr";
10168 static const HChar *
10169 s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10171 IRTemp op2 = newTemp(Ity_I32);
10172 IRTemp op3 = newTemp(Ity_I32);
10173 IRTemp result = newTemp(Ity_I32);
10175 assign(op2, get_gpr_w0(r1));
10176 assign(op3, get_gpr_w1(r2));
10177 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10178 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
10179 put_gpr_w0(r1, mkexpr(result));
10181 return "slhhlr";
10184 static const HChar *
10185 s390_irgen_SLBR(UChar r1, UChar r2)
10187 IRTemp op1 = newTemp(Ity_I32);
10188 IRTemp op2 = newTemp(Ity_I32);
10189 IRTemp result = newTemp(Ity_I32);
10190 IRTemp borrow_in = newTemp(Ity_I32);
10192 assign(op1, get_gpr_w1(r1));
10193 assign(op2, get_gpr_w1(r2));
10194 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
10195 s390_call_calculate_cc(), mkU8(1))));
10196 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
10197 mkexpr(borrow_in)));
10198 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
10199 put_gpr_w1(r1, mkexpr(result));
10201 return "slbr";
10204 static const HChar *
10205 s390_irgen_SLBGR(UChar r1, UChar r2)
10207 IRTemp op1 = newTemp(Ity_I64);
10208 IRTemp op2 = newTemp(Ity_I64);
10209 IRTemp result = newTemp(Ity_I64);
10210 IRTemp borrow_in = newTemp(Ity_I64);
10212 assign(op1, get_gpr_dw0(r1));
10213 assign(op2, get_gpr_dw0(r2));
10214 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
10215 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
10216 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
10217 mkexpr(borrow_in)));
10218 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
10219 put_gpr_dw0(r1, mkexpr(result));
10221 return "slbgr";
10224 static const HChar *
10225 s390_irgen_SLB(UChar r1, IRTemp op2addr)
10227 IRTemp op1 = newTemp(Ity_I32);
10228 IRTemp op2 = newTemp(Ity_I32);
10229 IRTemp result = newTemp(Ity_I32);
10230 IRTemp borrow_in = newTemp(Ity_I32);
10232 assign(op1, get_gpr_w1(r1));
10233 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10234 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
10235 s390_call_calculate_cc(), mkU8(1))));
10236 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
10237 mkexpr(borrow_in)));
10238 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
10239 put_gpr_w1(r1, mkexpr(result));
10241 return "slb";
10244 static const HChar *
10245 s390_irgen_SLBG(UChar r1, IRTemp op2addr)
10247 IRTemp op1 = newTemp(Ity_I64);
10248 IRTemp op2 = newTemp(Ity_I64);
10249 IRTemp result = newTemp(Ity_I64);
10250 IRTemp borrow_in = newTemp(Ity_I64);
10252 assign(op1, get_gpr_dw0(r1));
10253 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10254 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
10255 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
10256 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
10257 mkexpr(borrow_in)));
10258 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
10259 put_gpr_dw0(r1, mkexpr(result));
10261 return "slbg";
10264 static const HChar *
10265 s390_irgen_SVC(UChar i)
10267 IRTemp sysno = newTemp(Ity_I64);
10269 if (i != 0) {
10270 assign(sysno, mkU64(i));
10271 } else {
10272 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
10274 system_call(mkexpr(sysno));
10276 return "svc";
10279 static const HChar *
10280 s390_irgen_TM(UChar i2, IRTemp op1addr)
10282 UChar mask;
10283 IRTemp value = newTemp(Ity_I8);
10285 mask = i2;
10286 assign(value, load(Ity_I8, mkexpr(op1addr)));
10287 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
10288 mkU8(mask)));
10290 return "tm";
10293 static const HChar *
10294 s390_irgen_TMY(UChar i2, IRTemp op1addr)
10296 UChar mask;
10297 IRTemp value = newTemp(Ity_I8);
10299 mask = i2;
10300 assign(value, load(Ity_I8, mkexpr(op1addr)));
10301 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
10302 mkU8(mask)));
10304 return "tmy";
10307 static const HChar *
10308 s390_irgen_TMHH(UChar r1, UShort i2)
10310 UShort mask;
10311 IRTemp value = newTemp(Ity_I16);
10313 mask = i2;
10314 assign(value, get_gpr_hw0(r1));
10315 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10316 mkU16(mask)));
10318 return "tmhh";
10321 static const HChar *
10322 s390_irgen_TMHL(UChar r1, UShort i2)
10324 UShort mask;
10325 IRTemp value = newTemp(Ity_I16);
10327 mask = i2;
10328 assign(value, get_gpr_hw1(r1));
10329 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10330 mkU16(mask)));
10332 return "tmhl";
10335 static const HChar *
10336 s390_irgen_TMLH(UChar r1, UShort i2)
10338 UShort mask;
10339 IRTemp value = newTemp(Ity_I16);
10341 mask = i2;
10342 assign(value, get_gpr_hw2(r1));
10343 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10344 mkU16(mask)));
10346 return "tmlh";
10349 static const HChar *
10350 s390_irgen_TMLL(UChar r1, UShort i2)
10352 UShort mask;
10353 IRTemp value = newTemp(Ity_I16);
10355 mask = i2;
10356 assign(value, get_gpr_hw3(r1));
10357 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10358 mkU16(mask)));
10360 return "tmll";
10363 static const HChar *
10364 s390_irgen_EFPC(UChar r1)
10366 put_gpr_w1(r1, get_fpc_w0());
10368 return "efpc";
10371 static const HChar *
10372 s390_irgen_LER(UChar r1, UChar r2)
10374 put_fpr_w0(r1, get_fpr_w0(r2));
10376 return "ler";
10379 static const HChar *
10380 s390_irgen_LDR(UChar r1, UChar r2)
10382 put_fpr_dw0(r1, get_fpr_dw0(r2));
10384 return "ldr";
10387 static const HChar *
10388 s390_irgen_LDER(UChar r1, UChar r2)
10390 put_fpr_dw0(r1, mkF64i(0x0));
10391 put_fpr_w0(r1, get_fpr_w0(r2));
10393 return "lder";
10396 static const HChar *
10397 s390_irgen_LXR(UChar r1, UChar r2)
10399 put_fpr_dw0(r1, get_fpr_dw0(r2));
10400 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
10402 return "lxr";
10405 static const HChar *
10406 s390_irgen_LE(UChar r1, IRTemp op2addr)
10408 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
10410 return "le";
10413 static const HChar *
10414 s390_irgen_LD(UChar r1, IRTemp op2addr)
10416 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
10418 return "ld";
10421 static const HChar *
10422 s390_irgen_LDE(UChar r1, IRTemp op2addr)
10424 put_fpr_dw0(r1, mkF64i(0x0));
10425 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
10427 return "lde";
10430 static const HChar *
10431 s390_irgen_LEY(UChar r1, IRTemp op2addr)
10433 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
10435 return "ley";
10438 static const HChar *
10439 s390_irgen_LDY(UChar r1, IRTemp op2addr)
10441 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
10443 return "ldy";
10446 static const HChar *
10447 s390_irgen_LFPC(IRTemp op2addr)
10449 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
10451 return "lfpc";
10454 static const HChar *
10455 s390_irgen_LZER(UChar r1)
10457 put_fpr_w0(r1, mkF32i(0x0));
10459 return "lzer";
10462 static const HChar *
10463 s390_irgen_LZDR(UChar r1)
10465 put_fpr_dw0(r1, mkF64i(0x0));
10467 return "lzdr";
10470 static const HChar *
10471 s390_irgen_LZXR(UChar r1)
10473 put_fpr_dw0(r1, mkF64i(0x0));
10474 put_fpr_dw0(r1 + 2, mkF64i(0x0));
10476 return "lzxr";
10479 static const HChar *
10480 s390_irgen_SRNM(IRTemp op2addr)
10482 UInt input_mask, fpc_mask;
10484 input_mask = 3;
10485 fpc_mask = s390_host_has_fpext ? 7 : 3;
10487 put_fpc_w0(binop(Iop_Or32,
10488 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
10489 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
10490 mkU32(input_mask))));
10491 return "srnm";
10494 static const HChar *
10495 s390_irgen_SRNMB(IRTemp op2addr)
10497 UInt input_mask, fpc_mask;
10499 input_mask = 7;
10500 fpc_mask = 7;
10502 put_fpc_w0(binop(Iop_Or32,
10503 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
10504 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
10505 mkU32(input_mask))));
10506 return "srnmb";
10509 static void
10510 s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
10512 if (b2 == 0) { /* This is the typical case */
10513 if (d2 > 3) {
10514 if (s390_host_has_fpext && d2 == 7) {
10515 /* ok */
10516 } else {
10517 emulation_warning(EmWarn_S390X_invalid_rounding);
10518 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
10523 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
10526 /* Wrapper to validate the parameter as in SRNMB is not required, as all
10527 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
10528 static const HChar *
10529 s390_irgen_SRNMT(IRTemp op2addr)
10531 UInt input_mask, fpc_mask;
10533 input_mask = 7;
10534 fpc_mask = 0x70;
10536 /* fpc[25:27] <- op2addr[61:63]
10537 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
10538 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
10539 binop(Iop_Shl32, binop(Iop_And32,
10540 unop(Iop_64to32, mkexpr(op2addr)),
10541 mkU32(input_mask)), mkU8(4))));
10542 return "srnmt";
10546 static const HChar *
10547 s390_irgen_SFPC(UChar r1)
10549 put_fpc_w0(get_gpr_w1(r1));
10551 return "sfpc";
10554 static const HChar *
10555 s390_irgen_STE(UChar r1, IRTemp op2addr)
10557 store(mkexpr(op2addr), get_fpr_w0(r1));
10559 return "ste";
10562 static const HChar *
10563 s390_irgen_STD(UChar r1, IRTemp op2addr)
10565 store(mkexpr(op2addr), get_fpr_dw0(r1));
10567 return "std";
10570 static const HChar *
10571 s390_irgen_STEY(UChar r1, IRTemp op2addr)
10573 store(mkexpr(op2addr), get_fpr_w0(r1));
10575 return "stey";
10578 static const HChar *
10579 s390_irgen_STDY(UChar r1, IRTemp op2addr)
10581 store(mkexpr(op2addr), get_fpr_dw0(r1));
10583 return "stdy";
10586 static const HChar *
10587 s390_irgen_STFPC(IRTemp op2addr)
10589 store(mkexpr(op2addr), get_fpc_w0());
10591 return "stfpc";
10594 static const HChar *
10595 s390_irgen_AEBR(UChar r1, UChar r2)
10597 IRTemp op1 = newTemp(Ity_F32);
10598 IRTemp op2 = newTemp(Ity_F32);
10599 IRTemp result = newTemp(Ity_F32);
10600 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10602 assign(op1, get_fpr_w0(r1));
10603 assign(op2, get_fpr_w0(r2));
10604 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
10605 mkexpr(op2)));
10606 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
10607 put_fpr_w0(r1, mkexpr(result));
10609 return "aebr";
10612 static const HChar *
10613 s390_irgen_ADBR(UChar r1, UChar r2)
10615 IRTemp op1 = newTemp(Ity_F64);
10616 IRTemp op2 = newTemp(Ity_F64);
10617 IRTemp result = newTemp(Ity_F64);
10618 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10620 assign(op1, get_fpr_dw0(r1));
10621 assign(op2, get_fpr_dw0(r2));
10622 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
10623 mkexpr(op2)));
10624 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
10625 put_fpr_dw0(r1, mkexpr(result));
10627 return "adbr";
10630 static const HChar *
10631 s390_irgen_AEB(UChar r1, IRTemp op2addr)
10633 IRTemp op1 = newTemp(Ity_F32);
10634 IRTemp op2 = newTemp(Ity_F32);
10635 IRTemp result = newTemp(Ity_F32);
10636 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10638 assign(op1, get_fpr_w0(r1));
10639 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10640 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
10641 mkexpr(op2)));
10642 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
10643 put_fpr_w0(r1, mkexpr(result));
10645 return "aeb";
10648 static const HChar *
10649 s390_irgen_ADB(UChar r1, IRTemp op2addr)
10651 IRTemp op1 = newTemp(Ity_F64);
10652 IRTemp op2 = newTemp(Ity_F64);
10653 IRTemp result = newTemp(Ity_F64);
10654 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10656 assign(op1, get_fpr_dw0(r1));
10657 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10658 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
10659 mkexpr(op2)));
10660 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
10661 put_fpr_dw0(r1, mkexpr(result));
10663 return "adb";
10666 static const HChar *
10667 s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
10668 UChar r1, UChar r2)
10670 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
10671 emulation_warning(EmWarn_S390X_fpext_rounding);
10672 m3 = S390_BFP_ROUND_PER_FPC;
10674 IRTemp op2 = newTemp(Ity_I32);
10676 assign(op2, get_gpr_w1(r2));
10677 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
10678 mkexpr(op2)));
10680 return "cefbr";
10683 static const HChar *
10684 s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
10685 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10687 IRTemp op2 = newTemp(Ity_I32);
10689 assign(op2, get_gpr_w1(r2));
10690 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
10692 return "cdfbr";
10695 static const HChar *
10696 s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
10697 UChar r1, UChar r2)
10699 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
10700 emulation_warning(EmWarn_S390X_fpext_rounding);
10701 m3 = S390_BFP_ROUND_PER_FPC;
10703 IRTemp op2 = newTemp(Ity_I64);
10705 assign(op2, get_gpr_dw0(r2));
10706 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
10707 mkexpr(op2)));
10709 return "cegbr";
10712 static const HChar *
10713 s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
10714 UChar r1, UChar r2)
10716 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
10717 emulation_warning(EmWarn_S390X_fpext_rounding);
10718 m3 = S390_BFP_ROUND_PER_FPC;
10720 IRTemp op2 = newTemp(Ity_I64);
10722 assign(op2, get_gpr_dw0(r2));
10723 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
10724 mkexpr(op2)));
10726 return "cdgbr";
10729 static const HChar *
10730 s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
10731 UChar r1, UChar r2)
10733 if (! s390_host_has_fpext) {
10734 emulation_failure(EmFail_S390X_fpext);
10735 } else {
10736 IRTemp op2 = newTemp(Ity_I32);
10738 assign(op2, get_gpr_w1(r2));
10739 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
10740 mkexpr(op2)));
10742 return "celfbr";
10745 static const HChar *
10746 s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
10747 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10749 if (! s390_host_has_fpext) {
10750 emulation_failure(EmFail_S390X_fpext);
10751 } else {
10752 IRTemp op2 = newTemp(Ity_I32);
10754 assign(op2, get_gpr_w1(r2));
10755 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
10757 return "cdlfbr";
10760 static const HChar *
10761 s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
10762 UChar r1, UChar r2)
10764 if (! s390_host_has_fpext) {
10765 emulation_failure(EmFail_S390X_fpext);
10766 } else {
10767 IRTemp op2 = newTemp(Ity_I64);
10769 assign(op2, get_gpr_dw0(r2));
10770 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
10771 mkexpr(op2)));
10773 return "celgbr";
10776 static const HChar *
10777 s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
10778 UChar r1, UChar r2)
10780 if (! s390_host_has_fpext) {
10781 emulation_failure(EmFail_S390X_fpext);
10782 } else {
10783 IRTemp op2 = newTemp(Ity_I64);
10785 assign(op2, get_gpr_dw0(r2));
10786 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
10787 mkexpr(encode_bfp_rounding_mode(m3)),
10788 mkexpr(op2)));
10790 return "cdlgbr";
10793 static const HChar *
10794 s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
10795 UChar r1, UChar r2)
10797 if (! s390_host_has_fpext) {
10798 emulation_failure(EmFail_S390X_fpext);
10799 } else {
10800 IRTemp op = newTemp(Ity_F32);
10801 IRTemp result = newTemp(Ity_I32);
10802 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
10804 assign(op, get_fpr_w0(r2));
10805 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
10806 mkexpr(op)));
10807 put_gpr_w1(r1, mkexpr(result));
10808 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
10810 return "clfebr";
10813 static const HChar *
10814 s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
10815 UChar r1, UChar r2)
10817 if (! s390_host_has_fpext) {
10818 emulation_failure(EmFail_S390X_fpext);
10819 } else {
10820 IRTemp op = newTemp(Ity_F64);
10821 IRTemp result = newTemp(Ity_I32);
10822 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
10824 assign(op, get_fpr_dw0(r2));
10825 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
10826 mkexpr(op)));
10827 put_gpr_w1(r1, mkexpr(result));
10828 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
10830 return "clfdbr";
10833 static const HChar *
10834 s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
10835 UChar r1, UChar r2)
10837 if (! s390_host_has_fpext) {
10838 emulation_failure(EmFail_S390X_fpext);
10839 } else {
10840 IRTemp op = newTemp(Ity_F32);
10841 IRTemp result = newTemp(Ity_I64);
10842 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
10844 assign(op, get_fpr_w0(r2));
10845 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
10846 mkexpr(op)));
10847 put_gpr_dw0(r1, mkexpr(result));
10848 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
10850 return "clgebr";
10853 static const HChar *
10854 s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
10855 UChar r1, UChar r2)
10857 if (! s390_host_has_fpext) {
10858 emulation_failure(EmFail_S390X_fpext);
10859 } else {
10860 IRTemp op = newTemp(Ity_F64);
10861 IRTemp result = newTemp(Ity_I64);
10862 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
10864 assign(op, get_fpr_dw0(r2));
10865 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
10866 mkexpr(op)));
10867 put_gpr_dw0(r1, mkexpr(result));
10868 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
10870 return "clgdbr";
10873 static const HChar *
10874 s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
10875 UChar r1, UChar r2)
10877 IRTemp op = newTemp(Ity_F32);
10878 IRTemp result = newTemp(Ity_I32);
10879 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
10881 assign(op, get_fpr_w0(r2));
10882 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
10883 mkexpr(op)));
10884 put_gpr_w1(r1, mkexpr(result));
10885 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
10887 return "cfebr";
10890 static const HChar *
10891 s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
10892 UChar r1, UChar r2)
10894 IRTemp op = newTemp(Ity_F64);
10895 IRTemp result = newTemp(Ity_I32);
10896 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
10898 assign(op, get_fpr_dw0(r2));
10899 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
10900 mkexpr(op)));
10901 put_gpr_w1(r1, mkexpr(result));
10902 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
10904 return "cfdbr";
10907 static const HChar *
10908 s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
10909 UChar r1, UChar r2)
10911 IRTemp op = newTemp(Ity_F32);
10912 IRTemp result = newTemp(Ity_I64);
10913 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
10915 assign(op, get_fpr_w0(r2));
10916 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
10917 mkexpr(op)));
10918 put_gpr_dw0(r1, mkexpr(result));
10919 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
10921 return "cgebr";
10924 static const HChar *
10925 s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
10926 UChar r1, UChar r2)
10928 IRTemp op = newTemp(Ity_F64);
10929 IRTemp result = newTemp(Ity_I64);
10930 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
10932 assign(op, get_fpr_dw0(r2));
10933 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
10934 mkexpr(op)));
10935 put_gpr_dw0(r1, mkexpr(result));
10936 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
10938 return "cgdbr";
10941 static const HChar *
10942 s390_irgen_DEBR(UChar r1, UChar r2)
10944 IRTemp op1 = newTemp(Ity_F32);
10945 IRTemp op2 = newTemp(Ity_F32);
10946 IRTemp result = newTemp(Ity_F32);
10947 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10949 assign(op1, get_fpr_w0(r1));
10950 assign(op2, get_fpr_w0(r2));
10951 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
10952 mkexpr(op2)));
10953 put_fpr_w0(r1, mkexpr(result));
10955 return "debr";
10958 static const HChar *
10959 s390_irgen_DDBR(UChar r1, UChar r2)
10961 IRTemp op1 = newTemp(Ity_F64);
10962 IRTemp op2 = newTemp(Ity_F64);
10963 IRTemp result = newTemp(Ity_F64);
10964 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10966 assign(op1, get_fpr_dw0(r1));
10967 assign(op2, get_fpr_dw0(r2));
10968 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
10969 mkexpr(op2)));
10970 put_fpr_dw0(r1, mkexpr(result));
10972 return "ddbr";
10975 static const HChar *
10976 s390_irgen_DEB(UChar r1, IRTemp op2addr)
10978 IRTemp op1 = newTemp(Ity_F32);
10979 IRTemp op2 = newTemp(Ity_F32);
10980 IRTemp result = newTemp(Ity_F32);
10981 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10983 assign(op1, get_fpr_w0(r1));
10984 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10985 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
10986 mkexpr(op2)));
10987 put_fpr_w0(r1, mkexpr(result));
10989 return "deb";
10992 static const HChar *
10993 s390_irgen_DDB(UChar r1, IRTemp op2addr)
10995 IRTemp op1 = newTemp(Ity_F64);
10996 IRTemp op2 = newTemp(Ity_F64);
10997 IRTemp result = newTemp(Ity_F64);
10998 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11000 assign(op1, get_fpr_dw0(r1));
11001 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11002 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
11003 mkexpr(op2)));
11004 put_fpr_dw0(r1, mkexpr(result));
11006 return "ddb";
11009 static const HChar *
11010 s390_irgen_LTEBR(UChar r1, UChar r2)
11012 IRTemp result = newTemp(Ity_F32);
11014 assign(result, get_fpr_w0(r2));
11015 put_fpr_w0(r1, mkexpr(result));
11016 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11018 return "ltebr";
11021 static const HChar *
11022 s390_irgen_LTDBR(UChar r1, UChar r2)
11024 IRTemp result = newTemp(Ity_F64);
11026 assign(result, get_fpr_dw0(r2));
11027 put_fpr_dw0(r1, mkexpr(result));
11028 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11030 return "ltdbr";
11033 static const HChar *
11034 s390_irgen_LCEBR(UChar r1, UChar r2)
11036 IRTemp result = newTemp(Ity_F32);
11038 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
11039 put_fpr_w0(r1, mkexpr(result));
11040 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11042 return "lcebr";
11045 static const HChar *
11046 s390_irgen_LCDBR(UChar r1, UChar r2)
11048 IRTemp result = newTemp(Ity_F64);
11050 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11051 put_fpr_dw0(r1, mkexpr(result));
11052 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11054 return "lcdbr";
11057 static const HChar *
11058 s390_irgen_LDEBR(UChar r1, UChar r2)
11060 IRTemp op = newTemp(Ity_F32);
11062 assign(op, get_fpr_w0(r2));
11063 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
11065 return "ldebr";
11068 static const HChar *
11069 s390_irgen_LDEB(UChar r1, IRTemp op2addr)
11071 IRTemp op = newTemp(Ity_F32);
11073 assign(op, load(Ity_F32, mkexpr(op2addr)));
11074 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
11076 return "ldeb";
11079 static const HChar *
11080 s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
11081 UChar r1, UChar r2)
11083 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
11084 emulation_warning(EmWarn_S390X_fpext_rounding);
11085 m3 = S390_BFP_ROUND_PER_FPC;
11087 IRTemp op = newTemp(Ity_F64);
11089 assign(op, get_fpr_dw0(r2));
11090 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
11091 mkexpr(op)));
11093 return "ledbr";
11096 static const HChar *
11097 s390_irgen_MEEBR(UChar r1, UChar r2)
11099 IRTemp op1 = newTemp(Ity_F32);
11100 IRTemp op2 = newTemp(Ity_F32);
11101 IRTemp result = newTemp(Ity_F32);
11102 IRRoundingMode rounding_mode =
11103 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11105 assign(op1, get_fpr_w0(r1));
11106 assign(op2, get_fpr_w0(r2));
11107 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
11108 mkexpr(op2)));
11109 put_fpr_w0(r1, mkexpr(result));
11111 return "meebr";
11114 static const HChar *
11115 s390_irgen_MDBR(UChar r1, UChar r2)
11117 IRTemp op1 = newTemp(Ity_F64);
11118 IRTemp op2 = newTemp(Ity_F64);
11119 IRTemp result = newTemp(Ity_F64);
11120 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11122 assign(op1, get_fpr_dw0(r1));
11123 assign(op2, get_fpr_dw0(r2));
11124 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
11125 mkexpr(op2)));
11126 put_fpr_dw0(r1, mkexpr(result));
11128 return "mdbr";
11131 static const HChar *
11132 s390_irgen_MEEB(UChar r1, IRTemp op2addr)
11134 IRTemp op1 = newTemp(Ity_F32);
11135 IRTemp op2 = newTemp(Ity_F32);
11136 IRTemp result = newTemp(Ity_F32);
11137 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11139 assign(op1, get_fpr_w0(r1));
11140 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11141 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
11142 mkexpr(op2)));
11143 put_fpr_w0(r1, mkexpr(result));
11145 return "meeb";
11148 static const HChar *
11149 s390_irgen_MDB(UChar r1, IRTemp op2addr)
11151 IRTemp op1 = newTemp(Ity_F64);
11152 IRTemp op2 = newTemp(Ity_F64);
11153 IRTemp result = newTemp(Ity_F64);
11154 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11156 assign(op1, get_fpr_dw0(r1));
11157 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11158 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
11159 mkexpr(op2)));
11160 put_fpr_dw0(r1, mkexpr(result));
11162 return "mdb";
11165 static const HChar *
11166 s390_irgen_SEBR(UChar r1, UChar r2)
11168 IRTemp op1 = newTemp(Ity_F32);
11169 IRTemp op2 = newTemp(Ity_F32);
11170 IRTemp result = newTemp(Ity_F32);
11171 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11173 assign(op1, get_fpr_w0(r1));
11174 assign(op2, get_fpr_w0(r2));
11175 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
11176 mkexpr(op2)));
11177 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11178 put_fpr_w0(r1, mkexpr(result));
11180 return "sebr";
11183 static const HChar *
11184 s390_irgen_SDBR(UChar r1, UChar r2)
11186 IRTemp op1 = newTemp(Ity_F64);
11187 IRTemp op2 = newTemp(Ity_F64);
11188 IRTemp result = newTemp(Ity_F64);
11189 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11191 assign(op1, get_fpr_dw0(r1));
11192 assign(op2, get_fpr_dw0(r2));
11193 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
11194 mkexpr(op2)));
11195 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11196 put_fpr_dw0(r1, mkexpr(result));
11198 return "sdbr";
11201 static const HChar *
11202 s390_irgen_SEB(UChar r1, IRTemp op2addr)
11204 IRTemp op1 = newTemp(Ity_F32);
11205 IRTemp op2 = newTemp(Ity_F32);
11206 IRTemp result = newTemp(Ity_F32);
11207 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11209 assign(op1, get_fpr_w0(r1));
11210 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11211 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
11212 mkexpr(op2)));
11213 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11214 put_fpr_w0(r1, mkexpr(result));
11216 return "seb";
11219 static const HChar *
11220 s390_irgen_SDB(UChar r1, IRTemp op2addr)
11222 IRTemp op1 = newTemp(Ity_F64);
11223 IRTemp op2 = newTemp(Ity_F64);
11224 IRTemp result = newTemp(Ity_F64);
11225 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11227 assign(op1, get_fpr_dw0(r1));
11228 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11229 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
11230 mkexpr(op2)));
11231 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11232 put_fpr_dw0(r1, mkexpr(result));
11234 return "sdb";
11237 static const HChar *
11238 s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11240 if (! s390_host_has_dfp) {
11241 emulation_failure(EmFail_S390X_DFP_insn);
11242 } else {
11243 IRTemp op1 = newTemp(Ity_D64);
11244 IRTemp op2 = newTemp(Ity_D64);
11245 IRTemp result = newTemp(Ity_D64);
11246 IRTemp rounding_mode;
11248 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11249 emulation_warning(EmWarn_S390X_fpext_rounding);
11250 m4 = S390_DFP_ROUND_PER_FPC_0;
11253 rounding_mode = encode_dfp_rounding_mode(m4);
11254 assign(op1, get_dpr_dw0(r2));
11255 assign(op2, get_dpr_dw0(r3));
11256 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
11257 mkexpr(op2)));
11258 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
11259 put_dpr_dw0(r1, mkexpr(result));
11261 return (m4 == 0) ? "adtr" : "adtra";
11264 static const HChar *
11265 s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11267 if (! s390_host_has_dfp) {
11268 emulation_failure(EmFail_S390X_DFP_insn);
11269 } else {
11270 IRTemp op1 = newTemp(Ity_D128);
11271 IRTemp op2 = newTemp(Ity_D128);
11272 IRTemp result = newTemp(Ity_D128);
11273 IRTemp rounding_mode;
11275 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11276 emulation_warning(EmWarn_S390X_fpext_rounding);
11277 m4 = S390_DFP_ROUND_PER_FPC_0;
11280 rounding_mode = encode_dfp_rounding_mode(m4);
11281 assign(op1, get_dpr_pair(r2));
11282 assign(op2, get_dpr_pair(r3));
11283 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
11284 mkexpr(op2)));
11285 put_dpr_pair(r1, mkexpr(result));
11287 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
11289 return (m4 == 0) ? "axtr" : "axtra";
11292 static const HChar *
11293 s390_irgen_CDTR(UChar r1, UChar r2)
11295 IRTemp op1 = newTemp(Ity_D64);
11296 IRTemp op2 = newTemp(Ity_D64);
11297 IRTemp cc_vex = newTemp(Ity_I32);
11298 IRTemp cc_s390 = newTemp(Ity_I32);
11300 assign(op1, get_dpr_dw0(r1));
11301 assign(op2, get_dpr_dw0(r2));
11302 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
11304 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11305 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11307 return "cdtr";
11310 static const HChar *
11311 s390_irgen_CXTR(UChar r1, UChar r2)
11313 IRTemp op1 = newTemp(Ity_D128);
11314 IRTemp op2 = newTemp(Ity_D128);
11315 IRTemp cc_vex = newTemp(Ity_I32);
11316 IRTemp cc_s390 = newTemp(Ity_I32);
11318 assign(op1, get_dpr_pair(r1));
11319 assign(op2, get_dpr_pair(r2));
11320 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
11322 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11323 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11325 return "cxtr";
11328 static const HChar *
11329 s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
11330 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11332 if (! s390_host_has_dfp) {
11333 emulation_failure(EmFail_S390X_DFP_insn);
11334 } else {
11335 if (! s390_host_has_fpext) {
11336 emulation_failure(EmFail_S390X_fpext);
11337 } else {
11338 IRTemp op2 = newTemp(Ity_I32);
11340 assign(op2, get_gpr_w1(r2));
11341 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
11344 return "cdftr";
11347 static const HChar *
11348 s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
11349 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11351 if (! s390_host_has_dfp) {
11352 emulation_failure(EmFail_S390X_DFP_insn);
11353 } else {
11354 if (! s390_host_has_fpext) {
11355 emulation_failure(EmFail_S390X_fpext);
11356 } else {
11357 IRTemp op2 = newTemp(Ity_I32);
11359 assign(op2, get_gpr_w1(r2));
11360 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
11363 return "cxftr";
11366 static const HChar *
11367 s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
11368 UChar r1, UChar r2)
11370 if (! s390_host_has_dfp) {
11371 emulation_failure(EmFail_S390X_DFP_insn);
11372 } else {
11373 IRTemp op2 = newTemp(Ity_I64);
11375 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
11376 emulation_warning(EmWarn_S390X_fpext_rounding);
11377 m3 = S390_DFP_ROUND_PER_FPC_0;
11380 assign(op2, get_gpr_dw0(r2));
11381 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
11382 mkexpr(op2)));
11384 return (m3 == 0) ? "cdgtr" : "cdgtra";
11387 static const HChar *
11388 s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
11389 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11391 if (! s390_host_has_dfp) {
11392 emulation_failure(EmFail_S390X_DFP_insn);
11393 } else {
11394 IRTemp op2 = newTemp(Ity_I64);
11396 /* No emulation warning here about an non-zero m3 on hosts without
11397 floating point extension facility. No rounding is performed */
11399 assign(op2, get_gpr_dw0(r2));
11400 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
11402 return "cxgtr";
11405 static const HChar *
11406 s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
11407 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11409 if (! s390_host_has_dfp) {
11410 emulation_failure(EmFail_S390X_DFP_insn);
11411 } else {
11412 if (! s390_host_has_fpext) {
11413 emulation_failure(EmFail_S390X_fpext);
11414 } else {
11415 IRTemp op2 = newTemp(Ity_I32);
11417 assign(op2, get_gpr_w1(r2));
11418 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
11421 return "cdlftr";
11424 static const HChar *
11425 s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
11426 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11428 if (! s390_host_has_dfp) {
11429 emulation_failure(EmFail_S390X_DFP_insn);
11430 } else {
11431 if (! s390_host_has_fpext) {
11432 emulation_failure(EmFail_S390X_fpext);
11433 } else {
11434 IRTemp op2 = newTemp(Ity_I32);
11436 assign(op2, get_gpr_w1(r2));
11437 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
11440 return "cxlftr";
11443 static const HChar *
11444 s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
11445 UChar r1, UChar r2)
11447 if (! s390_host_has_dfp) {
11448 emulation_failure(EmFail_S390X_DFP_insn);
11449 } else {
11450 if (! s390_host_has_fpext) {
11451 emulation_failure(EmFail_S390X_fpext);
11452 } else {
11453 IRTemp op2 = newTemp(Ity_I64);
11455 assign(op2, get_gpr_dw0(r2));
11456 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
11457 mkexpr(encode_dfp_rounding_mode(m3)),
11458 mkexpr(op2)));
11461 return "cdlgtr";
11464 static const HChar *
11465 s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
11466 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11468 if (! s390_host_has_dfp) {
11469 emulation_failure(EmFail_S390X_DFP_insn);
11470 } else {
11471 if (! s390_host_has_fpext) {
11472 emulation_failure(EmFail_S390X_fpext);
11473 } else {
11474 IRTemp op2 = newTemp(Ity_I64);
11476 assign(op2, get_gpr_dw0(r2));
11477 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
11480 return "cxlgtr";
11483 static const HChar *
11484 s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
11485 UChar r1, UChar r2)
11487 if (! s390_host_has_dfp) {
11488 emulation_failure(EmFail_S390X_DFP_insn);
11489 } else {
11490 if (! s390_host_has_fpext) {
11491 emulation_failure(EmFail_S390X_fpext);
11492 } else {
11493 IRTemp op = newTemp(Ity_D64);
11494 IRTemp result = newTemp(Ity_I32);
11495 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11497 assign(op, get_dpr_dw0(r2));
11498 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
11499 mkexpr(op)));
11500 put_gpr_w1(r1, mkexpr(result));
11501 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
11504 return "cfdtr";
11507 static const HChar *
11508 s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
11509 UChar r1, UChar r2)
11511 if (! s390_host_has_dfp) {
11512 emulation_failure(EmFail_S390X_DFP_insn);
11513 } else {
11514 if (! s390_host_has_fpext) {
11515 emulation_failure(EmFail_S390X_fpext);
11516 } else {
11517 IRTemp op = newTemp(Ity_D128);
11518 IRTemp result = newTemp(Ity_I32);
11519 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11521 assign(op, get_dpr_pair(r2));
11522 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
11523 mkexpr(op)));
11524 put_gpr_w1(r1, mkexpr(result));
11525 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
11526 rounding_mode);
11529 return "cfxtr";
11532 static const HChar *
11533 s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
11534 UChar r1, UChar r2)
11536 if (! s390_host_has_dfp) {
11537 emulation_failure(EmFail_S390X_DFP_insn);
11538 } else {
11539 IRTemp op = newTemp(Ity_D64);
11540 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11542 /* If fpext is not installed and m3 is in 1:7,
11543 rounding mode performed is unpredictable */
11544 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
11545 emulation_warning(EmWarn_S390X_fpext_rounding);
11546 m3 = S390_DFP_ROUND_PER_FPC_0;
11549 assign(op, get_dpr_dw0(r2));
11550 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
11551 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
11553 return "cgdtr";
11556 static const HChar *
11557 s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
11558 UChar r1, UChar r2)
11560 if (! s390_host_has_dfp) {
11561 emulation_failure(EmFail_S390X_DFP_insn);
11562 } else {
11563 IRTemp op = newTemp(Ity_D128);
11564 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11566 /* If fpext is not installed and m3 is in 1:7,
11567 rounding mode performed is unpredictable */
11568 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
11569 emulation_warning(EmWarn_S390X_fpext_rounding);
11570 m3 = S390_DFP_ROUND_PER_FPC_0;
11572 assign(op, get_dpr_pair(r2));
11573 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
11574 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
11576 return "cgxtr";
11579 static const HChar *
11580 s390_irgen_CEDTR(UChar r1, UChar r2)
11582 if (! s390_host_has_dfp) {
11583 emulation_failure(EmFail_S390X_DFP_insn);
11584 } else {
11585 IRTemp op1 = newTemp(Ity_D64);
11586 IRTemp op2 = newTemp(Ity_D64);
11587 IRTemp cc_vex = newTemp(Ity_I32);
11588 IRTemp cc_s390 = newTemp(Ity_I32);
11590 assign(op1, get_dpr_dw0(r1));
11591 assign(op2, get_dpr_dw0(r2));
11592 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
11594 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11595 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11597 return "cedtr";
11600 static const HChar *
11601 s390_irgen_CEXTR(UChar r1, UChar r2)
11603 if (! s390_host_has_dfp) {
11604 emulation_failure(EmFail_S390X_DFP_insn);
11605 } else {
11606 IRTemp op1 = newTemp(Ity_D128);
11607 IRTemp op2 = newTemp(Ity_D128);
11608 IRTemp cc_vex = newTemp(Ity_I32);
11609 IRTemp cc_s390 = newTemp(Ity_I32);
11611 assign(op1, get_dpr_pair(r1));
11612 assign(op2, get_dpr_pair(r2));
11613 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
11615 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11616 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11618 return "cextr";
11621 static const HChar *
11622 s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
11623 UChar r1, UChar r2)
11625 if (! s390_host_has_dfp) {
11626 emulation_failure(EmFail_S390X_DFP_insn);
11627 } else {
11628 if (! s390_host_has_fpext) {
11629 emulation_failure(EmFail_S390X_fpext);
11630 } else {
11631 IRTemp op = newTemp(Ity_D64);
11632 IRTemp result = newTemp(Ity_I32);
11633 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11635 assign(op, get_dpr_dw0(r2));
11636 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
11637 mkexpr(op)));
11638 put_gpr_w1(r1, mkexpr(result));
11639 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
11642 return "clfdtr";
11645 static const HChar *
11646 s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
11647 UChar r1, UChar r2)
11649 if (! s390_host_has_dfp) {
11650 emulation_failure(EmFail_S390X_DFP_insn);
11651 } else {
11652 if (! s390_host_has_fpext) {
11653 emulation_failure(EmFail_S390X_fpext);
11654 } else {
11655 IRTemp op = newTemp(Ity_D128);
11656 IRTemp result = newTemp(Ity_I32);
11657 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11659 assign(op, get_dpr_pair(r2));
11660 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
11661 mkexpr(op)));
11662 put_gpr_w1(r1, mkexpr(result));
11663 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
11664 rounding_mode);
11667 return "clfxtr";
11670 static const HChar *
11671 s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
11672 UChar r1, UChar r2)
11674 if (! s390_host_has_dfp) {
11675 emulation_failure(EmFail_S390X_DFP_insn);
11676 } else {
11677 if (! s390_host_has_fpext) {
11678 emulation_failure(EmFail_S390X_fpext);
11679 } else {
11680 IRTemp op = newTemp(Ity_D64);
11681 IRTemp result = newTemp(Ity_I64);
11682 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11684 assign(op, get_dpr_dw0(r2));
11685 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
11686 mkexpr(op)));
11687 put_gpr_dw0(r1, mkexpr(result));
11688 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
11691 return "clgdtr";
11694 static const HChar *
11695 s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
11696 UChar r1, UChar r2)
11698 if (! s390_host_has_dfp) {
11699 emulation_failure(EmFail_S390X_DFP_insn);
11700 } else {
11701 if (! s390_host_has_fpext) {
11702 emulation_failure(EmFail_S390X_fpext);
11703 } else {
11704 IRTemp op = newTemp(Ity_D128);
11705 IRTemp result = newTemp(Ity_I64);
11706 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11708 assign(op, get_dpr_pair(r2));
11709 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
11710 mkexpr(op)));
11711 put_gpr_dw0(r1, mkexpr(result));
11712 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
11713 rounding_mode);
11716 return "clgxtr";
11719 static const HChar *
11720 s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11722 if (! s390_host_has_dfp) {
11723 emulation_failure(EmFail_S390X_DFP_insn);
11724 } else {
11725 IRTemp op1 = newTemp(Ity_D64);
11726 IRTemp op2 = newTemp(Ity_D64);
11727 IRTemp result = newTemp(Ity_D64);
11728 IRTemp rounding_mode;
11730 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11731 emulation_warning(EmWarn_S390X_fpext_rounding);
11732 m4 = S390_DFP_ROUND_PER_FPC_0;
11735 rounding_mode = encode_dfp_rounding_mode(m4);
11736 assign(op1, get_dpr_dw0(r2));
11737 assign(op2, get_dpr_dw0(r3));
11738 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
11739 mkexpr(op2)));
11740 put_dpr_dw0(r1, mkexpr(result));
11742 return (m4 == 0) ? "ddtr" : "ddtra";
11745 static const HChar *
11746 s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11748 if (! s390_host_has_dfp) {
11749 emulation_failure(EmFail_S390X_DFP_insn);
11750 } else {
11751 IRTemp op1 = newTemp(Ity_D128);
11752 IRTemp op2 = newTemp(Ity_D128);
11753 IRTemp result = newTemp(Ity_D128);
11754 IRTemp rounding_mode;
11756 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11757 emulation_warning(EmWarn_S390X_fpext_rounding);
11758 m4 = S390_DFP_ROUND_PER_FPC_0;
11761 rounding_mode = encode_dfp_rounding_mode(m4);
11762 assign(op1, get_dpr_pair(r2));
11763 assign(op2, get_dpr_pair(r3));
11764 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
11765 mkexpr(op2)));
11766 put_dpr_pair(r1, mkexpr(result));
11768 return (m4 == 0) ? "dxtr" : "dxtra";
11771 static const HChar *
11772 s390_irgen_EEDTR(UChar r1, UChar r2)
11774 if (! s390_host_has_dfp) {
11775 emulation_failure(EmFail_S390X_DFP_insn);
11776 } else {
11777 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
11779 return "eedtr";
11782 static const HChar *
11783 s390_irgen_EEXTR(UChar r1, UChar r2)
11785 if (! s390_host_has_dfp) {
11786 emulation_failure(EmFail_S390X_DFP_insn);
11787 } else {
11788 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
11790 return "eextr";
11793 static const HChar *
11794 s390_irgen_ESDTR(UChar r1, UChar r2)
11796 if (! s390_host_has_dfp) {
11797 emulation_failure(EmFail_S390X_DFP_insn);
11798 } else {
11799 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
11801 return "esdtr";
11804 static const HChar *
11805 s390_irgen_ESXTR(UChar r1, UChar r2)
11807 if (! s390_host_has_dfp) {
11808 emulation_failure(EmFail_S390X_DFP_insn);
11809 } else {
11810 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
11812 return "esxtr";
11815 static const HChar *
11816 s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
11818 if (! s390_host_has_dfp) {
11819 emulation_failure(EmFail_S390X_DFP_insn);
11820 } else {
11821 IRTemp op1 = newTemp(Ity_I64);
11822 IRTemp op2 = newTemp(Ity_D64);
11823 IRTemp result = newTemp(Ity_D64);
11825 assign(op1, get_gpr_dw0(r2));
11826 assign(op2, get_dpr_dw0(r3));
11827 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
11828 put_dpr_dw0(r1, mkexpr(result));
11830 return "iedtr";
11833 static const HChar *
11834 s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
11836 if (! s390_host_has_dfp) {
11837 emulation_failure(EmFail_S390X_DFP_insn);
11838 } else {
11839 IRTemp op1 = newTemp(Ity_I64);
11840 IRTemp op2 = newTemp(Ity_D128);
11841 IRTemp result = newTemp(Ity_D128);
11843 assign(op1, get_gpr_dw0(r2));
11844 assign(op2, get_dpr_pair(r3));
11845 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
11846 put_dpr_pair(r1, mkexpr(result));
11848 return "iextr";
11851 static const HChar *
11852 s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11854 if (! s390_host_has_dfp) {
11855 emulation_failure(EmFail_S390X_DFP_insn);
11856 } else {
11857 IRTemp op = newTemp(Ity_D32);
11859 assign(op, get_dpr_w0(r2));
11860 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
11862 return "ldetr";
11865 static const HChar *
11866 s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11868 IRTemp op = newTemp(Ity_D64);
11870 assign(op, get_dpr_dw0(r2));
11871 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
11873 return "lxdtr";
11876 static const HChar *
11877 s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
11878 UChar r1, UChar r2)
11880 if (! s390_host_has_dfp) {
11881 emulation_failure(EmFail_S390X_DFP_insn);
11882 } else {
11883 /* If fpext is not installed and m3 is in 1:7,
11884 rounding mode performed is unpredictable */
11885 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
11886 emulation_warning(EmWarn_S390X_fpext_rounding);
11887 m3 = S390_DFP_ROUND_PER_FPC_0;
11889 IRTemp result = newTemp(Ity_D64);
11891 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
11892 get_dpr_pair(r2)));
11893 put_dpr_dw0(r1, mkexpr(result));
11895 return "ldxtr";
11898 static const HChar *
11899 s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
11900 UChar r1, UChar r2)
11902 if (! s390_host_has_dfp) {
11903 emulation_failure(EmFail_S390X_DFP_insn);
11904 } else {
11905 /* If fpext is not installed and m3 is in 1:7,
11906 rounding mode performed is unpredictable */
11907 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
11908 emulation_warning(EmWarn_S390X_fpext_rounding);
11909 m3 = S390_DFP_ROUND_PER_FPC_0;
11911 IRTemp op = newTemp(Ity_D64);
11913 assign(op, get_dpr_dw0(r2));
11914 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
11915 mkexpr(op)));
11917 return "ledtr";
11920 static const HChar *
11921 s390_irgen_LTDTR(UChar r1, UChar r2)
11923 IRTemp result = newTemp(Ity_D64);
11925 assign(result, get_dpr_dw0(r2));
11926 put_dpr_dw0(r1, mkexpr(result));
11927 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
11929 return "ltdtr";
11932 static const HChar *
11933 s390_irgen_LTXTR(UChar r1, UChar r2)
11935 IRTemp result = newTemp(Ity_D128);
11937 assign(result, get_dpr_pair(r2));
11938 put_dpr_pair(r1, mkexpr(result));
11939 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
11941 return "ltxtr";
11944 static const HChar *
11945 s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11947 if (! s390_host_has_dfp) {
11948 emulation_failure(EmFail_S390X_DFP_insn);
11949 } else {
11950 IRTemp op1 = newTemp(Ity_D64);
11951 IRTemp op2 = newTemp(Ity_D64);
11952 IRTemp result = newTemp(Ity_D64);
11953 IRTemp rounding_mode;
11955 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11956 emulation_warning(EmWarn_S390X_fpext_rounding);
11957 m4 = S390_DFP_ROUND_PER_FPC_0;
11960 rounding_mode = encode_dfp_rounding_mode(m4);
11961 assign(op1, get_dpr_dw0(r2));
11962 assign(op2, get_dpr_dw0(r3));
11963 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
11964 mkexpr(op2)));
11965 put_dpr_dw0(r1, mkexpr(result));
11967 return (m4 == 0) ? "mdtr" : "mdtra";
11970 static const HChar *
11971 s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11973 if (! s390_host_has_dfp) {
11974 emulation_failure(EmFail_S390X_DFP_insn);
11975 } else {
11976 IRTemp op1 = newTemp(Ity_D128);
11977 IRTemp op2 = newTemp(Ity_D128);
11978 IRTemp result = newTemp(Ity_D128);
11979 IRTemp rounding_mode;
11981 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11982 emulation_warning(EmWarn_S390X_fpext_rounding);
11983 m4 = S390_DFP_ROUND_PER_FPC_0;
11986 rounding_mode = encode_dfp_rounding_mode(m4);
11987 assign(op1, get_dpr_pair(r2));
11988 assign(op2, get_dpr_pair(r3));
11989 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
11990 mkexpr(op2)));
11991 put_dpr_pair(r1, mkexpr(result));
11993 return (m4 == 0) ? "mxtr" : "mxtra";
11996 static const HChar *
11997 s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
11999 if (! s390_host_has_dfp) {
12000 emulation_failure(EmFail_S390X_DFP_insn);
12001 } else {
12002 IRTemp op1 = newTemp(Ity_D64);
12003 IRTemp op2 = newTemp(Ity_D64);
12004 IRTemp result = newTemp(Ity_D64);
12005 IRTemp rounding_mode;
12007 /* If fpext is not installed and m4 is in 1:7,
12008 rounding mode performed is unpredictable */
12009 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12010 emulation_warning(EmWarn_S390X_fpext_rounding);
12011 m4 = S390_DFP_ROUND_PER_FPC_0;
12014 rounding_mode = encode_dfp_rounding_mode(m4);
12015 assign(op1, get_dpr_dw0(r2));
12016 assign(op2, get_dpr_dw0(r3));
12017 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
12018 mkexpr(op2)));
12019 put_dpr_dw0(r1, mkexpr(result));
12021 return "qadtr";
12024 static const HChar *
12025 s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
12027 if (! s390_host_has_dfp) {
12028 emulation_failure(EmFail_S390X_DFP_insn);
12029 } else {
12030 IRTemp op1 = newTemp(Ity_D128);
12031 IRTemp op2 = newTemp(Ity_D128);
12032 IRTemp result = newTemp(Ity_D128);
12033 IRTemp rounding_mode;
12035 /* If fpext is not installed and m4 is in 1:7,
12036 rounding mode performed is unpredictable */
12037 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12038 emulation_warning(EmWarn_S390X_fpext_rounding);
12039 m4 = S390_DFP_ROUND_PER_FPC_0;
12042 rounding_mode = encode_dfp_rounding_mode(m4);
12043 assign(op1, get_dpr_pair(r2));
12044 assign(op2, get_dpr_pair(r3));
12045 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
12046 mkexpr(op2)));
12047 put_dpr_pair(r1, mkexpr(result));
12049 return "qaxtr";
12052 static const HChar *
12053 s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
12055 if (! s390_host_has_dfp) {
12056 emulation_failure(EmFail_S390X_DFP_insn);
12057 } else {
12058 IRTemp op1 = newTemp(Ity_I8);
12059 IRTemp op2 = newTemp(Ity_D64);
12060 IRTemp result = newTemp(Ity_D64);
12061 IRTemp rounding_mode;
12063 /* If fpext is not installed and m4 is in 1:7,
12064 rounding mode performed is unpredictable */
12065 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12066 emulation_warning(EmWarn_S390X_fpext_rounding);
12067 m4 = S390_DFP_ROUND_PER_FPC_0;
12070 rounding_mode = encode_dfp_rounding_mode(m4);
12071 assign(op1, get_gpr_b7(r2));
12072 assign(op2, get_dpr_dw0(r3));
12073 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
12074 mkexpr(op1), mkexpr(op2)));
12075 put_dpr_dw0(r1, mkexpr(result));
12077 return "rrdtr";
12080 static const HChar *
12081 s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
12083 if (! s390_host_has_dfp) {
12084 emulation_failure(EmFail_S390X_DFP_insn);
12085 } else {
12086 IRTemp op1 = newTemp(Ity_I8);
12087 IRTemp op2 = newTemp(Ity_D128);
12088 IRTemp result = newTemp(Ity_D128);
12089 IRTemp rounding_mode;
12091 /* If fpext is not installed and m4 is in 1:7,
12092 rounding mode performed is unpredictable */
12093 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12094 emulation_warning(EmWarn_S390X_fpext_rounding);
12095 m4 = S390_DFP_ROUND_PER_FPC_0;
12098 rounding_mode = encode_dfp_rounding_mode(m4);
12099 assign(op1, get_gpr_b7(r2));
12100 assign(op2, get_dpr_pair(r3));
12101 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
12102 mkexpr(op1), mkexpr(op2)));
12103 put_dpr_pair(r1, mkexpr(result));
12105 return "rrxtr";
12108 static const HChar *
12109 s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12111 if (! s390_host_has_dfp) {
12112 emulation_failure(EmFail_S390X_DFP_insn);
12113 } else {
12114 IRTemp op1 = newTemp(Ity_D64);
12115 IRTemp op2 = newTemp(Ity_D64);
12116 IRTemp result = newTemp(Ity_D64);
12117 IRTemp rounding_mode;
12119 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12120 emulation_warning(EmWarn_S390X_fpext_rounding);
12121 m4 = S390_DFP_ROUND_PER_FPC_0;
12124 rounding_mode = encode_dfp_rounding_mode(m4);
12125 assign(op1, get_dpr_dw0(r2));
12126 assign(op2, get_dpr_dw0(r3));
12127 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
12128 mkexpr(op2)));
12129 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
12130 put_dpr_dw0(r1, mkexpr(result));
12132 return (m4 == 0) ? "sdtr" : "sdtra";
12135 static const HChar *
12136 s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12138 if (! s390_host_has_dfp) {
12139 emulation_failure(EmFail_S390X_DFP_insn);
12140 } else {
12141 IRTemp op1 = newTemp(Ity_D128);
12142 IRTemp op2 = newTemp(Ity_D128);
12143 IRTemp result = newTemp(Ity_D128);
12144 IRTemp rounding_mode;
12146 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12147 emulation_warning(EmWarn_S390X_fpext_rounding);
12148 m4 = S390_DFP_ROUND_PER_FPC_0;
12151 rounding_mode = encode_dfp_rounding_mode(m4);
12152 assign(op1, get_dpr_pair(r2));
12153 assign(op2, get_dpr_pair(r3));
12154 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
12155 mkexpr(op2)));
12156 put_dpr_pair(r1, mkexpr(result));
12158 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
12160 return (m4 == 0) ? "sxtr" : "sxtra";
12163 static const HChar *
12164 s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
12166 if (! s390_host_has_dfp) {
12167 emulation_failure(EmFail_S390X_DFP_insn);
12168 } else {
12169 IRTemp op = newTemp(Ity_D64);
12171 assign(op, get_dpr_dw0(r3));
12172 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
12173 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12174 mkU64(63)))));
12176 return "sldt";
12179 static const HChar *
12180 s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
12182 if (! s390_host_has_dfp) {
12183 emulation_failure(EmFail_S390X_DFP_insn);
12184 } else {
12185 IRTemp op = newTemp(Ity_D128);
12187 assign(op, get_dpr_pair(r3));
12188 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
12189 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12190 mkU64(63)))));
12192 return "slxt";
12195 static const HChar *
12196 s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
12198 if (! s390_host_has_dfp) {
12199 emulation_failure(EmFail_S390X_DFP_insn);
12200 } else {
12201 IRTemp op = newTemp(Ity_D64);
12203 assign(op, get_dpr_dw0(r3));
12204 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
12205 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12206 mkU64(63)))));
12208 return "srdt";
12211 static const HChar *
12212 s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
12214 if (! s390_host_has_dfp) {
12215 emulation_failure(EmFail_S390X_DFP_insn);
12216 } else {
12217 IRTemp op = newTemp(Ity_D128);
12219 assign(op, get_dpr_pair(r3));
12220 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
12221 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12222 mkU64(63)))));
12224 return "srxt";
12227 static const HChar *
12228 s390_irgen_TDCET(UChar r1, IRTemp op2addr)
12230 if (! s390_host_has_dfp) {
12231 emulation_failure(EmFail_S390X_DFP_insn);
12232 } else {
12233 IRTemp value = newTemp(Ity_D32);
12235 assign(value, get_dpr_w0(r1));
12237 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
12239 return "tdcet";
12242 static const HChar *
12243 s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
12245 if (! s390_host_has_dfp) {
12246 emulation_failure(EmFail_S390X_DFP_insn);
12247 } else {
12248 IRTemp value = newTemp(Ity_D64);
12250 assign(value, get_dpr_dw0(r1));
12252 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
12254 return "tdcdt";
12257 static const HChar *
12258 s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
12260 if (! s390_host_has_dfp) {
12261 emulation_failure(EmFail_S390X_DFP_insn);
12262 } else {
12263 IRTemp value = newTemp(Ity_D128);
12265 assign(value, get_dpr_pair(r1));
12267 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
12269 return "tdcxt";
12272 static const HChar *
12273 s390_irgen_TDGET(UChar r1, IRTemp op2addr)
12275 if (! s390_host_has_dfp) {
12276 emulation_failure(EmFail_S390X_DFP_insn);
12277 } else {
12278 IRTemp value = newTemp(Ity_D32);
12280 assign(value, get_dpr_w0(r1));
12282 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
12284 return "tdget";
12287 static const HChar *
12288 s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
12290 if (! s390_host_has_dfp) {
12291 emulation_failure(EmFail_S390X_DFP_insn);
12292 } else {
12293 IRTemp value = newTemp(Ity_D64);
12295 assign(value, get_dpr_dw0(r1));
12297 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
12299 return "tdgdt";
12302 static const HChar *
12303 s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
12305 if (! s390_host_has_dfp) {
12306 emulation_failure(EmFail_S390X_DFP_insn);
12307 } else {
12308 IRTemp value = newTemp(Ity_D128);
12310 assign(value, get_dpr_pair(r1));
12312 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
12314 return "tdgxt";
12317 static const HChar *
12318 s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
12320 IRTemp len = newTemp(Ity_I64);
12322 assign(len, mkU64(length));
12323 s390_irgen_CLC_EX(len, start1, start2);
12325 return "clc";
12328 static const HChar *
12329 s390_irgen_CLCL(UChar r1, UChar r2)
12331 IRTemp addr1 = newTemp(Ity_I64);
12332 IRTemp addr2 = newTemp(Ity_I64);
12333 IRTemp addr1_load = newTemp(Ity_I64);
12334 IRTemp addr2_load = newTemp(Ity_I64);
12335 IRTemp len1 = newTemp(Ity_I32);
12336 IRTemp len2 = newTemp(Ity_I32);
12337 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
12338 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
12339 IRTemp single1 = newTemp(Ity_I8);
12340 IRTemp single2 = newTemp(Ity_I8);
12341 IRTemp pad = newTemp(Ity_I8);
12343 assign(addr1, get_gpr_dw0(r1));
12344 assign(r1p1, get_gpr_w1(r1 + 1));
12345 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
12346 assign(addr2, get_gpr_dw0(r2));
12347 assign(r2p1, get_gpr_w1(r2 + 1));
12348 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
12349 assign(pad, get_gpr_b4(r2 + 1));
12351 /* len1 == 0 and len2 == 0? Exit */
12352 s390_cc_set_val(0);
12353 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
12354 mkexpr(len2)), mkU32(0)));
12356 /* Because mkite evaluates both the then-clause and the else-clause
12357 we cannot load directly from addr1 here. If len1 is 0, then adddr1
12358 may be NULL and loading from there would segfault. So we provide a
12359 valid dummy address in that case. Loading from there does no harm and
12360 the value will be discarded at runtime. */
12361 assign(addr1_load,
12362 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12363 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
12364 assign(single1,
12365 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12366 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
12368 assign(addr2_load,
12369 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12370 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
12371 assign(single2,
12372 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12373 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
12375 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
12376 /* Fields differ ? */
12377 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
12379 /* Update len1 and addr1, unless len1 == 0. */
12380 put_gpr_dw0(r1,
12381 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12382 mkexpr(addr1),
12383 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
12385 /* When updating len1 we must not modify bits (r1+1)[0:39] */
12386 put_gpr_w1(r1 + 1,
12387 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12388 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
12389 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
12391 /* Update len2 and addr2, unless len2 == 0. */
12392 put_gpr_dw0(r2,
12393 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12394 mkexpr(addr2),
12395 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
12397 /* When updating len2 we must not modify bits (r2+1)[0:39] */
12398 put_gpr_w1(r2 + 1,
12399 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12400 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
12401 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
12403 iterate();
12405 return "clcl";
12408 static const HChar *
12409 s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
12411 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
12413 addr1 = newTemp(Ity_I64);
12414 addr3 = newTemp(Ity_I64);
12415 addr1_load = newTemp(Ity_I64);
12416 addr3_load = newTemp(Ity_I64);
12417 len1 = newTemp(Ity_I64);
12418 len3 = newTemp(Ity_I64);
12419 single1 = newTemp(Ity_I8);
12420 single3 = newTemp(Ity_I8);
12422 assign(addr1, get_gpr_dw0(r1));
12423 assign(len1, get_gpr_dw0(r1 + 1));
12424 assign(addr3, get_gpr_dw0(r3));
12425 assign(len3, get_gpr_dw0(r3 + 1));
12427 /* len1 == 0 and len3 == 0? Exit */
12428 s390_cc_set_val(0);
12429 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
12430 mkexpr(len3)), mkU64(0)));
12432 /* A mux requires both ways to be possible. This is a way to prevent clcle
12433 from reading from addr1 if it should read from the pad. Since the pad
12434 has no address, just read from the instruction, we discard that anyway */
12435 assign(addr1_load,
12436 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
12437 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
12439 /* same for addr3 */
12440 assign(addr3_load,
12441 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
12442 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
12444 assign(single1,
12445 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
12446 unop(Iop_64to8, mkexpr(pad2)),
12447 load(Ity_I8, mkexpr(addr1_load))));
12449 assign(single3,
12450 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
12451 unop(Iop_64to8, mkexpr(pad2)),
12452 load(Ity_I8, mkexpr(addr3_load))));
12454 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
12455 /* Both fields differ ? */
12456 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
12458 /* If a length in 0 we must not change this length and the address */
12459 put_gpr_dw0(r1,
12460 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
12461 mkexpr(addr1),
12462 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
12464 put_gpr_dw0(r1 + 1,
12465 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
12466 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
12468 put_gpr_dw0(r3,
12469 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
12470 mkexpr(addr3),
12471 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
12473 put_gpr_dw0(r3 + 1,
12474 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
12475 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
12477 iterate();
12479 return "clcle";
12483 static void
12484 s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12486 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
12490 static void
12491 s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12493 s390_irgen_xonc(Iop_And8, length, start1, start2);
12497 static void
12498 s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12500 s390_irgen_xonc(Iop_Or8, length, start1, start2);
12504 static void
12505 s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12507 IRTemp current1 = newTemp(Ity_I8);
12508 IRTemp current2 = newTemp(Ity_I8);
12509 IRTemp counter = newTemp(Ity_I64);
12511 assign(counter, get_counter_dw0());
12512 put_counter_dw0(mkU64(0));
12514 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
12515 mkexpr(counter))));
12516 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
12517 mkexpr(counter))));
12518 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
12519 False);
12521 /* Both fields differ ? */
12522 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
12524 /* Check for end of field */
12525 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12526 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
12527 put_counter_dw0(mkU64(0));
12530 static void
12531 s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12533 IRTemp counter = newTemp(Ity_I64);
12535 assign(counter, get_counter_dw0());
12537 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
12538 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
12540 /* Check for end of field */
12541 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12542 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
12543 put_counter_dw0(mkU64(0));
12546 static void
12547 s390_irgen_MVCIN_EX(IRTemp length, IRTemp start1, IRTemp start2)
12549 IRTemp counter = newTemp(Ity_I64);
12551 assign(counter, get_counter_dw0());
12553 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
12554 load(Ity_I8, binop(Iop_Sub64, mkexpr(start2), mkexpr(counter))));
12556 /* Check for end of field */
12557 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12558 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
12559 put_counter_dw0(mkU64(0));
12562 static void
12563 s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
12565 IRTemp op = newTemp(Ity_I8);
12566 IRTemp op1 = newTemp(Ity_I8);
12567 IRTemp result = newTemp(Ity_I64);
12568 IRTemp counter = newTemp(Ity_I64);
12570 assign(counter, get_counter_dw0());
12572 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
12574 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
12576 assign(op1, load(Ity_I8, mkexpr(result)));
12577 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
12579 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12580 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
12581 put_counter_dw0(mkU64(0));
12585 static void
12586 s390_irgen_EX_SS(UChar r, IRTemp addr2,
12587 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
12588 UInt lensize)
12590 struct SS {
12591 unsigned int op : 8;
12592 unsigned int l : 8;
12593 unsigned int b1 : 4;
12594 unsigned int d1 : 12;
12595 unsigned int b2 : 4;
12596 unsigned int d2 : 12;
12598 union {
12599 struct SS dec;
12600 unsigned long bytes;
12601 } ss;
12602 IRTemp cond;
12603 IRDirty *d;
12604 IRTemp torun;
12606 IRTemp start1 = newTemp(Ity_I64);
12607 IRTemp start2 = newTemp(Ity_I64);
12608 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
12609 cond = newTemp(Ity_I1);
12610 torun = newTemp(Ity_I64);
12612 assign(torun, load(Ity_I64, mkexpr(addr2)));
12613 /* Start with a check that the saved code is still correct */
12614 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
12615 /* If not, save the new value */
12616 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
12617 mkIRExprVec_1(mkexpr(torun)));
12618 d->guard = mkexpr(cond);
12619 stmt(IRStmt_Dirty(d));
12621 /* and restart */
12622 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
12623 mkU64(guest_IA_curr_instr)));
12624 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
12625 restart_if(mkexpr(cond));
12627 ss.dec.op = ss.dec.l = ss.dec.b1 = ss.dec.d1 = ss.dec.b2 = ss.dec.d2 = 0;
12628 ss.bytes = last_execute_target;
12629 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
12630 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
12631 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
12632 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
12633 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
12634 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
12635 irgen(len, start1, start2);
12637 last_execute_target = 0;
12640 static const HChar *
12641 s390_irgen_EX(UChar r1, IRTemp addr2)
12643 switch(last_execute_target & 0xff00000000000000ULL) {
12644 case 0:
12646 /* no code information yet */
12647 IRDirty *d;
12649 /* so safe the code... */
12650 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
12651 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
12652 stmt(IRStmt_Dirty(d));
12653 /* and restart */
12654 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
12655 mkU64(guest_IA_curr_instr)));
12656 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
12657 restart_if(IRExpr_Const(IRConst_U1(True)));
12659 /* we know that this will be invalidated */
12660 put_IA(mkaddr_expr(guest_IA_next_instr));
12661 dis_res->whatNext = Dis_StopHere;
12662 dis_res->jk_StopHere = Ijk_InvalICache;
12663 break;
12666 case 0xd200000000000000ULL:
12667 /* special case MVC */
12668 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
12669 return "ex@mvc";
12671 case 0xd500000000000000ULL:
12672 /* special case CLC */
12673 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
12674 return "ex@clc";
12676 case 0xd700000000000000ULL:
12677 /* special case XC */
12678 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
12679 return "ex@xc";
12681 case 0xd600000000000000ULL:
12682 /* special case OC */
12683 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
12684 return "ex@oc";
12686 case 0xd400000000000000ULL:
12687 /* special case NC */
12688 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
12689 return "ex@nc";
12691 case 0xdc00000000000000ULL:
12692 /* special case TR */
12693 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
12694 return "ex@tr";
12696 case 0xe800000000000000ULL:
12697 /* special case MVCIN */
12698 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVCIN_EX, 64);
12699 return "ex@mvcin";
12701 default:
12703 /* everything else will get a self checking prefix that also checks the
12704 register content */
12705 IRDirty *d;
12706 UChar *bytes;
12707 IRTemp cond;
12708 IRTemp orperand;
12709 IRTemp torun;
12711 cond = newTemp(Ity_I1);
12712 orperand = newTemp(Ity_I64);
12713 torun = newTemp(Ity_I64);
12715 if (r1 == 0)
12716 assign(orperand, mkU64(0));
12717 else
12718 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
12719 /* This code is going to be translated */
12720 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
12721 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
12723 /* Start with a check that saved code is still correct */
12724 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
12725 mkU64(last_execute_target)));
12726 /* If not, save the new value */
12727 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
12728 mkIRExprVec_1(mkexpr(torun)));
12729 d->guard = mkexpr(cond);
12730 stmt(IRStmt_Dirty(d));
12732 /* and restart */
12733 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
12734 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
12735 restart_if(mkexpr(cond));
12737 /* Now comes the actual translation */
12738 bytes = (UChar *) &last_execute_target;
12739 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
12740 dis_res);
12741 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
12742 vex_printf(" which was executed by\n");
12743 /* dont make useless translations in the next execute */
12744 last_execute_target = 0;
12747 return "ex";
12750 static const HChar *
12751 s390_irgen_EXRL(UChar r1, UInt offset)
12753 IRTemp addr = newTemp(Ity_I64);
12754 /* we might save one round trip because we know the target */
12755 if (!last_execute_target)
12756 last_execute_target = *(ULong *)(HWord)
12757 (guest_IA_curr_instr + offset * 2UL);
12758 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
12759 s390_irgen_EX(r1, addr);
12760 return "exrl";
12763 static const HChar *
12764 s390_irgen_IPM(UChar r1)
12766 // As long as we dont support SPM, lets just assume 0 as program mask
12767 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
12768 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
12770 return "ipm";
12774 static const HChar *
12775 s390_irgen_SRST(UChar r1, UChar r2)
12777 IRTemp address = newTemp(Ity_I64);
12778 IRTemp next = newTemp(Ity_I64);
12779 IRTemp delim = newTemp(Ity_I8);
12780 IRTemp counter = newTemp(Ity_I64);
12781 IRTemp byte = newTemp(Ity_I8);
12783 assign(address, get_gpr_dw0(r2));
12784 assign(next, get_gpr_dw0(r1));
12786 assign(counter, get_counter_dw0());
12787 put_counter_dw0(mkU64(0));
12789 // start = next? CC=2 and out r1 and r2 unchanged
12790 s390_cc_set_val(2);
12791 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
12792 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
12794 assign(byte, load(Ity_I8, mkexpr(address)));
12795 assign(delim, get_gpr_b7(0));
12797 // byte = delim? CC=1, R1=address
12798 s390_cc_set_val(1);
12799 put_gpr_dw0(r1, mkexpr(address));
12800 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
12802 // else: all equal, no end yet, loop
12803 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12804 put_gpr_dw0(r1, mkexpr(next));
12805 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
12807 iterate();
12809 return "srst";
12812 static const HChar *
12813 s390_irgen_CLST(UChar r1, UChar r2)
12815 IRTemp address1 = newTemp(Ity_I64);
12816 IRTemp address2 = newTemp(Ity_I64);
12817 IRTemp end = newTemp(Ity_I8);
12818 IRTemp counter = newTemp(Ity_I64);
12819 IRTemp byte1 = newTemp(Ity_I8);
12820 IRTemp byte2 = newTemp(Ity_I8);
12822 assign(address1, get_gpr_dw0(r1));
12823 assign(address2, get_gpr_dw0(r2));
12824 assign(end, get_gpr_b7(0));
12825 assign(counter, get_counter_dw0());
12826 put_counter_dw0(mkU64(0));
12827 assign(byte1, load(Ity_I8, mkexpr(address1)));
12828 assign(byte2, load(Ity_I8, mkexpr(address2)));
12830 // end in both? all equal, reset r1 and r2 to start values
12831 s390_cc_set_val(0);
12832 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
12833 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
12834 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
12835 binop(Iop_Or8,
12836 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
12837 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
12839 put_gpr_dw0(r1, mkexpr(address1));
12840 put_gpr_dw0(r2, mkexpr(address2));
12842 // End found in string1
12843 s390_cc_set_val(1);
12844 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
12846 // End found in string2
12847 s390_cc_set_val(2);
12848 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
12850 // string1 < string2
12851 s390_cc_set_val(1);
12852 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
12853 unop(Iop_8Uto32, mkexpr(byte2))));
12855 // string2 < string1
12856 s390_cc_set_val(2);
12857 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
12858 unop(Iop_8Uto32, mkexpr(byte1))));
12860 // else: all equal, no end yet, loop
12861 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12862 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
12863 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
12865 iterate();
12867 return "clst";
12870 static void
12871 s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
12873 UChar reg;
12874 IRTemp addr = newTemp(Ity_I64);
12876 assign(addr, mkexpr(op2addr));
12877 reg = r1;
12878 do {
12879 IRTemp old = addr;
12881 reg %= 16;
12882 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
12883 addr = newTemp(Ity_I64);
12884 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
12885 reg++;
12886 } while (reg != (r3 + 1));
12889 static const HChar *
12890 s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
12892 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
12894 return "lm";
12897 static const HChar *
12898 s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
12900 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
12902 return "lmy";
12905 static const HChar *
12906 s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
12908 UChar reg;
12909 IRTemp addr = newTemp(Ity_I64);
12911 assign(addr, mkexpr(op2addr));
12912 reg = r1;
12913 do {
12914 IRTemp old = addr;
12916 reg %= 16;
12917 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
12918 addr = newTemp(Ity_I64);
12919 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
12920 reg++;
12921 } while (reg != (r3 + 1));
12923 return "lmh";
12926 static const HChar *
12927 s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
12929 UChar reg;
12930 IRTemp addr = newTemp(Ity_I64);
12932 assign(addr, mkexpr(op2addr));
12933 reg = r1;
12934 do {
12935 IRTemp old = addr;
12937 reg %= 16;
12938 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
12939 addr = newTemp(Ity_I64);
12940 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
12941 reg++;
12942 } while (reg != (r3 + 1));
12944 return "lmg";
12947 static void
12948 s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
12950 UChar reg;
12951 IRTemp addr = newTemp(Ity_I64);
12953 assign(addr, mkexpr(op2addr));
12954 reg = r1;
12955 do {
12956 IRTemp old = addr;
12958 reg %= 16;
12959 store(mkexpr(addr), get_gpr_w1(reg));
12960 addr = newTemp(Ity_I64);
12961 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
12962 reg++;
12963 } while( reg != (r3 + 1));
12966 static const HChar *
12967 s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
12969 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
12971 return "stm";
12974 static const HChar *
12975 s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
12977 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
12979 return "stmy";
12982 static const HChar *
12983 s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
12985 UChar reg;
12986 IRTemp addr = newTemp(Ity_I64);
12988 assign(addr, mkexpr(op2addr));
12989 reg = r1;
12990 do {
12991 IRTemp old = addr;
12993 reg %= 16;
12994 store(mkexpr(addr), get_gpr_w0(reg));
12995 addr = newTemp(Ity_I64);
12996 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
12997 reg++;
12998 } while( reg != (r3 + 1));
13000 return "stmh";
13003 static const HChar *
13004 s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
13006 UChar reg;
13007 IRTemp addr = newTemp(Ity_I64);
13009 assign(addr, mkexpr(op2addr));
13010 reg = r1;
13011 do {
13012 IRTemp old = addr;
13014 reg %= 16;
13015 store(mkexpr(addr), get_gpr_dw0(reg));
13016 addr = newTemp(Ity_I64);
13017 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
13018 reg++;
13019 } while( reg != (r3 + 1));
13021 return "stmg";
13024 static void
13025 s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
13027 IRTemp old1 = newTemp(Ity_I8);
13028 IRTemp old2 = newTemp(Ity_I8);
13029 IRTemp new1 = newTemp(Ity_I8);
13030 IRTemp counter = newTemp(Ity_I32);
13031 IRTemp addr1 = newTemp(Ity_I64);
13033 assign(counter, get_counter_w0());
13035 assign(addr1, binop(Iop_Add64, mkexpr(start1),
13036 unop(Iop_32Uto64, mkexpr(counter))));
13038 assign(old1, load(Ity_I8, mkexpr(addr1)));
13039 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
13040 unop(Iop_32Uto64,mkexpr(counter)))));
13041 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
13043 /* Special case: xc is used to zero memory */
13044 if (op == Iop_Xor8) {
13045 store(mkexpr(addr1),
13046 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
13047 mkU8(0), mkexpr(new1)));
13048 } else
13049 store(mkexpr(addr1), mkexpr(new1));
13050 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
13051 get_counter_w1()));
13053 /* Check for end of field */
13054 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
13055 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
13056 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
13057 False);
13058 put_counter_dw0(mkU64(0));
13061 static const HChar *
13062 s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
13064 IRTemp len = newTemp(Ity_I32);
13066 assign(len, mkU32(length));
13067 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
13069 return "xc";
13072 static void
13073 s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
13075 IRTemp counter = newTemp(Ity_I32);
13076 IRTemp start = newTemp(Ity_I64);
13077 IRTemp addr = newTemp(Ity_I64);
13079 assign(start,
13080 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
13082 if (length < 8) {
13083 UInt i;
13085 for (i = 0; i <= length; ++i) {
13086 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
13088 } else {
13089 assign(counter, get_counter_w0());
13091 assign(addr, binop(Iop_Add64, mkexpr(start),
13092 unop(Iop_32Uto64, mkexpr(counter))));
13094 store(mkexpr(addr), mkU8(0));
13096 /* Check for end of field */
13097 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
13098 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
13100 /* Reset counter */
13101 put_counter_dw0(mkU64(0));
13104 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
13106 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
13107 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
13110 static const HChar *
13111 s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
13113 IRTemp len = newTemp(Ity_I32);
13115 assign(len, mkU32(length));
13116 s390_irgen_xonc(Iop_And8, len, start1, start2);
13118 return "nc";
13121 static const HChar *
13122 s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
13124 IRTemp len = newTemp(Ity_I32);
13126 assign(len, mkU32(length));
13127 s390_irgen_xonc(Iop_Or8, len, start1, start2);
13129 return "oc";
13133 static const HChar *
13134 s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
13136 IRTemp len = newTemp(Ity_I64);
13138 assign(len, mkU64(length));
13139 s390_irgen_MVC_EX(len, start1, start2);
13141 return "mvc";
13144 static const HChar *
13145 s390_irgen_MVCIN(UChar length, IRTemp start1, IRTemp start2)
13147 IRTemp len = newTemp(Ity_I64);
13149 assign(len, mkU64(length));
13150 s390_irgen_MVCIN_EX(len, start1, start2);
13152 return "mvcin";
13155 static const HChar *
13156 s390_irgen_MVCL(UChar r1, UChar r2)
13158 IRTemp addr1 = newTemp(Ity_I64);
13159 IRTemp addr2 = newTemp(Ity_I64);
13160 IRTemp addr2_load = newTemp(Ity_I64);
13161 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
13162 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
13163 IRTemp len1 = newTemp(Ity_I32);
13164 IRTemp len2 = newTemp(Ity_I32);
13165 IRTemp pad = newTemp(Ity_I8);
13166 IRTemp single = newTemp(Ity_I8);
13168 assign(addr1, get_gpr_dw0(r1));
13169 assign(r1p1, get_gpr_w1(r1 + 1));
13170 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
13171 assign(addr2, get_gpr_dw0(r2));
13172 assign(r2p1, get_gpr_w1(r2 + 1));
13173 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
13174 assign(pad, get_gpr_b4(r2 + 1));
13176 /* len1 == 0 ? */
13177 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
13178 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
13180 /* Check for destructive overlap:
13181 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
13182 s390_cc_set_val(3);
13183 IRTemp cond1 = newTemp(Ity_I32);
13184 assign(cond1, unop(Iop_1Uto32,
13185 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
13186 IRTemp cond2 = newTemp(Ity_I32);
13187 assign(cond2, unop(Iop_1Uto32,
13188 binop(Iop_CmpLT64U, mkexpr(addr1),
13189 binop(Iop_Add64, mkexpr(addr2),
13190 unop(Iop_32Uto64, mkexpr(len1))))));
13191 IRTemp cond3 = newTemp(Ity_I32);
13192 assign(cond3, unop(Iop_1Uto32,
13193 binop(Iop_CmpLT64U,
13194 mkexpr(addr1),
13195 binop(Iop_Add64, mkexpr(addr2),
13196 unop(Iop_32Uto64, mkexpr(len2))))));
13198 next_insn_if(binop(Iop_CmpEQ32,
13199 binop(Iop_And32,
13200 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
13201 mkexpr(cond3)),
13202 mkU32(1)));
13204 /* See s390_irgen_CLCL for explanation why we cannot load directly
13205 and need two steps. */
13206 assign(addr2_load,
13207 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13208 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
13209 assign(single,
13210 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13211 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
13213 store(mkexpr(addr1), mkexpr(single));
13215 /* Update addr1 and len1 */
13216 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
13217 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
13219 /* Update addr2 and len2 */
13220 put_gpr_dw0(r2,
13221 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13222 mkexpr(addr2),
13223 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
13225 /* When updating len2 we must not modify bits (r2+1)[0:39] */
13226 put_gpr_w1(r2 + 1,
13227 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13228 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
13229 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
13231 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
13232 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
13234 return "mvcl";
13238 static const HChar *
13239 s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
13241 IRTemp addr1, addr3, addr3_load, len1, len3, single;
13243 addr1 = newTemp(Ity_I64);
13244 addr3 = newTemp(Ity_I64);
13245 addr3_load = newTemp(Ity_I64);
13246 len1 = newTemp(Ity_I64);
13247 len3 = newTemp(Ity_I64);
13248 single = newTemp(Ity_I8);
13250 assign(addr1, get_gpr_dw0(r1));
13251 assign(len1, get_gpr_dw0(r1 + 1));
13252 assign(addr3, get_gpr_dw0(r3));
13253 assign(len3, get_gpr_dw0(r3 + 1));
13255 // len1 == 0 ?
13256 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
13257 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
13259 /* This is a hack to prevent mvcle from reading from addr3 if it
13260 should read from the pad. Since the pad has no address, just
13261 read from the instruction, we discard that anyway */
13262 assign(addr3_load,
13263 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13264 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
13266 assign(single,
13267 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13268 unop(Iop_64to8, mkexpr(pad2)),
13269 load(Ity_I8, mkexpr(addr3_load))));
13270 store(mkexpr(addr1), mkexpr(single));
13272 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
13274 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
13276 put_gpr_dw0(r3,
13277 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13278 mkexpr(addr3),
13279 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
13281 put_gpr_dw0(r3 + 1,
13282 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13283 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
13285 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
13286 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
13288 return "mvcle";
13291 static const HChar *
13292 s390_irgen_MVST(UChar r1, UChar r2)
13294 IRTemp addr1 = newTemp(Ity_I64);
13295 IRTemp addr2 = newTemp(Ity_I64);
13296 IRTemp end = newTemp(Ity_I8);
13297 IRTemp byte = newTemp(Ity_I8);
13298 IRTemp counter = newTemp(Ity_I64);
13300 assign(addr1, get_gpr_dw0(r1));
13301 assign(addr2, get_gpr_dw0(r2));
13302 assign(counter, get_counter_dw0());
13303 assign(end, get_gpr_b7(0));
13304 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
13305 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
13307 // We use unlimited as cpu-determined number
13308 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13309 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
13311 // and always set cc=1 at the end + update r1
13312 s390_cc_set_val(1);
13313 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
13314 put_counter_dw0(mkU64(0));
13316 return "mvst";
13319 static void
13320 s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
13322 IRTemp op1 = newTemp(Ity_I64);
13323 IRTemp result = newTemp(Ity_I64);
13325 assign(op1, binop(Iop_32HLto64,
13326 get_gpr_w1(r1), // high 32 bits
13327 get_gpr_w1(r1 + 1))); // low 32 bits
13328 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
13329 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
13330 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
13333 static void
13334 s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
13336 IRTemp op1 = newTemp(Ity_I128);
13337 IRTemp result = newTemp(Ity_I128);
13339 assign(op1, binop(Iop_64HLto128,
13340 get_gpr_dw0(r1), // high 64 bits
13341 get_gpr_dw0(r1 + 1))); // low 64 bits
13342 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
13343 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
13344 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
13347 static void
13348 s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
13350 IRTemp op1 = newTemp(Ity_I64);
13351 IRTemp result = newTemp(Ity_I128);
13353 assign(op1, get_gpr_dw0(r1 + 1));
13354 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
13355 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
13356 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
13359 static const HChar *
13360 s390_irgen_DR(UChar r1, UChar r2)
13362 IRTemp op2 = newTemp(Ity_I32);
13364 assign(op2, get_gpr_w1(r2));
13366 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
13368 return "dr";
13371 static const HChar *
13372 s390_irgen_D(UChar r1, IRTemp op2addr)
13374 IRTemp op2 = newTemp(Ity_I32);
13376 assign(op2, load(Ity_I32, mkexpr(op2addr)));
13378 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
13380 return "d";
13383 static const HChar *
13384 s390_irgen_DLR(UChar r1, UChar r2)
13386 IRTemp op2 = newTemp(Ity_I32);
13388 assign(op2, get_gpr_w1(r2));
13390 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
13392 return "dlr";
13395 static const HChar *
13396 s390_irgen_DL(UChar r1, IRTemp op2addr)
13398 IRTemp op2 = newTemp(Ity_I32);
13400 assign(op2, load(Ity_I32, mkexpr(op2addr)));
13402 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
13404 return "dl";
13407 static const HChar *
13408 s390_irgen_DLG(UChar r1, IRTemp op2addr)
13410 IRTemp op2 = newTemp(Ity_I64);
13412 assign(op2, load(Ity_I64, mkexpr(op2addr)));
13414 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
13416 return "dlg";
13419 static const HChar *
13420 s390_irgen_DLGR(UChar r1, UChar r2)
13422 IRTemp op2 = newTemp(Ity_I64);
13424 assign(op2, get_gpr_dw0(r2));
13426 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
13428 return "dlgr";
13431 static const HChar *
13432 s390_irgen_DSGR(UChar r1, UChar r2)
13434 IRTemp op2 = newTemp(Ity_I64);
13436 assign(op2, get_gpr_dw0(r2));
13438 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
13440 return "dsgr";
13443 static const HChar *
13444 s390_irgen_DSG(UChar r1, IRTemp op2addr)
13446 IRTemp op2 = newTemp(Ity_I64);
13448 assign(op2, load(Ity_I64, mkexpr(op2addr)));
13450 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
13452 return "dsg";
13455 static const HChar *
13456 s390_irgen_DSGFR(UChar r1, UChar r2)
13458 IRTemp op2 = newTemp(Ity_I64);
13460 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
13462 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
13464 return "dsgfr";
13467 static const HChar *
13468 s390_irgen_DSGF(UChar r1, IRTemp op2addr)
13470 IRTemp op2 = newTemp(Ity_I64);
13472 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
13474 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
13476 return "dsgf";
13479 static void
13480 s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
13482 UChar reg;
13483 IRTemp addr = newTemp(Ity_I64);
13485 assign(addr, mkexpr(op2addr));
13486 reg = r1;
13487 do {
13488 IRTemp old = addr;
13490 reg %= 16;
13491 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
13492 addr = newTemp(Ity_I64);
13493 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13494 reg++;
13495 } while (reg != (r3 + 1));
13498 static const HChar *
13499 s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
13501 s390_irgen_load_ar_multiple(r1, r3, op2addr);
13503 return "lam";
13506 static const HChar *
13507 s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
13509 s390_irgen_load_ar_multiple(r1, r3, op2addr);
13511 return "lamy";
13514 static void
13515 s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
13517 UChar reg;
13518 IRTemp addr = newTemp(Ity_I64);
13520 assign(addr, mkexpr(op2addr));
13521 reg = r1;
13522 do {
13523 IRTemp old = addr;
13525 reg %= 16;
13526 store(mkexpr(addr), get_ar_w0(reg));
13527 addr = newTemp(Ity_I64);
13528 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13529 reg++;
13530 } while (reg != (r3 + 1));
13533 static const HChar *
13534 s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
13536 s390_irgen_store_ar_multiple(r1, r3, op2addr);
13538 return "stam";
13541 static const HChar *
13542 s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
13544 s390_irgen_store_ar_multiple(r1, r3, op2addr);
13546 return "stamy";
13550 /* Implementation for 32-bit compare-and-swap */
13551 static void
13552 s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
13554 IRCAS *cas;
13555 IRTemp op1 = newTemp(Ity_I32);
13556 IRTemp old_mem = newTemp(Ity_I32);
13557 IRTemp op3 = newTemp(Ity_I32);
13558 IRTemp result = newTemp(Ity_I32);
13559 IRTemp nequal = newTemp(Ity_I1);
13561 assign(op1, get_gpr_w1(r1));
13562 assign(op3, get_gpr_w1(r3));
13564 /* The first and second operands are compared. If they are equal,
13565 the third operand is stored at the second- operand location. */
13566 cas = mkIRCAS(IRTemp_INVALID, old_mem,
13567 Iend_BE, mkexpr(op2addr),
13568 NULL, mkexpr(op1), /* expected value */
13569 NULL, mkexpr(op3) /* new value */);
13570 stmt(IRStmt_CAS(cas));
13572 /* Set CC. Operands compared equal -> 0, else 1. */
13573 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
13574 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
13576 /* If operands were equal (cc == 0) just store the old value op1 in r1.
13577 Otherwise, store the old_value from memory in r1 and yield. */
13578 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
13579 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
13580 yield_if(mkexpr(nequal));
13583 static const HChar *
13584 s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
13586 s390_irgen_cas_32(r1, r3, op2addr);
13588 return "cs";
13591 static const HChar *
13592 s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
13594 s390_irgen_cas_32(r1, r3, op2addr);
13596 return "csy";
13599 static const HChar *
13600 s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
13602 IRCAS *cas;
13603 IRTemp op1 = newTemp(Ity_I64);
13604 IRTemp old_mem = newTemp(Ity_I64);
13605 IRTemp op3 = newTemp(Ity_I64);
13606 IRTemp result = newTemp(Ity_I64);
13607 IRTemp nequal = newTemp(Ity_I1);
13609 assign(op1, get_gpr_dw0(r1));
13610 assign(op3, get_gpr_dw0(r3));
13612 /* The first and second operands are compared. If they are equal,
13613 the third operand is stored at the second- operand location. */
13614 cas = mkIRCAS(IRTemp_INVALID, old_mem,
13615 Iend_BE, mkexpr(op2addr),
13616 NULL, mkexpr(op1), /* expected value */
13617 NULL, mkexpr(op3) /* new value */);
13618 stmt(IRStmt_CAS(cas));
13620 /* Set CC. Operands compared equal -> 0, else 1. */
13621 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
13622 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
13624 /* If operands were equal (cc == 0) just store the old value op1 in r1.
13625 Otherwise, store the old_value from memory in r1 and yield. */
13626 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
13627 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
13628 yield_if(mkexpr(nequal));
13630 return "csg";
13633 /* Implementation for 32-bit compare-double-and-swap */
13634 static void
13635 s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
13637 IRCAS *cas;
13638 IRTemp op1_high = newTemp(Ity_I32);
13639 IRTemp op1_low = newTemp(Ity_I32);
13640 IRTemp old_mem_high = newTemp(Ity_I32);
13641 IRTemp old_mem_low = newTemp(Ity_I32);
13642 IRTemp op3_high = newTemp(Ity_I32);
13643 IRTemp op3_low = newTemp(Ity_I32);
13644 IRTemp result = newTemp(Ity_I32);
13645 IRTemp nequal = newTemp(Ity_I1);
13647 assign(op1_high, get_gpr_w1(r1));
13648 assign(op1_low, get_gpr_w1(r1+1));
13649 assign(op3_high, get_gpr_w1(r3));
13650 assign(op3_low, get_gpr_w1(r3+1));
13652 /* The first and second operands are compared. If they are equal,
13653 the third operand is stored at the second-operand location. */
13654 cas = mkIRCAS(old_mem_high, old_mem_low,
13655 Iend_BE, mkexpr(op2addr),
13656 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
13657 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
13658 stmt(IRStmt_CAS(cas));
13660 /* Set CC. Operands compared equal -> 0, else 1. */
13661 assign(result, unop(Iop_1Uto32,
13662 binop(Iop_CmpNE32,
13663 binop(Iop_Or32,
13664 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
13665 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
13666 mkU32(0))));
13668 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
13670 /* If operands were equal (cc == 0) just store the old value op1 in r1.
13671 Otherwise, store the old_value from memory in r1 and yield. */
13672 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
13673 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
13674 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
13675 yield_if(mkexpr(nequal));
13678 static const HChar *
13679 s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
13681 s390_irgen_cdas_32(r1, r3, op2addr);
13683 return "cds";
13686 static const HChar *
13687 s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
13689 s390_irgen_cdas_32(r1, r3, op2addr);
13691 return "cdsy";
13694 static const HChar *
13695 s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
13697 IRCAS *cas;
13698 IRTemp op1_high = newTemp(Ity_I64);
13699 IRTemp op1_low = newTemp(Ity_I64);
13700 IRTemp old_mem_high = newTemp(Ity_I64);
13701 IRTemp old_mem_low = newTemp(Ity_I64);
13702 IRTemp op3_high = newTemp(Ity_I64);
13703 IRTemp op3_low = newTemp(Ity_I64);
13704 IRTemp result = newTemp(Ity_I64);
13705 IRTemp nequal = newTemp(Ity_I1);
13707 assign(op1_high, get_gpr_dw0(r1));
13708 assign(op1_low, get_gpr_dw0(r1+1));
13709 assign(op3_high, get_gpr_dw0(r3));
13710 assign(op3_low, get_gpr_dw0(r3+1));
13712 /* The first and second operands are compared. If they are equal,
13713 the third operand is stored at the second-operand location. */
13714 cas = mkIRCAS(old_mem_high, old_mem_low,
13715 Iend_BE, mkexpr(op2addr),
13716 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
13717 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
13718 stmt(IRStmt_CAS(cas));
13720 /* Set CC. Operands compared equal -> 0, else 1. */
13721 assign(result, unop(Iop_1Uto64,
13722 binop(Iop_CmpNE64,
13723 binop(Iop_Or64,
13724 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
13725 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
13726 mkU64(0))));
13728 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
13730 /* If operands were equal (cc == 0) just store the old value op1 in r1.
13731 Otherwise, store the old_value from memory in r1 and yield. */
13732 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
13733 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
13734 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
13735 yield_if(mkexpr(nequal));
13737 return "cdsg";
13741 /* Binary floating point */
13743 static const HChar *
13744 s390_irgen_AXBR(UChar r1, UChar r2)
13746 IRTemp op1 = newTemp(Ity_F128);
13747 IRTemp op2 = newTemp(Ity_F128);
13748 IRTemp result = newTemp(Ity_F128);
13749 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
13751 assign(op1, get_fpr_pair(r1));
13752 assign(op2, get_fpr_pair(r2));
13753 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
13754 mkexpr(op2)));
13755 put_fpr_pair(r1, mkexpr(result));
13757 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
13759 return "axbr";
13762 static const HChar *
13763 s390_irgen_CEBR(UChar r1, UChar r2)
13765 IRTemp op1 = newTemp(Ity_F32);
13766 IRTemp op2 = newTemp(Ity_F32);
13767 IRTemp cc_vex = newTemp(Ity_I32);
13768 IRTemp cc_s390 = newTemp(Ity_I32);
13770 assign(op1, get_fpr_w0(r1));
13771 assign(op2, get_fpr_w0(r2));
13772 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
13774 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
13775 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
13777 return "cebr";
13780 static const HChar *
13781 s390_irgen_CDBR(UChar r1, UChar r2)
13783 IRTemp op1 = newTemp(Ity_F64);
13784 IRTemp op2 = newTemp(Ity_F64);
13785 IRTemp cc_vex = newTemp(Ity_I32);
13786 IRTemp cc_s390 = newTemp(Ity_I32);
13788 assign(op1, get_fpr_dw0(r1));
13789 assign(op2, get_fpr_dw0(r2));
13790 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
13792 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
13793 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
13795 return "cdbr";
13798 static const HChar *
13799 s390_irgen_CXBR(UChar r1, UChar r2)
13801 IRTemp op1 = newTemp(Ity_F128);
13802 IRTemp op2 = newTemp(Ity_F128);
13803 IRTemp cc_vex = newTemp(Ity_I32);
13804 IRTemp cc_s390 = newTemp(Ity_I32);
13806 assign(op1, get_fpr_pair(r1));
13807 assign(op2, get_fpr_pair(r2));
13808 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
13810 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
13811 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
13813 return "cxbr";
13816 static const HChar *
13817 s390_irgen_CEB(UChar r1, IRTemp op2addr)
13819 IRTemp op1 = newTemp(Ity_F32);
13820 IRTemp op2 = newTemp(Ity_F32);
13821 IRTemp cc_vex = newTemp(Ity_I32);
13822 IRTemp cc_s390 = newTemp(Ity_I32);
13824 assign(op1, get_fpr_w0(r1));
13825 assign(op2, load(Ity_F32, mkexpr(op2addr)));
13826 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
13828 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
13829 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
13831 return "ceb";
13834 static const HChar *
13835 s390_irgen_CDB(UChar r1, IRTemp op2addr)
13837 IRTemp op1 = newTemp(Ity_F64);
13838 IRTemp op2 = newTemp(Ity_F64);
13839 IRTemp cc_vex = newTemp(Ity_I32);
13840 IRTemp cc_s390 = newTemp(Ity_I32);
13842 assign(op1, get_fpr_dw0(r1));
13843 assign(op2, load(Ity_F64, mkexpr(op2addr)));
13844 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
13846 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
13847 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
13849 return "cdb";
13852 static const HChar *
13853 s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
13854 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
13856 IRTemp op2 = newTemp(Ity_I32);
13858 assign(op2, get_gpr_w1(r2));
13859 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
13861 return "cxfbr";
13864 static const HChar *
13865 s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
13866 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
13868 if (! s390_host_has_fpext) {
13869 emulation_failure(EmFail_S390X_fpext);
13870 } else {
13871 IRTemp op2 = newTemp(Ity_I32);
13873 assign(op2, get_gpr_w1(r2));
13874 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
13876 return "cxlfbr";
13880 static const HChar *
13881 s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
13882 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
13884 IRTemp op2 = newTemp(Ity_I64);
13886 assign(op2, get_gpr_dw0(r2));
13887 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
13889 return "cxgbr";
13892 static const HChar *
13893 s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
13894 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
13896 if (! s390_host_has_fpext) {
13897 emulation_failure(EmFail_S390X_fpext);
13898 } else {
13899 IRTemp op2 = newTemp(Ity_I64);
13901 assign(op2, get_gpr_dw0(r2));
13902 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
13904 return "cxlgbr";
13907 static const HChar *
13908 s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
13909 UChar r1, UChar r2)
13911 IRTemp op = newTemp(Ity_F128);
13912 IRTemp result = newTemp(Ity_I32);
13913 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
13915 assign(op, get_fpr_pair(r2));
13916 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
13917 mkexpr(op)));
13918 put_gpr_w1(r1, mkexpr(result));
13919 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
13921 return "cfxbr";
13924 static const HChar *
13925 s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
13926 UChar r1, UChar r2)
13928 if (! s390_host_has_fpext) {
13929 emulation_failure(EmFail_S390X_fpext);
13930 } else {
13931 IRTemp op = newTemp(Ity_F128);
13932 IRTemp result = newTemp(Ity_I32);
13933 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
13935 assign(op, get_fpr_pair(r2));
13936 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
13937 mkexpr(op)));
13938 put_gpr_w1(r1, mkexpr(result));
13939 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
13941 return "clfxbr";
13945 static const HChar *
13946 s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
13947 UChar r1, UChar r2)
13949 IRTemp op = newTemp(Ity_F128);
13950 IRTemp result = newTemp(Ity_I64);
13951 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
13953 assign(op, get_fpr_pair(r2));
13954 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
13955 mkexpr(op)));
13956 put_gpr_dw0(r1, mkexpr(result));
13957 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
13959 return "cgxbr";
13962 static const HChar *
13963 s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
13964 UChar r1, UChar r2)
13966 if (! s390_host_has_fpext) {
13967 emulation_failure(EmFail_S390X_fpext);
13968 } else {
13969 IRTemp op = newTemp(Ity_F128);
13970 IRTemp result = newTemp(Ity_I64);
13971 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
13973 assign(op, get_fpr_pair(r2));
13974 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
13975 mkexpr(op)));
13976 put_gpr_dw0(r1, mkexpr(result));
13977 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
13978 rounding_mode);
13980 return "clgxbr";
13983 static const HChar *
13984 s390_irgen_DXBR(UChar r1, UChar r2)
13986 IRTemp op1 = newTemp(Ity_F128);
13987 IRTemp op2 = newTemp(Ity_F128);
13988 IRTemp result = newTemp(Ity_F128);
13989 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
13991 assign(op1, get_fpr_pair(r1));
13992 assign(op2, get_fpr_pair(r2));
13993 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
13994 mkexpr(op2)));
13995 put_fpr_pair(r1, mkexpr(result));
13997 return "dxbr";
14000 static const HChar *
14001 s390_irgen_LTXBR(UChar r1, UChar r2)
14003 IRTemp result = newTemp(Ity_F128);
14005 assign(result, get_fpr_pair(r2));
14006 put_fpr_pair(r1, mkexpr(result));
14007 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14009 return "ltxbr";
14012 static const HChar *
14013 s390_irgen_LCXBR(UChar r1, UChar r2)
14015 IRTemp result = newTemp(Ity_F128);
14017 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
14018 put_fpr_pair(r1, mkexpr(result));
14019 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14021 return "lcxbr";
14024 static const HChar *
14025 s390_irgen_LXDBR(UChar r1, UChar r2)
14027 IRTemp op = newTemp(Ity_F64);
14029 assign(op, get_fpr_dw0(r2));
14030 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
14032 return "lxdbr";
14035 static const HChar *
14036 s390_irgen_LXEBR(UChar r1, UChar r2)
14038 IRTemp op = newTemp(Ity_F32);
14040 assign(op, get_fpr_w0(r2));
14041 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
14043 return "lxebr";
14046 static const HChar *
14047 s390_irgen_LXDB(UChar r1, IRTemp op2addr)
14049 IRTemp op = newTemp(Ity_F64);
14051 assign(op, load(Ity_F64, mkexpr(op2addr)));
14052 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
14054 return "lxdb";
14057 static const HChar *
14058 s390_irgen_LXEB(UChar r1, IRTemp op2addr)
14060 IRTemp op = newTemp(Ity_F32);
14062 assign(op, load(Ity_F32, mkexpr(op2addr)));
14063 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
14065 return "lxeb";
14068 static const HChar *
14069 s390_irgen_FIEBRA(UChar m3, UChar m4 __attribute__((unused)),
14070 UChar r1, UChar r2)
14072 IRTemp result = newTemp(Ity_F32);
14074 assign(result, binop(Iop_RoundF32toInt, mkexpr(encode_bfp_rounding_mode(m3)),
14075 get_fpr_w0(r2)));
14076 put_fpr_w0(r1, mkexpr(result));
14078 return "fiebra";
14081 static const HChar *
14082 s390_irgen_FIDBRA(UChar m3, UChar m4 __attribute__((unused)),
14083 UChar r1, UChar r2)
14085 IRTemp result = newTemp(Ity_F64);
14087 assign(result, binop(Iop_RoundF64toInt, mkexpr(encode_bfp_rounding_mode(m3)),
14088 get_fpr_dw0(r2)));
14089 put_fpr_dw0(r1, mkexpr(result));
14091 return "fidbra";
14094 static const HChar *
14095 s390_irgen_FIXBRA(UChar m3, UChar m4 __attribute__((unused)),
14096 UChar r1, UChar r2)
14098 IRTemp result = newTemp(Ity_F128);
14100 assign(result, binop(Iop_RoundF128toInt, mkexpr(encode_bfp_rounding_mode(m3)),
14101 get_fpr_pair(r2)));
14102 put_fpr_pair(r1, mkexpr(result));
14104 return "fixbra";
14107 static const HChar *
14108 s390_irgen_LNEBR(UChar r1, UChar r2)
14110 IRTemp result = newTemp(Ity_F32);
14112 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
14113 put_fpr_w0(r1, mkexpr(result));
14114 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
14116 return "lnebr";
14119 static const HChar *
14120 s390_irgen_LNDBR(UChar r1, UChar r2)
14122 IRTemp result = newTemp(Ity_F64);
14124 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
14125 put_fpr_dw0(r1, mkexpr(result));
14126 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
14128 return "lndbr";
14131 static const HChar *
14132 s390_irgen_LNXBR(UChar r1, UChar r2)
14134 IRTemp result = newTemp(Ity_F128);
14136 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
14137 put_fpr_pair(r1, mkexpr(result));
14138 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14140 return "lnxbr";
14143 static const HChar *
14144 s390_irgen_LPEBR(UChar r1, UChar r2)
14146 IRTemp result = newTemp(Ity_F32);
14148 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
14149 put_fpr_w0(r1, mkexpr(result));
14150 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
14152 return "lpebr";
14155 static const HChar *
14156 s390_irgen_LPDBR(UChar r1, UChar r2)
14158 IRTemp result = newTemp(Ity_F64);
14160 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
14161 put_fpr_dw0(r1, mkexpr(result));
14162 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
14164 return "lpdbr";
14167 static const HChar *
14168 s390_irgen_LPXBR(UChar r1, UChar r2)
14170 IRTemp result = newTemp(Ity_F128);
14172 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
14173 put_fpr_pair(r1, mkexpr(result));
14174 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14176 return "lpxbr";
14179 static const HChar *
14180 s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
14181 UChar r1, UChar r2)
14183 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
14184 emulation_warning(EmWarn_S390X_fpext_rounding);
14185 m3 = S390_BFP_ROUND_PER_FPC;
14187 IRTemp result = newTemp(Ity_F64);
14189 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
14190 get_fpr_pair(r2)));
14191 put_fpr_dw0(r1, mkexpr(result));
14193 return "ldxbr";
14196 static const HChar *
14197 s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
14198 UChar r1, UChar r2)
14200 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
14201 emulation_warning(EmWarn_S390X_fpext_rounding);
14202 m3 = S390_BFP_ROUND_PER_FPC;
14204 IRTemp result = newTemp(Ity_F32);
14206 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
14207 get_fpr_pair(r2)));
14208 put_fpr_w0(r1, mkexpr(result));
14210 return "lexbr";
14213 static const HChar *
14214 s390_irgen_MXBR(UChar r1, UChar r2)
14216 IRTemp op1 = newTemp(Ity_F128);
14217 IRTemp op2 = newTemp(Ity_F128);
14218 IRTemp result = newTemp(Ity_F128);
14219 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14221 assign(op1, get_fpr_pair(r1));
14222 assign(op2, get_fpr_pair(r2));
14223 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
14224 mkexpr(op2)));
14225 put_fpr_pair(r1, mkexpr(result));
14227 return "mxbr";
14230 static const HChar *
14231 s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
14233 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14235 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
14236 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
14238 return "maebr";
14241 static const HChar *
14242 s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
14244 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14246 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
14247 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
14249 return "madbr";
14252 static const HChar *
14253 s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
14255 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
14256 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14258 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
14259 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
14261 return "maeb";
14264 static const HChar *
14265 s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
14267 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
14268 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14270 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
14271 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
14273 return "madb";
14276 static const HChar *
14277 s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
14279 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14281 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
14282 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
14284 return "msebr";
14287 static const HChar *
14288 s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
14290 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14292 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
14293 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
14295 return "msdbr";
14298 static const HChar *
14299 s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
14301 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
14302 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14304 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
14305 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
14307 return "mseb";
14310 static const HChar *
14311 s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
14313 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
14314 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14316 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
14317 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
14319 return "msdb";
14322 static const HChar *
14323 s390_irgen_SQEBR(UChar r1, UChar r2)
14325 IRTemp result = newTemp(Ity_F32);
14326 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14328 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
14329 put_fpr_w0(r1, mkexpr(result));
14331 return "sqebr";
14334 static const HChar *
14335 s390_irgen_SQDBR(UChar r1, UChar r2)
14337 IRTemp result = newTemp(Ity_F64);
14338 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14340 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
14341 put_fpr_dw0(r1, mkexpr(result));
14343 return "sqdbr";
14346 static const HChar *
14347 s390_irgen_SQXBR(UChar r1, UChar r2)
14349 IRTemp result = newTemp(Ity_F128);
14350 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14352 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
14353 get_fpr_pair(r2)));
14354 put_fpr_pair(r1, mkexpr(result));
14356 return "sqxbr";
14359 static const HChar *
14360 s390_irgen_SQEB(UChar r1, IRTemp op2addr)
14362 IRTemp op = newTemp(Ity_F32);
14363 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14365 assign(op, load(Ity_F32, mkexpr(op2addr)));
14366 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
14368 return "sqeb";
14371 static const HChar *
14372 s390_irgen_SQDB(UChar r1, IRTemp op2addr)
14374 IRTemp op = newTemp(Ity_F64);
14375 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14377 assign(op, load(Ity_F64, mkexpr(op2addr)));
14378 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
14380 return "sqdb";
14383 static const HChar *
14384 s390_irgen_SXBR(UChar r1, UChar r2)
14386 IRTemp op1 = newTemp(Ity_F128);
14387 IRTemp op2 = newTemp(Ity_F128);
14388 IRTemp result = newTemp(Ity_F128);
14389 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14391 assign(op1, get_fpr_pair(r1));
14392 assign(op2, get_fpr_pair(r2));
14393 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
14394 mkexpr(op2)));
14395 put_fpr_pair(r1, mkexpr(result));
14396 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14398 return "sxbr";
14401 static const HChar *
14402 s390_irgen_TCEB(UChar r1, IRTemp op2addr)
14404 IRTemp value = newTemp(Ity_F32);
14406 assign(value, get_fpr_w0(r1));
14408 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
14410 return "tceb";
14413 static const HChar *
14414 s390_irgen_TCDB(UChar r1, IRTemp op2addr)
14416 IRTemp value = newTemp(Ity_F64);
14418 assign(value, get_fpr_dw0(r1));
14420 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
14422 return "tcdb";
14425 static const HChar *
14426 s390_irgen_TCXB(UChar r1, IRTemp op2addr)
14428 IRTemp value = newTemp(Ity_F128);
14430 assign(value, get_fpr_pair(r1));
14432 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
14434 return "tcxb";
14437 static const HChar *
14438 s390_irgen_LCDFR(UChar r1, UChar r2)
14440 IRTemp result = newTemp(Ity_F64);
14442 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
14443 put_fpr_dw0(r1, mkexpr(result));
14445 return "lcdfr";
14448 static const HChar *
14449 s390_irgen_LNDFR(UChar r1, UChar r2)
14451 IRTemp result = newTemp(Ity_F64);
14453 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
14454 put_fpr_dw0(r1, mkexpr(result));
14456 return "lndfr";
14459 static const HChar *
14460 s390_irgen_LPDFR(UChar r1, UChar r2)
14462 IRTemp result = newTemp(Ity_F64);
14464 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
14465 put_fpr_dw0(r1, mkexpr(result));
14467 return "lpdfr";
14470 static const HChar *
14471 s390_irgen_LDGR(UChar r1, UChar r2)
14473 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
14475 return "ldgr";
14478 static const HChar *
14479 s390_irgen_LGDR(UChar r1, UChar r2)
14481 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
14483 return "lgdr";
14487 static const HChar *
14488 s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
14490 IRTemp sign = newTemp(Ity_I64);
14491 IRTemp value = newTemp(Ity_I64);
14493 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
14494 mkU64(1ULL << 63)));
14495 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
14496 mkU64((1ULL << 63) - 1)));
14497 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
14498 mkexpr(sign))));
14500 return "cpsdr";
14504 static IRExpr *
14505 s390_call_cvb(IRExpr *in)
14507 IRExpr **args, *call;
14509 args = mkIRExprVec_1(in);
14510 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
14511 "s390_do_cvb", &s390_do_cvb, args);
14513 /* Nothing is excluded from definedness checking. */
14514 call->Iex.CCall.cee->mcx_mask = 0;
14516 return call;
14519 static const HChar *
14520 s390_irgen_CVB(UChar r1, IRTemp op2addr)
14522 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
14524 return "cvb";
14527 static const HChar *
14528 s390_irgen_CVBY(UChar r1, IRTemp op2addr)
14530 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
14532 return "cvby";
14536 static IRExpr *
14537 s390_call_cvd(IRExpr *in)
14539 IRExpr **args, *call;
14541 args = mkIRExprVec_1(in);
14542 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
14543 "s390_do_cvd", &s390_do_cvd, args);
14545 /* Nothing is excluded from definedness checking. */
14546 call->Iex.CCall.cee->mcx_mask = 0;
14548 return call;
14551 static const HChar *
14552 s390_irgen_CVD(UChar r1, IRTemp op2addr)
14554 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
14556 return "cvd";
14559 static const HChar *
14560 s390_irgen_CVDY(UChar r1, IRTemp op2addr)
14562 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
14564 return "cvdy";
14567 static const HChar *
14568 s390_irgen_FLOGR(UChar r1, UChar r2)
14570 IRTemp input = newTemp(Ity_I64);
14571 IRTemp not_zero = newTemp(Ity_I64);
14572 IRTemp tmpnum = newTemp(Ity_I64);
14573 IRTemp num = newTemp(Ity_I64);
14574 IRTemp shift_amount = newTemp(Ity_I8);
14576 /* We use the "count leading zeroes" operator because the number of
14577 leading zeroes is identical with the bit position of the first '1' bit.
14578 However, that operator does not work when the input value is zero.
14579 Therefore, we set the LSB of the input value to 1 and use Clz64 on
14580 the modified value. If input == 0, then the result is 64. Otherwise,
14581 the result of Clz64 is what we want. */
14583 assign(input, get_gpr_dw0(r2));
14584 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
14585 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
14587 /* num = (input == 0) ? 64 : tmpnum */
14588 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
14589 /* == 0 */ mkU64(64),
14590 /* != 0 */ mkexpr(tmpnum)));
14592 put_gpr_dw0(r1, mkexpr(num));
14594 /* Set the leftmost '1' bit of the input value to zero. The general scheme
14595 is to first shift the input value by NUM + 1 bits to the left which
14596 causes the leftmost '1' bit to disappear. Then we shift logically to
14597 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
14598 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
14599 the width of the value-to-be-shifted, we need to special case
14600 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
14601 For both such INPUT values the result will be 0. */
14603 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
14604 mkU64(1))));
14606 put_gpr_dw0(r1 + 1,
14607 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
14608 /* == 0 || == 1*/ mkU64(0),
14609 /* otherwise */
14610 binop(Iop_Shr64,
14611 binop(Iop_Shl64, mkexpr(input),
14612 mkexpr(shift_amount)),
14613 mkexpr(shift_amount))));
14615 /* Compare the original value as an unsigned integer with 0. */
14616 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
14617 mktemp(Ity_I64, mkU64(0)), False);
14619 return "flogr";
14622 static const HChar *
14623 s390_irgen_POPCNT(UChar r1, UChar r2)
14625 Int i;
14626 IRTemp val = newTemp(Ity_I64);
14627 IRTemp mask[3];
14629 assign(val, get_gpr_dw0(r2));
14630 for (i = 0; i < 3; i++) {
14631 mask[i] = newTemp(Ity_I64);
14633 assign(mask[0], mkU64(0x5555555555555555ULL));
14634 assign(mask[1], mkU64(0x3333333333333333ULL));
14635 assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
14636 for (i = 0; i < 3; i++) {
14637 IRTemp tmp = newTemp(Ity_I64);
14639 assign(tmp,
14640 binop(Iop_Add64,
14641 binop(Iop_And64,
14642 mkexpr(val),
14643 mkexpr(mask[i])),
14644 binop(Iop_And64,
14645 binop(Iop_Shr64, mkexpr(val), mkU8(1 << i)),
14646 mkexpr(mask[i]))));
14647 val = tmp;
14649 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, val);
14650 put_gpr_dw0(r1, mkexpr(val));
14651 return "popcnt";
14654 static const HChar *
14655 s390_irgen_STCK(IRTemp op2addr)
14657 IRDirty *d;
14658 IRTemp cc = newTemp(Ity_I64);
14660 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
14661 &s390x_dirtyhelper_STCK,
14662 mkIRExprVec_1(mkexpr(op2addr)));
14663 d->mFx = Ifx_Write;
14664 d->mAddr = mkexpr(op2addr);
14665 d->mSize = 8;
14666 stmt(IRStmt_Dirty(d));
14667 s390_cc_set(cc);
14668 return "stck";
14671 static const HChar *
14672 s390_irgen_STCKF(IRTemp op2addr)
14674 if (! s390_host_has_stckf) {
14675 emulation_failure(EmFail_S390X_stckf);
14676 } else {
14677 IRTemp cc = newTemp(Ity_I64);
14679 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
14680 &s390x_dirtyhelper_STCKF,
14681 mkIRExprVec_1(mkexpr(op2addr)));
14682 d->mFx = Ifx_Write;
14683 d->mAddr = mkexpr(op2addr);
14684 d->mSize = 8;
14685 stmt(IRStmt_Dirty(d));
14686 s390_cc_set(cc);
14688 return "stckf";
14691 static const HChar *
14692 s390_irgen_STCKE(IRTemp op2addr)
14694 IRDirty *d;
14695 IRTemp cc = newTemp(Ity_I64);
14697 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
14698 &s390x_dirtyhelper_STCKE,
14699 mkIRExprVec_1(mkexpr(op2addr)));
14700 d->mFx = Ifx_Write;
14701 d->mAddr = mkexpr(op2addr);
14702 d->mSize = 16;
14703 stmt(IRStmt_Dirty(d));
14704 s390_cc_set(cc);
14705 return "stcke";
14708 static const HChar *
14709 s390_irgen_STFLE(IRTemp op2addr)
14711 if (! s390_host_has_stfle) {
14712 emulation_failure(EmFail_S390X_stfle);
14713 return "stfle";
14716 IRDirty *d;
14717 IRTemp cc = newTemp(Ity_I64);
14719 /* IRExpr_GSPTR() => Need to pass pointer to guest state to helper */
14720 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
14721 &s390x_dirtyhelper_STFLE,
14722 mkIRExprVec_2(IRExpr_GSPTR(), mkexpr(op2addr)));
14724 d->nFxState = 1;
14725 vex_bzero(&d->fxState, sizeof(d->fxState));
14727 d->fxState[0].fx = Ifx_Modify; /* read then write */
14728 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
14729 d->fxState[0].size = sizeof(ULong);
14731 d->mAddr = mkexpr(op2addr);
14732 /* Pretend all double words are written */
14733 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
14734 d->mFx = Ifx_Write;
14736 stmt(IRStmt_Dirty(d));
14738 s390_cc_set(cc);
14740 return "stfle";
14743 static const HChar *
14744 s390_irgen_CKSM(UChar r1,UChar r2)
14746 IRTemp addr = newTemp(Ity_I64);
14747 IRTemp op = newTemp(Ity_I32);
14748 IRTemp len = newTemp(Ity_I64);
14749 IRTemp oldval = newTemp(Ity_I32);
14750 IRTemp mask = newTemp(Ity_I32);
14751 IRTemp newop = newTemp(Ity_I32);
14752 IRTemp result = newTemp(Ity_I32);
14753 IRTemp result1 = newTemp(Ity_I32);
14754 IRTemp inc = newTemp(Ity_I64);
14756 assign(oldval, get_gpr_w1(r1));
14757 assign(addr, get_gpr_dw0(r2));
14758 assign(len, get_gpr_dw0(r2+1));
14760 /* Condition code is always zero. */
14761 s390_cc_set_val(0);
14763 /* If length is zero, there is no need to calculate the checksum */
14764 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
14766 /* Assiging the increment variable to adjust address and length
14767 later on. */
14768 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
14769 mkexpr(len), mkU64(4)));
14771 /* If length < 4 the final 4-byte 2nd operand value is computed by
14772 appending the remaining bytes to the right with 0. This is done
14773 by AND'ing the 4 bytes loaded from memory with an appropriate
14774 mask. If length >= 4, that mask is simply 0xffffffff. */
14776 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
14777 /* Mask computation when len < 4:
14778 0xffffffff << (32 - (len % 4)*8) */
14779 binop(Iop_Shl32, mkU32(0xffffffff),
14780 unop(Iop_32to8,
14781 binop(Iop_Sub32, mkU32(32),
14782 binop(Iop_Shl32,
14783 unop(Iop_64to32,
14784 binop(Iop_And64,
14785 mkexpr(len), mkU64(3))),
14786 mkU8(3))))),
14787 mkU32(0xffffffff)));
14789 assign(op, load(Ity_I32, mkexpr(addr)));
14790 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
14791 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
14793 /* Checking for carry */
14794 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
14795 binop(Iop_Add32, mkexpr(result), mkU32(1)),
14796 mkexpr(result)));
14798 put_gpr_w1(r1, mkexpr(result1));
14799 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
14800 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
14802 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
14804 return "cksm";
14807 static const HChar *
14808 s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
14810 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
14811 src_addr = newTemp(Ity_I64);
14812 des_addr = newTemp(Ity_I64);
14813 tab_addr = newTemp(Ity_I64);
14814 test_byte = newTemp(Ity_I8);
14815 src_len = newTemp(Ity_I64);
14817 assign(src_addr, get_gpr_dw0(r2));
14818 assign(des_addr, get_gpr_dw0(r1));
14819 assign(tab_addr, get_gpr_dw0(1));
14820 assign(src_len, get_gpr_dw0(r1+1));
14821 assign(test_byte, get_gpr_b7(0));
14823 IRTemp op = newTemp(Ity_I8);
14824 IRTemp op1 = newTemp(Ity_I8);
14825 IRTemp result = newTemp(Ity_I64);
14827 /* End of source string? We're done; proceed to next insn */
14828 s390_cc_set_val(0);
14829 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
14831 /* Load character from source string, index translation table and
14832 store translated character in op1. */
14833 assign(op, load(Ity_I8, mkexpr(src_addr)));
14835 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
14836 mkexpr(tab_addr)));
14837 assign(op1, load(Ity_I8, mkexpr(result)));
14839 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
14840 s390_cc_set_val(1);
14841 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
14843 store(get_gpr_dw0(r1), mkexpr(op1));
14845 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
14846 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
14847 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
14849 iterate();
14851 return "troo";
14854 static const HChar *
14855 s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
14857 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
14858 src_addr = newTemp(Ity_I64);
14859 des_addr = newTemp(Ity_I64);
14860 tab_addr = newTemp(Ity_I64);
14861 test_byte = newTemp(Ity_I8);
14862 src_len = newTemp(Ity_I64);
14864 assign(src_addr, get_gpr_dw0(r2));
14865 assign(des_addr, get_gpr_dw0(r1));
14866 assign(tab_addr, get_gpr_dw0(1));
14867 assign(src_len, get_gpr_dw0(r1+1));
14868 assign(test_byte, get_gpr_b7(0));
14870 IRTemp op = newTemp(Ity_I16);
14871 IRTemp op1 = newTemp(Ity_I8);
14872 IRTemp result = newTemp(Ity_I64);
14874 /* End of source string? We're done; proceed to next insn */
14875 s390_cc_set_val(0);
14876 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
14878 /* Load character from source string, index translation table and
14879 store translated character in op1. */
14880 assign(op, load(Ity_I16, mkexpr(src_addr)));
14882 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
14883 mkexpr(tab_addr)));
14885 assign(op1, load(Ity_I8, mkexpr(result)));
14887 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
14888 s390_cc_set_val(1);
14889 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
14891 store(get_gpr_dw0(r1), mkexpr(op1));
14893 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
14894 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
14895 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
14897 iterate();
14899 return "trto";
14902 static const HChar *
14903 s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
14905 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
14906 src_addr = newTemp(Ity_I64);
14907 des_addr = newTemp(Ity_I64);
14908 tab_addr = newTemp(Ity_I64);
14909 test_byte = newTemp(Ity_I16);
14910 src_len = newTemp(Ity_I64);
14912 assign(src_addr, get_gpr_dw0(r2));
14913 assign(des_addr, get_gpr_dw0(r1));
14914 assign(tab_addr, get_gpr_dw0(1));
14915 assign(src_len, get_gpr_dw0(r1+1));
14916 assign(test_byte, get_gpr_hw3(0));
14918 IRTemp op = newTemp(Ity_I8);
14919 IRTemp op1 = newTemp(Ity_I16);
14920 IRTemp result = newTemp(Ity_I64);
14922 /* End of source string? We're done; proceed to next insn */
14923 s390_cc_set_val(0);
14924 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
14926 /* Load character from source string, index translation table and
14927 store translated character in op1. */
14928 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
14930 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
14931 mkexpr(tab_addr)));
14932 assign(op1, load(Ity_I16, mkexpr(result)));
14934 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
14935 s390_cc_set_val(1);
14936 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
14938 store(get_gpr_dw0(r1), mkexpr(op1));
14940 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
14941 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
14942 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
14944 iterate();
14946 return "trot";
14949 static const HChar *
14950 s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
14952 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
14953 src_addr = newTemp(Ity_I64);
14954 des_addr = newTemp(Ity_I64);
14955 tab_addr = newTemp(Ity_I64);
14956 test_byte = newTemp(Ity_I16);
14957 src_len = newTemp(Ity_I64);
14959 assign(src_addr, get_gpr_dw0(r2));
14960 assign(des_addr, get_gpr_dw0(r1));
14961 assign(tab_addr, get_gpr_dw0(1));
14962 assign(src_len, get_gpr_dw0(r1+1));
14963 assign(test_byte, get_gpr_hw3(0));
14965 IRTemp op = newTemp(Ity_I16);
14966 IRTemp op1 = newTemp(Ity_I16);
14967 IRTemp result = newTemp(Ity_I64);
14969 /* End of source string? We're done; proceed to next insn */
14970 s390_cc_set_val(0);
14971 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
14973 /* Load character from source string, index translation table and
14974 store translated character in op1. */
14975 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
14977 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
14978 mkexpr(tab_addr)));
14979 assign(op1, load(Ity_I16, mkexpr(result)));
14981 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
14982 s390_cc_set_val(1);
14983 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
14986 store(get_gpr_dw0(r1), mkexpr(op1));
14988 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
14989 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
14990 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
14992 iterate();
14994 return "trtt";
14997 static const HChar *
14998 s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
15000 IRTemp len = newTemp(Ity_I64);
15002 assign(len, mkU64(length));
15003 s390_irgen_TR_EX(len, start1, start2);
15005 return "tr";
15008 static const HChar *
15009 s390_irgen_TRE(UChar r1,UChar r2)
15011 IRTemp src_addr, tab_addr, src_len, test_byte;
15012 src_addr = newTemp(Ity_I64);
15013 tab_addr = newTemp(Ity_I64);
15014 src_len = newTemp(Ity_I64);
15015 test_byte = newTemp(Ity_I8);
15017 assign(src_addr, get_gpr_dw0(r1));
15018 assign(src_len, get_gpr_dw0(r1+1));
15019 assign(tab_addr, get_gpr_dw0(r2));
15020 assign(test_byte, get_gpr_b7(0));
15022 IRTemp op = newTemp(Ity_I8);
15023 IRTemp op1 = newTemp(Ity_I8);
15024 IRTemp result = newTemp(Ity_I64);
15026 /* End of source string? We're done; proceed to next insn */
15027 s390_cc_set_val(0);
15028 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15030 /* Load character from source string and compare with test byte */
15031 assign(op, load(Ity_I8, mkexpr(src_addr)));
15033 s390_cc_set_val(1);
15034 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
15036 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
15037 mkexpr(tab_addr)));
15039 assign(op1, load(Ity_I8, mkexpr(result)));
15041 store(get_gpr_dw0(r1), mkexpr(op1));
15042 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
15043 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
15045 iterate();
15047 return "tre";
15050 static IRExpr *
15051 s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
15053 IRExpr **args, *call;
15054 args = mkIRExprVec_2(srcval, low_surrogate);
15055 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15056 "s390_do_cu21", &s390_do_cu21, args);
15058 /* Nothing is excluded from definedness checking. */
15059 call->Iex.CCall.cee->mcx_mask = 0;
15061 return call;
15064 static const HChar *
15065 s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
15067 IRTemp addr1 = newTemp(Ity_I64);
15068 IRTemp addr2 = newTemp(Ity_I64);
15069 IRTemp len1 = newTemp(Ity_I64);
15070 IRTemp len2 = newTemp(Ity_I64);
15072 assign(addr1, get_gpr_dw0(r1));
15073 assign(addr2, get_gpr_dw0(r2));
15074 assign(len1, get_gpr_dw0(r1 + 1));
15075 assign(len2, get_gpr_dw0(r2 + 1));
15077 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
15078 there are less than 2 bytes left, then the 2nd operand is exhausted
15079 and we're done here. cc = 0 */
15080 s390_cc_set_val(0);
15081 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
15083 /* There are at least two bytes there. Read them. */
15084 IRTemp srcval = newTemp(Ity_I32);
15085 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
15087 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
15088 inside the interval [0xd800 - 0xdbff] */
15089 IRTemp is_high_surrogate = newTemp(Ity_I32);
15090 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
15091 mkU32(1), mkU32(0));
15092 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
15093 mkU32(1), mkU32(0));
15094 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
15096 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
15097 then the 2nd operand is exhausted and we're done here. cc = 0 */
15098 IRExpr *not_enough_bytes =
15099 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
15101 next_insn_if(binop(Iop_CmpEQ32,
15102 binop(Iop_And32, mkexpr(is_high_surrogate),
15103 not_enough_bytes), mkU32(1)));
15105 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
15106 surrogate, read the next two bytes (low surrogate). */
15107 IRTemp low_surrogate = newTemp(Ity_I32);
15108 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
15110 assign(low_surrogate,
15111 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15112 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
15113 mkU32(0))); // any value is fine; it will not be used
15115 /* Call the helper */
15116 IRTemp retval = newTemp(Ity_I64);
15117 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
15118 unop(Iop_32Uto64, mkexpr(low_surrogate))));
15120 /* Before we can test whether the 1st operand is exhausted we need to
15121 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
15122 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
15123 IRExpr *invalid_low_surrogate =
15124 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15126 s390_cc_set_val(2);
15127 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
15130 /* Now test whether the 1st operand is exhausted */
15131 IRTemp num_bytes = newTemp(Ity_I64);
15132 assign(num_bytes, binop(Iop_And64,
15133 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
15134 mkU64(0xff)));
15135 s390_cc_set_val(1);
15136 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15138 /* Extract the bytes to be stored at addr1 */
15139 IRTemp data = newTemp(Ity_I64);
15140 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
15142 /* To store the bytes construct 4 dirty helper calls. The helper calls
15143 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
15144 one of them will be called at runtime. */
15145 UInt i;
15146 for (i = 1; i <= 4; ++i) {
15147 IRDirty *d;
15149 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15150 &s390x_dirtyhelper_CUxy,
15151 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15152 mkexpr(num_bytes)));
15153 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15154 d->mFx = Ifx_Write;
15155 d->mAddr = mkexpr(addr1);
15156 d->mSize = i;
15157 stmt(IRStmt_Dirty(d));
15160 /* Update source address and length */
15161 IRTemp num_src_bytes = newTemp(Ity_I64);
15162 assign(num_src_bytes,
15163 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15164 mkU64(4), mkU64(2)));
15165 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
15166 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
15168 /* Update destination address and length */
15169 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15170 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
15172 iterate();
15174 return "cu21";
15177 static IRExpr *
15178 s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
15180 IRExpr **args, *call;
15181 args = mkIRExprVec_2(srcval, low_surrogate);
15182 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15183 "s390_do_cu24", &s390_do_cu24, args);
15185 /* Nothing is excluded from definedness checking. */
15186 call->Iex.CCall.cee->mcx_mask = 0;
15188 return call;
15191 static const HChar *
15192 s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
15194 IRTemp addr1 = newTemp(Ity_I64);
15195 IRTemp addr2 = newTemp(Ity_I64);
15196 IRTemp len1 = newTemp(Ity_I64);
15197 IRTemp len2 = newTemp(Ity_I64);
15199 assign(addr1, get_gpr_dw0(r1));
15200 assign(addr2, get_gpr_dw0(r2));
15201 assign(len1, get_gpr_dw0(r1 + 1));
15202 assign(len2, get_gpr_dw0(r2 + 1));
15204 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
15205 there are less than 2 bytes left, then the 2nd operand is exhausted
15206 and we're done here. cc = 0 */
15207 s390_cc_set_val(0);
15208 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
15210 /* There are at least two bytes there. Read them. */
15211 IRTemp srcval = newTemp(Ity_I32);
15212 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
15214 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
15215 inside the interval [0xd800 - 0xdbff] */
15216 IRTemp is_high_surrogate = newTemp(Ity_I32);
15217 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
15218 mkU32(1), mkU32(0));
15219 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
15220 mkU32(1), mkU32(0));
15221 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
15223 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
15224 then the 2nd operand is exhausted and we're done here. cc = 0 */
15225 IRExpr *not_enough_bytes =
15226 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
15228 next_insn_if(binop(Iop_CmpEQ32,
15229 binop(Iop_And32, mkexpr(is_high_surrogate),
15230 not_enough_bytes),
15231 mkU32(1)));
15233 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
15234 surrogate, read the next two bytes (low surrogate). */
15235 IRTemp low_surrogate = newTemp(Ity_I32);
15236 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
15238 assign(low_surrogate,
15239 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15240 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
15241 mkU32(0))); // any value is fine; it will not be used
15243 /* Call the helper */
15244 IRTemp retval = newTemp(Ity_I64);
15245 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
15246 unop(Iop_32Uto64, mkexpr(low_surrogate))));
15248 /* Before we can test whether the 1st operand is exhausted we need to
15249 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
15250 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
15251 IRExpr *invalid_low_surrogate =
15252 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15254 s390_cc_set_val(2);
15255 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
15258 /* Now test whether the 1st operand is exhausted */
15259 s390_cc_set_val(1);
15260 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
15262 /* Extract the bytes to be stored at addr1 */
15263 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
15265 store(mkexpr(addr1), data);
15267 /* Update source address and length */
15268 IRTemp num_src_bytes = newTemp(Ity_I64);
15269 assign(num_src_bytes,
15270 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15271 mkU64(4), mkU64(2)));
15272 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
15273 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
15275 /* Update destination address and length */
15276 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
15277 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
15279 iterate();
15281 return "cu24";
15284 static IRExpr *
15285 s390_call_cu42(IRExpr *srcval)
15287 IRExpr **args, *call;
15288 args = mkIRExprVec_1(srcval);
15289 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15290 "s390_do_cu42", &s390_do_cu42, args);
15292 /* Nothing is excluded from definedness checking. */
15293 call->Iex.CCall.cee->mcx_mask = 0;
15295 return call;
15298 static const HChar *
15299 s390_irgen_CU42(UChar r1, UChar r2)
15301 IRTemp addr1 = newTemp(Ity_I64);
15302 IRTemp addr2 = newTemp(Ity_I64);
15303 IRTemp len1 = newTemp(Ity_I64);
15304 IRTemp len2 = newTemp(Ity_I64);
15306 assign(addr1, get_gpr_dw0(r1));
15307 assign(addr2, get_gpr_dw0(r2));
15308 assign(len1, get_gpr_dw0(r1 + 1));
15309 assign(len2, get_gpr_dw0(r2 + 1));
15311 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
15312 there are less than 4 bytes left, then the 2nd operand is exhausted
15313 and we're done here. cc = 0 */
15314 s390_cc_set_val(0);
15315 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
15317 /* Read the 2nd operand. */
15318 IRTemp srcval = newTemp(Ity_I32);
15319 assign(srcval, load(Ity_I32, mkexpr(addr2)));
15321 /* Call the helper */
15322 IRTemp retval = newTemp(Ity_I64);
15323 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
15325 /* If the UTF-32 character was invalid, set cc=2 and we're done.
15326 cc=2 outranks cc=1 (1st operand exhausted) */
15327 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15329 s390_cc_set_val(2);
15330 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
15332 /* Now test whether the 1st operand is exhausted */
15333 IRTemp num_bytes = newTemp(Ity_I64);
15334 assign(num_bytes, binop(Iop_And64,
15335 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
15336 mkU64(0xff)));
15337 s390_cc_set_val(1);
15338 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15340 /* Extract the bytes to be stored at addr1 */
15341 IRTemp data = newTemp(Ity_I64);
15342 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
15344 /* To store the bytes construct 2 dirty helper calls. The helper calls
15345 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
15346 that only one of them will be called at runtime. */
15348 Int i;
15349 for (i = 2; i <= 4; ++i) {
15350 IRDirty *d;
15352 if (i == 3) continue; // skip this one
15354 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15355 &s390x_dirtyhelper_CUxy,
15356 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15357 mkexpr(num_bytes)));
15358 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15359 d->mFx = Ifx_Write;
15360 d->mAddr = mkexpr(addr1);
15361 d->mSize = i;
15362 stmt(IRStmt_Dirty(d));
15365 /* Update source address and length */
15366 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
15367 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
15369 /* Update destination address and length */
15370 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15371 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
15373 iterate();
15375 return "cu42";
15378 static IRExpr *
15379 s390_call_cu41(IRExpr *srcval)
15381 IRExpr **args, *call;
15382 args = mkIRExprVec_1(srcval);
15383 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15384 "s390_do_cu41", &s390_do_cu41, args);
15386 /* Nothing is excluded from definedness checking. */
15387 call->Iex.CCall.cee->mcx_mask = 0;
15389 return call;
15392 static const HChar *
15393 s390_irgen_CU41(UChar r1, UChar r2)
15395 IRTemp addr1 = newTemp(Ity_I64);
15396 IRTemp addr2 = newTemp(Ity_I64);
15397 IRTemp len1 = newTemp(Ity_I64);
15398 IRTemp len2 = newTemp(Ity_I64);
15400 assign(addr1, get_gpr_dw0(r1));
15401 assign(addr2, get_gpr_dw0(r2));
15402 assign(len1, get_gpr_dw0(r1 + 1));
15403 assign(len2, get_gpr_dw0(r2 + 1));
15405 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
15406 there are less than 4 bytes left, then the 2nd operand is exhausted
15407 and we're done here. cc = 0 */
15408 s390_cc_set_val(0);
15409 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
15411 /* Read the 2nd operand. */
15412 IRTemp srcval = newTemp(Ity_I32);
15413 assign(srcval, load(Ity_I32, mkexpr(addr2)));
15415 /* Call the helper */
15416 IRTemp retval = newTemp(Ity_I64);
15417 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
15419 /* If the UTF-32 character was invalid, set cc=2 and we're done.
15420 cc=2 outranks cc=1 (1st operand exhausted) */
15421 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15423 s390_cc_set_val(2);
15424 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
15426 /* Now test whether the 1st operand is exhausted */
15427 IRTemp num_bytes = newTemp(Ity_I64);
15428 assign(num_bytes, binop(Iop_And64,
15429 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
15430 mkU64(0xff)));
15431 s390_cc_set_val(1);
15432 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15434 /* Extract the bytes to be stored at addr1 */
15435 IRTemp data = newTemp(Ity_I64);
15436 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
15438 /* To store the bytes construct 4 dirty helper calls. The helper calls
15439 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
15440 one of them will be called at runtime. */
15441 UInt i;
15442 for (i = 1; i <= 4; ++i) {
15443 IRDirty *d;
15445 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15446 &s390x_dirtyhelper_CUxy,
15447 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15448 mkexpr(num_bytes)));
15449 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15450 d->mFx = Ifx_Write;
15451 d->mAddr = mkexpr(addr1);
15452 d->mSize = i;
15453 stmt(IRStmt_Dirty(d));
15456 /* Update source address and length */
15457 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
15458 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
15460 /* Update destination address and length */
15461 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15462 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
15464 iterate();
15466 return "cu41";
15469 static IRExpr *
15470 s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
15472 IRExpr **args, *call;
15473 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
15474 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
15475 &s390_do_cu12_cu14_helper1, args);
15477 /* Nothing is excluded from definedness checking. */
15478 call->Iex.CCall.cee->mcx_mask = 0;
15480 return call;
15483 static IRExpr *
15484 s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
15485 IRExpr *byte4, IRExpr *stuff)
15487 IRExpr **args, *call;
15488 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
15489 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15490 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
15492 /* Nothing is excluded from definedness checking. */
15493 call->Iex.CCall.cee->mcx_mask = 0;
15495 return call;
15498 static IRExpr *
15499 s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
15500 IRExpr *byte4, IRExpr *stuff)
15502 IRExpr **args, *call;
15503 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
15504 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15505 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
15507 /* Nothing is excluded from definedness checking. */
15508 call->Iex.CCall.cee->mcx_mask = 0;
15510 return call;
15513 static void
15514 s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
15516 IRTemp addr1 = newTemp(Ity_I64);
15517 IRTemp addr2 = newTemp(Ity_I64);
15518 IRTemp len1 = newTemp(Ity_I64);
15519 IRTemp len2 = newTemp(Ity_I64);
15521 assign(addr1, get_gpr_dw0(r1));
15522 assign(addr2, get_gpr_dw0(r2));
15523 assign(len1, get_gpr_dw0(r1 + 1));
15524 assign(len2, get_gpr_dw0(r2 + 1));
15526 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
15528 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
15529 there is less than 1 byte left, then the 2nd operand is exhausted
15530 and we're done here. cc = 0 */
15531 s390_cc_set_val(0);
15532 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
15534 /* There is at least one byte there. Read it. */
15535 IRTemp byte1 = newTemp(Ity_I64);
15536 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
15538 /* Call the helper to get number of bytes and invalid byte indicator */
15539 IRTemp retval1 = newTemp(Ity_I64);
15540 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
15541 mkU64(extended_checking)));
15543 /* Check for invalid 1st byte */
15544 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
15545 s390_cc_set_val(2);
15546 next_insn_if(is_invalid);
15548 /* How many bytes do we have to read? */
15549 IRTemp num_src_bytes = newTemp(Ity_I64);
15550 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
15552 /* Now test whether the 2nd operand is exhausted */
15553 s390_cc_set_val(0);
15554 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
15556 /* Read the remaining bytes */
15557 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
15559 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
15560 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
15561 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
15562 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
15563 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
15564 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
15565 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
15566 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
15567 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
15569 /* Call the helper to get the converted value and invalid byte indicator.
15570 We can pass at most 5 arguments; therefore some encoding is needed
15571 here */
15572 IRExpr *stuff = binop(Iop_Or64,
15573 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
15574 mkU64(extended_checking));
15575 IRTemp retval2 = newTemp(Ity_I64);
15577 if (is_cu12) {
15578 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
15579 byte4, stuff));
15580 } else {
15581 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
15582 byte4, stuff));
15585 /* Check for invalid character */
15586 s390_cc_set_val(2);
15587 is_invalid = unop(Iop_64to1, mkexpr(retval2));
15588 next_insn_if(is_invalid);
15590 /* Now test whether the 1st operand is exhausted */
15591 IRTemp num_bytes = newTemp(Ity_I64);
15592 assign(num_bytes, binop(Iop_And64,
15593 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
15594 mkU64(0xff)));
15595 s390_cc_set_val(1);
15596 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15598 /* Extract the bytes to be stored at addr1 */
15599 IRTemp data = newTemp(Ity_I64);
15600 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
15602 if (is_cu12) {
15603 /* To store the bytes construct 2 dirty helper calls. The helper calls
15604 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
15605 that only one of them will be called at runtime. */
15607 Int i;
15608 for (i = 2; i <= 4; ++i) {
15609 IRDirty *d;
15611 if (i == 3) continue; // skip this one
15613 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15614 &s390x_dirtyhelper_CUxy,
15615 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15616 mkexpr(num_bytes)));
15617 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15618 d->mFx = Ifx_Write;
15619 d->mAddr = mkexpr(addr1);
15620 d->mSize = i;
15621 stmt(IRStmt_Dirty(d));
15623 } else {
15624 // cu14
15625 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
15628 /* Update source address and length */
15629 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
15630 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
15632 /* Update destination address and length */
15633 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15634 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
15636 iterate();
15639 static const HChar *
15640 s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
15642 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
15644 return "cu12";
15647 static const HChar *
15648 s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
15650 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
15652 return "cu14";
15655 static IRExpr *
15656 s390_call_ecag(IRExpr *op2addr)
15658 IRExpr **args, *call;
15660 args = mkIRExprVec_1(op2addr);
15661 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15662 "s390_do_ecag", &s390_do_ecag, args);
15664 /* Nothing is excluded from definedness checking. */
15665 call->Iex.CCall.cee->mcx_mask = 0;
15667 return call;
15670 static const HChar *
15671 s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
15673 if (! s390_host_has_gie) {
15674 emulation_failure(EmFail_S390X_ecag);
15675 } else {
15676 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
15679 return "ecag";
15682 static const HChar *
15683 s390_irgen_VL(UChar v1, IRTemp op2addr)
15685 put_vr_qw(v1, load(Ity_V128, mkexpr(op2addr)));
15687 return "vl";
15690 static const HChar *
15691 s390_irgen_VLR(UChar v1, UChar v2)
15693 put_vr_qw(v1, get_vr_qw(v2));
15695 return "vlr";
15698 static const HChar *
15699 s390_irgen_VST(UChar v1, IRTemp op2addr)
15701 store(mkexpr(op2addr), get_vr_qw(v1));
15703 return "vst";
15706 static const HChar *
15707 s390_irgen_VLREP(UChar v1, IRTemp op2addr, UChar m3)
15709 IRType o2type = s390_vr_get_type(m3);
15710 IRExpr* o2 = load(o2type, mkexpr(op2addr));
15711 s390_vr_fill(v1, o2);
15712 return "vlrep";
15715 static const HChar *
15716 s390_irgen_VLEB(UChar v1, IRTemp op2addr, UChar m3)
15718 IRExpr* o2 = load(Ity_I8, mkexpr(op2addr));
15719 put_vr(v1, Ity_I8, m3, o2);
15721 return "vleb";
15724 static const HChar *
15725 s390_irgen_VLEH(UChar v1, IRTemp op2addr, UChar m3)
15727 IRExpr* o2 = load(Ity_I16, mkexpr(op2addr));
15728 put_vr(v1, Ity_I16, m3, o2);
15730 return "vleh";
15733 static const HChar *
15734 s390_irgen_VLEF(UChar v1, IRTemp op2addr, UChar m3)
15736 IRExpr* o2 = load(Ity_I32, mkexpr(op2addr));
15737 put_vr(v1, Ity_I32, m3, o2);
15739 return "vlef";
15742 static const HChar *
15743 s390_irgen_VLEG(UChar v1, IRTemp op2addr, UChar m3)
15745 IRExpr* o2 = load(Ity_I64, mkexpr(op2addr));
15746 put_vr(v1, Ity_I64, m3, o2);
15748 return "vleg";
15751 static const HChar *
15752 s390_irgen_VLEIB(UChar v1, UShort i2, UChar m3)
15754 IRExpr* o2 = unop(Iop_16to8, mkU16(i2));
15755 put_vr(v1, Ity_I8, m3, o2);
15757 return "vleib";
15760 static const HChar *
15761 s390_irgen_VLEIH(UChar v1, UShort i2, UChar m3)
15763 IRExpr* o2 = mkU16(i2);
15764 put_vr(v1, Ity_I16, m3, o2);
15766 return "vleih";
15769 static const HChar *
15770 s390_irgen_VLEIF(UChar v1, UShort i2, UChar m3)
15772 IRExpr* o2 = unop(Iop_16Sto32, mkU16(i2));
15773 put_vr(v1, Ity_I32, m3, o2);
15775 return "vleif";
15778 static const HChar *
15779 s390_irgen_VLEIG(UChar v1, UShort i2, UChar m3)
15781 IRExpr* o2 = unop(Iop_16Sto64, mkU16(i2));
15782 put_vr(v1, Ity_I64, m3, o2);
15784 return "vleig";
15787 static const HChar *
15788 s390_irgen_VLGV(UChar r1, IRTemp op2addr, UChar v3, UChar m4)
15790 IRType o2type = s390_vr_get_type(m4);
15791 IRExpr* index = unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(0xf)));
15792 IRExpr* o2;
15793 IRExpr* result;
15794 switch (o2type) {
15795 case Ity_I8:
15796 o2 = binop(Iop_GetElem8x16, get_vr_qw(v3), index);
15797 result = unop(Iop_8Uto64, o2);
15798 break;
15799 case Ity_I16:
15800 o2 = binop(Iop_GetElem16x8, get_vr_qw(v3), index);
15801 result = unop(Iop_16Uto64, o2);
15802 break;
15803 case Ity_I32:
15804 o2 = binop(Iop_GetElem32x4, get_vr_qw(v3), index);
15805 result = unop(Iop_32Uto64, o2);
15806 break;
15807 case Ity_I64:
15808 result = binop(Iop_GetElem64x2, get_vr_qw(v3), index);
15809 break;
15810 default:
15811 ppIRType(o2type);
15812 vpanic("s390_irgen_VLGV: unknown o2type");
15815 put_gpr_dw0(r1, result);
15816 return "vlgv";
15819 static const HChar *
15820 s390_irgen_VGBM(UChar v1, UShort i2, UChar m3 __attribute__((unused)))
15822 put_vr_qw(v1, IRExpr_Const(IRConst_V128(i2)));
15824 return "vgbm";
15827 static const HChar *
15828 s390_irgen_VGM(UChar v1, UShort i2, UChar m3)
15830 UChar from = (i2 & 0xff00) >> 8;
15831 UChar to = (i2 & 0x00ff);
15832 ULong value = 0UL;
15833 IRType type = s390_vr_get_type(m3);
15834 vassert(from <= to);
15836 UChar maxIndex = 0;
15837 switch (type) {
15838 case Ity_I8:
15839 maxIndex = 7;
15840 break;
15841 case Ity_I16:
15842 maxIndex = 15;
15843 break;
15844 case Ity_I32:
15845 maxIndex = 31;
15846 break;
15847 case Ity_I64:
15848 maxIndex = 63;
15849 break;
15850 default:
15851 vpanic("s390_irgen_VGM: unknown type");
15854 for(UChar index = from; index <= to; index++) {
15855 value |= (1ULL << (maxIndex - index));
15858 IRExpr *fillValue;
15859 switch (type) {
15860 case Ity_I8:
15861 fillValue = mkU8(value);
15862 break;
15863 case Ity_I16:
15864 fillValue = mkU16(value);
15865 break;
15866 case Ity_I32:
15867 fillValue = mkU32(value);
15868 break;
15869 case Ity_I64:
15870 fillValue = mkU64(value);
15871 break;
15872 default:
15873 vpanic("s390_irgen_VGM: unknown type");
15876 s390_vr_fill(v1, fillValue);
15877 return "vgm";
15880 static const HChar *
15881 s390_irgen_VLLEZ(UChar v1, IRTemp op2addr, UChar m3)
15883 IRType type = s390_vr_get_type(m3);
15884 IRExpr* op2 = load(type, mkexpr(op2addr));
15885 IRExpr* op2as64bit;
15886 switch (type) {
15887 case Ity_I8:
15888 op2as64bit = unop(Iop_8Uto64, op2);
15889 break;
15890 case Ity_I16:
15891 op2as64bit = unop(Iop_16Uto64, op2);
15892 break;
15893 case Ity_I32:
15894 op2as64bit = unop(Iop_32Uto64, op2);
15895 break;
15896 case Ity_I64:
15897 op2as64bit = op2;
15898 break;
15899 default:
15900 vpanic("s390_irgen_VLLEZ: unknown type");
15903 put_vr_dw0(v1, op2as64bit);
15904 put_vr_dw1(v1, mkU64(0));
15905 return "vllez";
15908 static const HChar *
15909 s390_irgen_VGEF(UChar v1, IRTemp op2addr, UChar m3)
15911 put_vr(v1, Ity_I32, m3, load(Ity_I32, mkexpr(op2addr)));
15912 return "vgef";
15915 static const HChar *
15916 s390_irgen_VGEG(UChar v1, IRTemp op2addr, UChar m3)
15918 put_vr(v1, Ity_I64, m3, load(Ity_I64, mkexpr(op2addr)));
15919 return "vgeg";
15922 static const HChar *
15923 s390_irgen_VLM(UChar v1, IRTemp op2addr, UChar v3)
15925 IRExpr* current = mkexpr(op2addr);
15926 vassert(v3 >= v1);
15927 vassert(v3 - v1 <= 16);
15929 for(UChar vr = v1; vr <= v3; vr++) {
15930 IRExpr* next = binop(Iop_Add64, current, mkU64(16));
15931 put_vr_qw(vr, load(Ity_V128, current));
15932 current = next;
15935 return "vlm";
15938 static const HChar *
15939 s390_irgen_VLVGP(UChar v1, UChar r2, UChar r3)
15941 put_vr_qw(v1, binop(Iop_64HLtoV128, get_gpr_dw0(r2), get_gpr_dw0(r3)));
15943 return "vlvgp";
15946 static const HChar *
15947 s390_irgen_VLVG(UChar v1, IRTemp op2addr, UChar r3, UChar m4)
15949 IRType type = s390_vr_get_type(m4);
15950 IRExpr* index = unop(Iop_64to8, mkexpr(op2addr));
15951 IRExpr* vr = get_vr_qw(v1);
15952 IRExpr* operand;
15953 switch (type) {
15954 case Ity_I8:
15955 operand = unop(Iop_64to8, get_gpr_dw0(r3));
15956 put_vr_qw(v1, triop(Iop_SetElem8x16, vr, index, operand));
15957 break;
15958 case Ity_I16:
15959 operand = unop(Iop_64to16, get_gpr_dw0(r3));
15960 put_vr_qw(v1, triop(Iop_SetElem16x8, vr, index, operand));
15961 break;
15962 case Ity_I32:
15963 operand = unop(Iop_64to32, get_gpr_dw0(r3));
15964 put_vr_qw(v1, triop(Iop_SetElem32x4, vr, index, operand));
15965 break;
15966 case Ity_I64:
15967 operand = get_gpr_dw0(r3);
15968 put_vr_qw(v1, triop(Iop_SetElem64x2, vr, index, operand));
15969 break;
15970 default:
15971 vpanic("s390_irgen_VLVG: unknown type");
15974 return "vlvg";
15977 static const HChar *
15978 s390_irgen_VMRH(UChar v1, UChar v2, UChar v3, UChar m4)
15980 const IROp ops[] = { Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
15981 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2 };
15982 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
15983 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
15985 return "vmrh";
15988 static const HChar *
15989 s390_irgen_VMRL(UChar v1, UChar v2, UChar v3, UChar m4)
15991 const IROp ops[] = { Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
15992 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2 };
15993 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
15994 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
15996 return "vmrl";
15999 static const HChar *
16000 s390_irgen_VPK(UChar v1, UChar v2, UChar v3, UChar m4)
16002 const IROp ops[] = { Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
16003 Iop_NarrowBin64to32x4 };
16004 Char index = m4 - 1;
16005 vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0])));
16006 put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3)));
16007 return "vpk";
16010 static const HChar *
16011 s390_irgen_VPERM(UChar v1, UChar v2, UChar v3, UChar v4)
16013 put_vr_qw(v1, triop(Iop_Perm8x16x2,
16014 get_vr_qw(v2), get_vr_qw(v3), get_vr_qw(v4)));
16016 return "vperm";
16019 static const HChar *
16020 s390_irgen_VSCEF(UChar v1, IRTemp op2addr, UChar m3)
16022 store(mkexpr(op2addr), get_vr(v1, Ity_I32, m3));
16023 return "vscef";
16026 static const HChar *
16027 s390_irgen_VSCEG(UChar v1, IRTemp op2addr, UChar m3)
16029 store(mkexpr(op2addr), get_vr(v1, Ity_I64, m3));
16030 return "vsceg";
16033 static const HChar *
16034 s390_irgen_VPDI(UChar v1, UChar v2, UChar v3, UChar m4)
16036 /* Theese bits are reserved by specification */
16037 vassert((m4 & 2) == 0);
16038 vassert((m4 & 8) == 0);
16040 if((m4 & 4) != 0)
16041 put_vr_dw0(v1, get_vr_dw1(v2));
16042 else
16043 put_vr_dw0(v1, get_vr_dw0(v2));
16045 if((m4 & 1) != 0)
16046 put_vr_dw1(v1, get_vr_dw1(v3));
16047 else
16048 put_vr_dw1(v1, get_vr_dw0(v3));
16050 return "vpdi";
16053 static const HChar *
16054 s390_irgen_VSEG(UChar v1, UChar v2, UChar m3)
16056 IRType type = s390_vr_get_type(m3);
16057 switch(type) {
16058 case Ity_I8:
16059 put_vr_dw0(v1, unop(Iop_8Sto64, get_vr_b7(v2)));
16060 put_vr_dw1(v1, unop(Iop_8Sto64, get_vr_b15(v2)));
16061 break;
16062 case Ity_I16:
16063 put_vr_dw0(v1, unop(Iop_16Sto64, get_vr_hw3(v2)));
16064 put_vr_dw1(v1, unop(Iop_16Sto64, get_vr_hw7(v2)));
16065 break;
16066 case Ity_I32:
16067 put_vr_dw0(v1, unop(Iop_32Sto64, get_vr_w1(v2)));
16068 put_vr_dw1(v1, unop(Iop_32Sto64, get_vr_w3(v2)));
16069 break;
16070 default:
16071 ppIRType(type);
16072 vpanic("s390_irgen_VSEG: unknown type");
16075 return "vseg";
16078 static const HChar *
16079 s390_irgen_VSTEB(UChar v1, IRTemp op2addr, UChar m3)
16081 store(mkexpr(op2addr), get_vr(v1, Ity_I8, m3));
16083 return "vsteb";
16086 static const HChar *
16087 s390_irgen_VSTEH(UChar v1, IRTemp op2addr, UChar m3)
16089 store(mkexpr(op2addr), get_vr(v1, Ity_I16, m3));
16091 return "vsteh";
16094 static const HChar *
16095 s390_irgen_VSTEF(UChar v1, IRTemp op2addr, UChar m3)
16097 store(mkexpr(op2addr), get_vr(v1, Ity_I32, m3));
16099 return "vstef";
16102 static const HChar *
16103 s390_irgen_VSTEG(UChar v1, IRTemp op2addr, UChar m3)
16105 store(mkexpr(op2addr), get_vr(v1, Ity_I64, m3));
16107 return "vsteg";
16110 static const HChar *
16111 s390_irgen_VSTM(UChar v1, IRTemp op2addr, UChar v3)
16113 IRExpr* current = mkexpr(op2addr);
16114 vassert(v3 >= v1);
16115 vassert(v3 - v1 <= 16);
16117 for(UChar vr = v1; vr <= v3; vr++) {
16118 IRExpr* next = binop(Iop_Add64, current, mkU64(16));
16119 store(current, get_vr_qw(vr));
16120 current = next;
16123 return "vstm";
16126 static const HChar *
16127 s390_irgen_VUPH(UChar v1, UChar v2, UChar m3)
16129 const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 };
16130 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16131 put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2)));
16133 return "vuph";
16136 static const HChar *
16137 s390_irgen_VUPLH(UChar v1, UChar v2, UChar m3)
16139 const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 };
16140 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16141 put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2)));
16142 return "vuplh";
16145 static const HChar *
16146 s390_irgen_VUPL(UChar v1, UChar v2, UChar m3)
16148 const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 };
16149 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16150 put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2)));
16152 return "vupl";
16155 static const HChar *
16156 s390_irgen_VUPLL(UChar v1, UChar v2, UChar m3)
16158 const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 };
16159 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16160 put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2)));
16162 return "vupll";
16165 static const HChar *
16166 s390_irgen_VREP(UChar v1, UChar v3, UShort i2, UChar m4)
16168 IRType type = s390_vr_get_type(m4);
16169 IRExpr* arg = get_vr(v3, type, i2);
16170 s390_vr_fill(v1, arg);
16172 return "vrep";
16175 static const HChar *
16176 s390_irgen_VREPI(UChar v1, UShort i2, UChar m3)
16178 IRType type = s390_vr_get_type(m3);
16179 IRExpr *value;
16180 switch (type) {
16181 case Ity_I8:
16182 value = mkU8((UChar)i2);
16183 break;
16184 case Ity_I16:
16185 value = mkU16(i2);
16186 break;
16187 case Ity_I32:
16188 value = unop(Iop_16Sto32, mkU16(i2));
16189 break;
16190 case Ity_I64:
16191 value = unop(Iop_16Sto64, mkU16(i2));
16192 break;
16193 default:
16194 ppIRType(type);
16195 vpanic("s390_irgen_VREPI: unknown type");
16197 s390_vr_fill(v1, value);
16199 return "vrepi";
16202 static const HChar *
16203 s390_irgen_VPKS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16205 if (!s390_vr_is_cs_set(m5)) {
16206 const IROp ops[] = { Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
16207 Iop_QNarrowBin64Sto32Sx4 };
16208 Char index = m4 - 1;
16209 vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0])));
16210 put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3)));
16212 } else {
16213 IRDirty* d;
16214 IRTemp cc = newTemp(Ity_I64);
16216 s390x_vec_op_details_t details = { .serialized = 0ULL };
16217 details.op = S390_VEC_OP_VPKS;
16218 details.v1 = v1;
16219 details.v2 = v2;
16220 details.v3 = v3;
16221 details.m4 = m4;
16222 details.m5 = m5;
16224 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16225 &s390x_dirtyhelper_vec_op,
16226 mkIRExprVec_2(IRExpr_GSPTR(),
16227 mkU64(details.serialized)));
16229 d->nFxState = 3;
16230 vex_bzero(&d->fxState, sizeof(d->fxState));
16231 d->fxState[0].fx = Ifx_Read;
16232 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16233 d->fxState[0].size = sizeof(V128);
16234 d->fxState[1].fx = Ifx_Read;
16235 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
16236 d->fxState[1].size = sizeof(V128);
16237 d->fxState[2].fx = Ifx_Write;
16238 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16239 d->fxState[2].size = sizeof(V128);
16241 stmt(IRStmt_Dirty(d));
16242 s390_cc_set(cc);
16245 return "vpks";
16248 static const HChar *
16249 s390_irgen_VPKLS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16251 if (!s390_vr_is_cs_set(m5)) {
16252 const IROp ops[] = { Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
16253 Iop_QNarrowBin64Uto32Ux4 };
16254 Char index = m4 - 1;
16255 vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0])));
16256 put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3)));
16258 } else {
16259 IRDirty* d;
16260 IRTemp cc = newTemp(Ity_I64);
16262 s390x_vec_op_details_t details = { .serialized = 0ULL };
16263 details.op = S390_VEC_OP_VPKLS;
16264 details.v1 = v1;
16265 details.v2 = v2;
16266 details.v3 = v3;
16267 details.m4 = m4;
16268 details.m5 = m5;
16270 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16271 &s390x_dirtyhelper_vec_op,
16272 mkIRExprVec_2(IRExpr_GSPTR(),
16273 mkU64(details.serialized)));
16275 d->nFxState = 3;
16276 vex_bzero(&d->fxState, sizeof(d->fxState));
16277 d->fxState[0].fx = Ifx_Read;
16278 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16279 d->fxState[0].size = sizeof(V128);
16280 d->fxState[1].fx = Ifx_Read;
16281 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
16282 d->fxState[1].size = sizeof(V128);
16283 d->fxState[2].fx = Ifx_Write;
16284 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16285 d->fxState[2].size = sizeof(V128);
16287 stmt(IRStmt_Dirty(d));
16288 s390_cc_set(cc);
16291 return "vpkls";
16294 static const HChar *
16295 s390_irgen_VSEL(UChar v1, UChar v2, UChar v3, UChar v4)
16297 IRExpr* vIfTrue = get_vr_qw(v2);
16298 IRExpr* vIfFalse = get_vr_qw(v3);
16299 IRExpr* vCond = get_vr_qw(v4);
16301 put_vr_qw(v1, s390_V128_bitwiseITE(vCond, vIfTrue, vIfFalse));
16302 return "vsel";
16305 static const HChar *
16306 s390_irgen_VLBB(UChar v1, IRTemp addr, UChar m3)
16308 IRExpr* maxIndex = binop(Iop_Sub32,
16309 s390_getCountToBlockBoundary(addr, m3),
16310 mkU32(1));
16312 s390_vr_loadWithLength(v1, addr, maxIndex);
16314 return "vlbb";
16317 static const HChar *
16318 s390_irgen_VLL(UChar v1, IRTemp addr, UChar r3)
16320 s390_vr_loadWithLength(v1, addr, get_gpr_w1(r3));
16322 return "vll";
16325 static const HChar *
16326 s390_irgen_VSTL(UChar v1, IRTemp addr, UChar r3)
16328 IRTemp counter = newTemp(Ity_I64);
16329 IRTemp maxIndexToStore = newTemp(Ity_I64);
16330 IRTemp gpr3 = newTemp(Ity_I64);
16332 assign(gpr3, unop(Iop_32Uto64, get_gpr_w1(r3)));
16333 assign(maxIndexToStore, mkite(binop(Iop_CmpLE64U,
16334 mkexpr(gpr3),
16335 mkU64(16)
16337 mkexpr(gpr3),
16338 mkU64(16)
16342 assign(counter, get_counter_dw0());
16344 store(binop(Iop_Add64, mkexpr(addr), mkexpr(counter)),
16345 binop(Iop_GetElem8x16, get_vr_qw(v1), unop(Iop_64to8, mkexpr(counter))));
16347 /* Check for end of field */
16348 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
16349 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(maxIndexToStore)));
16350 put_counter_dw0(mkU64(0));
16352 return "vstl";
16355 static const HChar *
16356 s390_irgen_VX(UChar v1, UChar v2, UChar v3)
16358 put_vr_qw(v1, binop(Iop_XorV128, get_vr_qw(v2), get_vr_qw(v3)));
16360 return "vx";
16363 static const HChar *
16364 s390_irgen_VN(UChar v1, UChar v2, UChar v3)
16366 put_vr_qw(v1, binop(Iop_AndV128, get_vr_qw(v2), get_vr_qw(v3)));
16368 return "vn";
16371 static const HChar *
16372 s390_irgen_VO(UChar v1, UChar v2, UChar v3)
16374 put_vr_qw(v1, binop(Iop_OrV128, get_vr_qw(v2), get_vr_qw(v3)));
16376 return "vo";
16379 static const HChar *
16380 s390_irgen_VNO(UChar v1, UChar v2, UChar v3)
16382 put_vr_qw(v1, unop(Iop_NotV128,
16383 binop(Iop_OrV128, get_vr_qw(v2), get_vr_qw(v3))));
16385 return "vno";
16388 static const HChar *
16389 s390_irgen_LZRF(UChar r1, IRTemp op2addr)
16391 IRTemp op2 = newTemp(Ity_I32);
16393 assign(op2, binop(Iop_And32, load(Ity_I32, mkexpr(op2addr)), mkU32(0xffffff00)));
16394 put_gpr_w1(r1, mkexpr(op2));
16396 return "lzrf";
16399 static const HChar *
16400 s390_irgen_LZRG(UChar r1, IRTemp op2addr)
16402 IRTemp op2 = newTemp(Ity_I64);
16404 assign(op2, binop(Iop_And64, load(Ity_I64, mkexpr(op2addr)), mkU64(0xffffffffffffff00UL)));
16405 put_gpr_dw0(r1, mkexpr(op2));
16407 return "lzrg";
16410 static const HChar *
16411 s390_irgen_LLZRGF(UChar r1, IRTemp op2addr)
16413 IRTemp op2 = newTemp(Ity_I32);
16415 assign(op2, binop(Iop_And32, load(Ity_I32, mkexpr(op2addr)), mkU32(0xffffff00)));
16416 put_gpr_w1(r1, mkexpr(op2));
16417 put_gpr_w0(r1, mkU32(0));
16419 return "llzrgf";
16422 static const HChar *
16423 s390_irgen_LOCFH(UChar r1, IRTemp op2addr)
16425 /* condition is checked in format handler */
16426 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
16428 return "locfh";
16431 static const HChar *
16432 s390_irgen_LOCFHR(UChar m3, UChar r1, UChar r2)
16434 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
16435 put_gpr_w0(r1, get_gpr_w0(r2));
16437 return "locfhr";
16440 static const HChar *
16441 s390_irgen_LOCHHI(UChar r1, UChar m3, UShort i2, UChar unused)
16443 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
16444 put_gpr_w0(r1, mkU32((UInt)(Int)(Short)i2));
16446 return "lochhi";
16449 static const HChar *
16450 s390_irgen_LOCHI(UChar r1, UChar m3, UShort i2, UChar unused)
16452 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
16453 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
16455 return "lochi";
16458 static const HChar *
16459 s390_irgen_LOCGHI(UChar r1, UChar m3, UShort i2, UChar unused)
16461 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
16462 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
16464 return "locghi";
16467 static const HChar *
16468 s390_irgen_STOCFH(UChar r1, IRTemp op2addr)
16470 /* condition is checked in format handler */
16471 store(mkexpr(op2addr), get_gpr_w1(r1));
16473 return "stocfh";
16476 static const HChar *
16477 s390_irgen_LCBB(UChar r1, IRTemp op2addr, UChar m3)
16479 IRTemp op2 = newTemp(Ity_I32);
16480 assign(op2, s390_getCountToBlockBoundary(op2addr, m3));
16481 put_gpr_w1(r1, mkexpr(op2));
16483 IRExpr* cc = mkite(binop(Iop_CmpEQ32, mkexpr(op2), mkU32(16)), mkU64(0), mkU64(3));
16484 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), cc, mkU64(0), mkU64(0));
16486 return "lcbb";
16489 /* Regarding the use of
16490 // Dummy helper which is used to signal VEX library that memory was loaded
16491 sha512_loadparam
16492 = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_PPNO_sha512_load_param_block",
16493 &s390x_dirtyhelper_PPNO_sha512_load_param_block,
16494 mkIRExprVec_0());
16496 in the following function (s390_irgen_PPNO). This is a workaround to get
16497 around the fact that IRDirty annotations cannot indicate two memory side
16498 effects, which are unfortunately necessary here. It will possibly lead to
16499 losing undefinedness (undefinedness in some inputs might not be propagated
16500 to the outputs as it shouod, in Memcheck). The correct fix would be to
16501 extend IRDirty to represent two memory side effects, but that's quite a bit
16502 of work.
16504 Here's a summary of what this insn does.
16506 // getReg(RegisterNumber n) returns the value of GPR number 'n'
16508 // reg1 and reg2 are even
16509 void ppno(RegisterNumber reg1, RegisterNumber reg2) {
16511 switch(getReg(0)) {
16512 case 0x0:
16513 // Query mode, ignore reg1 and reg2
16514 // Write 16 bytes at getReg(1)
16515 break;
16517 case 0x3:
16518 // SHA-512 generate mode, ignore reg2
16520 // Read 240 bytes at getReg(1)
16521 // Write getReg(reg1 + 1) bytes at getReg(reg1)
16522 // Write some of 240 bytes starting at getReg(1)
16523 break;
16525 case 0x83:
16526 // SHA-512 seed mode, ignore reg1
16528 // Read some of 240 bytes starting at getReg(1)
16529 // Read getReg(reg2 + 1) bytes at getReg(reg2)
16530 // Write 240 bytes at getReg(1)
16531 break;
16533 default:
16534 // Specification exception, abort execution.
16538 /* Also known as "prno"
16539 If you implement new functions please don't forget to update
16540 "s390x_dirtyhelper_PPNO_query" function.
16542 static const HChar *
16543 s390_irgen_PPNO(UChar r1, UChar r2)
16545 if (!s390_host_has_msa5) {
16546 emulation_failure(EmFail_S390X_ppno);
16547 return "ppno";
16550 /* Theese conditions lead to specification exception */
16551 vassert(r1 % 2 == 0);
16552 vassert(r2 % 2 == 0);
16553 vassert((r1 != 0) && (r2 != 0));
16555 IRDirty *query, *sha512_gen, *sha512_seed, *sha512_loadparam;
16556 IRTemp gpr1num = newTemp(Ity_I64);
16557 IRTemp gpr2num = newTemp(Ity_I64);
16559 IRTemp funcCode = newTemp(Ity_I8);
16560 IRTemp is_query = newTemp(Ity_I1);
16561 IRTemp is_sha512_gen = newTemp(Ity_I1);
16562 IRTemp is_sha512_seed = newTemp(Ity_I1);
16563 IRTemp is_sha512 = newTemp(Ity_I1);
16565 assign(funcCode, unop(Iop_64to8, binop(Iop_And64, get_gpr_dw0(0),
16566 mkU64(0xffULL))));
16567 assign(gpr1num, mkU64(r1));
16568 assign(gpr2num, mkU64(r2));
16570 assign(is_query, binop(Iop_CmpEQ8, mkexpr(funcCode), mkU8(S390_PPNO_QUERY)));
16571 assign(is_sha512_gen, binop(Iop_CmpEQ8, mkexpr(funcCode),
16572 mkU8(S390_PPNO_SHA512_GEN)));
16573 assign(is_sha512_seed, binop(Iop_CmpEQ8, mkexpr(funcCode),
16574 mkU8(S390_PPNO_SHA512_SEED)));
16575 assign(is_sha512, binop(Iop_CmpEQ8,
16576 mkU8(S390_PPNO_SHA512_GEN),
16577 binop(Iop_And8,
16578 mkexpr(funcCode),
16579 mkU8(S390_PPNO_SHA512_GEN)
16583 query = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_PPNO_query",
16584 &s390x_dirtyhelper_PPNO_query,
16585 mkIRExprVec_3(IRExpr_GSPTR(), mkexpr(gpr1num),
16586 mkexpr(gpr2num)));
16587 query->guard = mkexpr(is_query);
16588 query->nFxState = 1;
16589 vex_bzero(&query->fxState, sizeof(query->fxState));
16590 query->fxState[0].fx = Ifx_Read;
16591 query->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
16592 query->fxState[0].size = 2 * sizeof(ULong); /* gpr0 and gpr1 are read */
16593 query->mAddr = get_gpr_dw0(1);
16594 query->mSize = S390_PPNO_PARAM_BLOCK_SIZE_QUERY;
16595 query->mFx = Ifx_Write;
16597 IRTemp gen_cc = newTemp(Ity_I64);
16598 sha512_gen = unsafeIRDirty_1_N(gen_cc, 0, "s390x_dirtyhelper_PPNO_sha512",
16599 &s390x_dirtyhelper_PPNO_sha512,
16600 mkIRExprVec_3(IRExpr_GSPTR(), mkexpr(gpr1num),
16601 mkexpr(gpr2num)));
16602 sha512_gen->guard = mkexpr(is_sha512_gen);
16603 sha512_gen->nFxState = 3;
16604 vex_bzero(&sha512_gen->fxState, sizeof(sha512_gen->fxState));
16605 sha512_gen->fxState[0].fx = Ifx_Read;
16606 sha512_gen->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
16607 sha512_gen->fxState[0].size = 2 * sizeof(ULong); /* gpr0 and gpr1 are read */
16608 sha512_gen->fxState[1].fx = Ifx_Read;
16609 sha512_gen->fxState[1].offset = S390X_GUEST_OFFSET(guest_r0) + r1 * sizeof(ULong);
16610 sha512_gen->fxState[1].size = sizeof(ULong);
16611 sha512_gen->fxState[2].fx = Ifx_Modify;
16612 sha512_gen->fxState[2].offset = S390X_GUEST_OFFSET(guest_r0) + (r1 + 1) * sizeof(ULong);
16613 sha512_gen->fxState[2].size = sizeof(ULong);
16614 sha512_gen->mAddr = get_gpr_dw0(r1);
16615 sha512_gen->mSize = S390_PPNO_MAX_SIZE_SHA512_GEN;
16616 sha512_gen->mFx = Ifx_Write;
16618 IRTemp unused = newTemp(Ity_I64);
16619 sha512_seed = unsafeIRDirty_1_N(unused, 0, "s390x_dirtyhelper_PPNO_sha512",
16620 &s390x_dirtyhelper_PPNO_sha512,
16621 mkIRExprVec_3(IRExpr_GSPTR(), mkexpr(gpr1num),
16622 mkexpr(gpr2num)));
16623 sha512_seed->guard = mkexpr(is_sha512_seed);
16624 sha512_seed->nFxState = 2;
16625 vex_bzero(&sha512_seed->fxState, sizeof(sha512_seed->fxState));
16626 sha512_seed->fxState[0].fx = Ifx_Read;
16627 sha512_seed->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
16628 sha512_seed->fxState[0].size = 2 * sizeof(ULong); /* gpr0 and gpr1 are read */
16629 sha512_seed->fxState[1].fx = Ifx_Read;
16630 sha512_seed->fxState[1].offset = S390X_GUEST_OFFSET(guest_r0) + r2 * sizeof(ULong);
16631 sha512_seed->fxState[1].size = 2 * sizeof(ULong); /* r2 and r2 + 1 are read */
16632 sha512_seed->mAddr = get_gpr_dw0(r2);
16633 sha512_seed->mSize = S390_PPNO_MAX_SIZE_SHA512_SEED;
16634 sha512_seed->mFx = Ifx_Write;
16636 /* Dummy helper which is used to signal VEX library that memory was loaded */
16637 sha512_loadparam =
16638 unsafeIRDirty_0_N(0, "s390x_dirtyhelper_PPNO_sha512_load_param_block",
16639 &s390x_dirtyhelper_PPNO_sha512_load_param_block,
16640 mkIRExprVec_0());
16641 sha512_loadparam->guard = mkexpr(is_sha512);
16642 sha512_loadparam->nFxState = 0;
16643 vex_bzero(&sha512_loadparam->fxState, sizeof(sha512_loadparam->fxState));
16644 sha512_loadparam->mAddr = get_gpr_dw0(1);
16645 sha512_loadparam->mSize = S390_PPNO_PARAM_BLOCK_SIZE_SHA512;
16646 sha512_loadparam->mFx = Ifx_Read;
16648 IRDirty* sha512_saveparam =
16649 unsafeIRDirty_0_N(0, "s390x_dirtyhelper_PPNO_sha512_save_param_block",
16650 &s390x_dirtyhelper_PPNO_sha512_load_param_block,
16651 mkIRExprVec_0());
16652 sha512_saveparam->guard = mkexpr(is_sha512);
16653 sha512_saveparam->nFxState = 0;
16654 vex_bzero(&sha512_saveparam->fxState, sizeof(sha512_saveparam->fxState));
16655 sha512_saveparam->mAddr = get_gpr_dw0(1);
16656 sha512_saveparam->mSize = S390_PPNO_PARAM_BLOCK_SIZE_SHA512;
16657 sha512_saveparam->mFx = Ifx_Write;
16659 stmt(IRStmt_Dirty(query));
16660 stmt(IRStmt_Dirty(sha512_loadparam));
16661 stmt(IRStmt_Dirty(sha512_gen));
16662 stmt(IRStmt_Dirty(sha512_seed));
16663 stmt(IRStmt_Dirty(sha512_saveparam));
16665 IRTemp cc = newTemp(Ity_I64);
16666 assign(cc,
16667 mkite(mkexpr(is_sha512_gen),
16668 mkexpr(gen_cc),
16669 mkU64(0)
16673 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
16675 return "ppno";
16678 static const HChar *
16679 s390_irgen_VFAE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16681 IRDirty* d;
16682 IRTemp cc = newTemp(Ity_I64);
16684 /* Check for specification exception */
16685 vassert(m4 < 3);
16687 s390x_vec_op_details_t details = { .serialized = 0ULL };
16688 details.op = S390_VEC_OP_VFAE;
16689 details.v1 = v1;
16690 details.v2 = v2;
16691 details.v3 = v3;
16692 details.m4 = m4;
16693 details.m5 = m5;
16695 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16696 &s390x_dirtyhelper_vec_op,
16697 mkIRExprVec_2(IRExpr_GSPTR(),
16698 mkU64(details.serialized)));
16700 d->nFxState = 3;
16701 vex_bzero(&d->fxState, sizeof(d->fxState));
16702 d->fxState[0].fx = Ifx_Read;
16703 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16704 d->fxState[0].size = sizeof(V128);
16705 d->fxState[1].fx = Ifx_Read;
16706 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
16707 d->fxState[1].size = sizeof(V128);
16708 d->fxState[2].fx = Ifx_Write;
16709 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16710 d->fxState[2].size = sizeof(V128);
16712 stmt(IRStmt_Dirty(d));
16714 if (s390_vr_is_cs_set(m5)) {
16715 s390_cc_set(cc);
16718 return "vfae";
16721 static const HChar *
16722 s390_irgen_VFEE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16724 IRDirty* d;
16725 IRTemp cc = newTemp(Ity_I64);
16727 /* Check for specification exception */
16728 vassert(m4 < 3);
16729 vassert((m5 & 0b1100) == 0);
16731 s390x_vec_op_details_t details = { .serialized = 0ULL };
16732 details.op = S390_VEC_OP_VFEE;
16733 details.v1 = v1;
16734 details.v2 = v2;
16735 details.v3 = v3;
16736 details.m4 = m4;
16737 details.m5 = m5;
16739 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16740 &s390x_dirtyhelper_vec_op,
16741 mkIRExprVec_2(IRExpr_GSPTR(),
16742 mkU64(details.serialized)));
16744 d->nFxState = 3;
16745 vex_bzero(&d->fxState, sizeof(d->fxState));
16746 d->fxState[0].fx = Ifx_Read;
16747 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16748 d->fxState[0].size = sizeof(V128);
16749 d->fxState[1].fx = Ifx_Read;
16750 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
16751 d->fxState[1].size = sizeof(V128);
16752 d->fxState[2].fx = Ifx_Write;
16753 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16754 d->fxState[2].size = sizeof(V128);
16756 stmt(IRStmt_Dirty(d));
16758 if (s390_vr_is_cs_set(m5)) {
16759 s390_cc_set(cc);
16762 return "vfee";
16765 static const HChar *
16766 s390_irgen_VFENE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16768 const Bool negateComparison = True;
16769 const IRType type = s390_vr_get_type(m4);
16771 /* Check for specification exception */
16772 vassert(m4 < 3);
16773 vassert((m5 & 0b1100) == 0);
16775 static const IROp elementGetters[] = {
16776 Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4
16778 IROp getter = elementGetters[m4];
16780 static const IROp elementComparators[] = {
16781 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32
16783 IROp comparator = elementComparators[m4];
16785 static const IROp resultConverter[] = {Iop_64to8, Iop_64to16, Iop_64to32};
16786 IROp converter = resultConverter[m4];
16788 IRTemp isZeroElem;
16790 IRTemp counter = newTemp(Ity_I64);
16791 assign(counter, get_counter_dw0());
16793 IRTemp arg1 = newTemp(type);
16794 assign(arg1, binop(getter, get_vr_qw(v2), unop(Iop_64to8, mkexpr(counter))));
16795 IRTemp arg2 = newTemp(type);
16796 assign(arg2, binop(getter, get_vr_qw(v3), unop(Iop_64to8, mkexpr(counter))));
16798 IRTemp isGoodPair = newTemp(Ity_I1);
16799 if(negateComparison) {
16800 assign(isGoodPair, unop(Iop_Not1, binop(comparator, mkexpr(arg1),
16801 mkexpr(arg2))));
16802 } else {
16803 assign(isGoodPair, binop(comparator, mkexpr(arg1), mkexpr(arg2)));
16806 if(s390_vr_is_zs_set(m5)) {
16807 isZeroElem = newTemp(Ity_I1);
16808 assign(isZeroElem, binop(comparator, mkexpr(arg1),
16809 unop(converter, mkU64(0))));
16812 static const UChar invalidIndices[] = {16, 8, 4};
16813 const UChar invalidIndex = invalidIndices[m4];
16814 IRTemp endOfVectorIsReached = newTemp(Ity_I1);
16815 assign(endOfVectorIsReached, binop(Iop_CmpEQ64, mkexpr(counter),
16816 mkU64(invalidIndex)));
16818 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
16819 IRExpr* shouldBreak = binop(Iop_Or32,
16820 unop(Iop_1Uto32, mkexpr(isGoodPair)),
16821 unop(Iop_1Uto32, mkexpr(endOfVectorIsReached))
16823 if(s390_vr_is_zs_set(m5)) {
16824 shouldBreak = binop(Iop_Or32,
16825 shouldBreak,
16826 unop(Iop_1Uto32, mkexpr(isZeroElem)));
16828 iterate_if(binop(Iop_CmpEQ32, shouldBreak, mkU32(0)));
16830 IRExpr* foundIndex = binop(Iop_Sub64, get_counter_dw0(), mkU64(1));
16831 if(m4 > 0) {
16832 /* We should return index of byte but we found index of element in
16833 general case.
16834 if byte elem (m4 == 0) then indexOfByte = indexOfElement
16835 if halfword elem (m4 == 1) then indexOfByte = 2 * indexOfElement
16836 = indexOfElement << 1
16837 if word elem (m4 == 2) then indexOfByte = 4 * indexOfElement
16838 = indexOfElement << 2
16840 foundIndex = binop(Iop_Shl64, foundIndex, mkU8(m4));
16843 IRTemp result = newTemp(Ity_I64);
16844 assign(result, mkite(mkexpr(endOfVectorIsReached),
16845 mkU64(16),
16846 foundIndex));
16847 put_vr_qw(v1, binop(Iop_64HLtoV128, mkexpr(result), mkU64(0)));
16850 if (s390_vr_is_cs_set(m5)) {
16851 static const IROp to64Converters[] = {Iop_8Uto64, Iop_16Uto64, Iop_32Uto64};
16852 IROp to64Converter = to64Converters[m4];
16854 IRExpr* arg1IsLessThanArg2 = binop(Iop_CmpLT64U,
16855 unop(to64Converter, mkexpr(arg1)),
16856 unop(to64Converter, mkexpr(arg2)));
16858 IRExpr* ccexp = mkite(binop(Iop_CmpEQ32,
16859 unop(Iop_1Uto32, mkexpr(isGoodPair)),
16860 mkU32(1)),
16861 mkite(arg1IsLessThanArg2, mkU64(1), mkU64(2)),
16862 mkU64(3));
16864 if(s390_vr_is_zs_set(m5)) {
16865 IRExpr* arg2IsZero = binop(comparator, mkexpr(arg2),
16866 unop(converter, mkU64(0)));
16867 IRExpr* bothArgsAreZero = binop(Iop_And32,
16868 unop(Iop_1Uto32, mkexpr(isZeroElem)),
16869 unop(Iop_1Uto32, arg2IsZero));
16870 ccexp = mkite(binop(Iop_CmpEQ32, bothArgsAreZero, mkU32(1)),
16871 mkU64(0),
16872 ccexp);
16874 IRTemp cc = newTemp(Ity_I64);
16875 assign(cc, ccexp);
16877 s390_cc_set(cc);
16881 put_counter_dw0(mkU64(0));
16882 return "vfene";
16885 static const HChar *
16886 s390_irgen_VISTR(UChar v1, UChar v2, UChar m3, UChar m5)
16888 IRDirty* d;
16889 IRTemp cc = newTemp(Ity_I64);
16891 /* Check for specification exception */
16892 vassert(m3 < 3);
16893 vassert((m5 & 0b1110) == 0);
16895 s390x_vec_op_details_t details = { .serialized = 0ULL };
16896 details.op = S390_VEC_OP_VISTR;
16897 details.v1 = v1;
16898 details.v2 = v2;
16899 details.m4 = m3;
16900 details.m5 = m5;
16902 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16903 &s390x_dirtyhelper_vec_op,
16904 mkIRExprVec_2(IRExpr_GSPTR(),
16905 mkU64(details.serialized)));
16907 d->nFxState = 2;
16908 vex_bzero(&d->fxState, sizeof(d->fxState));
16909 d->fxState[0].fx = Ifx_Read;
16910 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16911 d->fxState[0].size = sizeof(V128);
16912 d->fxState[1].fx = Ifx_Write;
16913 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16914 d->fxState[1].size = sizeof(V128);
16916 stmt(IRStmt_Dirty(d));
16918 if (s390_vr_is_cs_set(m5)) {
16919 s390_cc_set(cc);
16922 return "vistr";
16925 static const HChar *
16926 s390_irgen_VSTRC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
16928 IRDirty* d;
16929 IRTemp cc = newTemp(Ity_I64);
16931 /* Check for specification exception */
16932 vassert(m5 < 3);
16934 s390x_vec_op_details_t details = { .serialized = 0ULL };
16935 details.op = S390_VEC_OP_VSTRC;
16936 details.v1 = v1;
16937 details.v2 = v2;
16938 details.v3 = v3;
16939 details.v4 = v4;
16940 details.m4 = m5;
16941 details.m5 = m6;
16943 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16944 &s390x_dirtyhelper_vec_op,
16945 mkIRExprVec_2(IRExpr_GSPTR(),
16946 mkU64(details.serialized)));
16948 d->nFxState = 4;
16949 vex_bzero(&d->fxState, sizeof(d->fxState));
16950 d->fxState[0].fx = Ifx_Read;
16951 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16952 d->fxState[0].size = sizeof(V128);
16953 d->fxState[1].fx = Ifx_Read;
16954 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
16955 d->fxState[1].size = sizeof(V128);
16956 d->fxState[2].fx = Ifx_Read;
16957 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
16958 d->fxState[2].size = sizeof(V128);
16959 d->fxState[3].fx = Ifx_Write;
16960 d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16961 d->fxState[3].size = sizeof(V128);
16963 stmt(IRStmt_Dirty(d));
16965 if (s390_vr_is_cs_set(m6)) {
16966 s390_cc_set(cc);
16969 return "vstrc";
16972 static const HChar *
16973 s390_irgen_VNC(UChar v1, UChar v2, UChar v3)
16975 put_vr_qw(v1, binop(Iop_AndV128,
16976 get_vr_qw(v2), unop(Iop_NotV128, get_vr_qw(v3)))
16979 return "vnc";
16982 static const HChar *
16983 s390_irgen_VA(UChar v1, UChar v2, UChar v3, UChar m4)
16985 const IROp ops[] = { Iop_Add8x16, Iop_Add16x8, Iop_Add32x4,
16986 Iop_Add64x2, Iop_Add128x1 };
16987 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
16988 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
16990 return "va";
16993 static const HChar *
16994 s390_irgen_VS(UChar v1, UChar v2, UChar v3, UChar m4)
16996 const IROp ops[] = { Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4,
16997 Iop_Sub64x2, Iop_Sub128x1 };
16998 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
16999 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17001 return "vs";
17004 static const HChar *
17005 s390_irgen_VMX(UChar v1, UChar v2, UChar v3, UChar m4)
17007 const IROp ops[] = { Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2 };
17008 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17009 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17011 return "vmx";
17014 static const HChar *
17015 s390_irgen_VMXL(UChar v1, UChar v2, UChar v3, UChar m4)
17017 const IROp ops[] = { Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2 };
17018 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17019 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17021 return "vmxl";
17024 static const HChar *
17025 s390_irgen_VMN(UChar v1, UChar v2, UChar v3, UChar m4)
17027 const IROp ops[] = { Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2 };
17028 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17029 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17031 return "vmn";
17034 static const HChar *
17035 s390_irgen_VMNL(UChar v1, UChar v2, UChar v3, UChar m4)
17037 const IROp ops[] = { Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2 };
17038 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17039 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17041 return "vmnl";
17044 static const HChar *
17045 s390_irgen_VAVG(UChar v1, UChar v2, UChar v3, UChar m4)
17047 const IROp ops[] = { Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4, Iop_Avg64Sx2 };
17048 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17049 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17051 return "vavg";
17054 static const HChar *
17055 s390_irgen_VAVGL(UChar v1, UChar v2, UChar v3, UChar m4)
17057 const IROp ops[] = { Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4, Iop_Avg64Ux2 };
17058 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17059 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17061 return "vavgl";
17064 static const HChar *
17065 s390_irgen_VLC(UChar v1, UChar v2, UChar m3)
17067 vassert(m3 < 4);
17068 IRType type = s390_vr_get_type(m3);
17069 put_vr_qw(v1, s390_V128_get_complement(get_vr_qw(v2), type));
17070 return "vlc";
17073 static const HChar *
17074 s390_irgen_VLP(UChar v1, UChar v2, UChar m3)
17076 const IROp ops[] = { Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, Iop_Abs64x2 };
17077 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
17078 put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2)));
17080 return "vlp";
17083 static const HChar *
17084 s390_irgen_VCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17086 if (!s390_vr_is_cs_set(m5)) {
17087 const IROp ops[] = { Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4,
17088 Iop_CmpGT64Sx2 };
17089 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17090 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17092 } else {
17093 IRDirty* d;
17094 IRTemp cc = newTemp(Ity_I64);
17096 s390x_vec_op_details_t details = { .serialized = 0ULL };
17097 details.op = S390_VEC_OP_VCH;
17098 details.v1 = v1;
17099 details.v2 = v2;
17100 details.v3 = v3;
17101 details.m4 = m4;
17102 details.m5 = m5;
17104 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17105 &s390x_dirtyhelper_vec_op,
17106 mkIRExprVec_2(IRExpr_GSPTR(),
17107 mkU64(details.serialized)));
17109 d->nFxState = 3;
17110 vex_bzero(&d->fxState, sizeof(d->fxState));
17111 d->fxState[0].fx = Ifx_Read;
17112 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17113 d->fxState[0].size = sizeof(V128);
17114 d->fxState[1].fx = Ifx_Read;
17115 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17116 d->fxState[1].size = sizeof(V128);
17117 d->fxState[2].fx = Ifx_Write;
17118 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17119 d->fxState[2].size = sizeof(V128);
17121 stmt(IRStmt_Dirty(d));
17122 s390_cc_set(cc);
17125 return "vch";
17128 static const HChar *
17129 s390_irgen_VCHL(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17131 if (!s390_vr_is_cs_set(m5)) {
17132 const IROp ops[] = { Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
17133 Iop_CmpGT64Ux2 };
17134 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17135 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17137 } else {
17138 IRDirty* d;
17139 IRTemp cc = newTemp(Ity_I64);
17141 s390x_vec_op_details_t details = { .serialized = 0ULL };
17142 details.op = S390_VEC_OP_VCHL;
17143 details.v1 = v1;
17144 details.v2 = v2;
17145 details.v3 = v3;
17146 details.m4 = m4;
17147 details.m5 = m5;
17149 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17150 &s390x_dirtyhelper_vec_op,
17151 mkIRExprVec_2(IRExpr_GSPTR(),
17152 mkU64(details.serialized)));
17154 d->nFxState = 3;
17155 vex_bzero(&d->fxState, sizeof(d->fxState));
17156 d->fxState[0].fx = Ifx_Read;
17157 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17158 d->fxState[0].size = sizeof(V128);
17159 d->fxState[1].fx = Ifx_Read;
17160 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17161 d->fxState[1].size = sizeof(V128);
17162 d->fxState[2].fx = Ifx_Write;
17163 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17164 d->fxState[2].size = sizeof(V128);
17166 stmt(IRStmt_Dirty(d));
17167 s390_cc_set(cc);
17170 return "vchl";
17173 static const HChar *
17174 s390_irgen_VCLZ(UChar v1, UChar v2, UChar m3)
17176 const IROp ops[] = { Iop_Clz8x16, Iop_Clz16x8, Iop_Clz32x4, Iop_Clz64x2 };
17177 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
17178 put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2)));
17180 return "vclz";
17183 static const HChar *
17184 s390_irgen_VCTZ(UChar v1, UChar v2, UChar m3)
17186 const IROp ops[] = { Iop_Ctz8x16, Iop_Ctz16x8, Iop_Ctz32x4, Iop_Ctz64x2 };
17187 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
17188 put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2)));
17190 return "vctz";
17193 static const HChar *
17194 s390_irgen_VPOPCT(UChar v1, UChar v2, UChar m3)
17196 vassert(m3 == 0);
17198 put_vr_qw(v1, unop(Iop_Cnt8x16, get_vr_qw(v2)));
17200 return "vpopct";
17203 static const HChar *
17204 s390_irgen_VML(UChar v1, UChar v2, UChar v3, UChar m4)
17206 const IROp ops[] = { Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4 };
17207 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17208 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17210 return "vml";
17213 static const HChar *
17214 s390_irgen_VMLH(UChar v1, UChar v2, UChar v3, UChar m4)
17216 const IROp ops[] = { Iop_MulHi8Ux16, Iop_MulHi16Ux8, Iop_MulHi32Ux4 };
17217 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17218 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17220 return "vmlh";
17223 static const HChar *
17224 s390_irgen_VMH(UChar v1, UChar v2, UChar v3, UChar m4)
17226 const IROp ops[] = { Iop_MulHi8Sx16, Iop_MulHi16Sx8, Iop_MulHi32Sx4 };
17227 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17228 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17230 return "vmh";
17233 static const HChar *
17234 s390_irgen_VME(UChar v1, UChar v2, UChar v3, UChar m4)
17236 const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4 };
17237 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17238 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17240 return "vme";
17243 static const HChar *
17244 s390_irgen_VMLE(UChar v1, UChar v2, UChar v3, UChar m4)
17246 const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4 };
17247 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17248 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17250 return "vmle";
17253 static const HChar *
17254 s390_irgen_VESLV(UChar v1, UChar v2, UChar v3, UChar m4)
17256 const IROp ops[] = { Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2};
17257 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17258 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17260 return "veslv";
17263 static const HChar *
17264 s390_irgen_VESL(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17266 IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr));
17267 const IROp ops[] = { Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2 };
17268 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17269 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount));
17271 return "vesl";
17274 static const HChar *
17275 s390_irgen_VESRAV(UChar v1, UChar v2, UChar v3, UChar m4)
17277 const IROp ops[] = { Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2 };
17278 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17279 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17281 return "vesrav";
17284 static const HChar *
17285 s390_irgen_VESRA(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17287 IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr));
17288 const IROp ops[] = { Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2 };
17289 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17290 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount));
17292 return "vesra";
17295 static const HChar *
17296 s390_irgen_VESRLV(UChar v1, UChar v2, UChar v3, UChar m4)
17298 const IROp ops[] = { Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2 };
17299 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17300 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17302 return "vesrlv";
17305 static const HChar *
17306 s390_irgen_VESRL(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17308 IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr));
17309 const IROp ops[] = { Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2 };
17310 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17311 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount));
17313 return "vesrl";
17316 static const HChar *
17317 s390_irgen_VERLLV(UChar v1, UChar v2, UChar v3, UChar m4)
17319 const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 };
17320 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17321 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17323 return "verllv";
17326 static const HChar *
17327 s390_irgen_VERLL(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17330 There is no Iop_RolN?x?? operations
17331 so we have to use VECTOR x VECTOR variant.
17333 IRExpr* shift_vector = unop(Iop_Dup8x16, unop(Iop_64to8, mkexpr(op2addr)));
17334 const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 };
17335 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17336 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_vector));
17338 return "verll";
17341 static const HChar *
17342 s390_irgen_VSL(UChar v1, UChar v2, UChar v3)
17344 IRTemp shift_amount = newTemp(Ity_I8);
17345 assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b00000111)));
17347 put_vr_qw(v1, binop(Iop_ShlV128, get_vr_qw(v2), mkexpr(shift_amount)));
17348 return "vsl";
17351 static const HChar *
17352 s390_irgen_VSRL(UChar v1, UChar v2, UChar v3)
17354 IRTemp shift_amount = newTemp(Ity_I8);
17355 assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b00000111)));
17357 put_vr_qw(v1, binop(Iop_ShrV128, get_vr_qw(v2), mkexpr(shift_amount)));
17358 return "vsrl";
17361 static const HChar *
17362 s390_irgen_VSRA(UChar v1, UChar v2, UChar v3)
17364 IRTemp shift_amount = newTemp(Ity_I8);
17365 assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b00000111)));
17367 put_vr_qw(v1, binop(Iop_SarV128, get_vr_qw(v2), mkexpr(shift_amount)));
17368 return "vsra";
17371 static const HChar *
17372 s390_irgen_VERIM(UChar v1, UChar v2, UChar v3, UChar i4, UChar m5)
17375 There is no Iop_RolN?x?? operations
17376 so we have to use VECTOR x VECTOR variant.
17378 const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 };
17379 vassert(m5 < sizeof(ops) / sizeof(ops[0]));
17380 IRExpr* shift_vector = unop(Iop_Dup8x16, mkU8(i4));
17381 IRExpr* rotated_vector = binop(ops[m5], get_vr_qw(v2), shift_vector);
17383 /* result = (result & ~mask) | (rotated_vector & mask) */
17384 IRExpr* mask = get_vr_qw(v3);
17385 IRExpr* result = get_vr_qw(v1);
17386 put_vr_qw(v1, s390_V128_bitwiseITE(mask, rotated_vector, result));
17388 return "verim";
17391 static const HChar *
17392 s390_irgen_VEC(UChar v1, UChar v2, UChar m3)
17394 IRType type = s390_vr_get_type(m3);
17395 IRTemp op1 = newTemp(type);
17396 IRTemp op2 = newTemp(type);
17398 switch(type) {
17399 case Ity_I8:
17400 assign(op1, get_vr_b7(v1));
17401 assign(op2, get_vr_b7(v2));
17402 break;
17403 case Ity_I16:
17404 assign(op1, get_vr_hw3(v1));
17405 assign(op2, get_vr_hw3(v2));
17406 break;
17407 case Ity_I32:
17408 assign(op1, get_vr_w1(v1));
17409 assign(op2, get_vr_w1(v2));
17410 break;
17411 case Ity_I64:
17412 assign(op1, get_vr_dw0(v1));
17413 assign(op2, get_vr_dw0(v2));
17414 break;
17415 default:
17416 vpanic("s390_irgen_VEC: unknown type");
17419 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
17421 return "vec";
17424 static const HChar *
17425 s390_irgen_VECL(UChar v1, UChar v2, UChar m3)
17427 IRType type = s390_vr_get_type(m3);
17428 IRTemp op1 = newTemp(type);
17429 IRTemp op2 = newTemp(type);
17431 switch(type) {
17432 case Ity_I8:
17433 assign(op1, get_vr_b7(v1));
17434 assign(op2, get_vr_b7(v2));
17435 break;
17436 case Ity_I16:
17437 assign(op1, get_vr_hw3(v1));
17438 assign(op2, get_vr_hw3(v2));
17439 break;
17440 case Ity_I32:
17441 assign(op1, get_vr_w1(v1));
17442 assign(op2, get_vr_w1(v2));
17443 break;
17444 case Ity_I64:
17445 assign(op1, get_vr_dw0(v1));
17446 assign(op2, get_vr_dw0(v2));
17447 break;
17448 default:
17449 vpanic("s390_irgen_VECL: unknown type");
17452 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
17454 return "vecl";
17457 static const HChar *
17458 s390_irgen_VCEQ(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17460 if (!s390_vr_is_cs_set(m5)) {
17461 const IROp ops[] = { Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4,
17462 Iop_CmpEQ64x2 };
17463 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17464 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17466 } else {
17467 IRDirty* d;
17468 IRTemp cc = newTemp(Ity_I64);
17470 s390x_vec_op_details_t details = { .serialized = 0ULL };
17471 details.op = S390_VEC_OP_VCEQ;
17472 details.v1 = v1;
17473 details.v2 = v2;
17474 details.v3 = v3;
17475 details.m4 = m4;
17476 details.m5 = m5;
17478 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17479 &s390x_dirtyhelper_vec_op,
17480 mkIRExprVec_2(IRExpr_GSPTR(),
17481 mkU64(details.serialized)));
17483 d->nFxState = 3;
17484 vex_bzero(&d->fxState, sizeof(d->fxState));
17485 d->fxState[0].fx = Ifx_Read;
17486 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17487 d->fxState[0].size = sizeof(V128);
17488 d->fxState[1].fx = Ifx_Read;
17489 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17490 d->fxState[1].size = sizeof(V128);
17491 d->fxState[2].fx = Ifx_Write;
17492 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17493 d->fxState[2].size = sizeof(V128);
17495 stmt(IRStmt_Dirty(d));
17496 s390_cc_set(cc);
17499 return "vceq";
17502 static const HChar *
17503 s390_irgen_VSLB(UChar v1, UChar v2, UChar v3)
17505 IRTemp shift_amount = newTemp(Ity_I8);
17506 assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000)));
17508 put_vr_qw(v1, binop(Iop_ShlV128, get_vr_qw(v2), mkexpr(shift_amount)));
17509 return "vslb";
17512 static const HChar *
17513 s390_irgen_VSRLB(UChar v1, UChar v2, UChar v3)
17515 IRTemp shift_amount = newTemp(Ity_I8);
17516 assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000)));
17518 put_vr_qw(v1, binop(Iop_ShrV128, get_vr_qw(v2), mkexpr(shift_amount)));
17519 return "vsrlb";
17522 static const HChar *
17523 s390_irgen_VSRAB(UChar v1, UChar v2, UChar v3)
17525 IRTemp shift_amount = newTemp(Ity_I8);
17526 assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000)));
17528 put_vr_qw(v1, binop(Iop_SarV128, get_vr_qw(v2), mkexpr(shift_amount)));
17529 return "vsrab";
17532 static const HChar *
17533 s390_irgen_VSLDB(UChar v1, UChar v2, UChar v3, UChar i4)
17535 UChar imm = i4 & 0b00001111;
17537 if (imm == 0) {
17538 /* Just copy v2. */
17539 put_vr_qw(v1, get_vr_qw(v2));
17540 } else {
17541 /* Concatenate v2's tail with v3's head. */
17542 put_vr_qw(v1,
17543 binop(Iop_OrV128,
17544 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(imm * 8)),
17545 binop(Iop_ShrV128, get_vr_qw(v3), mkU8((16 - imm) * 8))
17550 return "vsldb";
17553 static const HChar *
17554 s390_irgen_VMO(UChar v1, UChar v2, UChar v3, UChar m4)
17556 const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8,
17557 Iop_MullEven32Sx4 };
17558 UChar shifts[] = { 8, 16, 32 };
17559 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17560 IRExpr* result = binop(ops[m4],
17561 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m4])),
17562 binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m4]))
17564 put_vr_qw(v1, result);
17566 return "vmo";
17569 static const HChar *
17570 s390_irgen_VMLO(UChar v1, UChar v2, UChar v3, UChar m4)
17572 const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8,
17573 Iop_MullEven32Ux4 };
17574 UChar shifts[] = { 8, 16, 32 };
17575 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17576 IRExpr* result = binop(ops[m4],
17577 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m4])),
17578 binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m4]))
17580 put_vr_qw(v1, result);
17582 return "vmlo";
17585 static const HChar *
17586 s390_irgen_VMAE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17588 const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8,
17589 Iop_MullEven32Sx4 };
17590 const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2};
17591 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17593 IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3));
17594 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17595 put_vr_qw(v1, result);
17597 return "vmae";
17600 static const HChar *
17601 s390_irgen_VMALE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17603 const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8,
17604 Iop_MullEven32Ux4 };
17605 const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 };
17606 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17608 IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3));
17609 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17610 put_vr_qw(v1, result);
17612 return "vmale";
17615 static const HChar *
17616 s390_irgen_VMAO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17618 const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8,
17619 Iop_MullEven32Sx4 };
17620 const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 };
17621 UChar shifts[] = { 8, 16, 32 };
17622 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17624 IRExpr* mul_result =
17625 binop(mul_ops[m5],
17626 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m5])),
17627 binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m5])));
17628 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17629 put_vr_qw(v1, result);
17631 return "vmao";
17634 static const HChar *
17635 s390_irgen_VMALO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17637 const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8,
17638 Iop_MullEven32Ux4 };
17639 const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 };
17640 UChar shifts[] = { 8, 16, 32 };
17641 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17643 IRExpr* mul_result = binop(mul_ops[m5],
17644 binop(Iop_ShlV128,
17645 get_vr_qw(v2), mkU8(shifts[m5])),
17646 binop(Iop_ShlV128,
17647 get_vr_qw(v3), mkU8(shifts[m5]))
17650 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17651 put_vr_qw(v1, result);
17653 return "vmalo";
17656 static const HChar *
17657 s390_irgen_VMAL(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17659 const IROp mul_ops[] = { Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4 };
17660 const IROp add_ops[] = { Iop_Add8x16, Iop_Add16x8, Iop_Add32x4 };
17661 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17663 IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3));
17664 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17665 put_vr_qw(v1, result);
17667 return "vmal";
17670 static const HChar *
17671 s390_irgen_VSUM(UChar v1, UChar v2, UChar v3, UChar m4)
17673 IRType type = s390_vr_get_type(m4);
17674 IRExpr* mask;
17675 IRExpr* sum;
17676 switch(type) {
17677 case Ity_I8:
17678 sum = unop(Iop_PwAddL16Ux8, unop(Iop_PwAddL8Ux16, get_vr_qw(v2)));
17679 mask = IRExpr_Const(IRConst_V128(0b0001000100010001));
17680 break;
17681 case Ity_I16:
17682 sum = unop(Iop_PwAddL16Ux8, get_vr_qw(v2));
17683 mask = IRExpr_Const(IRConst_V128(0b0011001100110011));
17684 break;
17685 default:
17686 vpanic("s390_irgen_VSUM: invalid type ");
17689 IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask);
17690 put_vr_qw(v1, binop(Iop_Add32x4, sum, addition));
17692 return "vsum";
17695 static const HChar *
17696 s390_irgen_VSUMG(UChar v1, UChar v2, UChar v3, UChar m4)
17698 IRType type = s390_vr_get_type(m4);
17699 IRExpr* mask;
17700 IRExpr* sum;
17701 switch(type) {
17702 case Ity_I16:
17703 sum = unop(Iop_PwAddL32Ux4, unop(Iop_PwAddL16Ux8, get_vr_qw(v2)));
17704 mask = IRExpr_Const(IRConst_V128(0b0000001100000011));
17705 break;
17706 case Ity_I32:
17707 sum = unop(Iop_PwAddL32Ux4, get_vr_qw(v2));
17708 mask = IRExpr_Const(IRConst_V128(0b0000111100001111));
17709 break;
17710 default:
17711 vpanic("s390_irgen_VSUMG: invalid type ");
17714 IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask);
17715 put_vr_qw(v1, binop(Iop_Add64x2, sum, addition));
17717 return "vsumg";
17720 static const HChar *
17721 s390_irgen_VSUMQ(UChar v1, UChar v2, UChar v3, UChar m4)
17723 IRType type = s390_vr_get_type(m4);
17724 IRExpr* mask;
17725 IRExpr* sum;
17726 switch(type) {
17727 case Ity_I32:
17728 sum = unop(Iop_PwAddL64Ux2, unop(Iop_PwAddL32Ux4, get_vr_qw(v2)));
17729 mask = IRExpr_Const(IRConst_V128(0b0000000000001111));
17730 break;
17731 case Ity_I64:
17732 sum = unop(Iop_PwAddL64Ux2, get_vr_qw(v2));
17733 mask = IRExpr_Const(IRConst_V128(0b0000000011111111));
17734 break;
17735 default:
17736 vpanic("s390_irgen_VSUMQ: invalid type ");
17739 IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask);
17740 put_vr_qw(v1, binop(Iop_Add128x1, sum, addition));
17742 return "vsumq";
17745 static const HChar *
17746 s390_irgen_VTM(UChar v1, UChar v2)
17748 IRDirty* d;
17749 IRTemp cc = newTemp(Ity_I64);
17751 s390x_vec_op_details_t details = { .serialized = 0ULL };
17752 details.op = S390_VEC_OP_VTM;
17753 details.v2 = v1;
17754 details.v3 = v2;
17755 details.read_only = 1;
17757 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17758 &s390x_dirtyhelper_vec_op,
17759 mkIRExprVec_2(IRExpr_GSPTR(),
17760 mkU64(details.serialized)));
17762 d->nFxState = 2;
17763 vex_bzero(&d->fxState, sizeof(d->fxState));
17764 d->fxState[0].fx = Ifx_Read;
17765 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17766 d->fxState[0].size = sizeof(V128);
17767 d->fxState[1].fx = Ifx_Read;
17768 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17769 d->fxState[1].size = sizeof(V128);
17771 stmt(IRStmt_Dirty(d));
17772 s390_cc_set(cc);
17774 return "vtm";
17777 static const HChar *
17778 s390_irgen_VAC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17780 vassert(m5 == 4); /* specification exception otherwise */
17782 IRTemp sum = newTemp(Ity_V128);
17783 assign(sum, binop(Iop_Add128x1, get_vr_qw(v2), get_vr_qw(v3)));
17785 IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0), mkU64(1));
17786 IRExpr* carry_in = binop(Iop_AndV128, get_vr_qw(v4), mask);
17787 put_vr_qw(v1, binop(Iop_Add128x1, mkexpr(sum), carry_in));
17789 return "vac";
17792 static const HChar *
17793 s390_irgen_VACC(UChar v1, UChar v2, UChar v3, UChar m4)
17795 IRType type = s390_vr_get_type(m4);
17796 IRExpr* arg1 = get_vr_qw(v2);
17797 IRExpr* arg2 = get_vr_qw(v3);
17799 put_vr_qw(v1, s390_V128_calculate_carry_out(arg1, arg2, type, False));
17800 return "vacc";
17803 static const HChar *
17804 s390_irgen_VACCC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17806 vassert(m5 == 4); /* specification exception otherwise */
17807 IRExpr* result =
17808 s390_V128_calculate_carry_out_with_carry(get_vr_qw(v2),
17809 get_vr_qw(v3),
17810 get_vr_qw(v4)
17813 put_vr_qw(v1, result);
17814 return "vaccc";
17817 static const HChar*
17818 s390_irgen_VCKSM(UChar v1, UChar v2, UChar v3)
17821 IRTemp sum1 = s390_checksum_add(get_vr_w1(v3), get_vr_w0(v2));
17822 IRTemp sum2 = s390_checksum_add(mkexpr(sum1), get_vr_w1(v2));
17823 IRTemp sum3 = s390_checksum_add(mkexpr(sum2), get_vr_w2(v2));
17824 IRTemp result = s390_checksum_add(mkexpr(sum3), get_vr_w3(v2));
17826 put_vr_qw(v1, binop(Iop_64HLtoV128,
17827 unop(Iop_32Uto64, mkexpr(result)), mkU64(0ULL)));
17829 return "vcksm";
17832 static const HChar *
17833 s390_irgen_VGFM(UChar v1, UChar v2, UChar v3, UChar m4)
17835 IRDirty* d;
17836 IRTemp cc = newTemp(Ity_I64);
17838 s390x_vec_op_details_t details = { .serialized = 0ULL };
17839 details.op = S390_VEC_OP_VGFM;
17840 details.v1 = v1;
17841 details.v2 = v2;
17842 details.v3 = v3;
17843 details.m4 = m4;
17845 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17846 &s390x_dirtyhelper_vec_op,
17847 mkIRExprVec_2(IRExpr_GSPTR(),
17848 mkU64(details.serialized)));
17850 d->nFxState = 3;
17851 vex_bzero(&d->fxState, sizeof(d->fxState));
17852 d->fxState[0].fx = Ifx_Read;
17853 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17854 d->fxState[0].size = sizeof(V128);
17855 d->fxState[1].fx = Ifx_Read;
17856 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17857 d->fxState[1].size = sizeof(V128);
17858 d->fxState[2].fx = Ifx_Write;
17859 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17860 d->fxState[2].size = sizeof(V128);
17862 stmt(IRStmt_Dirty(d));
17863 return "vgfm";
17866 static const HChar *
17867 s390_irgen_VGFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17869 IRDirty* d;
17870 IRTemp cc = newTemp(Ity_I64);
17872 s390x_vec_op_details_t details = { .serialized = 0ULL };
17873 details.op = S390_VEC_OP_VGFMA;
17874 details.v1 = v1;
17875 details.v2 = v2;
17876 details.v3 = v3;
17877 details.v4 = v4;
17878 details.m4 = m5;
17880 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17881 &s390x_dirtyhelper_vec_op,
17882 mkIRExprVec_2(IRExpr_GSPTR(),
17883 mkU64(details.serialized)));
17885 d->nFxState = 4;
17886 vex_bzero(&d->fxState, sizeof(d->fxState));
17887 d->fxState[0].fx = Ifx_Read;
17888 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17889 d->fxState[0].size = sizeof(V128);
17890 d->fxState[1].fx = Ifx_Read;
17891 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17892 d->fxState[1].size = sizeof(V128);
17893 d->fxState[2].fx = Ifx_Read;
17894 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
17895 d->fxState[2].size = sizeof(V128);
17896 d->fxState[3].fx = Ifx_Write;
17897 d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17898 d->fxState[3].size = sizeof(V128);
17900 stmt(IRStmt_Dirty(d));
17901 return "vgfma";
17904 static const HChar *
17905 s390_irgen_VSBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17907 vassert(m5 == 4); /* specification exception otherwise */
17909 IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0ULL), mkU64(1ULL));
17910 IRExpr* carry_in = binop(Iop_AndV128, get_vr_qw(v4), mask);
17912 IRTemp sum = newTemp(Ity_V128);
17913 assign(sum, binop(Iop_Add128x1,
17914 get_vr_qw(v2),
17915 unop(Iop_NotV128, get_vr_qw(v3))
17919 put_vr_qw(v1, binop(Iop_Add128x1, mkexpr(sum), carry_in));
17920 return "vsbi";
17923 static const HChar *
17924 s390_irgen_VSCBI(UChar v1, UChar v2, UChar v3, UChar m4)
17926 IRType type = s390_vr_get_type(m4);
17927 IRExpr* arg1 = get_vr_qw(v2);
17928 IRExpr* arg2 = s390_V128_get_complement(get_vr_qw(v3), type);
17929 IRExpr* result = s390_V128_calculate_carry_out(arg1, arg2, type, True);
17931 put_vr_qw(v1, result);
17932 return "vscbi";
17935 static const HChar *
17936 s390_irgen_VSBCBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17938 vassert(m5 == 4); /* specification exception otherwise */
17939 IRExpr* result =
17940 s390_V128_calculate_carry_out_with_carry(get_vr_qw(v2),
17941 unop(Iop_NotV128, get_vr_qw(v3)),
17942 get_vr_qw(v4));
17944 put_vr_qw(v1, result);
17945 return "vsbcbi";
17948 static const HChar *
17949 s390_irgen_VMAH(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17951 IRDirty* d;
17952 IRTemp cc = newTemp(Ity_I64);
17954 /* Check for specification exception */
17955 vassert(m5 < 3);
17957 s390x_vec_op_details_t details = { .serialized = 0ULL };
17958 details.op = S390_VEC_OP_VMAH;
17959 details.v1 = v1;
17960 details.v2 = v2;
17961 details.v3 = v3;
17962 details.v4 = v4;
17963 details.m4 = m5;
17965 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17966 &s390x_dirtyhelper_vec_op,
17967 mkIRExprVec_2(IRExpr_GSPTR(),
17968 mkU64(details.serialized)));
17970 d->nFxState = 4;
17971 vex_bzero(&d->fxState, sizeof(d->fxState));
17972 d->fxState[0].fx = Ifx_Read;
17973 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17974 d->fxState[0].size = sizeof(V128);
17975 d->fxState[1].fx = Ifx_Read;
17976 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17977 d->fxState[1].size = sizeof(V128);
17978 d->fxState[2].fx = Ifx_Read;
17979 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
17980 d->fxState[2].size = sizeof(V128);
17981 d->fxState[3].fx = Ifx_Write;
17982 d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17983 d->fxState[3].size = sizeof(V128);
17985 stmt(IRStmt_Dirty(d));
17987 return "vmah";
17990 static const HChar *
17991 s390_irgen_VMALH(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17993 IRDirty* d;
17994 IRTemp cc = newTemp(Ity_I64);
17996 /* Check for specification exception */
17997 vassert(m5 < 3);
17999 s390x_vec_op_details_t details = { .serialized = 0ULL };
18000 details.op = S390_VEC_OP_VMALH;
18001 details.v1 = v1;
18002 details.v2 = v2;
18003 details.v3 = v3;
18004 details.v4 = v4;
18005 details.m4 = m5;
18007 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18008 &s390x_dirtyhelper_vec_op,
18009 mkIRExprVec_2(IRExpr_GSPTR(),
18010 mkU64(details.serialized)));
18012 d->nFxState = 4;
18013 vex_bzero(&d->fxState, sizeof(d->fxState));
18014 d->fxState[0].fx = Ifx_Read;
18015 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18016 d->fxState[0].size = sizeof(V128);
18017 d->fxState[1].fx = Ifx_Read;
18018 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18019 d->fxState[1].size = sizeof(V128);
18020 d->fxState[2].fx = Ifx_Read;
18021 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
18022 d->fxState[2].size = sizeof(V128);
18023 d->fxState[3].fx = Ifx_Write;
18024 d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18025 d->fxState[3].size = sizeof(V128);
18027 stmt(IRStmt_Dirty(d));
18029 return "vmalh";
18032 static void
18033 s390_vector_fp_convert(IROp op, IRType fromType, IRType toType,
18034 UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18036 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m4);
18037 UChar maxIndex = isSingleElementOp ? 0 : 1;
18039 /* For Iop_F32toF64 we do this:
18040 f32[0] -> f64[0]
18041 f32[2] -> f64[1]
18043 For Iop_F64toF32 we do this:
18044 f64[0] -> f32[0]
18045 f64[1] -> f32[2]
18047 The magic below with scaling factors is used to achieve the logic
18048 described above.
18050 const UChar sourceIndexScaleFactor = (op == Iop_F32toF64) ? 2 : 1;
18051 const UChar destinationIndexScaleFactor = (op == Iop_F64toF32) ? 2 : 1;
18053 const Bool isUnary = (op == Iop_F32toF64);
18054 for (UChar i = 0; i <= maxIndex; i++) {
18055 IRExpr* argument = get_vr(v2, fromType, i * sourceIndexScaleFactor);
18056 IRExpr* result;
18057 if (!isUnary) {
18058 result = binop(op,
18059 mkexpr(encode_bfp_rounding_mode(m5)),
18060 argument);
18061 } else {
18062 result = unop(op, argument);
18064 put_vr(v1, toType, i * destinationIndexScaleFactor, result);
18067 if (isSingleElementOp) {
18068 put_vr_dw1(v1, mkU64(0));
18072 static const HChar *
18073 s390_irgen_VCDG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18075 s390_insn_assert("vcdg", m3 == 3);
18077 if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18078 emulation_warning(EmWarn_S390X_fpext_rounding);
18079 m5 = S390_BFP_ROUND_PER_FPC;
18082 s390_vector_fp_convert(Iop_I64StoF64, Ity_I64, Ity_F64, v1, v2, m3, m4, m5);
18084 return "vcdg";
18087 static const HChar *
18088 s390_irgen_VCDLG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18090 s390_insn_assert("vcdlg", m3 == 3);
18092 if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18093 emulation_warning(EmWarn_S390X_fpext_rounding);
18094 m5 = S390_BFP_ROUND_PER_FPC;
18097 s390_vector_fp_convert(Iop_I64UtoF64, Ity_I64, Ity_F64, v1, v2, m3, m4, m5);
18099 return "vcdlg";
18102 static const HChar *
18103 s390_irgen_VCGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18105 s390_insn_assert("vcgd", m3 == 3);
18107 if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18108 emulation_warning(EmWarn_S390X_fpext_rounding);
18109 m5 = S390_BFP_ROUND_PER_FPC;
18112 s390_vector_fp_convert(Iop_F64toI64S, Ity_F64, Ity_I64, v1, v2, m3, m4, m5);
18114 return "vcgd";
18117 static const HChar *
18118 s390_irgen_VCLGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18120 s390_insn_assert("vclgd", m3 == 3);
18122 if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18123 emulation_warning(EmWarn_S390X_fpext_rounding);
18124 m5 = S390_BFP_ROUND_PER_FPC;
18127 s390_vector_fp_convert(Iop_F64toI64U, Ity_F64, Ity_I64, v1, v2, m3, m4, m5);
18129 return "vclgd";
18132 static const HChar *
18133 s390_irgen_VFI(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18135 s390_insn_assert("vfi", m3 == 3);
18137 if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18138 emulation_warning(EmWarn_S390X_fpext_rounding);
18139 m5 = S390_BFP_ROUND_PER_FPC;
18142 s390_vector_fp_convert(Iop_RoundF64toInt, Ity_F64, Ity_F64,
18143 v1, v2, m3, m4, m5);
18145 return "vcgld";
18148 static const HChar *
18149 s390_irgen_VLDE(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18151 s390_insn_assert("vlde", m3 == 2);
18153 s390_vector_fp_convert(Iop_F32toF64, Ity_F32, Ity_F64, v1, v2, m3, m4, m5);
18155 return "vlde";
18158 static const HChar *
18159 s390_irgen_VLED(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18161 s390_insn_assert("vled", m3 == 3);
18163 if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18164 m5 = S390_BFP_ROUND_PER_FPC;
18167 s390_vector_fp_convert(Iop_F64toF32, Ity_F64, Ity_F32, v1, v2, m3, m4, m5);
18169 return "vled";
18172 static const HChar *
18173 s390_irgen_VFPSO(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18175 s390_insn_assert("vfpso", m3 == 3);
18177 IRExpr* result;
18178 switch (m5) {
18179 case 0: {
18180 /* Invert sign */
18181 if (!s390_vr_is_single_element_control_set(m4)) {
18182 result = unop(Iop_Neg64Fx2, get_vr_qw(v2));
18184 else {
18185 result = binop(Iop_64HLtoV128,
18186 unop(Iop_ReinterpF64asI64,
18187 unop(Iop_NegF64, get_vr(v2, Ity_F64, 0))),
18188 mkU64(0));
18190 break;
18193 case 1: {
18194 /* Set sign to negative */
18195 IRExpr* highHalf = mkU64(0x8000000000000000ULL);
18196 if (!s390_vr_is_single_element_control_set(m4)) {
18197 IRExpr* lowHalf = highHalf;
18198 IRExpr* mask = binop(Iop_64HLtoV128, highHalf, lowHalf);
18199 result = binop(Iop_OrV128, get_vr_qw(v2), mask);
18201 else {
18202 result = binop(Iop_64HLtoV128,
18203 binop(Iop_Or64, get_vr_dw0(v2), highHalf),
18204 mkU64(0ULL));
18207 break;
18210 case 2: {
18211 /* Set sign to positive */
18212 if (!s390_vr_is_single_element_control_set(m4)) {
18213 result = unop(Iop_Abs64Fx2, get_vr_qw(v2));
18215 else {
18216 result = binop(Iop_64HLtoV128,
18217 unop(Iop_ReinterpF64asI64,
18218 unop(Iop_AbsF64, get_vr(v2, Ity_F64, 0))),
18219 mkU64(0));
18222 break;
18225 default:
18226 vpanic("s390_irgen_VFPSO: Invalid m5 value");
18229 put_vr_qw(v1, result);
18230 if (s390_vr_is_single_element_control_set(m4)) {
18231 put_vr_dw1(v1, mkU64(0ULL));
18234 return "vfpso";
18237 static void s390x_vec_fp_binary_op(IROp generalOp, IROp singleElementOp,
18238 UChar v1, UChar v2, UChar v3, UChar m4,
18239 UChar m5)
18241 IRExpr* result;
18242 if (!s390_vr_is_single_element_control_set(m5)) {
18243 result = triop(generalOp, get_bfp_rounding_mode_from_fpc(),
18244 get_vr_qw(v2), get_vr_qw(v3));
18245 } else {
18246 IRExpr* highHalf = triop(singleElementOp,
18247 get_bfp_rounding_mode_from_fpc(),
18248 get_vr(v2, Ity_F64, 0),
18249 get_vr(v3, Ity_F64, 0));
18250 result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf),
18251 mkU64(0ULL));
18254 put_vr_qw(v1, result);
18257 static void s390x_vec_fp_unary_op(IROp generalOp, IROp singleElementOp,
18258 UChar v1, UChar v2, UChar m3, UChar m4)
18260 IRExpr* result;
18261 if (!s390_vr_is_single_element_control_set(m4)) {
18262 result = binop(generalOp, get_bfp_rounding_mode_from_fpc(),
18263 get_vr_qw(v2));
18265 else {
18266 IRExpr* highHalf = binop(singleElementOp,
18267 get_bfp_rounding_mode_from_fpc(),
18268 get_vr(v2, Ity_F64, 0));
18269 result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf),
18270 mkU64(0ULL));
18273 put_vr_qw(v1, result);
18277 static void
18278 s390_vector_fp_mulAddOrSub(IROp singleElementOp,
18279 UChar v1, UChar v2, UChar v3, UChar v4,
18280 UChar m5, UChar m6)
18282 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18283 IRTemp irrm_temp = newTemp(Ity_I32);
18284 assign(irrm_temp, get_bfp_rounding_mode_from_fpc());
18285 IRExpr* irrm = mkexpr(irrm_temp);
18286 IRExpr* result;
18287 IRExpr* highHalf = qop(singleElementOp,
18288 irrm,
18289 get_vr(v2, Ity_F64, 0),
18290 get_vr(v3, Ity_F64, 0),
18291 get_vr(v4, Ity_F64, 0));
18293 if (isSingleElementOp) {
18294 result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf),
18295 mkU64(0ULL));
18296 } else {
18297 IRExpr* lowHalf = qop(singleElementOp,
18298 irrm,
18299 get_vr(v2, Ity_F64, 1),
18300 get_vr(v3, Ity_F64, 1),
18301 get_vr(v4, Ity_F64, 1));
18302 result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf),
18303 unop(Iop_ReinterpF64asI64, lowHalf));
18306 put_vr_qw(v1, result);
18309 static const HChar *
18310 s390_irgen_VFA(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
18312 s390_insn_assert("vfa", m4 == 3);
18313 s390x_vec_fp_binary_op(Iop_Add64Fx2, Iop_AddF64, v1, v2, v3, m4, m5);
18314 return "vfa";
18317 static const HChar *
18318 s390_irgen_VFS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
18320 s390_insn_assert("vfs", m4 == 3);
18321 s390x_vec_fp_binary_op(Iop_Sub64Fx2, Iop_SubF64, v1, v2, v3, m4, m5);
18322 return "vfs";
18325 static const HChar *
18326 s390_irgen_VFM(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
18328 s390_insn_assert("vfm", m4 == 3);
18329 s390x_vec_fp_binary_op(Iop_Mul64Fx2, Iop_MulF64, v1, v2, v3, m4, m5);
18330 return "vfm";
18333 static const HChar *
18334 s390_irgen_VFD(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
18336 s390_insn_assert("vfd", m4 == 3);
18337 s390x_vec_fp_binary_op(Iop_Div64Fx2, Iop_DivF64, v1, v2, v3, m4, m5);
18338 return "vfd";
18341 static const HChar *
18342 s390_irgen_VFSQ(UChar v1, UChar v2, UChar m3, UChar m4)
18344 s390_insn_assert("vfsq", m3 == 3);
18345 s390x_vec_fp_unary_op(Iop_Sqrt64Fx2, Iop_SqrtF64, v1, v2, m3, m4);
18347 return "vfsq";
18350 static const HChar *
18351 s390_irgen_VFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
18353 s390_insn_assert("vfma", m6 == 3);
18354 s390_vector_fp_mulAddOrSub(Iop_MAddF64, v1, v2, v3, v4, m5, m6);
18355 return "vfma";
18358 static const HChar *
18359 s390_irgen_VFMS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
18361 s390_insn_assert("vfms", m6 == 3);
18362 s390_vector_fp_mulAddOrSub(Iop_MSubF64, v1, v2, v3, v4, m5, m6);
18363 return "vfms";
18366 static const HChar *
18367 s390_irgen_WFC(UChar v1, UChar v2, UChar m3, UChar m4)
18369 s390_insn_assert("wfc", m3 == 3);
18370 s390_insn_assert("wfc", m4 == 0);
18372 IRTemp cc_vex = newTemp(Ity_I32);
18373 assign(cc_vex, binop(Iop_CmpF64,
18374 get_vr(v1, Ity_F64, 0), get_vr(v2, Ity_F64, 0)));
18376 IRTemp cc_s390 = newTemp(Ity_I32);
18377 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
18378 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
18380 return "wfc";
18383 static const HChar *
18384 s390_irgen_WFK(UChar v1, UChar v2, UChar m3, UChar m4)
18386 s390_irgen_WFC(v1, v2, m3, m4);
18388 return "wfk";
18391 static const HChar *
18392 s390_irgen_VFCE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
18394 s390_insn_assert("vfce", m4 == 3);
18396 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18397 if (!s390_vr_is_cs_set(m6)) {
18398 if (!isSingleElementOp) {
18399 put_vr_qw(v1, binop(Iop_CmpEQ64Fx2, get_vr_qw(v2), get_vr_qw(v3)));
18400 } else {
18401 IRExpr* comparisonResult = binop(Iop_CmpF64, get_vr(v2, Ity_F64, 0),
18402 get_vr(v3, Ity_F64, 0));
18403 IRExpr* result = mkite(binop(Iop_CmpEQ32, comparisonResult,
18404 mkU32(Ircr_EQ)),
18405 mkU64(0xffffffffffffffffULL),
18406 mkU64(0ULL));
18407 put_vr_qw(v1, binop(Iop_64HLtoV128, result, mkU64(0ULL)));
18409 } else {
18410 IRDirty* d;
18411 IRTemp cc = newTemp(Ity_I64);
18413 s390x_vec_op_details_t details = { .serialized = 0ULL };
18414 details.op = S390_VEC_OP_VFCE;
18415 details.v1 = v1;
18416 details.v2 = v2;
18417 details.v3 = v3;
18418 details.m4 = m4;
18419 details.m5 = m5;
18420 details.m6 = m6;
18422 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18423 &s390x_dirtyhelper_vec_op,
18424 mkIRExprVec_2(IRExpr_GSPTR(),
18425 mkU64(details.serialized)));
18427 const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128);
18428 d->nFxState = 3;
18429 vex_bzero(&d->fxState, sizeof(d->fxState));
18430 d->fxState[0].fx = Ifx_Read;
18431 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18432 d->fxState[0].size = elementSize;
18433 d->fxState[1].fx = Ifx_Read;
18434 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18435 d->fxState[1].size = elementSize;
18436 d->fxState[2].fx = Ifx_Write;
18437 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18438 d->fxState[2].size = sizeof(V128);
18440 stmt(IRStmt_Dirty(d));
18441 s390_cc_set(cc);
18444 return "vfce";
18447 static const HChar *
18448 s390_irgen_VFCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
18450 vassert(m4 == 3);
18452 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18453 if (!s390_vr_is_cs_set(m6)) {
18454 if (!isSingleElementOp) {
18455 put_vr_qw(v1, binop(Iop_CmpLE64Fx2, get_vr_qw(v3), get_vr_qw(v2)));
18456 } else {
18457 IRExpr* comparisonResult = binop(Iop_CmpF64, get_vr(v2, Ity_F64, 0),
18458 get_vr(v3, Ity_F64, 0));
18459 IRExpr* result = mkite(binop(Iop_CmpEQ32, comparisonResult,
18460 mkU32(Ircr_GT)),
18461 mkU64(0xffffffffffffffffULL),
18462 mkU64(0ULL));
18463 put_vr_qw(v1, binop(Iop_64HLtoV128, result, mkU64(0ULL)));
18466 else {
18467 IRDirty* d;
18468 IRTemp cc = newTemp(Ity_I64);
18470 s390x_vec_op_details_t details = { .serialized = 0ULL };
18471 details.op = S390_VEC_OP_VFCH;
18472 details.v1 = v1;
18473 details.v2 = v2;
18474 details.v3 = v3;
18475 details.m4 = m4;
18476 details.m5 = m5;
18477 details.m6 = m6;
18479 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18480 &s390x_dirtyhelper_vec_op,
18481 mkIRExprVec_2(IRExpr_GSPTR(),
18482 mkU64(details.serialized)));
18484 const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128);
18485 d->nFxState = 3;
18486 vex_bzero(&d->fxState, sizeof(d->fxState));
18487 d->fxState[0].fx = Ifx_Read;
18488 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18489 d->fxState[0].size = elementSize;
18490 d->fxState[1].fx = Ifx_Read;
18491 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18492 d->fxState[1].size = elementSize;
18493 d->fxState[2].fx = Ifx_Write;
18494 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18495 d->fxState[2].size = sizeof(V128);
18497 stmt(IRStmt_Dirty(d));
18498 s390_cc_set(cc);
18501 return "vfch";
18504 static const HChar *
18505 s390_irgen_VFCHE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
18507 s390_insn_assert("vfche", m4 == 3);
18509 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18510 if (!s390_vr_is_cs_set(m6)) {
18511 if (!isSingleElementOp) {
18512 put_vr_qw(v1, binop(Iop_CmpLT64Fx2, get_vr_qw(v3), get_vr_qw(v2)));
18514 else {
18515 IRExpr* comparisonResult = binop(Iop_CmpF64, get_vr(v3, Ity_F64, 0),
18516 get_vr(v2, Ity_F64, 0));
18517 IRExpr* result = mkite(binop(Iop_CmpEQ32, comparisonResult,
18518 mkU32(Ircr_LT)),
18519 mkU64(0xffffffffffffffffULL),
18520 mkU64(0ULL));
18521 put_vr_qw(v1, binop(Iop_64HLtoV128, result, mkU64(0ULL)));
18524 else {
18525 IRDirty* d;
18526 IRTemp cc = newTemp(Ity_I64);
18528 s390x_vec_op_details_t details = { .serialized = 0ULL };
18529 details.op = S390_VEC_OP_VFCHE;
18530 details.v1 = v1;
18531 details.v2 = v2;
18532 details.v3 = v3;
18533 details.m4 = m4;
18534 details.m5 = m5;
18535 details.m6 = m6;
18537 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18538 &s390x_dirtyhelper_vec_op,
18539 mkIRExprVec_2(IRExpr_GSPTR(),
18540 mkU64(details.serialized)));
18542 const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128);
18543 d->nFxState = 3;
18544 vex_bzero(&d->fxState, sizeof(d->fxState));
18545 d->fxState[0].fx = Ifx_Read;
18546 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18547 d->fxState[0].size = elementSize;
18548 d->fxState[1].fx = Ifx_Read;
18549 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18550 d->fxState[1].size = elementSize;
18551 d->fxState[2].fx = Ifx_Write;
18552 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18553 d->fxState[2].size = sizeof(V128);
18555 stmt(IRStmt_Dirty(d));
18556 s390_cc_set(cc);
18559 return "vfche";
18562 static const HChar *
18563 s390_irgen_VFTCI(UChar v1, UChar v2, UShort i3, UChar m4, UChar m5)
18565 s390_insn_assert("vftci", m4 == 3);
18567 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18569 IRDirty* d;
18570 IRTemp cc = newTemp(Ity_I64);
18572 s390x_vec_op_details_t details = { .serialized = 0ULL };
18573 details.op = S390_VEC_OP_VFTCI;
18574 details.v1 = v1;
18575 details.v2 = v2;
18576 details.i3 = i3;
18577 details.m4 = m4;
18578 details.m5 = m5;
18580 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18581 &s390x_dirtyhelper_vec_op,
18582 mkIRExprVec_2(IRExpr_GSPTR(),
18583 mkU64(details.serialized)));
18585 const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128);
18586 d->nFxState = 2;
18587 vex_bzero(&d->fxState, sizeof(d->fxState));
18588 d->fxState[0].fx = Ifx_Read;
18589 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18590 d->fxState[0].size = elementSize;
18591 d->fxState[1].fx = Ifx_Write;
18592 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18593 d->fxState[1].size = sizeof(V128);
18595 stmt(IRStmt_Dirty(d));
18596 s390_cc_set(cc);
18598 return "vftci";
18601 /* New insns are added here.
18602 If an insn is contingent on a facility being installed also
18603 check whether the list of supported facilities in function
18604 s390x_dirtyhelper_STFLE needs updating */
18606 /*------------------------------------------------------------*/
18607 /*--- Build IR for special instructions ---*/
18608 /*------------------------------------------------------------*/
18610 static void
18611 s390_irgen_client_request(void)
18613 if (0)
18614 vex_printf("%%R3 = client_request ( %%R2 )\n");
18616 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
18617 + S390_SPECIAL_OP_SIZE;
18619 dis_res->jk_StopHere = Ijk_ClientReq;
18620 dis_res->whatNext = Dis_StopHere;
18622 put_IA(mkaddr_expr(next));
18625 static void
18626 s390_irgen_guest_NRADDR(void)
18628 if (0)
18629 vex_printf("%%R3 = guest_NRADDR\n");
18631 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
18634 static void
18635 s390_irgen_call_noredir(void)
18637 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
18638 + S390_SPECIAL_OP_SIZE;
18640 /* Continue after special op */
18641 put_gpr_dw0(14, mkaddr_expr(next));
18643 /* The address is in REG1, all parameters are in the right (guest) places */
18644 put_IA(get_gpr_dw0(1));
18646 dis_res->whatNext = Dis_StopHere;
18647 dis_res->jk_StopHere = Ijk_NoRedir;
18650 /* Force proper alignment for the structures below. */
18651 #pragma pack(1)
18654 static s390_decode_t
18655 s390_decode_2byte_and_irgen(const UChar *bytes)
18657 typedef union {
18658 struct {
18659 unsigned int op : 16;
18660 } E;
18661 struct {
18662 unsigned int op : 8;
18663 unsigned int i : 8;
18664 } I;
18665 struct {
18666 unsigned int op : 8;
18667 unsigned int r1 : 4;
18668 unsigned int r2 : 4;
18669 } RR;
18670 } formats;
18671 union {
18672 formats fmt;
18673 UShort value;
18674 } ovl;
18676 vassert(sizeof(formats) == 2);
18678 ((UChar *)(&ovl.value))[0] = bytes[0];
18679 ((UChar *)(&ovl.value))[1] = bytes[1];
18681 switch (ovl.value & 0xffff) {
18682 case 0x0101: /* PR */ goto unimplemented;
18683 case 0x0102: /* UPT */ goto unimplemented;
18684 case 0x0104: /* PTFF */ goto unimplemented;
18685 case 0x0107: /* SCKPF */ goto unimplemented;
18686 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
18687 case 0x010b: /* TAM */ goto unimplemented;
18688 case 0x010c: /* SAM24 */ goto unimplemented;
18689 case 0x010d: /* SAM31 */ goto unimplemented;
18690 case 0x010e: /* SAM64 */ goto unimplemented;
18691 case 0x01ff: /* TRAP2 */ goto unimplemented;
18694 switch ((ovl.value & 0xff00) >> 8) {
18695 case 0x04: /* SPM */ goto unimplemented;
18696 case 0x05: /* BALR */ goto unimplemented;
18697 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18698 goto ok;
18699 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18700 goto ok;
18701 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
18702 case 0x0b: /* BSM */ goto unimplemented;
18703 case 0x0c: /* BASSM */ goto unimplemented;
18704 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18705 goto ok;
18706 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18707 goto ok;
18708 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18709 goto ok;
18710 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18711 goto ok;
18712 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18713 goto ok;
18714 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18715 goto ok;
18716 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18717 goto ok;
18718 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18719 goto ok;
18720 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18721 goto ok;
18722 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18723 goto ok;
18724 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18725 goto ok;
18726 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18727 goto ok;
18728 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18729 goto ok;
18730 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18731 goto ok;
18732 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18733 goto ok;
18734 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18735 goto ok;
18736 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18737 goto ok;
18738 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18739 goto ok;
18740 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18741 goto ok;
18742 case 0x20: /* LPDR */ goto unimplemented;
18743 case 0x21: /* LNDR */ goto unimplemented;
18744 case 0x22: /* LTDR */ goto unimplemented;
18745 case 0x23: /* LCDR */ goto unimplemented;
18746 case 0x24: /* HDR */ goto unimplemented;
18747 case 0x25: /* LDXR */ goto unimplemented;
18748 case 0x26: /* MXR */ goto unimplemented;
18749 case 0x27: /* MXDR */ goto unimplemented;
18750 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18751 goto ok;
18752 case 0x29: /* CDR */ goto unimplemented;
18753 case 0x2a: /* ADR */ goto unimplemented;
18754 case 0x2b: /* SDR */ goto unimplemented;
18755 case 0x2c: /* MDR */ goto unimplemented;
18756 case 0x2d: /* DDR */ goto unimplemented;
18757 case 0x2e: /* AWR */ goto unimplemented;
18758 case 0x2f: /* SWR */ goto unimplemented;
18759 case 0x30: /* LPER */ goto unimplemented;
18760 case 0x31: /* LNER */ goto unimplemented;
18761 case 0x32: /* LTER */ goto unimplemented;
18762 case 0x33: /* LCER */ goto unimplemented;
18763 case 0x34: /* HER */ goto unimplemented;
18764 case 0x35: /* LEDR */ goto unimplemented;
18765 case 0x36: /* AXR */ goto unimplemented;
18766 case 0x37: /* SXR */ goto unimplemented;
18767 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
18768 goto ok;
18769 case 0x39: /* CER */ goto unimplemented;
18770 case 0x3a: /* AER */ goto unimplemented;
18771 case 0x3b: /* SER */ goto unimplemented;
18772 case 0x3c: /* MDER */ goto unimplemented;
18773 case 0x3d: /* DER */ goto unimplemented;
18774 case 0x3e: /* AUR */ goto unimplemented;
18775 case 0x3f: /* SUR */ goto unimplemented;
18778 return S390_DECODE_UNKNOWN_INSN;
18781 return S390_DECODE_OK;
18783 unimplemented:
18784 return S390_DECODE_UNIMPLEMENTED_INSN;
18787 static s390_decode_t
18788 s390_decode_4byte_and_irgen(const UChar *bytes)
18790 typedef union {
18791 struct {
18792 unsigned int op1 : 8;
18793 unsigned int r1 : 4;
18794 unsigned int op2 : 4;
18795 unsigned int i2 : 16;
18796 } RI;
18797 struct {
18798 unsigned int op : 16;
18799 unsigned int : 8;
18800 unsigned int r1 : 4;
18801 unsigned int r2 : 4;
18802 } RRE;
18803 struct {
18804 unsigned int op : 16;
18805 unsigned int r1 : 4;
18806 unsigned int : 4;
18807 unsigned int r3 : 4;
18808 unsigned int r2 : 4;
18809 } RRF;
18810 struct {
18811 unsigned int op : 16;
18812 unsigned int m3 : 4;
18813 unsigned int m4 : 4;
18814 unsigned int r1 : 4;
18815 unsigned int r2 : 4;
18816 } RRF2;
18817 struct {
18818 unsigned int op : 16;
18819 unsigned int r3 : 4;
18820 unsigned int : 4;
18821 unsigned int r1 : 4;
18822 unsigned int r2 : 4;
18823 } RRF3;
18824 struct {
18825 unsigned int op : 16;
18826 unsigned int r3 : 4;
18827 unsigned int : 4;
18828 unsigned int r1 : 4;
18829 unsigned int r2 : 4;
18830 } RRR;
18831 struct {
18832 unsigned int op : 16;
18833 unsigned int r3 : 4;
18834 unsigned int m4 : 4;
18835 unsigned int r1 : 4;
18836 unsigned int r2 : 4;
18837 } RRF4;
18838 struct {
18839 unsigned int op : 16;
18840 unsigned int : 4;
18841 unsigned int m4 : 4;
18842 unsigned int r1 : 4;
18843 unsigned int r2 : 4;
18844 } RRF5;
18845 struct {
18846 unsigned int op : 8;
18847 unsigned int r1 : 4;
18848 unsigned int r3 : 4;
18849 unsigned int b2 : 4;
18850 unsigned int d2 : 12;
18851 } RS;
18852 struct {
18853 unsigned int op : 8;
18854 unsigned int r1 : 4;
18855 unsigned int r3 : 4;
18856 unsigned int i2 : 16;
18857 } RSI;
18858 struct {
18859 unsigned int op : 8;
18860 unsigned int r1 : 4;
18861 unsigned int x2 : 4;
18862 unsigned int b2 : 4;
18863 unsigned int d2 : 12;
18864 } RX;
18865 struct {
18866 unsigned int op : 16;
18867 unsigned int b2 : 4;
18868 unsigned int d2 : 12;
18869 } S;
18870 struct {
18871 unsigned int op : 8;
18872 unsigned int i2 : 8;
18873 unsigned int b1 : 4;
18874 unsigned int d1 : 12;
18875 } SI;
18876 } formats;
18877 union {
18878 formats fmt;
18879 UInt value;
18880 } ovl;
18882 vassert(sizeof(formats) == 4);
18884 ((UChar *)(&ovl.value))[0] = bytes[0];
18885 ((UChar *)(&ovl.value))[1] = bytes[1];
18886 ((UChar *)(&ovl.value))[2] = bytes[2];
18887 ((UChar *)(&ovl.value))[3] = bytes[3];
18889 switch ((ovl.value & 0xff0f0000) >> 16) {
18890 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
18891 ovl.fmt.RI.i2); goto ok;
18892 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
18893 ovl.fmt.RI.i2); goto ok;
18894 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
18895 ovl.fmt.RI.i2); goto ok;
18896 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
18897 ovl.fmt.RI.i2); goto ok;
18898 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
18899 ovl.fmt.RI.i2); goto ok;
18900 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
18901 ovl.fmt.RI.i2); goto ok;
18902 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
18903 ovl.fmt.RI.i2); goto ok;
18904 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
18905 ovl.fmt.RI.i2); goto ok;
18906 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
18907 ovl.fmt.RI.i2); goto ok;
18908 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
18909 ovl.fmt.RI.i2); goto ok;
18910 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
18911 ovl.fmt.RI.i2); goto ok;
18912 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
18913 ovl.fmt.RI.i2); goto ok;
18914 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
18915 ovl.fmt.RI.i2); goto ok;
18916 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
18917 ovl.fmt.RI.i2); goto ok;
18918 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
18919 ovl.fmt.RI.i2); goto ok;
18920 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
18921 ovl.fmt.RI.i2); goto ok;
18922 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
18923 ovl.fmt.RI.i2); goto ok;
18924 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
18925 ovl.fmt.RI.i2); goto ok;
18926 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
18927 ovl.fmt.RI.i2); goto ok;
18928 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
18929 ovl.fmt.RI.i2); goto ok;
18930 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
18931 goto ok;
18932 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
18933 ovl.fmt.RI.i2); goto ok;
18934 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
18935 ovl.fmt.RI.i2); goto ok;
18936 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
18937 ovl.fmt.RI.i2); goto ok;
18938 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
18939 goto ok;
18940 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
18941 ovl.fmt.RI.i2); goto ok;
18942 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
18943 goto ok;
18944 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
18945 ovl.fmt.RI.i2); goto ok;
18946 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
18947 goto ok;
18948 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
18949 ovl.fmt.RI.i2); goto ok;
18950 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
18951 goto ok;
18952 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
18953 ovl.fmt.RI.i2); goto ok;
18956 switch ((ovl.value & 0xffff0000) >> 16) {
18957 case 0x8000: /* SSM */ goto unimplemented;
18958 case 0x8200: /* LPSW */ goto unimplemented;
18959 case 0x9300: /* TS */ goto unimplemented;
18960 case 0xb202: /* STIDP */ goto unimplemented;
18961 case 0xb204: /* SCK */ goto unimplemented;
18962 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
18963 goto ok;
18964 case 0xb206: /* SCKC */ goto unimplemented;
18965 case 0xb207: /* STCKC */ goto unimplemented;
18966 case 0xb208: /* SPT */ goto unimplemented;
18967 case 0xb209: /* STPT */ goto unimplemented;
18968 case 0xb20a: /* SPKA */ goto unimplemented;
18969 case 0xb20b: /* IPK */ goto unimplemented;
18970 case 0xb20d: /* PTLB */ goto unimplemented;
18971 case 0xb210: /* SPX */ goto unimplemented;
18972 case 0xb211: /* STPX */ goto unimplemented;
18973 case 0xb212: /* STAP */ goto unimplemented;
18974 case 0xb214: /* SIE */ goto unimplemented;
18975 case 0xb218: /* PC */ goto unimplemented;
18976 case 0xb219: /* SAC */ goto unimplemented;
18977 case 0xb21a: /* CFC */ goto unimplemented;
18978 case 0xb221: /* IPTE */ goto unimplemented;
18979 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
18980 case 0xb223: /* IVSK */ goto unimplemented;
18981 case 0xb224: /* IAC */ goto unimplemented;
18982 case 0xb225: /* SSAR */ goto unimplemented;
18983 case 0xb226: /* EPAR */ goto unimplemented;
18984 case 0xb227: /* ESAR */ goto unimplemented;
18985 case 0xb228: /* PT */ goto unimplemented;
18986 case 0xb229: /* ISKE */ goto unimplemented;
18987 case 0xb22a: /* RRBE */ goto unimplemented;
18988 case 0xb22b: /* SSKE */ goto unimplemented;
18989 case 0xb22c: /* TB */ goto unimplemented;
18990 case 0xb22d: /* DXR */ goto unimplemented;
18991 case 0xb22e: /* PGIN */ goto unimplemented;
18992 case 0xb22f: /* PGOUT */ goto unimplemented;
18993 case 0xb230: /* CSCH */ goto unimplemented;
18994 case 0xb231: /* HSCH */ goto unimplemented;
18995 case 0xb232: /* MSCH */ goto unimplemented;
18996 case 0xb233: /* SSCH */ goto unimplemented;
18997 case 0xb234: /* STSCH */ goto unimplemented;
18998 case 0xb235: /* TSCH */ goto unimplemented;
18999 case 0xb236: /* TPI */ goto unimplemented;
19000 case 0xb237: /* SAL */ goto unimplemented;
19001 case 0xb238: /* RSCH */ goto unimplemented;
19002 case 0xb239: /* STCRW */ goto unimplemented;
19003 case 0xb23a: /* STCPS */ goto unimplemented;
19004 case 0xb23b: /* RCHP */ goto unimplemented;
19005 case 0xb23c: /* SCHM */ goto unimplemented;
19006 case 0xb240: /* BAKR */ goto unimplemented;
19007 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
19008 ovl.fmt.RRE.r2); goto ok;
19009 case 0xb244: /* SQDR */ goto unimplemented;
19010 case 0xb245: /* SQER */ goto unimplemented;
19011 case 0xb246: /* STURA */ goto unimplemented;
19012 case 0xb247: /* MSTA */ goto unimplemented;
19013 case 0xb248: /* PALB */ goto unimplemented;
19014 case 0xb249: /* EREG */ goto unimplemented;
19015 case 0xb24a: /* ESTA */ goto unimplemented;
19016 case 0xb24b: /* LURA */ goto unimplemented;
19017 case 0xb24c: /* TAR */ goto unimplemented;
19018 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
19019 ovl.fmt.RRE.r2); goto ok;
19020 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
19021 goto ok;
19022 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
19023 goto ok;
19024 case 0xb250: /* CSP */ goto unimplemented;
19025 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
19026 ovl.fmt.RRE.r2); goto ok;
19027 case 0xb254: /* MVPG */ goto unimplemented;
19028 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
19029 ovl.fmt.RRE.r2); goto ok;
19030 case 0xb257: /* CUSE */ goto unimplemented;
19031 case 0xb258: /* BSG */ goto unimplemented;
19032 case 0xb25a: /* BSA */ goto unimplemented;
19033 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
19034 ovl.fmt.RRE.r2); goto ok;
19035 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
19036 ovl.fmt.RRE.r2); goto ok;
19037 case 0xb263: /* CMPSC */ goto unimplemented;
19038 case 0xb274: /* SIGA */ goto unimplemented;
19039 case 0xb276: /* XSCH */ goto unimplemented;
19040 case 0xb277: /* RP */ goto unimplemented;
19041 case 0xb278: s390_format_S_RD(s390_irgen_STCKE, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
19042 case 0xb279: /* SACF */ goto unimplemented;
19043 case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
19044 case 0xb27d: /* STSI */ goto unimplemented;
19045 case 0xb280: /* LPP */ goto unimplemented;
19046 case 0xb284: /* LCCTL */ goto unimplemented;
19047 case 0xb285: /* LPCTL */ goto unimplemented;
19048 case 0xb286: /* QSI */ goto unimplemented;
19049 case 0xb287: /* LSCTL */ goto unimplemented;
19050 case 0xb28e: /* QCTRI */ goto unimplemented;
19051 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
19052 goto ok;
19053 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
19054 goto ok;
19055 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
19056 goto ok;
19057 case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2); goto ok;
19058 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
19059 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
19060 goto ok;
19061 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
19062 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
19063 goto ok;
19064 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
19065 goto ok;
19066 case 0xb2b1: /* STFL */ goto unimplemented;
19067 case 0xb2b2: /* LPSWE */ goto unimplemented;
19068 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
19069 goto ok;
19070 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
19071 goto ok;
19072 case 0xb2bd: /* LFAS */ goto unimplemented;
19073 case 0xb2e0: /* SCCTR */ goto unimplemented;
19074 case 0xb2e1: /* SPCTR */ goto unimplemented;
19075 case 0xb2e4: /* ECCTR */ goto unimplemented;
19076 case 0xb2e5: /* EPCTR */ goto unimplemented;
19077 case 0xb2e8: /* PPA */ goto unimplemented;
19078 case 0xb2ec: /* ETND */ goto unimplemented;
19079 case 0xb2ed: /* ECPGA */ goto unimplemented;
19080 case 0xb2f8: /* TEND */ goto unimplemented;
19081 case 0xb2fa: /* NIAI */ goto unimplemented;
19082 case 0xb2fc: /* TABORT */ goto unimplemented;
19083 case 0xb2ff: /* TRAP4 */ goto unimplemented;
19084 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
19085 ovl.fmt.RRE.r2); goto ok;
19086 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
19087 ovl.fmt.RRE.r2); goto ok;
19088 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
19089 ovl.fmt.RRE.r2); goto ok;
19090 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
19091 ovl.fmt.RRE.r2); goto ok;
19092 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
19093 ovl.fmt.RRE.r2); goto ok;
19094 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
19095 ovl.fmt.RRE.r2); goto ok;
19096 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
19097 ovl.fmt.RRE.r2); goto ok;
19098 case 0xb307: /* MXDBR */ goto unimplemented;
19099 case 0xb308: /* KEBR */ goto unimplemented;
19100 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
19101 ovl.fmt.RRE.r2); goto ok;
19102 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
19103 ovl.fmt.RRE.r2); goto ok;
19104 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
19105 ovl.fmt.RRE.r2); goto ok;
19106 case 0xb30c: /* MDEBR */ goto unimplemented;
19107 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
19108 ovl.fmt.RRE.r2); goto ok;
19109 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
19110 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
19111 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
19112 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
19113 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
19114 ovl.fmt.RRE.r2); goto ok;
19115 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
19116 ovl.fmt.RRE.r2); goto ok;
19117 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
19118 ovl.fmt.RRE.r2); goto ok;
19119 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
19120 ovl.fmt.RRE.r2); goto ok;
19121 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
19122 ovl.fmt.RRE.r2); goto ok;
19123 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
19124 ovl.fmt.RRE.r2); goto ok;
19125 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
19126 ovl.fmt.RRE.r2); goto ok;
19127 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
19128 ovl.fmt.RRE.r2); goto ok;
19129 case 0xb318: /* KDBR */ goto unimplemented;
19130 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
19131 ovl.fmt.RRE.r2); goto ok;
19132 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
19133 ovl.fmt.RRE.r2); goto ok;
19134 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
19135 ovl.fmt.RRE.r2); goto ok;
19136 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
19137 ovl.fmt.RRE.r2); goto ok;
19138 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
19139 ovl.fmt.RRE.r2); goto ok;
19140 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
19141 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
19142 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
19143 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
19144 case 0xb324: s390_format_RRE_FF(s390_irgen_LDER, ovl.fmt.RRE.r1,
19145 ovl.fmt.RRE.r2); goto ok;
19146 case 0xb325: /* LXDR */ goto unimplemented;
19147 case 0xb326: /* LXER */ goto unimplemented;
19148 case 0xb32e: /* MAER */ goto unimplemented;
19149 case 0xb32f: /* MSER */ goto unimplemented;
19150 case 0xb336: /* SQXR */ goto unimplemented;
19151 case 0xb337: /* MEER */ goto unimplemented;
19152 case 0xb338: /* MAYLR */ goto unimplemented;
19153 case 0xb339: /* MYLR */ goto unimplemented;
19154 case 0xb33a: /* MAYR */ goto unimplemented;
19155 case 0xb33b: /* MYR */ goto unimplemented;
19156 case 0xb33c: /* MAYHR */ goto unimplemented;
19157 case 0xb33d: /* MYHR */ goto unimplemented;
19158 case 0xb33e: /* MADR */ goto unimplemented;
19159 case 0xb33f: /* MSDR */ goto unimplemented;
19160 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
19161 ovl.fmt.RRE.r2); goto ok;
19162 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
19163 ovl.fmt.RRE.r2); goto ok;
19164 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
19165 ovl.fmt.RRE.r2); goto ok;
19166 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
19167 ovl.fmt.RRE.r2); goto ok;
19168 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
19169 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19170 ovl.fmt.RRF2.r2); goto ok;
19171 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
19172 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19173 ovl.fmt.RRF2.r2); goto ok;
19174 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
19175 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19176 ovl.fmt.RRF2.r2); goto ok;
19177 case 0xb347: s390_format_RRF_UUFF(s390_irgen_FIXBRA, ovl.fmt.RRF2.m3,
19178 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19179 ovl.fmt.RRF2.r2); goto ok;
19180 case 0xb348: /* KXBR */ goto unimplemented;
19181 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
19182 ovl.fmt.RRE.r2); goto ok;
19183 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
19184 ovl.fmt.RRE.r2); goto ok;
19185 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
19186 ovl.fmt.RRE.r2); goto ok;
19187 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
19188 ovl.fmt.RRE.r2); goto ok;
19189 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
19190 ovl.fmt.RRE.r2); goto ok;
19191 case 0xb350: /* TBEDR */ goto unimplemented;
19192 case 0xb351: /* TBDR */ goto unimplemented;
19193 case 0xb353: /* DIEBR */ goto unimplemented;
19194 case 0xb357: s390_format_RRF_UUFF(s390_irgen_FIEBRA, ovl.fmt.RRF2.m3,
19195 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19196 ovl.fmt.RRF2.r2); goto ok;
19197 case 0xb358: /* THDER */ goto unimplemented;
19198 case 0xb359: /* THDR */ goto unimplemented;
19199 case 0xb35b: /* DIDBR */ goto unimplemented;
19200 case 0xb35f: s390_format_RRF_UUFF(s390_irgen_FIDBRA, ovl.fmt.RRF2.m3,
19201 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19202 ovl.fmt.RRF2.r2); goto ok;
19203 case 0xb360: /* LPXR */ goto unimplemented;
19204 case 0xb361: /* LNXR */ goto unimplemented;
19205 case 0xb362: /* LTXR */ goto unimplemented;
19206 case 0xb363: /* LCXR */ goto unimplemented;
19207 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
19208 ovl.fmt.RRE.r2); goto ok;
19209 case 0xb366: /* LEXR */ goto unimplemented;
19210 case 0xb367: /* FIXR */ goto unimplemented;
19211 case 0xb369: /* CXR */ goto unimplemented;
19212 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
19213 ovl.fmt.RRE.r2); goto ok;
19214 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
19215 ovl.fmt.RRE.r2); goto ok;
19216 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
19217 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
19218 goto ok;
19219 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
19220 ovl.fmt.RRE.r2); goto ok;
19221 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
19222 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
19223 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
19224 case 0xb377: /* FIER */ goto unimplemented;
19225 case 0xb37f: /* FIDR */ goto unimplemented;
19226 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
19227 case 0xb385: /* SFASR */ goto unimplemented;
19228 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
19229 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
19230 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19231 ovl.fmt.RRF2.r2); goto ok;
19232 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
19233 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19234 ovl.fmt.RRF2.r2); goto ok;
19235 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
19236 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19237 ovl.fmt.RRF2.r2); goto ok;
19238 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
19239 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19240 ovl.fmt.RRF2.r2); goto ok;
19241 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
19242 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19243 ovl.fmt.RRF2.r2); goto ok;
19244 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
19245 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19246 ovl.fmt.RRF2.r2); goto ok;
19247 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
19248 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19249 ovl.fmt.RRF2.r2); goto ok;
19250 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
19251 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19252 ovl.fmt.RRF2.r2); goto ok;
19253 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
19254 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19255 ovl.fmt.RRF2.r2); goto ok;
19256 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
19257 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19258 ovl.fmt.RRF2.r2); goto ok;
19259 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
19260 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19261 ovl.fmt.RRF2.r2); goto ok;
19262 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
19263 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19264 ovl.fmt.RRF2.r2); goto ok;
19265 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
19266 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19267 ovl.fmt.RRF2.r2); goto ok;
19268 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
19269 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19270 ovl.fmt.RRF2.r2); goto ok;
19271 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
19272 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19273 ovl.fmt.RRF2.r2); goto ok;
19274 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
19275 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19276 ovl.fmt.RRF2.r2); goto ok;
19277 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
19278 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19279 ovl.fmt.RRF2.r2); goto ok;
19280 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
19281 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19282 ovl.fmt.RRF2.r2); goto ok;
19283 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
19284 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19285 ovl.fmt.RRF2.r2); goto ok;
19286 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
19287 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19288 ovl.fmt.RRF2.r2); goto ok;
19289 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
19290 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19291 ovl.fmt.RRF2.r2); goto ok;
19292 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
19293 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19294 ovl.fmt.RRF2.r2); goto ok;
19295 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
19296 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19297 ovl.fmt.RRF2.r2); goto ok;
19298 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
19299 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19300 ovl.fmt.RRF2.r2); goto ok;
19301 case 0xb3b4: /* CEFR */ goto unimplemented;
19302 case 0xb3b5: /* CDFR */ goto unimplemented;
19303 case 0xb3b6: /* CXFR */ goto unimplemented;
19304 case 0xb3b8: /* CFER */ goto unimplemented;
19305 case 0xb3b9: /* CFDR */ goto unimplemented;
19306 case 0xb3ba: /* CFXR */ goto unimplemented;
19307 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
19308 ovl.fmt.RRE.r2); goto ok;
19309 case 0xb3c4: /* CEGR */ goto unimplemented;
19310 case 0xb3c5: /* CDGR */ goto unimplemented;
19311 case 0xb3c6: /* CXGR */ goto unimplemented;
19312 case 0xb3c8: /* CGER */ goto unimplemented;
19313 case 0xb3c9: /* CGDR */ goto unimplemented;
19314 case 0xb3ca: /* CGXR */ goto unimplemented;
19315 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
19316 ovl.fmt.RRE.r2); goto ok;
19317 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
19318 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19319 ovl.fmt.RRF4.r2); goto ok;
19320 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
19321 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19322 ovl.fmt.RRF4.r2); goto ok;
19323 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
19324 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19325 ovl.fmt.RRF4.r2); goto ok;
19326 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
19327 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19328 ovl.fmt.RRF4.r2); goto ok;
19329 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
19330 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
19331 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
19332 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19333 ovl.fmt.RRF2.r2); goto ok;
19334 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
19335 ovl.fmt.RRE.r2); goto ok;
19336 case 0xb3d7: /* FIDTR */ goto unimplemented;
19337 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
19338 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19339 ovl.fmt.RRF4.r2); goto ok;
19340 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
19341 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19342 ovl.fmt.RRF4.r2); goto ok;
19343 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
19344 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19345 ovl.fmt.RRF4.r2); goto ok;
19346 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
19347 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19348 ovl.fmt.RRF4.r2); goto ok;
19349 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
19350 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
19351 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
19352 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19353 ovl.fmt.RRF2.r2); goto ok;
19354 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
19355 ovl.fmt.RRE.r2); goto ok;
19356 case 0xb3df: /* FIXTR */ goto unimplemented;
19357 case 0xb3e0: /* KDTR */ goto unimplemented;
19358 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
19359 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19360 ovl.fmt.RRF2.r2); goto ok;
19361 case 0xb3e2: /* CUDTR */ goto unimplemented;
19362 case 0xb3e3: /* CSDTR */ goto unimplemented;
19363 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
19364 ovl.fmt.RRE.r2); goto ok;
19365 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
19366 ovl.fmt.RRE.r2); goto ok;
19367 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
19368 ovl.fmt.RRE.r2); goto ok;
19369 case 0xb3e8: /* KXTR */ goto unimplemented;
19370 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
19371 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19372 ovl.fmt.RRF2.r2); goto ok;
19373 case 0xb3ea: /* CUXTR */ goto unimplemented;
19374 case 0xb3eb: /* CSXTR */ goto unimplemented;
19375 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
19376 ovl.fmt.RRE.r2); goto ok;
19377 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
19378 ovl.fmt.RRE.r2); goto ok;
19379 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
19380 ovl.fmt.RRE.r2); goto ok;
19381 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
19382 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19383 ovl.fmt.RRF2.r2); goto ok;
19384 case 0xb3f2: /* CDUTR */ goto unimplemented;
19385 case 0xb3f3: /* CDSTR */ goto unimplemented;
19386 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
19387 ovl.fmt.RRE.r2); goto ok;
19388 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
19389 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19390 ovl.fmt.RRF4.r2); goto ok;
19391 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
19392 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
19393 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
19394 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19395 ovl.fmt.RRF4.r2); goto ok;
19396 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
19397 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19398 ovl.fmt.RRF2.r2); goto ok;
19399 case 0xb3fa: /* CXUTR */ goto unimplemented;
19400 case 0xb3fb: /* CXSTR */ goto unimplemented;
19401 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
19402 ovl.fmt.RRE.r2); goto ok;
19403 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
19404 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19405 ovl.fmt.RRF4.r2); goto ok;
19406 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
19407 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
19408 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
19409 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
19410 ovl.fmt.RRF4.r2); goto ok;
19411 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
19412 ovl.fmt.RRE.r2); goto ok;
19413 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
19414 ovl.fmt.RRE.r2); goto ok;
19415 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
19416 ovl.fmt.RRE.r2); goto ok;
19417 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
19418 ovl.fmt.RRE.r2); goto ok;
19419 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
19420 ovl.fmt.RRE.r2); goto ok;
19421 case 0xb905: /* LURAG */ goto unimplemented;
19422 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
19423 ovl.fmt.RRE.r2); goto ok;
19424 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
19425 ovl.fmt.RRE.r2); goto ok;
19426 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
19427 ovl.fmt.RRE.r2); goto ok;
19428 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
19429 ovl.fmt.RRE.r2); goto ok;
19430 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
19431 ovl.fmt.RRE.r2); goto ok;
19432 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
19433 ovl.fmt.RRE.r2); goto ok;
19434 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
19435 ovl.fmt.RRE.r2); goto ok;
19436 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
19437 ovl.fmt.RRE.r2); goto ok;
19438 case 0xb90e: /* EREGG */ goto unimplemented;
19439 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
19440 ovl.fmt.RRE.r2); goto ok;
19441 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
19442 ovl.fmt.RRE.r2); goto ok;
19443 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
19444 ovl.fmt.RRE.r2); goto ok;
19445 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
19446 ovl.fmt.RRE.r2); goto ok;
19447 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
19448 ovl.fmt.RRE.r2); goto ok;
19449 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
19450 ovl.fmt.RRE.r2); goto ok;
19451 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
19452 ovl.fmt.RRE.r2); goto ok;
19453 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
19454 ovl.fmt.RRE.r2); goto ok;
19455 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
19456 ovl.fmt.RRE.r2); goto ok;
19457 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
19458 ovl.fmt.RRE.r2); goto ok;
19459 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
19460 ovl.fmt.RRE.r2); goto ok;
19461 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
19462 ovl.fmt.RRE.r2); goto ok;
19463 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
19464 ovl.fmt.RRE.r2); goto ok;
19465 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
19466 ovl.fmt.RRE.r2); goto ok;
19467 case 0xb91e: /* KMAC */ goto unimplemented;
19468 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
19469 ovl.fmt.RRE.r2); goto ok;
19470 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
19471 ovl.fmt.RRE.r2); goto ok;
19472 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
19473 ovl.fmt.RRE.r2); goto ok;
19474 case 0xb925: /* STURG */ goto unimplemented;
19475 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
19476 ovl.fmt.RRE.r2); goto ok;
19477 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
19478 ovl.fmt.RRE.r2); goto ok;
19479 case 0xb928: /* PCKMO */ goto unimplemented;
19480 case 0xb929: /* KMA */ goto unimplemented;
19481 case 0xb92a: /* KMF */ goto unimplemented;
19482 case 0xb92b: /* KMO */ goto unimplemented;
19483 case 0xb92c: /* PCC */ goto unimplemented;
19484 case 0xb92d: /* KMCTR */ goto unimplemented;
19485 case 0xb92e: /* KM */ goto unimplemented;
19486 case 0xb92f: /* KMC */ goto unimplemented;
19487 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
19488 ovl.fmt.RRE.r2); goto ok;
19489 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
19490 ovl.fmt.RRE.r2); goto ok;
19491 case 0xb93c: s390_format_RRE_RR(s390_irgen_PPNO, ovl.fmt.RRE.r1,
19492 ovl.fmt.RRE.r2); goto ok;
19493 case 0xb93e: /* KIMD */ goto unimplemented;
19494 case 0xb93f: /* KLMD */ goto unimplemented;
19495 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
19496 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19497 ovl.fmt.RRF2.r2); goto ok;
19498 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
19499 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19500 ovl.fmt.RRF2.r2); goto ok;
19501 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
19502 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19503 ovl.fmt.RRF2.r2); goto ok;
19504 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
19505 ovl.fmt.RRE.r2); goto ok;
19506 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
19507 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19508 ovl.fmt.RRF2.r2); goto ok;
19509 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
19510 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19511 ovl.fmt.RRF2.r2); goto ok;
19512 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
19513 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19514 ovl.fmt.RRF2.r2); goto ok;
19515 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
19516 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19517 ovl.fmt.RRF2.r2); goto ok;
19518 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
19519 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19520 ovl.fmt.RRF2.r2); goto ok;
19521 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
19522 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19523 ovl.fmt.RRF2.r2); goto ok;
19524 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
19525 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19526 ovl.fmt.RRF2.r2); goto ok;
19527 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
19528 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19529 ovl.fmt.RRF2.r2); goto ok;
19530 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
19531 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
19532 ovl.fmt.RRF2.r2); goto ok;
19533 case 0xb960: s390_format_RRF_U0RR(s390_irgen_CGRT, ovl.fmt.RRF2.m3,
19534 ovl.fmt.RRF2.r1, ovl.fmt.RRF2.r2,
19535 S390_XMNM_CAB); goto ok;
19536 case 0xb961: s390_format_RRF_U0RR(s390_irgen_CLGRT, ovl.fmt.RRF2.m3,
19537 ovl.fmt.RRF2.r1, ovl.fmt.RRF2.r2,
19538 S390_XMNM_CAB); goto ok;
19539 case 0xb972: s390_format_RRF_U0RR(s390_irgen_CRT, ovl.fmt.RRF2.m3,
19540 ovl.fmt.RRF2.r1, ovl.fmt.RRF2.r2,
19541 S390_XMNM_CAB); goto ok;
19542 case 0xb973: s390_format_RRF_U0RR(s390_irgen_CLRT, ovl.fmt.RRF2.m3,
19543 ovl.fmt.RRF2.r1, ovl.fmt.RRF2.r2,
19544 S390_XMNM_CAB); goto ok;
19545 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
19546 ovl.fmt.RRE.r2); goto ok;
19547 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
19548 ovl.fmt.RRE.r2); goto ok;
19549 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
19550 ovl.fmt.RRE.r2); goto ok;
19551 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
19552 ovl.fmt.RRE.r2); goto ok;
19553 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
19554 ovl.fmt.RRE.r2); goto ok;
19555 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
19556 ovl.fmt.RRE.r2); goto ok;
19557 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
19558 ovl.fmt.RRE.r2); goto ok;
19559 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
19560 ovl.fmt.RRE.r2); goto ok;
19561 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
19562 ovl.fmt.RRE.r2); goto ok;
19563 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
19564 ovl.fmt.RRE.r2); goto ok;
19565 case 0xb98a: /* CSPG */ goto unimplemented;
19566 case 0xb98d: /* EPSW */ goto unimplemented;
19567 case 0xb98e: /* IDTE */ goto unimplemented;
19568 case 0xb98f: /* CRDTE */ goto unimplemented;
19569 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
19570 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
19571 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
19572 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
19573 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
19574 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
19575 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
19576 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
19577 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
19578 ovl.fmt.RRE.r2); goto ok;
19579 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
19580 ovl.fmt.RRE.r2); goto ok;
19581 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
19582 ovl.fmt.RRE.r2); goto ok;
19583 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
19584 ovl.fmt.RRE.r2); goto ok;
19585 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
19586 ovl.fmt.RRE.r2); goto ok;
19587 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
19588 ovl.fmt.RRE.r2); goto ok;
19589 case 0xb99a: /* EPAIR */ goto unimplemented;
19590 case 0xb99b: /* ESAIR */ goto unimplemented;
19591 case 0xb99d: /* ESEA */ goto unimplemented;
19592 case 0xb99e: /* PTI */ goto unimplemented;
19593 case 0xb99f: /* SSAIR */ goto unimplemented;
19594 case 0xb9a2: /* PTF */ goto unimplemented;
19595 case 0xb9aa: /* LPTEA */ goto unimplemented;
19596 case 0xb9ae: /* RRBM */ goto unimplemented;
19597 case 0xb9af: /* PFMF */ goto unimplemented;
19598 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
19599 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
19600 goto ok;
19601 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
19602 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
19603 goto ok;
19604 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
19605 ovl.fmt.RRE.r2); goto ok;
19606 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
19607 ovl.fmt.RRE.r2); goto ok;
19608 case 0xb9bd: /* TRTRE */ goto unimplemented;
19609 case 0xb9be: /* SRSTU */ goto unimplemented;
19610 case 0xb9bf: /* TRTE */ goto unimplemented;
19611 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
19612 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19613 goto ok;
19614 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
19615 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19616 goto ok;
19617 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
19618 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19619 goto ok;
19620 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
19621 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19622 goto ok;
19623 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
19624 ovl.fmt.RRE.r2); goto ok;
19625 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
19626 ovl.fmt.RRE.r2); goto ok;
19627 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
19628 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19629 goto ok;
19630 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
19631 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19632 goto ok;
19633 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
19634 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19635 goto ok;
19636 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
19637 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19638 goto ok;
19639 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
19640 ovl.fmt.RRE.r2); goto ok;
19641 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
19642 ovl.fmt.RRE.r2); goto ok;
19643 case 0xb9e0: s390_format_RRF_U0RR(s390_irgen_LOCFHR, ovl.fmt.RRF3.r3,
19644 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
19645 S390_XMNM_LOCFHR); goto ok;
19646 case 0xb9e1: s390_format_RRE_RR(s390_irgen_POPCNT, ovl.fmt.RRE.r1,
19647 ovl.fmt.RRE.r2); goto ok;
19648 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
19649 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
19650 S390_XMNM_LOCGR); goto ok;
19651 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
19652 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19653 goto ok;
19654 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
19655 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19656 goto ok;
19657 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
19658 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19659 goto ok;
19660 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
19661 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19662 goto ok;
19663 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
19664 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19665 goto ok;
19666 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
19667 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19668 goto ok;
19669 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
19670 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19671 goto ok;
19672 case 0xb9ec: /* MGRK */ goto unimplemented;
19673 case 0xb9ed: /* MSGRKC */ goto unimplemented;
19674 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
19675 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
19676 S390_XMNM_LOCR); goto ok;
19677 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
19678 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19679 goto ok;
19680 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
19681 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19682 goto ok;
19683 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
19684 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19685 goto ok;
19686 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
19687 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19688 goto ok;
19689 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
19690 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19691 goto ok;
19692 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
19693 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19694 goto ok;
19695 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
19696 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
19697 goto ok;
19698 case 0xb9fd: /* MSRKC */ goto unimplemented;
19701 switch ((ovl.value & 0xff000000) >> 24) {
19702 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19703 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19704 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19705 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19706 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19707 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19708 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19709 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19710 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19711 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19712 case 0x45: /* BAL */ goto unimplemented;
19713 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19714 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19715 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19716 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19717 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19718 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19719 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19720 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19721 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19722 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19723 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19724 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19725 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19726 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19727 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19728 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19729 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19730 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19731 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19732 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19733 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19734 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19735 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19736 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19737 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19738 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19739 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19740 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19741 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19742 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19743 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19744 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19745 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19746 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19747 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19748 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19749 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19750 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19751 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19752 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19753 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19754 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19755 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19756 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19757 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19758 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19759 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19760 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19761 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19762 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19763 case 0x67: /* MXD */ goto unimplemented;
19764 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19765 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19766 case 0x69: /* CD */ goto unimplemented;
19767 case 0x6a: /* AD */ goto unimplemented;
19768 case 0x6b: /* SD */ goto unimplemented;
19769 case 0x6c: /* MD */ goto unimplemented;
19770 case 0x6d: /* DD */ goto unimplemented;
19771 case 0x6e: /* AW */ goto unimplemented;
19772 case 0x6f: /* SW */ goto unimplemented;
19773 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19774 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19775 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19776 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19777 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
19778 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
19779 case 0x79: /* CE */ goto unimplemented;
19780 case 0x7a: /* AE */ goto unimplemented;
19781 case 0x7b: /* SE */ goto unimplemented;
19782 case 0x7c: /* MDE */ goto unimplemented;
19783 case 0x7d: /* DE */ goto unimplemented;
19784 case 0x7e: /* AU */ goto unimplemented;
19785 case 0x7f: /* SU */ goto unimplemented;
19786 case 0x83: /* DIAG */ goto unimplemented;
19787 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
19788 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
19789 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
19790 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
19791 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19792 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19793 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19794 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19795 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
19796 ovl.fmt.RS.d2); goto ok;
19797 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
19798 ovl.fmt.RS.d2); goto ok;
19799 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
19800 ovl.fmt.RS.d2); goto ok;
19801 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
19802 ovl.fmt.RS.d2); goto ok;
19803 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
19804 ovl.fmt.RS.d2); goto ok;
19805 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
19806 ovl.fmt.RS.d2); goto ok;
19807 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
19808 ovl.fmt.RS.d2); goto ok;
19809 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
19810 ovl.fmt.RS.d2); goto ok;
19811 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19812 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19813 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
19814 ovl.fmt.SI.d1); goto ok;
19815 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
19816 ovl.fmt.SI.d1); goto ok;
19817 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
19818 ovl.fmt.SI.d1); goto ok;
19819 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
19820 ovl.fmt.SI.d1); goto ok;
19821 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
19822 ovl.fmt.SI.d1); goto ok;
19823 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
19824 ovl.fmt.SI.d1); goto ok;
19825 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19826 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19827 case 0x99: /* TRACE */ goto unimplemented;
19828 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19829 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19830 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19831 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19832 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
19833 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
19834 goto ok;
19835 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
19836 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
19837 goto ok;
19838 case 0xac: /* STNSM */ goto unimplemented;
19839 case 0xad: /* STOSM */ goto unimplemented;
19840 case 0xae: /* SIGP */ goto unimplemented;
19841 case 0xaf: /* MC */ goto unimplemented;
19842 case 0xb1: /* LRA */ goto unimplemented;
19843 case 0xb6: /* STCTL */ goto unimplemented;
19844 case 0xb7: /* LCTL */ goto unimplemented;
19845 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19846 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19847 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19848 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19849 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19850 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19851 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19852 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19853 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
19854 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
19857 return S390_DECODE_UNKNOWN_INSN;
19860 return S390_DECODE_OK;
19862 unimplemented:
19863 return S390_DECODE_UNIMPLEMENTED_INSN;
19866 static s390_decode_t
19867 s390_decode_6byte_and_irgen(const UChar *bytes)
19869 typedef union {
19870 struct {
19871 unsigned int op1 : 8;
19872 unsigned int r1 : 4;
19873 unsigned int r3 : 4;
19874 unsigned int i2 : 16;
19875 unsigned int : 8;
19876 unsigned int op2 : 8;
19877 } RIE;
19878 struct {
19879 unsigned int op1 : 8;
19880 unsigned int r1 : 4;
19881 unsigned int r2 : 4;
19882 unsigned int i3 : 8;
19883 unsigned int i4 : 8;
19884 unsigned int i5 : 8;
19885 unsigned int op2 : 8;
19886 } RIE_RRUUU;
19887 struct {
19888 unsigned int op1 : 8;
19889 unsigned int r1 : 4;
19890 unsigned int : 4;
19891 unsigned int i2 : 16;
19892 unsigned int m3 : 4;
19893 unsigned int : 4;
19894 unsigned int op2 : 8;
19895 } RIEv1;
19896 struct {
19897 unsigned int op1 : 8;
19898 unsigned int r1 : 4;
19899 unsigned int r2 : 4;
19900 unsigned int i4 : 16;
19901 unsigned int m3 : 4;
19902 unsigned int : 4;
19903 unsigned int op2 : 8;
19904 } RIE_RRPU;
19905 struct {
19906 unsigned int op1 : 8;
19907 unsigned int r1 : 4;
19908 unsigned int m3 : 4;
19909 unsigned int i4 : 16;
19910 unsigned int i2 : 8;
19911 unsigned int op2 : 8;
19912 } RIEv3;
19913 struct {
19914 unsigned int op1 : 8;
19915 unsigned int r1 : 4;
19916 unsigned int op2 : 4;
19917 unsigned int i2 : 32;
19918 } RIL;
19919 struct {
19920 unsigned int op1 : 8;
19921 unsigned int r1 : 4;
19922 unsigned int m3 : 4;
19923 unsigned int b4 : 4;
19924 unsigned int d4 : 12;
19925 unsigned int i2 : 8;
19926 unsigned int op2 : 8;
19927 } RIS;
19928 struct {
19929 unsigned int op1 : 8;
19930 unsigned int r1 : 4;
19931 unsigned int r2 : 4;
19932 unsigned int b4 : 4;
19933 unsigned int d4 : 12;
19934 unsigned int m3 : 4;
19935 unsigned int : 4;
19936 unsigned int op2 : 8;
19937 } RRS;
19938 struct {
19939 unsigned int op1 : 8;
19940 unsigned int l1 : 4;
19941 unsigned int : 4;
19942 unsigned int b1 : 4;
19943 unsigned int d1 : 12;
19944 unsigned int : 8;
19945 unsigned int op2 : 8;
19946 } RSL;
19947 struct {
19948 unsigned int op1 : 8;
19949 unsigned int r1 : 4;
19950 unsigned int r3 : 4;
19951 unsigned int b2 : 4;
19952 unsigned int dl2 : 12;
19953 unsigned int dh2 : 8;
19954 unsigned int op2 : 8;
19955 } RSY;
19956 struct {
19957 unsigned int op1 : 8;
19958 unsigned int r1 : 4;
19959 unsigned int x2 : 4;
19960 unsigned int b2 : 4;
19961 unsigned int d2 : 12;
19962 unsigned int m3 : 4;
19963 unsigned int : 4;
19964 unsigned int op2 : 8;
19965 } RXE;
19966 struct {
19967 unsigned int op1 : 8;
19968 unsigned int r3 : 4;
19969 unsigned int x2 : 4;
19970 unsigned int b2 : 4;
19971 unsigned int d2 : 12;
19972 unsigned int r1 : 4;
19973 unsigned int : 4;
19974 unsigned int op2 : 8;
19975 } RXF;
19976 struct {
19977 unsigned int op1 : 8;
19978 unsigned int r1 : 4;
19979 unsigned int x2 : 4;
19980 unsigned int b2 : 4;
19981 unsigned int dl2 : 12;
19982 unsigned int dh2 : 8;
19983 unsigned int op2 : 8;
19984 } RXY;
19985 struct {
19986 unsigned int op1 : 8;
19987 unsigned int i2 : 8;
19988 unsigned int b1 : 4;
19989 unsigned int dl1 : 12;
19990 unsigned int dh1 : 8;
19991 unsigned int op2 : 8;
19992 } SIY;
19993 struct {
19994 unsigned int op : 8;
19995 unsigned int l : 8;
19996 unsigned int b1 : 4;
19997 unsigned int d1 : 12;
19998 unsigned int b2 : 4;
19999 unsigned int d2 : 12;
20000 } SS;
20001 struct {
20002 unsigned int op : 8;
20003 unsigned int l1 : 4;
20004 unsigned int l2 : 4;
20005 unsigned int b1 : 4;
20006 unsigned int d1 : 12;
20007 unsigned int b2 : 4;
20008 unsigned int d2 : 12;
20009 } SS_LLRDRD;
20010 struct {
20011 unsigned int op : 8;
20012 unsigned int r1 : 4;
20013 unsigned int r3 : 4;
20014 unsigned int b2 : 4;
20015 unsigned int d2 : 12;
20016 unsigned int b4 : 4;
20017 unsigned int d4 : 12;
20018 } SS_RRRDRD2;
20019 struct {
20020 unsigned int op : 16;
20021 unsigned int b1 : 4;
20022 unsigned int d1 : 12;
20023 unsigned int b2 : 4;
20024 unsigned int d2 : 12;
20025 } SSE;
20026 struct {
20027 unsigned int op1 : 8;
20028 unsigned int r3 : 4;
20029 unsigned int op2 : 4;
20030 unsigned int b1 : 4;
20031 unsigned int d1 : 12;
20032 unsigned int b2 : 4;
20033 unsigned int d2 : 12;
20034 } SSF;
20035 struct {
20036 unsigned int op : 16;
20037 unsigned int b1 : 4;
20038 unsigned int d1 : 12;
20039 unsigned int i2 : 16;
20040 } SIL;
20041 struct {
20042 unsigned int op1 : 8;
20043 unsigned int v1 : 4;
20044 unsigned int x2 : 4;
20045 unsigned int b2 : 4;
20046 unsigned int d2 : 12;
20047 unsigned int m3 : 4;
20048 unsigned int rxb : 4;
20049 unsigned int op2 : 8;
20050 } VRX;
20051 struct {
20052 unsigned int op1 : 8;
20053 unsigned int v1 : 4;
20054 unsigned int v2 : 4;
20055 unsigned int r3 : 4;
20056 unsigned int : 4;
20057 unsigned int m5 : 4;
20058 unsigned int : 4;
20059 unsigned int m4 : 4;
20060 unsigned int rxb : 4;
20061 unsigned int op2 : 8;
20062 } VRR;
20063 struct {
20064 UInt op1 : 8;
20065 UInt v1 : 4;
20066 UInt v2 : 4;
20067 UInt v3 : 4;
20068 UInt : 4;
20069 UInt m5 : 4;
20070 UInt m4 : 4;
20071 UInt m3 : 4;
20072 UInt rxb : 4;
20073 UInt op2 : 8;
20074 } VRRa;
20075 struct {
20076 unsigned int op1 : 8;
20077 unsigned int v1 : 4;
20078 unsigned int v2 : 4;
20079 unsigned int v3 : 4;
20080 unsigned int m5 : 4;
20081 unsigned int m6 : 4;
20082 unsigned int : 4;
20083 unsigned int v4 : 4;
20084 unsigned int rxb : 4;
20085 unsigned int op2 : 8;
20086 } VRRd;
20087 struct {
20088 unsigned int op1 : 8;
20089 unsigned int v1 : 4;
20090 unsigned int v2 : 4;
20091 unsigned int v3 : 4;
20092 unsigned int m6 : 4;
20093 unsigned int : 4;
20094 unsigned int m5 : 4;
20095 unsigned int v4 : 4;
20096 unsigned int rxb : 4;
20097 unsigned int op2 : 8;
20098 } VRRe;
20099 struct {
20100 unsigned int op1 : 8;
20101 unsigned int v1 : 4;
20102 unsigned int v3 : 4;
20103 unsigned int i2 : 16;
20104 unsigned int m3 : 4;
20105 unsigned int rxb : 4;
20106 unsigned int op2 : 8;
20107 } VRI;
20108 struct {
20109 unsigned int op1 : 8;
20110 unsigned int v1 : 4;
20111 unsigned int v2 : 4;
20112 unsigned int v3 : 4;
20113 unsigned int : 4;
20114 unsigned int i4 : 8;
20115 unsigned int m5 : 4;
20116 unsigned int rxb : 4;
20117 unsigned int op2 : 8;
20118 } VRId;
20119 struct {
20120 UInt op1 : 8;
20121 UInt v1 : 4;
20122 UInt v2 : 4;
20123 UInt i3 : 12;
20124 UInt m5 : 4;
20125 UInt m4 : 4;
20126 UInt rxb : 4;
20127 UInt op2 : 8;
20128 } VRIe;
20129 struct {
20130 unsigned int op1 : 8;
20131 unsigned int v1 : 4;
20132 unsigned int v3 : 4;
20133 unsigned int b2 : 4;
20134 unsigned int d2 : 12;
20135 unsigned int m4 : 4;
20136 unsigned int rxb : 4;
20137 unsigned int op2 : 8;
20138 } VRS;
20139 struct {
20140 unsigned int op1 : 8;
20141 unsigned int v1 : 4;
20142 unsigned int v2 : 4;
20143 unsigned int b2 : 4;
20144 unsigned int d2 : 12;
20145 unsigned int m3 : 4;
20146 unsigned int rxb : 4;
20147 unsigned int op2 : 8;
20148 } VRV;
20149 } formats;
20150 union {
20151 formats fmt;
20152 ULong value;
20153 } ovl;
20155 vassert(sizeof(formats) == 6);
20157 ((UChar *)(&ovl.value))[0] = bytes[0];
20158 ((UChar *)(&ovl.value))[1] = bytes[1];
20159 ((UChar *)(&ovl.value))[2] = bytes[2];
20160 ((UChar *)(&ovl.value))[3] = bytes[3];
20161 ((UChar *)(&ovl.value))[4] = bytes[4];
20162 ((UChar *)(&ovl.value))[5] = bytes[5];
20163 ((UChar *)(&ovl.value))[6] = 0x0;
20164 ((UChar *)(&ovl.value))[7] = 0x0;
20166 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
20167 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
20168 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20169 ovl.fmt.RXY.dl2,
20170 ovl.fmt.RXY.dh2); goto ok;
20171 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
20172 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
20173 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20174 ovl.fmt.RXY.dl2,
20175 ovl.fmt.RXY.dh2); goto ok;
20176 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
20177 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20178 ovl.fmt.RXY.dl2,
20179 ovl.fmt.RXY.dh2); goto ok;
20180 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
20181 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20182 ovl.fmt.RXY.dl2,
20183 ovl.fmt.RXY.dh2); goto ok;
20184 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
20185 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20186 ovl.fmt.RXY.dl2,
20187 ovl.fmt.RXY.dh2); goto ok;
20188 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
20189 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20190 ovl.fmt.RXY.dl2,
20191 ovl.fmt.RXY.dh2); goto ok;
20192 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
20193 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20194 ovl.fmt.RXY.dl2,
20195 ovl.fmt.RXY.dh2); goto ok;
20196 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
20197 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20198 ovl.fmt.RXY.dl2,
20199 ovl.fmt.RXY.dh2); goto ok;
20200 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
20201 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20202 ovl.fmt.RXY.dl2,
20203 ovl.fmt.RXY.dh2); goto ok;
20204 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
20205 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
20206 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20207 ovl.fmt.RXY.dl2,
20208 ovl.fmt.RXY.dh2); goto ok;
20209 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
20210 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20211 ovl.fmt.RXY.dl2,
20212 ovl.fmt.RXY.dh2); goto ok;
20213 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
20214 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
20215 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20216 ovl.fmt.RXY.dl2,
20217 ovl.fmt.RXY.dh2); goto ok;
20218 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
20219 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20220 ovl.fmt.RXY.dl2,
20221 ovl.fmt.RXY.dh2); goto ok;
20222 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
20223 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20224 ovl.fmt.RXY.dl2,
20225 ovl.fmt.RXY.dh2); goto ok;
20226 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
20227 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20228 ovl.fmt.RXY.dl2,
20229 ovl.fmt.RXY.dh2); goto ok;
20230 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
20231 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20232 ovl.fmt.RXY.dl2,
20233 ovl.fmt.RXY.dh2); goto ok;
20234 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
20235 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20236 ovl.fmt.RXY.dl2,
20237 ovl.fmt.RXY.dh2); goto ok;
20238 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
20239 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20240 ovl.fmt.RXY.dl2,
20241 ovl.fmt.RXY.dh2); goto ok;
20242 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
20243 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20244 ovl.fmt.RXY.dl2,
20245 ovl.fmt.RXY.dh2); goto ok;
20246 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
20247 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20248 ovl.fmt.RXY.dl2,
20249 ovl.fmt.RXY.dh2); goto ok;
20250 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
20251 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20252 ovl.fmt.RXY.dl2,
20253 ovl.fmt.RXY.dh2); goto ok;
20254 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
20255 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20256 ovl.fmt.RXY.dl2,
20257 ovl.fmt.RXY.dh2); goto ok;
20258 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
20259 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20260 ovl.fmt.RXY.dl2,
20261 ovl.fmt.RXY.dh2); goto ok;
20262 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
20263 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20264 ovl.fmt.RXY.dl2,
20265 ovl.fmt.RXY.dh2); goto ok;
20266 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
20267 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20268 ovl.fmt.RXY.dl2,
20269 ovl.fmt.RXY.dh2); goto ok;
20270 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
20271 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20272 ovl.fmt.RXY.dl2,
20273 ovl.fmt.RXY.dh2); goto ok;
20274 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
20275 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
20276 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20277 ovl.fmt.RXY.dl2,
20278 ovl.fmt.RXY.dh2); goto ok;
20279 case 0xe3000000002aULL: s390_format_RXY_RRRD(s390_irgen_LZRG, ovl.fmt.RXY.r1,
20280 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20281 ovl.fmt.RXY.dl2,
20282 ovl.fmt.RXY.dh2); goto ok;
20283 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
20284 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
20285 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
20286 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
20287 ovl.fmt.RXY.dh2); goto ok;
20288 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
20289 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20290 ovl.fmt.RXY.dl2,
20291 ovl.fmt.RXY.dh2); goto ok;
20292 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
20293 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20294 ovl.fmt.RXY.dl2,
20295 ovl.fmt.RXY.dh2); goto ok;
20296 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
20297 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20298 ovl.fmt.RXY.dl2,
20299 ovl.fmt.RXY.dh2); goto ok;
20300 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
20301 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20302 ovl.fmt.RXY.dl2,
20303 ovl.fmt.RXY.dh2); goto ok;
20304 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
20305 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20306 ovl.fmt.RXY.dl2,
20307 ovl.fmt.RXY.dh2); goto ok;
20308 case 0xe30000000038ULL: /* AGH */ goto unimplemented;
20309 case 0xe30000000039ULL: /* SGH */ goto unimplemented;
20310 case 0xe3000000003aULL: s390_format_RXY_RRRD(s390_irgen_LLZRGF, ovl.fmt.RXY.r1,
20311 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20312 ovl.fmt.RXY.dl2,
20313 ovl.fmt.RXY.dh2); goto ok;
20314 case 0xe3000000003bULL: s390_format_RXY_RRRD(s390_irgen_LZRF, ovl.fmt.RXY.r1,
20315 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20316 ovl.fmt.RXY.dl2,
20317 ovl.fmt.RXY.dh2); goto ok;
20318 case 0xe3000000003cULL: /* MGH */ goto unimplemented;
20319 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
20320 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20321 ovl.fmt.RXY.dl2,
20322 ovl.fmt.RXY.dh2); goto ok;
20323 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
20324 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
20325 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
20326 ovl.fmt.RXY.dh2); goto ok;
20327 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
20328 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20329 ovl.fmt.RXY.dl2,
20330 ovl.fmt.RXY.dh2); goto ok;
20331 case 0xe30000000047ULL: /* BIC */ goto unimplemented;
20332 case 0xe30000000048ULL: /* LLGFSG */ goto unimplemented;
20333 case 0xe30000000049ULL: /* STGSC */ goto unimplemented;
20334 case 0xe3000000004cULL: /* LGG */ goto unimplemented;
20335 case 0xe3000000004dULL: /* LGSC */ goto unimplemented;
20336 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
20337 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20338 ovl.fmt.RXY.dl2,
20339 ovl.fmt.RXY.dh2); goto ok;
20340 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
20341 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20342 ovl.fmt.RXY.dl2,
20343 ovl.fmt.RXY.dh2); goto ok;
20344 case 0xe30000000053ULL: /* MSC */ goto unimplemented;
20345 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
20346 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20347 ovl.fmt.RXY.dl2,
20348 ovl.fmt.RXY.dh2); goto ok;
20349 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
20350 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20351 ovl.fmt.RXY.dl2,
20352 ovl.fmt.RXY.dh2); goto ok;
20353 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
20354 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20355 ovl.fmt.RXY.dl2,
20356 ovl.fmt.RXY.dh2); goto ok;
20357 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
20358 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20359 ovl.fmt.RXY.dl2,
20360 ovl.fmt.RXY.dh2); goto ok;
20361 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
20362 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20363 ovl.fmt.RXY.dl2,
20364 ovl.fmt.RXY.dh2); goto ok;
20365 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
20366 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20367 ovl.fmt.RXY.dl2,
20368 ovl.fmt.RXY.dh2); goto ok;
20369 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
20370 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20371 ovl.fmt.RXY.dl2,
20372 ovl.fmt.RXY.dh2); goto ok;
20373 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
20374 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20375 ovl.fmt.RXY.dl2,
20376 ovl.fmt.RXY.dh2); goto ok;
20377 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
20378 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20379 ovl.fmt.RXY.dl2,
20380 ovl.fmt.RXY.dh2); goto ok;
20381 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
20382 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20383 ovl.fmt.RXY.dl2,
20384 ovl.fmt.RXY.dh2); goto ok;
20385 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
20386 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20387 ovl.fmt.RXY.dl2,
20388 ovl.fmt.RXY.dh2); goto ok;
20389 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
20390 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20391 ovl.fmt.RXY.dl2,
20392 ovl.fmt.RXY.dh2); goto ok;
20393 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
20394 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20395 ovl.fmt.RXY.dl2,
20396 ovl.fmt.RXY.dh2); goto ok;
20397 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
20398 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20399 ovl.fmt.RXY.dl2,
20400 ovl.fmt.RXY.dh2); goto ok;
20401 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
20402 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20403 ovl.fmt.RXY.dl2,
20404 ovl.fmt.RXY.dh2); goto ok;
20405 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
20406 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20407 ovl.fmt.RXY.dl2,
20408 ovl.fmt.RXY.dh2); goto ok;
20409 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
20410 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20411 ovl.fmt.RXY.dl2,
20412 ovl.fmt.RXY.dh2); goto ok;
20413 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
20414 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20415 ovl.fmt.RXY.dl2,
20416 ovl.fmt.RXY.dh2); goto ok;
20417 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
20418 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20419 ovl.fmt.RXY.dl2,
20420 ovl.fmt.RXY.dh2); goto ok;
20421 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
20422 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20423 ovl.fmt.RXY.dl2,
20424 ovl.fmt.RXY.dh2); goto ok;
20425 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
20426 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20427 ovl.fmt.RXY.dl2,
20428 ovl.fmt.RXY.dh2); goto ok;
20429 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
20430 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20431 ovl.fmt.RXY.dl2,
20432 ovl.fmt.RXY.dh2); goto ok;
20433 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
20434 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20435 ovl.fmt.RXY.dl2,
20436 ovl.fmt.RXY.dh2); goto ok;
20437 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
20438 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20439 ovl.fmt.RXY.dl2,
20440 ovl.fmt.RXY.dh2); goto ok;
20441 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
20442 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20443 ovl.fmt.RXY.dl2,
20444 ovl.fmt.RXY.dh2); goto ok;
20445 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
20446 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20447 ovl.fmt.RXY.dl2,
20448 ovl.fmt.RXY.dh2); goto ok;
20449 case 0xe30000000083ULL: /* MSGC */ goto unimplemented;
20450 case 0xe30000000084ULL: /* MG */ goto unimplemented;
20451 case 0xe30000000085ULL: s390_format_RXY_RRRD(s390_irgen_LGAT, ovl.fmt.RXY.r1,
20452 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20453 ovl.fmt.RXY.dl2,
20454 ovl.fmt.RXY.dh2); goto ok;
20456 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
20457 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20458 ovl.fmt.RXY.dl2,
20459 ovl.fmt.RXY.dh2); goto ok;
20460 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
20461 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20462 ovl.fmt.RXY.dl2,
20463 ovl.fmt.RXY.dh2); goto ok;
20464 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
20465 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20466 ovl.fmt.RXY.dl2,
20467 ovl.fmt.RXY.dh2); goto ok;
20468 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
20469 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20470 ovl.fmt.RXY.dl2,
20471 ovl.fmt.RXY.dh2); goto ok;
20472 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
20473 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20474 ovl.fmt.RXY.dl2,
20475 ovl.fmt.RXY.dh2); goto ok;
20476 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
20477 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20478 ovl.fmt.RXY.dl2,
20479 ovl.fmt.RXY.dh2); goto ok;
20480 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
20481 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20482 ovl.fmt.RXY.dl2,
20483 ovl.fmt.RXY.dh2); goto ok;
20484 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
20485 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20486 ovl.fmt.RXY.dl2,
20487 ovl.fmt.RXY.dh2); goto ok;
20488 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
20489 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20490 ovl.fmt.RXY.dl2,
20491 ovl.fmt.RXY.dh2); goto ok;
20492 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
20493 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20494 ovl.fmt.RXY.dl2,
20495 ovl.fmt.RXY.dh2); goto ok;
20496 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
20497 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20498 ovl.fmt.RXY.dl2,
20499 ovl.fmt.RXY.dh2); goto ok;
20500 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
20501 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20502 ovl.fmt.RXY.dl2,
20503 ovl.fmt.RXY.dh2); goto ok;
20504 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
20505 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20506 ovl.fmt.RXY.dl2,
20507 ovl.fmt.RXY.dh2); goto ok;
20508 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
20509 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20510 ovl.fmt.RXY.dl2,
20511 ovl.fmt.RXY.dh2); goto ok;
20512 case 0xe3000000009cULL: s390_format_RXY_RRRD(s390_irgen_LLGTAT, ovl.fmt.RXY.r1,
20513 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20514 ovl.fmt.RXY.dl2,
20515 ovl.fmt.RXY.dh2); goto ok;
20516 case 0xe3000000009dULL: s390_format_RXY_RRRD(s390_irgen_LLGFAT, ovl.fmt.RXY.r1,
20517 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20518 ovl.fmt.RXY.dl2,
20519 ovl.fmt.RXY.dh2); goto ok;
20520 case 0xe3000000009fULL: s390_format_RXY_RRRD(s390_irgen_LAT, ovl.fmt.RXY.r1,
20521 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20522 ovl.fmt.RXY.dl2,
20523 ovl.fmt.RXY.dh2); goto ok;
20524 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
20525 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20526 ovl.fmt.RXY.dl2,
20527 ovl.fmt.RXY.dh2); goto ok;
20528 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
20529 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20530 ovl.fmt.RXY.dl2,
20531 ovl.fmt.RXY.dh2); goto ok;
20532 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
20533 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20534 ovl.fmt.RXY.dl2,
20535 ovl.fmt.RXY.dh2); goto ok;
20536 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
20537 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20538 ovl.fmt.RXY.dl2,
20539 ovl.fmt.RXY.dh2); goto ok;
20540 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
20541 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20542 ovl.fmt.RXY.dl2,
20543 ovl.fmt.RXY.dh2); goto ok;
20544 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
20545 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20546 ovl.fmt.RXY.dl2,
20547 ovl.fmt.RXY.dh2); goto ok;
20548 case 0xe300000000c8ULL: s390_format_RXY_RRRD(s390_irgen_LFHAT, ovl.fmt.RXY.r1,
20549 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20550 ovl.fmt.RXY.dl2,
20551 ovl.fmt.RXY.dh2); goto ok;
20552 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
20553 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20554 ovl.fmt.RXY.dl2,
20555 ovl.fmt.RXY.dh2); goto ok;
20556 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
20557 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20558 ovl.fmt.RXY.dl2,
20559 ovl.fmt.RXY.dh2); goto ok;
20560 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
20561 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20562 ovl.fmt.RXY.dl2,
20563 ovl.fmt.RXY.dh2); goto ok;
20564 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
20565 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
20566 ovl.fmt.RXY.dl2,
20567 ovl.fmt.RXY.dh2); goto ok;
20568 case 0xe60000000034ULL: /* VPKZ */ goto unimplemented;
20569 case 0xe60000000035ULL: /* VLRL */ goto unimplemented;
20570 case 0xe60000000037ULL: /* VLRLR */ goto unimplemented;
20571 case 0xe6000000003cULL: /* VUPKZ */ goto unimplemented;
20572 case 0xe6000000003dULL: /* VSTRL */ goto unimplemented;
20573 case 0xe6000000003fULL: /* VSTRLR */ goto unimplemented;
20574 case 0xe60000000049ULL: /* VLIP */ goto unimplemented;
20575 case 0xe60000000050ULL: /* VCVB */ goto unimplemented;
20576 case 0xe60000000052ULL: /* VCVBG */ goto unimplemented;
20577 case 0xe60000000058ULL: /* VCVD */ goto unimplemented;
20578 case 0xe60000000059ULL: /* VSRP */ goto unimplemented;
20579 case 0xe6000000005aULL: /* VCVDG */ goto unimplemented;
20580 case 0xe6000000005bULL: /* VPSOP */ goto unimplemented;
20581 case 0xe6000000005fULL: /* VTP */ goto unimplemented;
20582 case 0xe60000000071ULL: /* VAP */ goto unimplemented;
20583 case 0xe60000000073ULL: /* VSP */ goto unimplemented;
20584 case 0xe60000000077ULL: /* VCP */ goto unimplemented;
20585 case 0xe60000000078ULL: /* VMP */ goto unimplemented;
20586 case 0xe60000000079ULL: /* VMSP */ goto unimplemented;
20587 case 0xe6000000007aULL: /* VDP */ goto unimplemented;
20588 case 0xe6000000007bULL: /* VRP */ goto unimplemented;
20589 case 0xe6000000007eULL: /* VSDP */ goto unimplemented;
20590 case 0xe70000000000ULL: s390_format_VRX_VRRDM(s390_irgen_VLEB, ovl.fmt.VRX.v1,
20591 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20592 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20593 ovl.fmt.VRX.rxb); goto ok;
20594 case 0xe70000000001ULL: s390_format_VRX_VRRDM(s390_irgen_VLEH, ovl.fmt.VRX.v1,
20595 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20596 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20597 ovl.fmt.VRX.rxb); goto ok;
20598 case 0xe70000000002ULL: s390_format_VRX_VRRDM(s390_irgen_VLEG, ovl.fmt.VRX.v1,
20599 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20600 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20601 ovl.fmt.VRX.rxb); goto ok;
20602 case 0xe70000000003ULL: s390_format_VRX_VRRDM(s390_irgen_VLEF, ovl.fmt.VRX.v1,
20603 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20604 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20605 ovl.fmt.VRX.rxb); goto ok;
20606 case 0xe70000000004ULL: s390_format_VRX_VRRDM(s390_irgen_VLLEZ, ovl.fmt.VRX.v1,
20607 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20608 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20609 ovl.fmt.VRX.rxb); goto ok;
20610 case 0xe70000000005ULL: s390_format_VRX_VRRDM(s390_irgen_VLREP, ovl.fmt.VRX.v1,
20611 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20612 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20613 ovl.fmt.VRX.rxb); goto ok;
20614 case 0xe70000000006ULL: s390_format_VRX_VRRD(s390_irgen_VL, ovl.fmt.VRX.v1,
20615 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20616 ovl.fmt.VRX.d2, ovl.fmt.VRX.rxb); goto ok;
20617 case 0xe70000000007ULL: s390_format_VRX_VRRDM(s390_irgen_VLBB, ovl.fmt.VRX.v1,
20618 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20619 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20620 ovl.fmt.VRX.rxb); goto ok;
20621 case 0xe70000000008ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEB, ovl.fmt.VRX.v1,
20622 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20623 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20624 ovl.fmt.VRX.rxb); goto ok;
20625 case 0xe70000000009ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEH, ovl.fmt.VRX.v1,
20626 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20627 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20628 ovl.fmt.VRX.rxb); goto ok;
20629 case 0xe7000000000aULL: s390_format_VRX_VRRDM(s390_irgen_VSTEG, ovl.fmt.VRX.v1,
20630 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20631 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20632 ovl.fmt.VRX.rxb); goto ok;
20633 case 0xe7000000000bULL: s390_format_VRX_VRRDM(s390_irgen_VSTEF, ovl.fmt.VRX.v1,
20634 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20635 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20636 ovl.fmt.VRX.rxb); goto ok;
20637 case 0xe7000000000eULL: s390_format_VRX_VRRD(s390_irgen_VST, ovl.fmt.VRX.v1,
20638 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20639 ovl.fmt.VRX.d2, ovl.fmt.VRX.rxb); goto ok;
20640 case 0xe70000000012ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEG, ovl.fmt.VRX.v1,
20641 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20642 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20643 ovl.fmt.VRX.rxb, Ity_I64); goto ok;
20644 case 0xe70000000013ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEF, ovl.fmt.VRX.v1,
20645 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20646 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20647 ovl.fmt.VRX.rxb, Ity_I32); goto ok;
20648 case 0xe7000000001aULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEG, ovl.fmt.VRX.v1,
20649 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20650 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20651 ovl.fmt.VRX.rxb, Ity_I64); goto ok;
20652 case 0xe7000000001bULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEF, ovl.fmt.VRX.v1,
20653 ovl.fmt.VRX.x2, ovl.fmt.VRX.b2,
20654 ovl.fmt.VRX.d2, ovl.fmt.VRX.m3,
20655 ovl.fmt.VRX.rxb, Ity_I32); goto ok;
20656 case 0xe70000000021ULL: s390_format_VRS_RRDVM(s390_irgen_VLGV, ovl.fmt.VRS.v1,
20657 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2, ovl.fmt.VRS.v3,
20658 ovl.fmt.VRS.m4, ovl.fmt.VRS.rxb); goto ok;
20659 case 0xe70000000022ULL: s390_format_VRS_VRRDM(s390_irgen_VLVG, ovl.fmt.VRS.v1,
20660 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2, ovl.fmt.VRS.v3,
20661 ovl.fmt.VRS.m4, ovl.fmt.VRS.rxb); goto ok;
20662 case 0xe70000000027ULL: s390_format_RXE_RRRDR(s390_irgen_LCBB, ovl.fmt.RXE.r1,
20663 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
20664 ovl.fmt.RXE.d2, ovl.fmt.RXE.m3); goto ok;
20665 case 0xe70000000030ULL: s390_format_VRS_VRDVM(s390_irgen_VESL, ovl.fmt.VRS.v1,
20666 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2,
20667 ovl.fmt.VRS.v3, ovl.fmt.VRS.m4,
20668 ovl.fmt.VRS.rxb); goto ok;
20669 case 0xe70000000033ULL: s390_format_VRS_VRDVM(s390_irgen_VERLL, ovl.fmt.VRS.v1,
20670 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2,
20671 ovl.fmt.VRS.v3, ovl.fmt.VRS.m4,
20672 ovl.fmt.VRS.rxb); goto ok;
20673 case 0xe70000000036ULL: s390_format_VRS_VRDV(s390_irgen_VLM, ovl.fmt.VRS.v1,
20674 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2, ovl.fmt.VRS.v3,
20675 ovl.fmt.VRS.rxb); goto ok;
20676 case 0xe70000000037ULL: s390_format_VRS_VRRD(s390_irgen_VLL, ovl.fmt.VRS.v1,
20677 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2, ovl.fmt.VRS.v3,
20678 ovl.fmt.VRS.rxb); goto ok;
20679 case 0xe70000000038ULL: s390_format_VRS_VRDVM(s390_irgen_VESRL, ovl.fmt.VRS.v1,
20680 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2,
20681 ovl.fmt.VRS.v3, ovl.fmt.VRS.m4,
20682 ovl.fmt.VRS.rxb); goto ok;
20683 case 0xe7000000003aULL: s390_format_VRS_VRDVM(s390_irgen_VESRA, ovl.fmt.VRS.v1,
20684 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2,
20685 ovl.fmt.VRS.v3, ovl.fmt.VRS.m4,
20686 ovl.fmt.VRS.rxb); goto ok;
20687 case 0xe7000000003eULL: s390_format_VRS_VRDV(s390_irgen_VSTM, ovl.fmt.VRS.v1,
20688 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2, ovl.fmt.VRS.v3,
20689 ovl.fmt.VRS.rxb); goto ok;
20690 case 0xe7000000003fULL: s390_format_VRS_VRRD(s390_irgen_VSTL, ovl.fmt.VRS.v1,
20691 ovl.fmt.VRS.b2, ovl.fmt.VRS.d2, ovl.fmt.VRS.v3,
20692 ovl.fmt.VRS.rxb); goto ok;
20693 case 0xe70000000040ULL: s390_format_VRI_VIM(s390_irgen_VLEIB, ovl.fmt.VRI.v1,
20694 ovl.fmt.VRI.i2, ovl.fmt.VRI.m3,
20695 ovl.fmt.VRI.rxb); goto ok;
20696 case 0xe70000000041ULL: s390_format_VRI_VIM(s390_irgen_VLEIH, ovl.fmt.VRI.v1,
20697 ovl.fmt.VRI.i2, ovl.fmt.VRI.m3,
20698 ovl.fmt.VRI.rxb); goto ok;
20699 case 0xe70000000042ULL: s390_format_VRI_VIM(s390_irgen_VLEIG, ovl.fmt.VRI.v1,
20700 ovl.fmt.VRI.i2, ovl.fmt.VRI.m3,
20701 ovl.fmt.VRI.rxb); goto ok;
20702 case 0xe70000000043ULL: s390_format_VRI_VIM(s390_irgen_VLEIF, ovl.fmt.VRI.v1,
20703 ovl.fmt.VRI.i2, ovl.fmt.VRI.m3,
20704 ovl.fmt.VRI.rxb); goto ok;break;
20705 case 0xe70000000044ULL: s390_format_VRI_VIM(s390_irgen_VGBM, ovl.fmt.VRI.v1,
20706 ovl.fmt.VRI.i2, ovl.fmt.VRI.m3,
20707 ovl.fmt.VRI.rxb); goto ok;
20708 case 0xe70000000045ULL: s390_format_VRI_VIM(s390_irgen_VREPI, ovl.fmt.VRI.v1,
20709 ovl.fmt.VRI.i2, ovl.fmt.VRI.m3,
20710 ovl.fmt.VRI.rxb); goto ok;
20711 case 0xe70000000046ULL: s390_format_VRI_VIM(s390_irgen_VGM, ovl.fmt.VRI.v1,
20712 ovl.fmt.VRI.i2, ovl.fmt.VRI.m3,
20713 ovl.fmt.VRI.rxb); goto ok;
20714 case 0xe7000000004aULL: s390_format_VRI_VVIMM(s390_irgen_VFTCI, ovl.fmt.VRIe.v1,
20715 ovl.fmt.VRIe.v2, ovl.fmt.VRIe.i3,
20716 ovl.fmt.VRIe.m4, ovl.fmt.VRIe.m5,
20717 ovl.fmt.VRIe.rxb); goto ok;
20718 case 0xe7000000004dULL: s390_format_VRI_VVIM(s390_irgen_VREP, ovl.fmt.VRI.v1,
20719 ovl.fmt.VRI.v3, ovl.fmt.VRI.i2,
20720 ovl.fmt.VRI.m3, ovl.fmt.VRI.rxb); goto ok;
20721 case 0xe70000000050ULL: s390_format_VRR_VVM(s390_irgen_VPOPCT, ovl.fmt.VRR.v1,
20722 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20723 ovl.fmt.VRR.rxb); goto ok;
20724 case 0xe70000000052ULL: s390_format_VRR_VVM(s390_irgen_VCTZ, ovl.fmt.VRR.v1,
20725 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20726 ovl.fmt.VRR.rxb); goto ok;
20727 case 0xe70000000053ULL: s390_format_VRR_VVM(s390_irgen_VCLZ, ovl.fmt.VRR.v1,
20728 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20729 ovl.fmt.VRR.rxb); goto ok;
20730 case 0xe70000000056ULL: s390_format_VRR_VV(s390_irgen_VLR, ovl.fmt.VRR.v1,
20731 ovl.fmt.VRR.v2, ovl.fmt.VRR.rxb); goto ok;
20732 case 0xe7000000005cULL: s390_format_VRR_VVMM(s390_irgen_VISTR, ovl.fmt.VRR.v1,
20733 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20734 ovl.fmt.VRR.m5, ovl.fmt.VRR.rxb); goto ok;
20735 case 0xe7000000005fULL: s390_format_VRR_VVM(s390_irgen_VSEG, ovl.fmt.VRR.v1,
20736 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20737 ovl.fmt.VRR.rxb); goto ok;
20738 case 0xe70000000060ULL: s390_format_VRR_VVVM(s390_irgen_VMRL, ovl.fmt.VRR.v1,
20739 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20740 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20741 case 0xe70000000061ULL: s390_format_VRR_VVVM(s390_irgen_VMRH, ovl.fmt.VRR.v1,
20742 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20743 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20744 case 0xe70000000062ULL: s390_format_VRR_VRR(s390_irgen_VLVGP, ovl.fmt.VRR.v1,
20745 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20746 ovl.fmt.VRR.rxb); goto ok;
20747 case 0xe70000000064ULL: s390_format_VRR_VVVM(s390_irgen_VSUM, ovl.fmt.VRR.v1,
20748 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20749 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20750 case 0xe70000000065ULL: s390_format_VRR_VVVM(s390_irgen_VSUMG, ovl.fmt.VRR.v1,
20751 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20752 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20753 case 0xe70000000066ULL: s390_format_VRR_VVV(s390_irgen_VCKSM, ovl.fmt.VRR.v1,
20754 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20755 ovl.fmt.VRR.rxb); goto ok;
20756 case 0xe70000000067ULL: s390_format_VRR_VVVM(s390_irgen_VSUMQ, ovl.fmt.VRR.v1,
20757 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20758 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20759 case 0xe70000000068ULL: s390_format_VRR_VVV(s390_irgen_VN, ovl.fmt.VRR.v1,
20760 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20761 ovl.fmt.VRR.rxb); goto ok;
20762 case 0xe70000000069ULL: s390_format_VRR_VVV(s390_irgen_VNC, ovl.fmt.VRR.v1,
20763 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20764 ovl.fmt.VRR.rxb); goto ok;
20765 case 0xe7000000006aULL: s390_format_VRR_VVV(s390_irgen_VO, ovl.fmt.VRR.v1,
20766 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20767 ovl.fmt.VRR.rxb); goto ok;
20768 case 0xe7000000006bULL: s390_format_VRR_VVV(s390_irgen_VNO, ovl.fmt.VRR.v1,
20769 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20770 ovl.fmt.VRR.rxb); goto ok;
20771 case 0xe7000000006cULL: /* VNX */ goto unimplemented;
20772 case 0xe7000000006dULL: s390_format_VRR_VVV(s390_irgen_VX, ovl.fmt.VRR.v1,
20773 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20774 ovl.fmt.VRR.rxb); goto ok;
20775 case 0xe7000000006eULL: /* VNN */ goto unimplemented;
20776 case 0xe7000000006fULL: /* VOC */ goto unimplemented;
20777 case 0xe70000000070ULL: s390_format_VRR_VVVM(s390_irgen_VESLV, ovl.fmt.VRR.v1,
20778 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20779 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20780 case 0xe70000000072ULL: s390_format_VRId_VVVIM(s390_irgen_VERIM, ovl.fmt.VRId.v1,
20781 ovl.fmt.VRId.v2, ovl.fmt.VRId.v3,
20782 ovl.fmt.VRId.i4, ovl.fmt.VRId.m5,
20783 ovl.fmt.VRId.rxb); goto ok;
20784 case 0xe70000000073ULL: s390_format_VRR_VVVM(s390_irgen_VERLLV, ovl.fmt.VRR.v1,
20785 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20786 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20787 case 0xe70000000074ULL: s390_format_VRR_VVV(s390_irgen_VSL, ovl.fmt.VRR.v1,
20788 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20789 ovl.fmt.VRR.rxb); goto ok;
20790 case 0xe70000000075ULL: s390_format_VRR_VVV(s390_irgen_VSLB, ovl.fmt.VRR.v1,
20791 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20792 ovl.fmt.VRR.rxb); goto ok;
20793 case 0xe70000000077ULL: s390_format_VRId_VVVI(s390_irgen_VSLDB, ovl.fmt.VRId.v1,
20794 ovl.fmt.VRId.v2, ovl.fmt.VRId.v3,
20795 ovl.fmt.VRId.i4, ovl.fmt.VRId.rxb); goto ok;
20796 case 0xe70000000078ULL: s390_format_VRR_VVVM(s390_irgen_VESRLV, ovl.fmt.VRR.v1,
20797 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20798 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20799 case 0xe7000000007aULL: s390_format_VRR_VVVM(s390_irgen_VESRAV, ovl.fmt.VRR.v1,
20800 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20801 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20802 case 0xe7000000007cULL: s390_format_VRR_VVV(s390_irgen_VSRL, ovl.fmt.VRR.v1,
20803 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20804 ovl.fmt.VRR.rxb); goto ok;
20805 case 0xe7000000007dULL: s390_format_VRR_VVV(s390_irgen_VSRLB, ovl.fmt.VRR.v1,
20806 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20807 ovl.fmt.VRR.rxb); goto ok;
20808 case 0xe7000000007eULL: s390_format_VRR_VVV(s390_irgen_VSRA, ovl.fmt.VRR.v1,
20809 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20810 ovl.fmt.VRR.rxb); goto ok;
20811 case 0xe7000000007fULL: s390_format_VRR_VVV(s390_irgen_VSRAB, ovl.fmt.VRR.v1,
20812 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20813 ovl.fmt.VRR.rxb); goto ok;
20814 case 0xe70000000080ULL: s390_format_VRR_VVVMM(s390_irgen_VFEE, ovl.fmt.VRR.v1,
20815 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20816 ovl.fmt.VRR.m4, ovl.fmt.VRR.m5,
20817 ovl.fmt.VRR.rxb); goto ok;
20818 case 0xe70000000081ULL: s390_format_VRR_VVVMM(s390_irgen_VFENE, ovl.fmt.VRR.v1,
20819 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20820 ovl.fmt.VRR.m4, ovl.fmt.VRR.m5,
20821 ovl.fmt.VRR.rxb); goto ok;
20822 case 0xe70000000082ULL: s390_format_VRR_VVVMM(s390_irgen_VFAE, ovl.fmt.VRR.v1,
20823 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20824 ovl.fmt.VRR.m4, ovl.fmt.VRR.m5,
20825 ovl.fmt.VRR.rxb); goto ok;
20826 case 0xe70000000084ULL: s390_format_VRR_VVVM(s390_irgen_VPDI, ovl.fmt.VRR.v1,
20827 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20828 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20829 case 0xe70000000085ULL: /* VBPERM */ goto unimplemented;
20830 case 0xe7000000008aULL: s390_format_VRR_VVVVMM(s390_irgen_VSTRC, ovl.fmt.VRRd.v1,
20831 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20832 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20833 ovl.fmt.VRRd.m6,
20834 ovl.fmt.VRRd.rxb); goto ok;
20835 case 0xe7000000008cULL: s390_format_VRR_VVVV(s390_irgen_VPERM, ovl.fmt.VRR.v1,
20836 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20837 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20838 case 0xe7000000008dULL: s390_format_VRR_VVVV(s390_irgen_VSEL, ovl.fmt.VRR.v1,
20839 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20840 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20841 case 0xe7000000008eULL: s390_format_VRR_VVVVMM(s390_irgen_VFMS, ovl.fmt.VRRe.v1,
20842 ovl.fmt.VRRe.v2, ovl.fmt.VRRe.v3,
20843 ovl.fmt.VRRe.v4, ovl.fmt.VRRe.m5,
20844 ovl.fmt.VRRe.m6,
20845 ovl.fmt.VRRe.rxb); goto ok;
20846 case 0xe7000000008fULL: s390_format_VRR_VVVVMM(s390_irgen_VFMA, ovl.fmt.VRRe.v1,
20847 ovl.fmt.VRRe.v2, ovl.fmt.VRRe.v3,
20848 ovl.fmt.VRRe.v4, ovl.fmt.VRRe.m5,
20849 ovl.fmt.VRRe.m6,
20850 ovl.fmt.VRRe.rxb); goto ok;
20851 case 0xe70000000094ULL: s390_format_VRR_VVVM(s390_irgen_VPK, ovl.fmt.VRR.v1,
20852 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20853 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20854 case 0xe70000000095ULL: s390_format_VRR_VVVMM(s390_irgen_VPKLS, ovl.fmt.VRR.v1,
20855 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20856 ovl.fmt.VRR.m4, ovl.fmt.VRR.m5, ovl.fmt.VRR.rxb); goto ok;
20857 case 0xe70000000097ULL: s390_format_VRR_VVVMM(s390_irgen_VPKS, ovl.fmt.VRR.v1,
20858 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20859 ovl.fmt.VRR.m4, ovl.fmt.VRR.m5, ovl.fmt.VRR.rxb); goto ok;
20860 case 0xe7000000009eULL: /* VFNMS */ goto unimplemented;
20861 case 0xe7000000009fULL: /* VFNMA */ goto unimplemented;
20862 case 0xe700000000a1ULL: s390_format_VRR_VVVM(s390_irgen_VMLH, ovl.fmt.VRR.v1,
20863 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20864 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20865 case 0xe700000000a2ULL: s390_format_VRR_VVVM(s390_irgen_VML, ovl.fmt.VRR.v1,
20866 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20867 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20868 case 0xe700000000a3ULL: s390_format_VRR_VVVM(s390_irgen_VMH, ovl.fmt.VRR.v1,
20869 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20870 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20871 case 0xe700000000a4ULL: s390_format_VRR_VVVM(s390_irgen_VMLE, ovl.fmt.VRR.v1,
20872 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20873 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20874 case 0xe700000000a5ULL: s390_format_VRR_VVVM(s390_irgen_VMLO, ovl.fmt.VRR.v1,
20875 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20876 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20877 case 0xe700000000a6ULL: s390_format_VRR_VVVM(s390_irgen_VME, ovl.fmt.VRR.v1,
20878 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20879 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20880 case 0xe700000000a7ULL: s390_format_VRR_VVVM(s390_irgen_VMO, ovl.fmt.VRR.v1,
20881 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20882 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20883 case 0xe700000000a9ULL: s390_format_VRRd_VVVVM(s390_irgen_VMALH, ovl.fmt.VRRd.v1,
20884 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20885 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20886 ovl.fmt.VRRd.rxb); goto ok;
20887 case 0xe700000000aaULL: s390_format_VRRd_VVVVM(s390_irgen_VMAL, ovl.fmt.VRRd.v1,
20888 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20889 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20890 ovl.fmt.VRRd.rxb); goto ok;
20891 case 0xe700000000abULL: s390_format_VRRd_VVVVM(s390_irgen_VMAH, ovl.fmt.VRRd.v1,
20892 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20893 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20894 ovl.fmt.VRRd.rxb); goto ok;
20895 case 0xe700000000acULL: s390_format_VRRd_VVVVM(s390_irgen_VMALE, ovl.fmt.VRRd.v1,
20896 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20897 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20898 ovl.fmt.VRRd.rxb); goto ok;
20899 case 0xe700000000adULL: s390_format_VRRd_VVVVM(s390_irgen_VMALO, ovl.fmt.VRRd.v1,
20900 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20901 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20902 ovl.fmt.VRRd.rxb); goto ok;
20903 case 0xe700000000aeULL: s390_format_VRRd_VVVVM(s390_irgen_VMAE, ovl.fmt.VRRd.v1,
20904 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20905 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20906 ovl.fmt.VRRd.rxb); goto ok;
20907 case 0xe700000000afULL: s390_format_VRRd_VVVVM(s390_irgen_VMAO, ovl.fmt.VRRd.v1,
20908 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20909 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20910 ovl.fmt.VRRd.rxb); goto ok;
20911 case 0xe700000000b4ULL: s390_format_VRR_VVVM(s390_irgen_VGFM, ovl.fmt.VRR.v1,
20912 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
20913 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
20914 case 0xe700000000b8ULL: /* VMSL */ goto unimplemented;
20915 case 0xe700000000b9ULL: s390_format_VRRd_VVVVM(s390_irgen_VACCC, ovl.fmt.VRRd.v1,
20916 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20917 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20918 ovl.fmt.VRRd.rxb); goto ok;
20919 case 0xe700000000bbULL: s390_format_VRRd_VVVVM(s390_irgen_VAC, ovl.fmt.VRRd.v1,
20920 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20921 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20922 ovl.fmt.VRRd.rxb); goto ok;
20923 case 0xe700000000bcULL: s390_format_VRRd_VVVVM(s390_irgen_VGFMA, ovl.fmt.VRRd.v1,
20924 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20925 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20926 ovl.fmt.VRRd.rxb); goto ok;
20927 case 0xe700000000bdULL: s390_format_VRRd_VVVVM(s390_irgen_VSBCBI, ovl.fmt.VRRd.v1,
20928 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20929 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20930 ovl.fmt.VRRd.rxb); goto ok;
20931 case 0xe700000000bfULL: s390_format_VRRd_VVVVM(s390_irgen_VSBI, ovl.fmt.VRRd.v1,
20932 ovl.fmt.VRRd.v2, ovl.fmt.VRRd.v3,
20933 ovl.fmt.VRRd.v4, ovl.fmt.VRRd.m5,
20934 ovl.fmt.VRRd.rxb); goto ok;
20935 case 0xe700000000c0ULL: s390_format_VRRa_VVMMM(s390_irgen_VCLGD, ovl.fmt.VRRa.v1,
20936 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20937 ovl.fmt.VRRa.m4, ovl.fmt.VRRa.m5,
20938 ovl.fmt.VRRa.rxb); goto ok;
20939 case 0xe700000000c1ULL: s390_format_VRRa_VVMMM(s390_irgen_VCDLG, ovl.fmt.VRRa.v1,
20940 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20941 ovl.fmt.VRRa.m4, ovl.fmt.VRRa.m5,
20942 ovl.fmt.VRRa.rxb); goto ok;
20943 case 0xe700000000c2ULL: s390_format_VRRa_VVMMM(s390_irgen_VCGD, ovl.fmt.VRRa.v1,
20944 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20945 ovl.fmt.VRRa.m4, ovl.fmt.VRRa.m5,
20946 ovl.fmt.VRRa.rxb); goto ok;
20947 case 0xe700000000c3ULL: s390_format_VRRa_VVMMM(s390_irgen_VCDG, ovl.fmt.VRRa.v1,
20948 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20949 ovl.fmt.VRRa.m4, ovl.fmt.VRRa.m5,
20950 ovl.fmt.VRRa.rxb); goto ok;
20951 case 0xe700000000c4ULL: s390_format_VRRa_VVMMM(s390_irgen_VLDE, ovl.fmt.VRRa.v1,
20952 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20953 ovl.fmt.VRRa.m4, ovl.fmt.VRRa.m5,
20954 ovl.fmt.VRRa.rxb); goto ok;
20955 case 0xe700000000c5ULL: s390_format_VRRa_VVMMM(s390_irgen_VLED, ovl.fmt.VRRa.v1,
20956 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20957 ovl.fmt.VRRa.m4, ovl.fmt.VRRa.m5,
20958 ovl.fmt.VRRa.rxb); goto ok;
20959 case 0xe700000000c7ULL: s390_format_VRRa_VVMMM(s390_irgen_VFI, ovl.fmt.VRRa.v1,
20960 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20961 ovl.fmt.VRRa.m4, ovl.fmt.VRRa.m5,
20962 ovl.fmt.VRRa.rxb); goto ok;
20963 case 0xe700000000caULL: s390_format_VRRa_VVMM(s390_irgen_WFK, ovl.fmt.VRRa.v1,
20964 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20965 ovl.fmt.VRRa.m4,
20966 ovl.fmt.VRRa.rxb); goto ok;
20967 case 0xe700000000cbULL: s390_format_VRRa_VVMM(s390_irgen_WFC, ovl.fmt.VRRa.v1,
20968 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20969 ovl.fmt.VRRa.m4,
20970 ovl.fmt.VRRa.rxb); goto ok;
20971 case 0xe700000000ccULL: s390_format_VRRa_VVMMM(s390_irgen_VFPSO, ovl.fmt.VRRa.v1,
20972 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20973 ovl.fmt.VRRa.m4, ovl.fmt.VRRa.m5,
20974 ovl.fmt.VRRa.rxb); goto ok;
20975 case 0xe700000000ceULL: s390_format_VRRa_VVMM(s390_irgen_VFSQ, ovl.fmt.VRRa.v1,
20976 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.m3,
20977 ovl.fmt.VRRa.m4,
20978 ovl.fmt.VRRa.rxb); goto ok;
20979 case 0xe700000000d4ULL: s390_format_VRR_VVM(s390_irgen_VUPLL, ovl.fmt.VRR.v1,
20980 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20981 ovl.fmt.VRR.rxb); goto ok;
20982 case 0xe700000000d5ULL: s390_format_VRR_VVM(s390_irgen_VUPLH, ovl.fmt.VRR.v1,
20983 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20984 ovl.fmt.VRR.rxb); goto ok;
20985 case 0xe700000000d6ULL: s390_format_VRR_VVM(s390_irgen_VUPL, ovl.fmt.VRR.v1,
20986 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20987 ovl.fmt.VRR.rxb); goto ok;
20988 case 0xe700000000d7ULL: s390_format_VRR_VVM(s390_irgen_VUPH, ovl.fmt.VRR.v1,
20989 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20990 ovl.fmt.VRR.rxb); goto ok;
20991 case 0xe700000000d8ULL: s390_format_VRR_VV(s390_irgen_VTM, ovl.fmt.VRR.v1,
20992 ovl.fmt.VRR.v2, ovl.fmt.VRR.rxb); goto ok;
20993 case 0xe700000000d9ULL: s390_format_VRR_VVM(s390_irgen_VECL, ovl.fmt.VRR.v1,
20994 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20995 ovl.fmt.VRR.rxb); goto ok;
20996 case 0xe700000000dbULL: s390_format_VRR_VVM(s390_irgen_VEC, ovl.fmt.VRR.v1,
20997 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
20998 ovl.fmt.VRR.rxb); goto ok;
20999 case 0xe700000000deULL: s390_format_VRR_VVM(s390_irgen_VLC, ovl.fmt.VRR.v1,
21000 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
21001 ovl.fmt.VRR.rxb); goto ok;
21002 case 0xe700000000dfULL: s390_format_VRR_VVM(s390_irgen_VLP, ovl.fmt.VRR.v1,
21003 ovl.fmt.VRR.v2, ovl.fmt.VRR.m4,
21004 ovl.fmt.VRR.rxb); goto ok;
21005 case 0xe700000000e2ULL: s390_format_VRRa_VVVMM(s390_irgen_VFS, ovl.fmt.VRRa.v1,
21006 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.v3,
21007 ovl.fmt.VRRa.m3, ovl.fmt.VRRa.m4,
21008 ovl.fmt.VRRa.rxb); goto ok;
21009 case 0xe700000000e3ULL: s390_format_VRRa_VVVMM(s390_irgen_VFA, ovl.fmt.VRRa.v1,
21010 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.v3,
21011 ovl.fmt.VRRa.m3, ovl.fmt.VRRa.m4,
21012 ovl.fmt.VRRa.rxb); goto ok;
21013 case 0xe700000000e5ULL: s390_format_VRRa_VVVMM(s390_irgen_VFD, ovl.fmt.VRRa.v1,
21014 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.v3,
21015 ovl.fmt.VRRa.m3, ovl.fmt.VRRa.m4,
21016 ovl.fmt.VRRa.rxb); goto ok;
21017 case 0xe700000000e7ULL: s390_format_VRRa_VVVMM(s390_irgen_VFM, ovl.fmt.VRRa.v1,
21018 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.v3,
21019 ovl.fmt.VRRa.m3, ovl.fmt.VRRa.m4,
21020 ovl.fmt.VRRa.rxb); goto ok;
21021 case 0xe700000000e8ULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCE, ovl.fmt.VRRa.v1,
21022 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.v3,
21023 ovl.fmt.VRRa.m3, ovl.fmt.VRRa.m4,
21024 ovl.fmt.VRRa.m5,
21025 ovl.fmt.VRRa.rxb); goto ok;
21026 case 0xe700000000eaULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCHE, ovl.fmt.VRRa.v1,
21027 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.v3,
21028 ovl.fmt.VRRa.m3, ovl.fmt.VRRa.m4,
21029 ovl.fmt.VRRa.m5,
21030 ovl.fmt.VRRa.rxb); goto ok;
21031 case 0xe700000000ebULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCH, ovl.fmt.VRRa.v1,
21032 ovl.fmt.VRRa.v2, ovl.fmt.VRRa.v3,
21033 ovl.fmt.VRRa.m3, ovl.fmt.VRRa.m4,
21034 ovl.fmt.VRRa.m5,
21035 ovl.fmt.VRRa.rxb); goto ok;
21036 case 0xe700000000eeULL: /* VFMIN */ goto unimplemented;
21037 case 0xe700000000efULL: /* VFMAX */ goto unimplemented;
21038 case 0xe700000000f0ULL: s390_format_VRR_VVVM(s390_irgen_VAVGL, ovl.fmt.VRR.v1,
21039 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21040 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21041 case 0xe700000000f1ULL: s390_format_VRR_VVVM(s390_irgen_VACC, ovl.fmt.VRR.v1,
21042 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21043 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21044 case 0xe700000000f2ULL: s390_format_VRR_VVVM(s390_irgen_VAVG, ovl.fmt.VRR.v1,
21045 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21046 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21047 case 0xe700000000f3ULL: s390_format_VRR_VVVM(s390_irgen_VA, ovl.fmt.VRR.v1,
21048 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21049 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21050 case 0xe700000000f5ULL: s390_format_VRR_VVVM(s390_irgen_VSCBI, ovl.fmt.VRR.v1,
21051 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21052 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21053 case 0xe700000000f7ULL: s390_format_VRR_VVVM(s390_irgen_VS, ovl.fmt.VRR.v1,
21054 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21055 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21056 case 0xe700000000f8ULL: s390_format_VRR_VVVMM(s390_irgen_VCEQ, ovl.fmt.VRR.v1,
21057 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21058 ovl.fmt.VRR.m4, ovl.fmt.VRR.m5,
21059 ovl.fmt.VRR.rxb); goto ok;
21060 case 0xe700000000f9ULL: s390_format_VRR_VVVMM(s390_irgen_VCHL, ovl.fmt.VRR.v1,
21061 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21062 ovl.fmt.VRR.m4, ovl.fmt.VRR.m5,
21063 ovl.fmt.VRR.rxb); goto ok;
21064 case 0xe700000000fbULL: s390_format_VRR_VVVMM(s390_irgen_VCH, ovl.fmt.VRR.v1,
21065 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21066 ovl.fmt.VRR.m4, ovl.fmt.VRR.m5,
21067 ovl.fmt.VRR.rxb); goto ok;
21068 case 0xe700000000fcULL: s390_format_VRR_VVVM(s390_irgen_VMNL, ovl.fmt.VRR.v1,
21069 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21070 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21071 case 0xe700000000fdULL: s390_format_VRR_VVVM(s390_irgen_VMXL, ovl.fmt.VRR.v1,
21072 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21073 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21074 case 0xe700000000feULL: s390_format_VRR_VVVM(s390_irgen_VMN, ovl.fmt.VRR.v1,
21075 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21076 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21077 case 0xe700000000ffULL: s390_format_VRR_VVVM(s390_irgen_VMX, ovl.fmt.VRR.v1,
21078 ovl.fmt.VRR.v2, ovl.fmt.VRR.r3,
21079 ovl.fmt.VRR.m4, ovl.fmt.VRR.rxb); goto ok;
21080 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
21081 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21082 ovl.fmt.RSY.dl2,
21083 ovl.fmt.RSY.dh2); goto ok;
21084 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
21085 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21086 ovl.fmt.RSY.dl2,
21087 ovl.fmt.RSY.dh2); goto ok;
21088 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
21089 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21090 ovl.fmt.RSY.dl2,
21091 ovl.fmt.RSY.dh2); goto ok;
21092 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
21093 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21094 ovl.fmt.RSY.dl2,
21095 ovl.fmt.RSY.dh2); goto ok;
21096 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
21097 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21098 ovl.fmt.RSY.dl2,
21099 ovl.fmt.RSY.dh2); goto ok;
21100 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
21101 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
21102 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21103 ovl.fmt.RSY.dl2,
21104 ovl.fmt.RSY.dh2); goto ok;
21105 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
21106 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21107 ovl.fmt.RSY.dl2,
21108 ovl.fmt.RSY.dh2); goto ok;
21109 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
21110 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21111 ovl.fmt.RSY.dl2,
21112 ovl.fmt.RSY.dh2); goto ok;
21113 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
21114 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21115 ovl.fmt.RSY.dl2,
21116 ovl.fmt.RSY.dh2); goto ok;
21117 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
21118 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21119 ovl.fmt.RSY.dl2,
21120 ovl.fmt.RSY.dh2); goto ok;
21121 case 0xeb0000000023ULL: s390_format_RSY_RURD(s390_irgen_CLT, ovl.fmt.RSY.r1,
21122 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21123 ovl.fmt.RSY.dl2,
21124 ovl.fmt.RSY.dh2); goto ok;
21125 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
21126 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21127 ovl.fmt.RSY.dl2,
21128 ovl.fmt.RSY.dh2); goto ok;
21129 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
21130 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
21131 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21132 ovl.fmt.RSY.dl2,
21133 ovl.fmt.RSY.dh2); goto ok;
21134 case 0xeb000000002bULL: s390_format_RSY_RURD(s390_irgen_CLGT, ovl.fmt.RSY.r1,
21135 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21136 ovl.fmt.RSY.dl2,
21137 ovl.fmt.RSY.dh2); goto ok;
21138 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
21139 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
21140 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
21141 ovl.fmt.RSY.dh2); goto ok;
21142 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
21143 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
21144 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
21145 ovl.fmt.RSY.dh2); goto ok;
21146 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
21147 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
21148 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21149 ovl.fmt.RSY.dl2,
21150 ovl.fmt.RSY.dh2); goto ok;
21151 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
21152 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21153 ovl.fmt.RSY.dl2,
21154 ovl.fmt.RSY.dh2); goto ok;
21155 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
21156 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21157 ovl.fmt.RSY.dl2,
21158 ovl.fmt.RSY.dh2); goto ok;
21159 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
21160 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21161 ovl.fmt.RSY.dl2,
21162 ovl.fmt.RSY.dh2); goto ok;
21163 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
21164 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
21165 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
21166 ovl.fmt.RSY.dh2); goto ok;
21167 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
21168 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21169 ovl.fmt.RSY.dl2,
21170 ovl.fmt.RSY.dh2); goto ok;
21171 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
21172 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21173 ovl.fmt.SIY.dh1); goto ok;
21174 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
21175 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21176 ovl.fmt.SIY.dh1); goto ok;
21177 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
21178 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21179 ovl.fmt.SIY.dh1); goto ok;
21180 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
21181 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21182 ovl.fmt.SIY.dh1); goto ok;
21183 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
21184 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21185 ovl.fmt.SIY.dh1); goto ok;
21186 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
21187 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21188 ovl.fmt.SIY.dh1); goto ok;
21189 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
21190 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21191 ovl.fmt.SIY.dh1); goto ok;
21192 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
21193 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21194 ovl.fmt.SIY.dh1); goto ok;
21195 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
21196 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21197 ovl.fmt.SIY.dh1); goto ok;
21198 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
21199 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
21200 ovl.fmt.SIY.dh1); goto ok;
21201 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
21202 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21203 ovl.fmt.RSY.dl2,
21204 ovl.fmt.RSY.dh2); goto ok;
21205 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
21206 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21207 ovl.fmt.RSY.dl2,
21208 ovl.fmt.RSY.dh2); goto ok;
21209 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
21210 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
21211 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
21212 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21213 ovl.fmt.RSY.dl2,
21214 ovl.fmt.RSY.dh2); goto ok;
21215 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
21216 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21217 ovl.fmt.RSY.dl2,
21218 ovl.fmt.RSY.dh2); goto ok;
21219 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
21220 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21221 ovl.fmt.RSY.dl2,
21222 ovl.fmt.RSY.dh2); goto ok;
21223 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
21224 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21225 ovl.fmt.RSY.dl2,
21226 ovl.fmt.RSY.dh2); goto ok;
21227 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
21228 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
21229 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
21230 ovl.fmt.RSY.dh2); goto ok;
21231 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
21232 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
21233 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21234 ovl.fmt.RSY.dl2,
21235 ovl.fmt.RSY.dh2); goto ok;
21236 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
21237 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21238 ovl.fmt.RSY.dl2,
21239 ovl.fmt.RSY.dh2); goto ok;
21240 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
21241 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21242 ovl.fmt.RSY.dl2,
21243 ovl.fmt.RSY.dh2); goto ok;
21244 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
21245 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21246 ovl.fmt.RSY.dl2,
21247 ovl.fmt.RSY.dh2); goto ok;
21248 case 0xeb00000000e0ULL: s390_format_RSY_RDRM(s390_irgen_LOCFH, ovl.fmt.RSY.r1,
21249 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21250 ovl.fmt.RSY.dl2,
21251 ovl.fmt.RSY.dh2,
21252 S390_XMNM_LOCFH); goto ok;
21253 case 0xeb00000000e1ULL: s390_format_RSY_RDRM(s390_irgen_STOCFH, ovl.fmt.RSY.r1,
21254 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21255 ovl.fmt.RSY.dl2,
21256 ovl.fmt.RSY.dh2,
21257 S390_XMNM_STOCFH); goto ok;
21258 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
21259 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21260 ovl.fmt.RSY.dl2,
21261 ovl.fmt.RSY.dh2,
21262 S390_XMNM_LOCG); goto ok;
21263 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
21264 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
21265 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
21266 ovl.fmt.RSY.dh2,
21267 S390_XMNM_STOCG); goto ok;
21268 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
21269 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21270 ovl.fmt.RSY.dl2,
21271 ovl.fmt.RSY.dh2); goto ok;
21272 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
21273 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21274 ovl.fmt.RSY.dl2,
21275 ovl.fmt.RSY.dh2); goto ok;
21276 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
21277 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21278 ovl.fmt.RSY.dl2,
21279 ovl.fmt.RSY.dh2); goto ok;
21280 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
21281 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21282 ovl.fmt.RSY.dl2,
21283 ovl.fmt.RSY.dh2); goto ok;
21284 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
21285 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
21286 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
21287 ovl.fmt.RSY.dh2); goto ok;
21288 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
21289 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21290 ovl.fmt.RSY.dl2,
21291 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
21292 goto ok;
21293 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
21294 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21295 ovl.fmt.RSY.dl2,
21296 ovl.fmt.RSY.dh2,
21297 S390_XMNM_STOC); goto ok;
21298 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
21299 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21300 ovl.fmt.RSY.dl2,
21301 ovl.fmt.RSY.dh2); goto ok;
21302 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
21303 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21304 ovl.fmt.RSY.dl2,
21305 ovl.fmt.RSY.dh2); goto ok;
21306 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
21307 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21308 ovl.fmt.RSY.dl2,
21309 ovl.fmt.RSY.dh2); goto ok;
21310 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
21311 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21312 ovl.fmt.RSY.dl2,
21313 ovl.fmt.RSY.dh2); goto ok;
21314 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
21315 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
21316 ovl.fmt.RSY.dl2,
21317 ovl.fmt.RSY.dh2); goto ok;
21318 case 0xec0000000042ULL: s390_format_RIE_RUPIX(s390_irgen_LOCHI,
21319 ovl.fmt.RIEv3.r1,
21320 ovl.fmt.RIEv3.m3,
21321 ovl.fmt.RIEv3.i4,
21322 ovl.fmt.RIEv3.i2,
21323 S390_XMNM_LOCHI); goto ok;
21324 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
21325 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
21326 goto ok;
21327 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
21328 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
21329 goto ok;
21330 case 0xec0000000046ULL: s390_format_RIE_RUPIX(s390_irgen_LOCGHI,
21331 ovl.fmt.RIEv3.r1,
21332 ovl.fmt.RIEv3.m3,
21333 ovl.fmt.RIEv3.i4,
21334 ovl.fmt.RIEv3.i2,
21335 S390_XMNM_LOCGHI); goto ok;
21336 case 0xec000000004eULL: s390_format_RIE_RUPIX(s390_irgen_LOCHHI,
21337 ovl.fmt.RIEv3.r1,
21338 ovl.fmt.RIEv3.m3,
21339 ovl.fmt.RIEv3.i4,
21340 ovl.fmt.RIEv3.i2,
21341 S390_XMNM_LOCHHI); goto ok;
21342 case 0xec0000000051ULL: s390_format_RIE_RRUUU(s390_irgen_RISBLG,
21343 ovl.fmt.RIE_RRUUU.r1,
21344 ovl.fmt.RIE_RRUUU.r2,
21345 ovl.fmt.RIE_RRUUU.i3,
21346 ovl.fmt.RIE_RRUUU.i4,
21347 ovl.fmt.RIE_RRUUU.i5);
21348 goto ok;
21349 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
21350 ovl.fmt.RIE_RRUUU.r1,
21351 ovl.fmt.RIE_RRUUU.r2,
21352 ovl.fmt.RIE_RRUUU.i3,
21353 ovl.fmt.RIE_RRUUU.i4,
21354 ovl.fmt.RIE_RRUUU.i5);
21355 goto ok;
21356 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
21357 ovl.fmt.RIE_RRUUU.r1,
21358 ovl.fmt.RIE_RRUUU.r2,
21359 ovl.fmt.RIE_RRUUU.i3,
21360 ovl.fmt.RIE_RRUUU.i4,
21361 ovl.fmt.RIE_RRUUU.i5);
21362 goto ok;
21363 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
21364 ovl.fmt.RIE_RRUUU.r1,
21365 ovl.fmt.RIE_RRUUU.r2,
21366 ovl.fmt.RIE_RRUUU.i3,
21367 ovl.fmt.RIE_RRUUU.i4,
21368 ovl.fmt.RIE_RRUUU.i5);
21369 goto ok;
21370 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
21371 ovl.fmt.RIE_RRUUU.r1,
21372 ovl.fmt.RIE_RRUUU.r2,
21373 ovl.fmt.RIE_RRUUU.i3,
21374 ovl.fmt.RIE_RRUUU.i4,
21375 ovl.fmt.RIE_RRUUU.i5);
21376 goto ok;
21377 case 0xec0000000059ULL: s390_format_RIE_RRUUU(s390_irgen_RISBGN,
21378 ovl.fmt.RIE_RRUUU.r1,
21379 ovl.fmt.RIE_RRUUU.r2,
21380 ovl.fmt.RIE_RRUUU.i3,
21381 ovl.fmt.RIE_RRUUU.i4,
21382 ovl.fmt.RIE_RRUUU.i5);
21383 goto ok;
21384 case 0xec000000005dULL: s390_format_RIE_RRUUU(s390_irgen_RISBHG,
21385 ovl.fmt.RIE_RRUUU.r1,
21386 ovl.fmt.RIE_RRUUU.r2,
21387 ovl.fmt.RIE_RRUUU.i3,
21388 ovl.fmt.RIE_RRUUU.i4,
21389 ovl.fmt.RIE_RRUUU.i5);
21390 goto ok;
21391 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
21392 ovl.fmt.RIE_RRPU.r1,
21393 ovl.fmt.RIE_RRPU.r2,
21394 ovl.fmt.RIE_RRPU.i4,
21395 ovl.fmt.RIE_RRPU.m3); goto ok;
21396 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
21397 ovl.fmt.RIE_RRPU.r1,
21398 ovl.fmt.RIE_RRPU.r2,
21399 ovl.fmt.RIE_RRPU.i4,
21400 ovl.fmt.RIE_RRPU.m3); goto ok;
21401 case 0xec0000000070ULL: s390_format_RIEv1(s390_irgen_CGIT,
21402 ovl.fmt.RIEv1.r1,
21403 ovl.fmt.RIEv1.i2,
21404 ovl.fmt.RIEv1.m3); goto ok;
21405 case 0xec0000000071ULL: s390_format_RIEv1(s390_irgen_CLGIT,
21406 ovl.fmt.RIEv1.r1,
21407 ovl.fmt.RIEv1.i2,
21408 ovl.fmt.RIEv1.m3); goto ok;
21409 case 0xec0000000072ULL: s390_format_RIEv1(s390_irgen_CIT,
21410 ovl.fmt.RIEv1.r1,
21411 ovl.fmt.RIEv1.i2,
21412 ovl.fmt.RIEv1.m3); goto ok;
21413 case 0xec0000000073ULL: s390_format_RIEv1(s390_irgen_CLFIT,
21414 ovl.fmt.RIEv1.r1,
21415 ovl.fmt.RIEv1.i2,
21416 ovl.fmt.RIEv1.m3); goto ok;
21417 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
21418 ovl.fmt.RIE_RRPU.r1,
21419 ovl.fmt.RIE_RRPU.r2,
21420 ovl.fmt.RIE_RRPU.i4,
21421 ovl.fmt.RIE_RRPU.m3); goto ok;
21422 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
21423 ovl.fmt.RIE_RRPU.r1,
21424 ovl.fmt.RIE_RRPU.r2,
21425 ovl.fmt.RIE_RRPU.i4,
21426 ovl.fmt.RIE_RRPU.m3); goto ok;
21427 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
21428 ovl.fmt.RIEv3.r1,
21429 ovl.fmt.RIEv3.m3,
21430 ovl.fmt.RIEv3.i4,
21431 ovl.fmt.RIEv3.i2); goto ok;
21432 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
21433 ovl.fmt.RIEv3.r1,
21434 ovl.fmt.RIEv3.m3,
21435 ovl.fmt.RIEv3.i4,
21436 ovl.fmt.RIEv3.i2); goto ok;
21437 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
21438 ovl.fmt.RIEv3.r1,
21439 ovl.fmt.RIEv3.m3,
21440 ovl.fmt.RIEv3.i4,
21441 ovl.fmt.RIEv3.i2); goto ok;
21442 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
21443 ovl.fmt.RIEv3.r1,
21444 ovl.fmt.RIEv3.m3,
21445 ovl.fmt.RIEv3.i4,
21446 ovl.fmt.RIEv3.i2); goto ok;
21447 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
21448 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
21449 goto ok;
21450 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
21451 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
21452 ovl.fmt.RIE.i2); goto ok;
21453 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
21454 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
21455 ovl.fmt.RIE.i2); goto ok;
21456 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
21457 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
21458 ovl.fmt.RIE.i2); goto ok;
21459 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
21460 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
21461 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
21462 goto ok;
21463 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
21464 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
21465 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
21466 goto ok;
21467 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
21468 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
21469 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
21470 goto ok;
21471 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
21472 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
21473 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
21474 goto ok;
21475 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
21476 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
21477 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
21478 ovl.fmt.RIS.i2); goto ok;
21479 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
21480 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
21481 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
21482 ovl.fmt.RIS.i2); goto ok;
21483 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
21484 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
21485 ovl.fmt.RIS.d4,
21486 ovl.fmt.RIS.i2); goto ok;
21487 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
21488 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
21489 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
21490 ovl.fmt.RIS.i2); goto ok;
21491 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
21492 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21493 ovl.fmt.RXE.d2); goto ok;
21494 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
21495 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21496 ovl.fmt.RXE.d2); goto ok;
21497 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
21498 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21499 ovl.fmt.RXE.d2); goto ok;
21500 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
21501 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
21502 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
21503 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21504 ovl.fmt.RXE.d2); goto ok;
21505 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
21506 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21507 ovl.fmt.RXE.d2); goto ok;
21508 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
21509 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21510 ovl.fmt.RXE.d2); goto ok;
21511 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
21512 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
21513 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21514 ovl.fmt.RXE.d2); goto ok;
21515 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
21516 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
21517 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
21518 ovl.fmt.RXF.r1); goto ok;
21519 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
21520 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
21521 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
21522 ovl.fmt.RXF.r1); goto ok;
21523 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
21524 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21525 ovl.fmt.RXE.d2); goto ok;
21526 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
21527 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21528 ovl.fmt.RXE.d2); goto ok;
21529 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
21530 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21531 ovl.fmt.RXE.d2); goto ok;
21532 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
21533 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21534 ovl.fmt.RXE.d2); goto ok;
21535 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
21536 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21537 ovl.fmt.RXE.d2); goto ok;
21538 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
21539 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21540 ovl.fmt.RXE.d2); goto ok;
21541 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
21542 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
21543 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21544 ovl.fmt.RXE.d2); goto ok;
21545 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
21546 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21547 ovl.fmt.RXE.d2); goto ok;
21548 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
21549 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21550 ovl.fmt.RXE.d2); goto ok;
21551 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
21552 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21553 ovl.fmt.RXE.d2); goto ok;
21554 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
21555 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21556 ovl.fmt.RXE.d2); goto ok;
21557 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
21558 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
21559 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
21560 ovl.fmt.RXF.r1); goto ok;
21561 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
21562 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
21563 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
21564 ovl.fmt.RXF.r1); goto ok;
21565 case 0xed0000000024ULL: s390_format_RXE_FRRD(s390_irgen_LDE,
21566 ovl.fmt.RXE.r1, ovl.fmt.RXE.x2,
21567 ovl.fmt.RXE.b2,
21568 ovl.fmt.RXE.d2); goto ok;
21569 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
21570 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
21571 case 0xed000000002eULL: /* MAE */ goto unimplemented;
21572 case 0xed000000002fULL: /* MSE */ goto unimplemented;
21573 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
21574 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
21575 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
21576 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
21577 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
21578 case 0xed000000003aULL: /* MAY */ goto unimplemented;
21579 case 0xed000000003bULL: /* MY */ goto unimplemented;
21580 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
21581 case 0xed000000003dULL: /* MYH */ goto unimplemented;
21582 case 0xed000000003eULL: /* MAD */ goto unimplemented;
21583 case 0xed000000003fULL: /* MSD */ goto unimplemented;
21584 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
21585 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
21586 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
21587 ovl.fmt.RXF.r1); goto ok;
21588 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
21589 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
21590 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
21591 ovl.fmt.RXF.r1); goto ok;
21592 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
21593 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
21594 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
21595 ovl.fmt.RXF.r1); goto ok;
21596 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
21597 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
21598 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
21599 ovl.fmt.RXF.r1); goto ok;
21600 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
21601 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21602 ovl.fmt.RXE.d2); goto ok;
21603 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
21604 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21605 ovl.fmt.RXE.d2); goto ok;
21606 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
21607 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21608 ovl.fmt.RXE.d2); goto ok;
21609 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
21610 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21611 ovl.fmt.RXE.d2); goto ok;
21612 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
21613 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21614 ovl.fmt.RXE.d2); goto ok;
21615 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
21616 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
21617 ovl.fmt.RXE.d2); goto ok;
21618 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
21619 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
21620 ovl.fmt.RXY.dl2,
21621 ovl.fmt.RXY.dh2); goto ok;
21622 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
21623 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
21624 ovl.fmt.RXY.dl2,
21625 ovl.fmt.RXY.dh2); goto ok;
21626 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
21627 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
21628 ovl.fmt.RXY.dl2,
21629 ovl.fmt.RXY.dh2); goto ok;
21630 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
21631 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
21632 ovl.fmt.RXY.dl2,
21633 ovl.fmt.RXY.dh2); goto ok;
21634 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
21635 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
21636 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
21637 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
21638 case 0xed00000000acULL: /* CPDT */ goto unimplemented;
21639 case 0xed00000000adULL: /* CPXT */ goto unimplemented;
21640 case 0xed00000000aeULL: /* CDPT */ goto unimplemented;
21641 case 0xed00000000afULL: /* CXPT */ goto unimplemented;
21644 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
21645 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
21646 ovl.fmt.RIL.i2); goto ok;
21647 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
21648 ovl.fmt.RIL.i2); goto ok;
21649 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
21650 ovl.fmt.RIL.i2); goto ok;
21651 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
21652 ovl.fmt.RIL.i2); goto ok;
21653 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
21654 ovl.fmt.RIL.i2); goto ok;
21655 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
21656 ovl.fmt.RIL.i2); goto ok;
21657 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
21658 ovl.fmt.RIL.i2); goto ok;
21659 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
21660 ovl.fmt.RIL.i2); goto ok;
21661 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
21662 ovl.fmt.RIL.i2); goto ok;
21663 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
21664 ovl.fmt.RIL.i2); goto ok;
21665 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
21666 ovl.fmt.RIL.i2); goto ok;
21667 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
21668 ovl.fmt.RIL.i2); goto ok;
21669 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
21670 ovl.fmt.RIL.i2); goto ok;
21671 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
21672 ovl.fmt.RIL.i2); goto ok;
21673 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
21674 ovl.fmt.RIL.i2); goto ok;
21675 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
21676 ovl.fmt.RIL.i2); goto ok;
21677 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
21678 ovl.fmt.RIL.i2); goto ok;
21679 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
21680 ovl.fmt.RIL.i2); goto ok;
21681 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
21682 ovl.fmt.RIL.i2); goto ok;
21683 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
21684 ovl.fmt.RIL.i2); goto ok;
21685 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
21686 ovl.fmt.RIL.i2); goto ok;
21687 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
21688 ovl.fmt.RIL.i2); goto ok;
21689 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
21690 ovl.fmt.RIL.i2); goto ok;
21691 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
21692 ovl.fmt.RIL.i2); goto ok;
21693 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
21694 ovl.fmt.RIL.i2); goto ok;
21695 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
21696 ovl.fmt.RIL.i2); goto ok;
21697 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
21698 ovl.fmt.RIL.i2); goto ok;
21699 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
21700 ovl.fmt.RIL.i2); goto ok;
21701 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
21702 ovl.fmt.RIL.i2); goto ok;
21703 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
21704 ovl.fmt.RIL.i2); goto ok;
21705 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
21706 ovl.fmt.RIL.i2); goto ok;
21707 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
21708 ovl.fmt.RIL.i2); goto ok;
21709 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
21710 ovl.fmt.RIL.i2); goto ok;
21711 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
21712 ovl.fmt.RIL.i2); goto ok;
21713 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
21714 ovl.fmt.RIL.i2); goto ok;
21715 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
21716 ovl.fmt.RIL.i2); goto ok;
21717 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
21718 ovl.fmt.RIL.i2); goto ok;
21719 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
21720 ovl.fmt.RIL.i2); goto ok;
21721 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
21722 ovl.fmt.RIL.i2); goto ok;
21723 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
21724 ovl.fmt.RIL.i2); goto ok;
21725 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
21726 ovl.fmt.RIL.i2); goto ok;
21727 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
21728 ovl.fmt.RIL.i2); goto ok;
21729 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
21730 ovl.fmt.RIL.i2); goto ok;
21731 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
21732 ovl.fmt.RIL.i2); goto ok;
21733 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
21734 ovl.fmt.RIL.i2); goto ok;
21735 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
21736 ovl.fmt.RIL.i2); goto ok;
21737 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
21738 ovl.fmt.RIL.i2); goto ok;
21739 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
21740 ovl.fmt.RIL.i2); goto ok;
21741 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
21742 ovl.fmt.RIL.i2); goto ok;
21743 case 0xc800ULL: /* MVCOS */ goto unimplemented;
21744 case 0xc801ULL: /* ECTG */ goto unimplemented;
21745 case 0xc802ULL: /* CSST */ goto unimplemented;
21746 case 0xc804ULL: /* LPD */ goto unimplemented;
21747 case 0xc805ULL: /* LPDG */ goto unimplemented;
21748 case 0xcc06ULL: s390_format_RIL_RP(s390_irgen_BRCTH, ovl.fmt.RIL.r1,
21749 ovl.fmt.RIL.i2); goto ok;
21750 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
21751 ovl.fmt.RIL.i2); goto ok;
21752 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
21753 ovl.fmt.RIL.i2); goto ok;
21754 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
21755 ovl.fmt.RIL.i2); goto ok;
21756 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
21757 ovl.fmt.RIL.i2); goto ok;
21758 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
21759 ovl.fmt.RIL.i2); goto ok;
21762 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
21763 case 0xc5ULL: /* BPRP */ goto unimplemented;
21764 case 0xc7ULL: /* BPP */ goto unimplemented;
21765 case 0xd0ULL: /* TRTR */ goto unimplemented;
21766 case 0xd1ULL: /* MVN */ goto unimplemented;
21767 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
21768 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
21769 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
21770 case 0xd3ULL: /* MVZ */ goto unimplemented;
21771 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
21772 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
21773 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
21774 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
21775 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
21776 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
21777 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
21778 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
21779 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
21780 case 0xd7ULL:
21781 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
21782 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
21783 else
21784 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
21785 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
21786 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
21787 goto ok;
21788 case 0xd9ULL: /* MVCK */ goto unimplemented;
21789 case 0xdaULL: /* MVCP */ goto unimplemented;
21790 case 0xdbULL: /* MVCS */ goto unimplemented;
21791 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
21792 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
21793 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
21794 case 0xddULL: /* TRT */ goto unimplemented;
21795 case 0xdeULL: /* ED */ goto unimplemented;
21796 case 0xdfULL: /* EDMK */ goto unimplemented;
21797 case 0xe1ULL: /* PKU */ goto unimplemented;
21798 case 0xe2ULL: /* UNPKU */ goto unimplemented;
21799 case 0xe8ULL: s390_format_SS_L0RDRD(s390_irgen_MVCIN, ovl.fmt.SS.l,
21800 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
21801 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
21802 case 0xe9ULL: /* PKA */ goto unimplemented;
21803 case 0xeaULL: /* UNPKA */ goto unimplemented;
21804 case 0xeeULL: /* PLO */ goto unimplemented;
21805 case 0xefULL: /* LMD */ goto unimplemented;
21806 case 0xf0ULL: /* SRP */ goto unimplemented;
21807 case 0xf1ULL: /* MVO */ goto unimplemented;
21808 case 0xf2ULL: /* PACK */ goto unimplemented;
21809 case 0xf3ULL: /* UNPK */ goto unimplemented;
21810 case 0xf8ULL: /* ZAP */ goto unimplemented;
21811 case 0xf9ULL: /* CP */ goto unimplemented;
21812 case 0xfaULL: /* AP */ goto unimplemented;
21813 case 0xfbULL: /* SP */ goto unimplemented;
21814 case 0xfcULL: /* MP */ goto unimplemented;
21815 case 0xfdULL: /* DP */ goto unimplemented;
21818 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
21819 case 0xe500ULL: /* LASP */ goto unimplemented;
21820 case 0xe501ULL: /* TPROT */ goto unimplemented;
21821 case 0xe502ULL: /* STRAG */ goto unimplemented;
21822 case 0xe50eULL: /* MVCSK */ goto unimplemented;
21823 case 0xe50fULL: /* MVCDK */ goto unimplemented;
21824 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
21825 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
21826 goto ok;
21827 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
21828 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
21829 goto ok;
21830 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
21831 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
21832 goto ok;
21833 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
21834 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
21835 goto ok;
21836 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
21837 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
21838 goto ok;
21839 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
21840 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
21841 goto ok;
21842 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
21843 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
21844 goto ok;
21845 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
21846 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
21847 goto ok;
21848 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
21849 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
21850 goto ok;
21851 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
21852 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
21855 return S390_DECODE_UNKNOWN_INSN;
21858 return S390_DECODE_OK;
21860 unimplemented:
21861 return S390_DECODE_UNIMPLEMENTED_INSN;
21864 /* Handle "special" instructions. */
21865 static s390_decode_t
21866 s390_decode_special_and_irgen(const UChar *bytes)
21868 s390_decode_t status = S390_DECODE_OK;
21870 /* Got a "Special" instruction preamble. Which one is it? */
21871 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
21872 s390_irgen_client_request();
21873 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
21874 s390_irgen_guest_NRADDR();
21875 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
21876 s390_irgen_call_noredir();
21877 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
21878 vex_inject_ir(irsb, Iend_BE);
21880 /* Invalidate the current insn. The reason is that the IRop we're
21881 injecting here can change. In which case the translation has to
21882 be redone. For ease of handling, we simply invalidate all the
21883 time. */
21884 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
21885 mkU64(guest_IA_curr_instr)));
21886 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
21887 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
21888 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
21889 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
21891 put_IA(mkaddr_expr(guest_IA_next_instr));
21892 dis_res->whatNext = Dis_StopHere;
21893 dis_res->jk_StopHere = Ijk_InvalICache;
21894 } else {
21895 /* We don't know what it is. */
21896 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
21899 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
21901 return status;
21905 /* Function returns # bytes that were decoded or 0 in case of failure */
21906 static UInt
21907 s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
21909 s390_decode_t status;
21911 dis_res = dres;
21913 /* Spot the 8-byte preamble: 18ff lr r15,r15
21914 1811 lr r1,r1
21915 1822 lr r2,r2
21916 1833 lr r3,r3 */
21917 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
21918 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
21919 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
21921 /* Handle special instruction that follows that preamble. */
21922 if (0) vex_printf("special function handling...\n");
21924 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
21925 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
21927 status =
21928 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
21929 } else {
21930 /* Handle normal instructions. */
21931 switch (insn_length) {
21932 case 2:
21933 status = s390_decode_2byte_and_irgen(bytes);
21934 break;
21936 case 4:
21937 status = s390_decode_4byte_and_irgen(bytes);
21938 break;
21940 case 6:
21941 status = s390_decode_6byte_and_irgen(bytes);
21942 break;
21944 default:
21945 status = S390_DECODE_ERROR;
21946 break;
21949 /* If next instruction is execute, stop here */
21950 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
21951 put_IA(mkaddr_expr(guest_IA_next_instr));
21952 dis_res->whatNext = Dis_StopHere;
21953 dis_res->jk_StopHere = Ijk_Boring;
21956 if (status == S390_DECODE_OK) {
21957 /* Adjust status if a specification exception was indicated. */
21958 if (is_specification_exception())
21959 status = S390_DECODE_SPECIFICATION_EXCEPTION;
21960 else
21961 return insn_length; /* OK */
21964 /* Decoding failed somehow */
21965 if (sigill_diag) {
21966 vex_printf("vex s390->IR: ");
21967 switch (status) {
21968 case S390_DECODE_UNKNOWN_INSN:
21969 vex_printf("unknown insn: ");
21970 break;
21972 case S390_DECODE_UNIMPLEMENTED_INSN:
21973 vex_printf("unimplemented insn: ");
21974 break;
21976 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
21977 vex_printf("unimplemented special insn: ");
21978 break;
21980 case S390_DECODE_SPECIFICATION_EXCEPTION:
21981 vex_printf("specification exception: ");
21982 break;
21984 case S390_DECODE_ERROR:
21985 vex_printf("decoding error: ");
21986 break;
21988 default:
21989 vpanic("s390_decode_and_irgen");
21992 vex_printf("%02x%02x", bytes[0], bytes[1]);
21993 if (insn_length > 2) {
21994 vex_printf(" %02x%02x", bytes[2], bytes[3]);
21996 if (insn_length > 4) {
21997 vex_printf(" %02x%02x", bytes[4], bytes[5]);
21999 vex_printf("\n");
22002 return 0; /* Failed */
22006 /* Disassemble a single instruction INSN into IR. */
22007 static DisResult
22008 disInstr_S390_WRK(const UChar *insn)
22010 UChar byte;
22011 UInt insn_length;
22012 DisResult dres;
22014 /* ---------------------------------------------------- */
22015 /* --- Compute instruction length -- */
22016 /* ---------------------------------------------------- */
22018 /* Get the first byte of the insn. */
22019 byte = insn[0];
22021 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
22022 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
22023 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
22025 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
22027 /* ---------------------------------------------------- */
22028 /* --- Initialise the DisResult data -- */
22029 /* ---------------------------------------------------- */
22030 dres.whatNext = Dis_Continue;
22031 dres.len = insn_length;
22032 dres.continueAt = 0;
22033 dres.jk_StopHere = Ijk_INVALID;
22034 dres.hint = Dis_HintNone;
22036 /* fixs390: consider chasing of conditional jumps */
22038 /* Normal and special instruction handling starts here. */
22039 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
22040 /* All decode failures end up here. The decoder has already issued an
22041 error message.
22042 Tell the dispatcher that this insn cannot be decoded, and so has
22043 not been executed, and (is currently) the next to be executed.
22044 The insn address in the guest state needs to be set to
22045 guest_IA_curr_instr, otherwise the complaint will report an
22046 incorrect address. */
22047 put_IA(mkaddr_expr(guest_IA_curr_instr));
22049 dres.len = 0;
22050 dres.whatNext = Dis_StopHere;
22051 dres.jk_StopHere = Ijk_NoDecode;
22052 dres.continueAt = 0;
22053 } else {
22054 /* Decode success */
22055 switch (dres.whatNext) {
22056 case Dis_Continue:
22057 put_IA(mkaddr_expr(guest_IA_next_instr));
22058 break;
22059 case Dis_ResteerU:
22060 case Dis_ResteerC:
22061 put_IA(mkaddr_expr(dres.continueAt));
22062 break;
22063 case Dis_StopHere:
22064 if (dres.jk_StopHere == Ijk_EmWarn ||
22065 dres.jk_StopHere == Ijk_EmFail) {
22066 /* We assume here, that emulation warnings are not given for
22067 insns that transfer control. There is no good way to
22068 do that. */
22069 put_IA(mkaddr_expr(guest_IA_next_instr));
22071 break;
22072 default:
22073 vpanic("disInstr_S390_WRK");
22077 return dres;
22081 /*------------------------------------------------------------*/
22082 /*--- Top-level fn ---*/
22083 /*------------------------------------------------------------*/
22085 /* Disassemble a single instruction into IR. The instruction
22086 is located in host memory at &guest_code[delta]. */
22088 DisResult
22089 disInstr_S390(IRSB *irsb_IN,
22090 Bool (*resteerOkFn)(void *, Addr),
22091 Bool resteerCisOk,
22092 void *callback_opaque,
22093 const UChar *guest_code,
22094 Long delta,
22095 Addr guest_IP,
22096 VexArch guest_arch,
22097 const VexArchInfo *archinfo,
22098 const VexAbiInfo *abiinfo,
22099 VexEndness host_endness,
22100 Bool sigill_diag_IN)
22102 vassert(guest_arch == VexArchS390X);
22104 /* The instruction decoder requires a big-endian machine. */
22105 vassert(host_endness == VexEndnessBE);
22107 /* Set globals (see top of this file) */
22108 guest_IA_curr_instr = guest_IP;
22109 irsb = irsb_IN;
22110 resteer_fn = resteerOkFn;
22111 resteer_data = callback_opaque;
22112 sigill_diag = sigill_diag_IN;
22114 return disInstr_S390_WRK(guest_code + delta);
22117 /*---------------------------------------------------------------*/
22118 /*--- end guest_s390_toIR.c ---*/
22119 /*---------------------------------------------------------------*/