2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
5 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
6 * Copyright (c) 2010 Richard Henderson <rth@twiddle.net>
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 /* We only support generating code for 64-bit mode. */
28 #if TCG_TARGET_REG_BITS != 64
29 #error "unsupported code generation mode"
32 #include "../tcg-ldst.c.inc"
33 #include "../tcg-pool.c.inc"
36 /* ??? The translation blocks produced by TCG are generally small enough to
37 be entirely reachable with a 16-bit displacement. Leaving the option for
38 a 32-bit displacement here Just In Case. */
39 #define USE_LONG_BRANCHES 0
41 #define TCG_CT_CONST_S16 0x100
42 #define TCG_CT_CONST_S32 0x200
43 #define TCG_CT_CONST_S33 0x400
44 #define TCG_CT_CONST_ZERO 0x800
46 #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 16)
47 #define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
50 * For softmmu, we need to avoid conflicts with the first 3
51 * argument registers to perform the tlb lookup, and to call
52 * the helper function.
55 #define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_R2, 3)
57 #define SOFTMMU_RESERVE_REGS 0
61 /* Several places within the instruction set 0 means "no register"
62 rather than TCG_REG_R0. */
63 #define TCG_REG_NONE 0
65 /* A scratch register that may be be used throughout the backend. */
66 #define TCG_TMP0 TCG_REG_R1
68 /* A scratch register that holds a pointer to the beginning of the TB.
69 We don't need this when we have pc-relative loads with the general
70 instructions extension facility. */
71 #define TCG_REG_TB TCG_REG_R12
72 #define USE_REG_TB (!HAVE_FACILITY(GEN_INST_EXT))
74 #ifndef CONFIG_SOFTMMU
75 #define TCG_GUEST_BASE_REG TCG_REG_R13
78 /* All of the following instructions are prefixed with their instruction
79 format, and are defined as 8- or 16-bit quantities, even when the two
80 halves of the 16-bit quantity may appear 32 bits apart in the insn.
81 This makes it easy to copy the values from the tables in Appendix B. */
82 typedef enum S390Opcode {
279 VRRc_VCEQ = 0xe7f8, /* we leave the m5 cs field 0 */
280 VRRc_VCH = 0xe7fb, /* " */
281 VRRc_VCHL = 0xe7f9, /* " */
282 VRRc_VERLLV = 0xe773,
284 VRRc_VESRAV = 0xe77a,
285 VRRc_VESRLV = 0xe778,
298 VRRc_VPKS = 0xe797, /* we leave the m5 cs field 0 */
323 #ifdef CONFIG_DEBUG_TCG
324 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
325 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
326 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
328 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
329 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
330 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
331 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
335 /* Since R6 is a potential argument register, choose it last of the
336 call-saved registers. Likewise prefer the call-clobbered registers
337 in reverse order to maximize the chance of avoiding the arguments. */
338 static const int tcg_target_reg_alloc_order[] = {
339 /* Call saved registers. */
348 /* Call clobbered registers. */
352 /* Argument registers, in reverse order of allocation. */
358 /* V8-V15 are call saved, and omitted. */
385 static const int tcg_target_call_iarg_regs[] = {
393 static const int tcg_target_call_oarg_regs[] = {
401 #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
402 #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
403 #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
404 #define S390_CC_NEVER 0
405 #define S390_CC_ALWAYS 15
407 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
408 static const uint8_t tcg_cond_to_s390_cond[] = {
409 [TCG_COND_EQ] = S390_CC_EQ,
410 [TCG_COND_NE] = S390_CC_NE,
411 [TCG_COND_LT] = S390_CC_LT,
412 [TCG_COND_LE] = S390_CC_LE,
413 [TCG_COND_GT] = S390_CC_GT,
414 [TCG_COND_GE] = S390_CC_GE,
415 [TCG_COND_LTU] = S390_CC_LT,
416 [TCG_COND_LEU] = S390_CC_LE,
417 [TCG_COND_GTU] = S390_CC_GT,
418 [TCG_COND_GEU] = S390_CC_GE,
421 /* Condition codes that result from a LOAD AND TEST. Here, we have no
422 unsigned instruction variation, however since the test is vs zero we
423 can re-map the outcomes appropriately. */
424 static const uint8_t tcg_cond_to_ltr_cond[] = {
425 [TCG_COND_EQ] = S390_CC_EQ,
426 [TCG_COND_NE] = S390_CC_NE,
427 [TCG_COND_LT] = S390_CC_LT,
428 [TCG_COND_LE] = S390_CC_LE,
429 [TCG_COND_GT] = S390_CC_GT,
430 [TCG_COND_GE] = S390_CC_GE,
431 [TCG_COND_LTU] = S390_CC_NEVER,
432 [TCG_COND_LEU] = S390_CC_EQ,
433 [TCG_COND_GTU] = S390_CC_NE,
434 [TCG_COND_GEU] = S390_CC_ALWAYS,
437 #ifdef CONFIG_SOFTMMU
438 static void * const qemu_ld_helpers[(MO_SSIZE | MO_BSWAP) + 1] = {
439 [MO_UB] = helper_ret_ldub_mmu,
440 [MO_SB] = helper_ret_ldsb_mmu,
441 [MO_LEUW] = helper_le_lduw_mmu,
442 [MO_LESW] = helper_le_ldsw_mmu,
443 [MO_LEUL] = helper_le_ldul_mmu,
444 [MO_LESL] = helper_le_ldsl_mmu,
445 [MO_LEUQ] = helper_le_ldq_mmu,
446 [MO_BEUW] = helper_be_lduw_mmu,
447 [MO_BESW] = helper_be_ldsw_mmu,
448 [MO_BEUL] = helper_be_ldul_mmu,
449 [MO_BESL] = helper_be_ldsl_mmu,
450 [MO_BEUQ] = helper_be_ldq_mmu,
453 static void * const qemu_st_helpers[(MO_SIZE | MO_BSWAP) + 1] = {
454 [MO_UB] = helper_ret_stb_mmu,
455 [MO_LEUW] = helper_le_stw_mmu,
456 [MO_LEUL] = helper_le_stl_mmu,
457 [MO_LEUQ] = helper_le_stq_mmu,
458 [MO_BEUW] = helper_be_stw_mmu,
459 [MO_BEUL] = helper_be_stl_mmu,
460 [MO_BEUQ] = helper_be_stq_mmu,
464 static const tcg_insn_unit *tb_ret_addr;
465 uint64_t s390_facilities[3];
467 static inline bool is_general_reg(TCGReg r)
469 return r <= TCG_REG_R15;
472 static inline bool is_vector_reg(TCGReg r)
474 return r >= TCG_REG_V0 && r <= TCG_REG_V31;
477 static bool patch_reloc(tcg_insn_unit *src_rw, int type,
478 intptr_t value, intptr_t addend)
480 const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
485 pcrel2 = (tcg_insn_unit *)value - src_rx;
489 if (pcrel2 == (int16_t)pcrel2) {
490 tcg_patch16(src_rw, pcrel2);
495 if (pcrel2 == (int32_t)pcrel2) {
496 tcg_patch32(src_rw, pcrel2);
501 if (value == sextract64(value, 0, 20)) {
502 old = *(uint32_t *)src_rw & 0xf00000ff;
503 old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
504 tcg_patch32(src_rw, old);
509 g_assert_not_reached();
514 /* Test if a constant matches the constraint. */
515 static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
517 if (ct & TCG_CT_CONST) {
521 if (type == TCG_TYPE_I32) {
525 /* The following are mutually exclusive. */
526 if (ct & TCG_CT_CONST_S16) {
527 return val == (int16_t)val;
528 } else if (ct & TCG_CT_CONST_S32) {
529 return val == (int32_t)val;
530 } else if (ct & TCG_CT_CONST_S33) {
531 return val >= -0xffffffffll && val <= 0xffffffffll;
532 } else if (ct & TCG_CT_CONST_ZERO) {
539 /* Emit instructions according to the given instruction format. */
541 static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
543 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
546 static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
547 TCGReg r1, TCGReg r2)
549 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
552 static void tcg_out_insn_RRF(TCGContext *s, S390Opcode op,
553 TCGReg r1, TCGReg r2, int m3)
555 tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
558 static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
560 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
563 static void tcg_out_insn_RIE(TCGContext *s, S390Opcode op, TCGReg r1,
566 tcg_out16(s, (op & 0xff00) | (r1 << 4) | m3);
567 tcg_out32(s, (i2 << 16) | (op & 0xff));
570 static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
572 tcg_out16(s, op | (r1 << 4));
576 static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
577 TCGReg b2, TCGReg r3, int disp)
579 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
583 static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
584 TCGReg b2, TCGReg r3, int disp)
586 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
587 tcg_out32(s, (op & 0xff) | (b2 << 28)
588 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
591 #define tcg_out_insn_RX tcg_out_insn_RS
592 #define tcg_out_insn_RXY tcg_out_insn_RSY
594 static int RXB(TCGReg v1, TCGReg v2, TCGReg v3, TCGReg v4)
597 * Shift bit 4 of each regno to its corresponding bit of RXB.
598 * RXB itself begins at bit 8 of the instruction so 8 - 4 = 4
599 * is the left-shift of the 4th operand.
601 return ((v1 & 0x10) << (4 + 3))
602 | ((v2 & 0x10) << (4 + 2))
603 | ((v3 & 0x10) << (4 + 1))
604 | ((v4 & 0x10) << (4 + 0));
607 static void tcg_out_insn_VRIa(TCGContext *s, S390Opcode op,
608 TCGReg v1, uint16_t i2, int m3)
610 tcg_debug_assert(is_vector_reg(v1));
611 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4));
613 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0) | (m3 << 12));
616 static void tcg_out_insn_VRIb(TCGContext *s, S390Opcode op,
617 TCGReg v1, uint8_t i2, uint8_t i3, int m4)
619 tcg_debug_assert(is_vector_reg(v1));
620 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4));
621 tcg_out16(s, (i2 << 8) | (i3 & 0xff));
622 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0) | (m4 << 12));
625 static void tcg_out_insn_VRIc(TCGContext *s, S390Opcode op,
626 TCGReg v1, uint16_t i2, TCGReg v3, int m4)
628 tcg_debug_assert(is_vector_reg(v1));
629 tcg_debug_assert(is_vector_reg(v3));
630 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v3 & 0xf));
632 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, v3, 0) | (m4 << 12));
635 static void tcg_out_insn_VRRa(TCGContext *s, S390Opcode op,
636 TCGReg v1, TCGReg v2, int m3)
638 tcg_debug_assert(is_vector_reg(v1));
639 tcg_debug_assert(is_vector_reg(v2));
640 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v2 & 0xf));
641 tcg_out32(s, (op & 0x00ff) | RXB(v1, v2, 0, 0) | (m3 << 12));
644 static void tcg_out_insn_VRRc(TCGContext *s, S390Opcode op,
645 TCGReg v1, TCGReg v2, TCGReg v3, int m4)
647 tcg_debug_assert(is_vector_reg(v1));
648 tcg_debug_assert(is_vector_reg(v2));
649 tcg_debug_assert(is_vector_reg(v3));
650 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v2 & 0xf));
651 tcg_out16(s, v3 << 12);
652 tcg_out16(s, (op & 0x00ff) | RXB(v1, v2, v3, 0) | (m4 << 12));
655 static void tcg_out_insn_VRRe(TCGContext *s, S390Opcode op,
656 TCGReg v1, TCGReg v2, TCGReg v3, TCGReg v4)
658 tcg_debug_assert(is_vector_reg(v1));
659 tcg_debug_assert(is_vector_reg(v2));
660 tcg_debug_assert(is_vector_reg(v3));
661 tcg_debug_assert(is_vector_reg(v4));
662 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v2 & 0xf));
663 tcg_out16(s, v3 << 12);
664 tcg_out16(s, (op & 0x00ff) | RXB(v1, v2, v3, v4) | (v4 << 12));
667 static void tcg_out_insn_VRRf(TCGContext *s, S390Opcode op,
668 TCGReg v1, TCGReg r2, TCGReg r3)
670 tcg_debug_assert(is_vector_reg(v1));
671 tcg_debug_assert(is_general_reg(r2));
672 tcg_debug_assert(is_general_reg(r3));
673 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | r2);
674 tcg_out16(s, r3 << 12);
675 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0));
678 static void tcg_out_insn_VRSa(TCGContext *s, S390Opcode op, TCGReg v1,
679 intptr_t d2, TCGReg b2, TCGReg v3, int m4)
681 tcg_debug_assert(is_vector_reg(v1));
682 tcg_debug_assert(d2 >= 0 && d2 <= 0xfff);
683 tcg_debug_assert(is_general_reg(b2));
684 tcg_debug_assert(is_vector_reg(v3));
685 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v3 & 0xf));
686 tcg_out16(s, b2 << 12 | d2);
687 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, v3, 0) | (m4 << 12));
690 static void tcg_out_insn_VRSb(TCGContext *s, S390Opcode op, TCGReg v1,
691 intptr_t d2, TCGReg b2, TCGReg r3, int m4)
693 tcg_debug_assert(is_vector_reg(v1));
694 tcg_debug_assert(d2 >= 0 && d2 <= 0xfff);
695 tcg_debug_assert(is_general_reg(b2));
696 tcg_debug_assert(is_general_reg(r3));
697 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | r3);
698 tcg_out16(s, b2 << 12 | d2);
699 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0) | (m4 << 12));
702 static void tcg_out_insn_VRSc(TCGContext *s, S390Opcode op, TCGReg r1,
703 intptr_t d2, TCGReg b2, TCGReg v3, int m4)
705 tcg_debug_assert(is_general_reg(r1));
706 tcg_debug_assert(d2 >= 0 && d2 <= 0xfff);
707 tcg_debug_assert(is_general_reg(b2));
708 tcg_debug_assert(is_vector_reg(v3));
709 tcg_out16(s, (op & 0xff00) | (r1 << 4) | (v3 & 0xf));
710 tcg_out16(s, b2 << 12 | d2);
711 tcg_out16(s, (op & 0x00ff) | RXB(0, 0, v3, 0) | (m4 << 12));
714 static void tcg_out_insn_VRX(TCGContext *s, S390Opcode op, TCGReg v1,
715 TCGReg b2, TCGReg x2, intptr_t d2, int m3)
717 tcg_debug_assert(is_vector_reg(v1));
718 tcg_debug_assert(d2 >= 0 && d2 <= 0xfff);
719 tcg_debug_assert(is_general_reg(x2));
720 tcg_debug_assert(is_general_reg(b2));
721 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | x2);
722 tcg_out16(s, (b2 << 12) | d2);
723 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0) | (m3 << 12));
726 /* Emit an opcode with "type-checking" of the format. */
727 #define tcg_out_insn(S, FMT, OP, ...) \
728 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
731 /* emit 64-bit shifts */
732 static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
733 TCGReg src, TCGReg sh_reg, int sh_imm)
735 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
738 /* emit 32-bit shifts */
739 static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
740 TCGReg sh_reg, int sh_imm)
742 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
745 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
752 if (likely(is_general_reg(dst) && is_general_reg(src))) {
753 tcg_out_insn(s, RR, LR, dst, src);
759 if (likely(is_general_reg(dst))) {
760 if (likely(is_general_reg(src))) {
761 tcg_out_insn(s, RRE, LGR, dst, src);
763 tcg_out_insn(s, VRSc, VLGV, dst, 0, 0, src, 3);
766 } else if (is_general_reg(src)) {
767 tcg_out_insn(s, VRSb, VLVG, dst, 0, 0, src, 3);
774 tcg_out_insn(s, VRRa, VLR, dst, src, 0);
778 g_assert_not_reached();
783 static const S390Opcode lli_insns[4] = {
784 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
787 static bool maybe_out_small_movi(TCGContext *s, TCGType type,
788 TCGReg ret, tcg_target_long sval)
790 tcg_target_ulong uval = sval;
793 if (type == TCG_TYPE_I32) {
794 uval = (uint32_t)sval;
795 sval = (int32_t)sval;
798 /* Try all 32-bit insns that can load it in one go. */
799 if (sval >= -0x8000 && sval < 0x8000) {
800 tcg_out_insn(s, RI, LGHI, ret, sval);
804 for (i = 0; i < 4; i++) {
805 tcg_target_long mask = 0xffffull << i*16;
806 if ((uval & mask) == uval) {
807 tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
815 /* load a register with an immediate value */
816 static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
817 tcg_target_long sval, bool in_prologue)
819 tcg_target_ulong uval;
821 /* Try all 32-bit insns that can load it in one go. */
822 if (maybe_out_small_movi(s, type, ret, sval)) {
827 if (type == TCG_TYPE_I32) {
828 uval = (uint32_t)sval;
829 sval = (int32_t)sval;
832 /* Try all 48-bit insns that can load it in one go. */
833 if (HAVE_FACILITY(EXT_IMM)) {
834 if (sval == (int32_t)sval) {
835 tcg_out_insn(s, RIL, LGFI, ret, sval);
838 if (uval <= 0xffffffff) {
839 tcg_out_insn(s, RIL, LLILF, ret, uval);
842 if ((uval & 0xffffffff) == 0) {
843 tcg_out_insn(s, RIL, LLIHF, ret, uval >> 32);
848 /* Try for PC-relative address load. For odd addresses,
849 attempt to use an offset from the start of the TB. */
850 if ((sval & 1) == 0) {
851 ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1;
852 if (off == (int32_t)off) {
853 tcg_out_insn(s, RIL, LARL, ret, off);
856 } else if (USE_REG_TB && !in_prologue) {
857 ptrdiff_t off = tcg_tbrel_diff(s, (void *)sval);
858 if (off == sextract64(off, 0, 20)) {
859 /* This is certain to be an address within TB, and therefore
860 OFF will be negative; don't try RX_LA. */
861 tcg_out_insn(s, RXY, LAY, ret, TCG_REG_TB, TCG_REG_NONE, off);
866 /* A 32-bit unsigned value can be loaded in 2 insns. And given
867 that LLILL, LLIHL, LLILF above did not succeed, we know that
868 both insns are required. */
869 if (uval <= 0xffffffff) {
870 tcg_out_insn(s, RI, LLILL, ret, uval);
871 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
875 /* Otherwise, stuff it in the constant pool. */
876 if (HAVE_FACILITY(GEN_INST_EXT)) {
877 tcg_out_insn(s, RIL, LGRL, ret, 0);
878 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
879 } else if (USE_REG_TB && !in_prologue) {
880 tcg_out_insn(s, RXY, LG, ret, TCG_REG_TB, TCG_REG_NONE, 0);
881 new_pool_label(s, sval, R_390_20, s->code_ptr - 2,
882 tcg_tbrel_diff(s, NULL));
884 TCGReg base = ret ? ret : TCG_TMP0;
885 tcg_out_insn(s, RIL, LARL, base, 0);
886 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
887 tcg_out_insn(s, RXY, LG, ret, base, TCG_REG_NONE, 0);
891 static void tcg_out_movi(TCGContext *s, TCGType type,
892 TCGReg ret, tcg_target_long sval)
894 tcg_out_movi_int(s, type, ret, sval, false);
897 /* Emit a load/store type instruction. Inputs are:
898 DATA: The register to be loaded or stored.
899 BASE+OFS: The effective address.
900 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
901 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
903 static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
904 TCGReg data, TCGReg base, TCGReg index,
907 if (ofs < -0x80000 || ofs >= 0x80000) {
908 /* Combine the low 20 bits of the offset with the actual load insn;
909 the high 44 bits must come from an immediate load. */
910 tcg_target_long low = ((ofs & 0xfffff) ^ 0x80000) - 0x80000;
911 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - low);
914 /* If we were already given an index register, add it in. */
915 if (index != TCG_REG_NONE) {
916 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
921 if (opc_rx && ofs >= 0 && ofs < 0x1000) {
922 tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
924 tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
928 static void tcg_out_vrx_mem(TCGContext *s, S390Opcode opc_vrx,
929 TCGReg data, TCGReg base, TCGReg index,
930 tcg_target_long ofs, int m3)
932 if (ofs < 0 || ofs >= 0x1000) {
933 if (ofs >= -0x80000 && ofs < 0x80000) {
934 tcg_out_insn(s, RXY, LAY, TCG_TMP0, base, index, ofs);
936 index = TCG_REG_NONE;
939 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs);
940 if (index != TCG_REG_NONE) {
941 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
947 tcg_out_insn_VRX(s, opc_vrx, data, base, index, ofs, m3);
950 /* load data without address translation or endianness conversion */
951 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
952 TCGReg base, intptr_t ofs)
956 if (likely(is_general_reg(data))) {
957 tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
960 tcg_out_vrx_mem(s, VRX_VLLEZ, data, base, TCG_REG_NONE, ofs, MO_32);
964 if (likely(is_general_reg(data))) {
965 tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
971 tcg_out_vrx_mem(s, VRX_VLLEZ, data, base, TCG_REG_NONE, ofs, MO_64);
975 /* Hint quadword aligned. */
976 tcg_out_vrx_mem(s, VRX_VL, data, base, TCG_REG_NONE, ofs, 4);
980 g_assert_not_reached();
984 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
985 TCGReg base, intptr_t ofs)
989 if (likely(is_general_reg(data))) {
990 tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
992 tcg_out_vrx_mem(s, VRX_VSTEF, data, base, TCG_REG_NONE, ofs, 1);
997 if (likely(is_general_reg(data))) {
998 tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
1004 tcg_out_vrx_mem(s, VRX_VSTEG, data, base, TCG_REG_NONE, ofs, 0);
1008 /* Hint quadword aligned. */
1009 tcg_out_vrx_mem(s, VRX_VST, data, base, TCG_REG_NONE, ofs, 4);
1013 g_assert_not_reached();
1017 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
1018 TCGReg base, intptr_t ofs)
1023 /* load data from an absolute host address */
1024 static void tcg_out_ld_abs(TCGContext *s, TCGType type,
1025 TCGReg dest, const void *abs)
1027 intptr_t addr = (intptr_t)abs;
1029 if (HAVE_FACILITY(GEN_INST_EXT) && !(addr & 1)) {
1030 ptrdiff_t disp = tcg_pcrel_diff(s, abs) >> 1;
1031 if (disp == (int32_t)disp) {
1032 if (type == TCG_TYPE_I32) {
1033 tcg_out_insn(s, RIL, LRL, dest, disp);
1035 tcg_out_insn(s, RIL, LGRL, dest, disp);
1041 ptrdiff_t disp = tcg_tbrel_diff(s, abs);
1042 if (disp == sextract64(disp, 0, 20)) {
1043 tcg_out_ld(s, type, dest, TCG_REG_TB, disp);
1048 tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
1049 tcg_out_ld(s, type, dest, dest, addr & 0xffff);
1052 static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
1053 int msb, int lsb, int ofs, int z)
1056 tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src);
1057 tcg_out16(s, (msb << 8) | (z << 7) | lsb);
1058 tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff));
1061 static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
1063 if (HAVE_FACILITY(EXT_IMM)) {
1064 tcg_out_insn(s, RRE, LGBR, dest, src);
1068 if (type == TCG_TYPE_I32) {
1070 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
1072 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
1074 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
1076 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
1077 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
1081 static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
1083 if (HAVE_FACILITY(EXT_IMM)) {
1084 tcg_out_insn(s, RRE, LLGCR, dest, src);
1089 tcg_out_movi(s, type, TCG_TMP0, 0xff);
1092 tcg_out_movi(s, type, dest, 0xff);
1094 if (type == TCG_TYPE_I32) {
1095 tcg_out_insn(s, RR, NR, dest, src);
1097 tcg_out_insn(s, RRE, NGR, dest, src);
1101 static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
1103 if (HAVE_FACILITY(EXT_IMM)) {
1104 tcg_out_insn(s, RRE, LGHR, dest, src);
1108 if (type == TCG_TYPE_I32) {
1110 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
1112 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
1114 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
1116 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
1117 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
1121 static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
1123 if (HAVE_FACILITY(EXT_IMM)) {
1124 tcg_out_insn(s, RRE, LLGHR, dest, src);
1129 tcg_out_movi(s, type, TCG_TMP0, 0xffff);
1132 tcg_out_movi(s, type, dest, 0xffff);
1134 if (type == TCG_TYPE_I32) {
1135 tcg_out_insn(s, RR, NR, dest, src);
1137 tcg_out_insn(s, RRE, NGR, dest, src);
1141 static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
1143 tcg_out_insn(s, RRE, LGFR, dest, src);
1146 static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
1148 tcg_out_insn(s, RRE, LLGFR, dest, src);
1151 /* Accept bit patterns like these:
1156 Copied from gcc sources. */
1157 static inline bool risbg_mask(uint64_t c)
1160 /* We don't change the number of transitions by inverting,
1161 so make sure we start with the LSB zero. */
1165 /* Reject all zeros or all ones. */
1169 /* Find the first transition. */
1171 /* Invert to look for a second transition. */
1173 /* Erase the first transition. */
1175 /* Find the second transition, if any. */
1177 /* Match if all the bits are 1's, or if c is zero. */
1181 static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
1184 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
1185 /* Achieve wraparound by swapping msb and lsb. */
1186 msb = 64 - ctz64(~val);
1187 lsb = clz64(~val) - 1;
1190 lsb = 63 - ctz64(val);
1192 tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
1195 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
1197 static const S390Opcode ni_insns[4] = {
1198 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
1200 static const S390Opcode nif_insns[2] = {
1203 uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
1206 /* Look for the zero-extensions. */
1207 if ((val & valid) == 0xffffffff) {
1208 tgen_ext32u(s, dest, dest);
1211 if (HAVE_FACILITY(EXT_IMM)) {
1212 if ((val & valid) == 0xff) {
1213 tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
1216 if ((val & valid) == 0xffff) {
1217 tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
1222 /* Try all 32-bit insns that can perform it in one go. */
1223 for (i = 0; i < 4; i++) {
1224 tcg_target_ulong mask = ~(0xffffull << i*16);
1225 if (((val | ~valid) & mask) == mask) {
1226 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
1231 /* Try all 48-bit insns that can perform it in one go. */
1232 if (HAVE_FACILITY(EXT_IMM)) {
1233 for (i = 0; i < 2; i++) {
1234 tcg_target_ulong mask = ~(0xffffffffull << i*32);
1235 if (((val | ~valid) & mask) == mask) {
1236 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
1241 if (HAVE_FACILITY(GEN_INST_EXT) && risbg_mask(val)) {
1242 tgen_andi_risbg(s, dest, dest, val);
1246 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1248 if (!maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1249 tcg_out_insn(s, RXY, NG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1250 new_pool_label(s, val & valid, R_390_20, s->code_ptr - 2,
1251 tcg_tbrel_diff(s, NULL));
1255 tcg_out_movi(s, type, TCG_TMP0, val);
1257 if (type == TCG_TYPE_I32) {
1258 tcg_out_insn(s, RR, NR, dest, TCG_TMP0);
1260 tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
1264 static void tgen_ori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
1266 static const S390Opcode oi_insns[4] = {
1267 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
1269 static const S390Opcode oif_insns[2] = {
1275 /* Look for no-op. */
1276 if (unlikely(val == 0)) {
1280 /* Try all 32-bit insns that can perform it in one go. */
1281 for (i = 0; i < 4; i++) {
1282 tcg_target_ulong mask = (0xffffull << i*16);
1283 if ((val & mask) != 0 && (val & ~mask) == 0) {
1284 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1289 /* Try all 48-bit insns that can perform it in one go. */
1290 if (HAVE_FACILITY(EXT_IMM)) {
1291 for (i = 0; i < 2; i++) {
1292 tcg_target_ulong mask = (0xffffffffull << i*32);
1293 if ((val & mask) != 0 && (val & ~mask) == 0) {
1294 tcg_out_insn_RIL(s, oif_insns[i], dest, val >> i*32);
1300 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1301 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1302 if (type == TCG_TYPE_I32) {
1303 tcg_out_insn(s, RR, OR, dest, TCG_TMP0);
1305 tcg_out_insn(s, RRE, OGR, dest, TCG_TMP0);
1307 } else if (USE_REG_TB) {
1308 tcg_out_insn(s, RXY, OG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1309 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
1310 tcg_tbrel_diff(s, NULL));
1312 /* Perform the OR via sequential modifications to the high and
1313 low parts. Do this via recursion to handle 16-bit vs 32-bit
1314 masks in each half. */
1315 tcg_debug_assert(HAVE_FACILITY(EXT_IMM));
1316 tgen_ori(s, type, dest, val & 0x00000000ffffffffull);
1317 tgen_ori(s, type, dest, val & 0xffffffff00000000ull);
1321 static void tgen_xori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
1323 /* Try all 48-bit insns that can perform it in one go. */
1324 if (HAVE_FACILITY(EXT_IMM)) {
1325 if ((val & 0xffffffff00000000ull) == 0) {
1326 tcg_out_insn(s, RIL, XILF, dest, val);
1329 if ((val & 0x00000000ffffffffull) == 0) {
1330 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1335 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1336 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1337 if (type == TCG_TYPE_I32) {
1338 tcg_out_insn(s, RR, XR, dest, TCG_TMP0);
1340 tcg_out_insn(s, RRE, XGR, dest, TCG_TMP0);
1342 } else if (USE_REG_TB) {
1343 tcg_out_insn(s, RXY, XG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1344 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
1345 tcg_tbrel_diff(s, NULL));
1347 /* Perform the xor by parts. */
1348 tcg_debug_assert(HAVE_FACILITY(EXT_IMM));
1349 if (val & 0xffffffff) {
1350 tcg_out_insn(s, RIL, XILF, dest, val);
1352 if (val > 0xffffffff) {
1353 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1358 static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1359 TCGArg c2, bool c2const, bool need_carry)
1361 bool is_unsigned = is_unsigned_cond(c);
1366 if (!(is_unsigned && need_carry)) {
1367 if (type == TCG_TYPE_I32) {
1368 tcg_out_insn(s, RR, LTR, r1, r1);
1370 tcg_out_insn(s, RRE, LTGR, r1, r1);
1372 return tcg_cond_to_ltr_cond[c];
1376 if (!is_unsigned && c2 == (int16_t)c2) {
1377 op = (type == TCG_TYPE_I32 ? RI_CHI : RI_CGHI);
1378 tcg_out_insn_RI(s, op, r1, c2);
1382 if (HAVE_FACILITY(EXT_IMM)) {
1383 if (type == TCG_TYPE_I32) {
1384 op = (is_unsigned ? RIL_CLFI : RIL_CFI);
1385 tcg_out_insn_RIL(s, op, r1, c2);
1387 } else if (c2 == (is_unsigned ? (TCGArg)(uint32_t)c2 : (TCGArg)(int32_t)c2)) {
1388 op = (is_unsigned ? RIL_CLGFI : RIL_CGFI);
1389 tcg_out_insn_RIL(s, op, r1, c2);
1394 /* Use the constant pool, but not for small constants. */
1395 if (maybe_out_small_movi(s, type, TCG_TMP0, c2)) {
1397 /* fall through to reg-reg */
1398 } else if (USE_REG_TB) {
1399 if (type == TCG_TYPE_I32) {
1400 op = (is_unsigned ? RXY_CLY : RXY_CY);
1401 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1402 new_pool_label(s, (uint32_t)c2, R_390_20, s->code_ptr - 2,
1403 4 - tcg_tbrel_diff(s, NULL));
1405 op = (is_unsigned ? RXY_CLG : RXY_CG);
1406 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1407 new_pool_label(s, c2, R_390_20, s->code_ptr - 2,
1408 tcg_tbrel_diff(s, NULL));
1412 if (type == TCG_TYPE_I32) {
1413 op = (is_unsigned ? RIL_CLRL : RIL_CRL);
1414 tcg_out_insn_RIL(s, op, r1, 0);
1415 new_pool_label(s, (uint32_t)c2, R_390_PC32DBL,
1416 s->code_ptr - 2, 2 + 4);
1418 op = (is_unsigned ? RIL_CLGRL : RIL_CGRL);
1419 tcg_out_insn_RIL(s, op, r1, 0);
1420 new_pool_label(s, c2, R_390_PC32DBL, s->code_ptr - 2, 2);
1426 if (type == TCG_TYPE_I32) {
1427 op = (is_unsigned ? RR_CLR : RR_CR);
1428 tcg_out_insn_RR(s, op, r1, c2);
1430 op = (is_unsigned ? RRE_CLGR : RRE_CGR);
1431 tcg_out_insn_RRE(s, op, r1, c2);
1435 return tcg_cond_to_s390_cond[c];
1438 static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
1439 TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
1444 /* With LOC2, we can always emit the minimum 3 insns. */
1445 if (HAVE_FACILITY(LOAD_ON_COND2)) {
1446 /* Emit: d = 0, d = (cc ? 1 : d). */
1447 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1448 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1449 tcg_out_insn(s, RIE, LOCGHI, dest, 1, cc);
1453 have_loc = HAVE_FACILITY(LOAD_ON_COND);
1455 /* For HAVE_LOC, only the paths through GTU/GT/LEU/LE are smaller. */
1459 /* X != 0 is X > 0. */
1460 if (c2const && c2 == 0) {
1461 cond = TCG_COND_GTU;
1469 /* The result of a compare has CC=2 for GT and CC=3 unused.
1470 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1471 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1472 tcg_out_movi(s, type, dest, 0);
1473 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1477 /* X == 0 is X <= 0. */
1478 if (c2const && c2 == 0) {
1479 cond = TCG_COND_LEU;
1487 /* As above, but we're looking for borrow, or !carry.
1488 The second insn computes d - d - borrow, or -1 for true
1489 and 0 for false. So we must mask to 1 bit afterward. */
1490 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1491 tcg_out_insn(s, RRE, SLBGR, dest, dest);
1492 tgen_andi(s, type, dest, 1);
1499 /* Swap operands so that we can use LEU/GTU/GT/LE. */
1504 tcg_out_movi(s, type, TCG_TMP0, c2);
1513 cond = tcg_swap_cond(cond);
1517 g_assert_not_reached();
1520 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1522 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1523 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1524 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1525 tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);
1527 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1528 tcg_out_movi(s, type, dest, 1);
1529 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1530 tcg_out_movi(s, type, dest, 0);
1534 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
1535 TCGReg c1, TCGArg c2, int c2const,
1536 TCGArg v3, int v3const)
1539 if (HAVE_FACILITY(LOAD_ON_COND)) {
1540 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1542 tcg_out_insn(s, RIE, LOCGHI, dest, v3, cc);
1544 tcg_out_insn(s, RRF, LOCGR, dest, v3, cc);
1547 c = tcg_invert_cond(c);
1548 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1550 /* Emit: if (cc) goto over; dest = r3; over: */
1551 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1552 tcg_out_insn(s, RRE, LGR, dest, v3);
1556 static void tgen_clz(TCGContext *s, TCGReg dest, TCGReg a1,
1557 TCGArg a2, int a2const)
1559 /* Since this sets both R and R+1, we have no choice but to store the
1560 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1561 QEMU_BUILD_BUG_ON(TCG_TMP0 != TCG_REG_R1);
1562 tcg_out_insn(s, RRE, FLOGR, TCG_REG_R0, a1);
1564 if (a2const && a2 == 64) {
1565 tcg_out_mov(s, TCG_TYPE_I64, dest, TCG_REG_R0);
1568 tcg_out_movi(s, TCG_TYPE_I64, dest, a2);
1570 tcg_out_mov(s, TCG_TYPE_I64, dest, a2);
1572 if (HAVE_FACILITY(LOAD_ON_COND)) {
1573 /* Emit: if (one bit found) dest = r0. */
1574 tcg_out_insn(s, RRF, LOCGR, dest, TCG_REG_R0, 2);
1576 /* Emit: if (no one bit found) goto over; dest = r0; over: */
1577 tcg_out_insn(s, RI, BRC, 8, (4 + 4) >> 1);
1578 tcg_out_insn(s, RRE, LGR, dest, TCG_REG_R0);
1583 static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
1584 int ofs, int len, int z)
1586 int lsb = (63 - ofs);
1587 int msb = lsb - (len - 1);
1588 tcg_out_risbg(s, dest, src, msb, lsb, ofs, z);
1591 static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
1594 tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
1597 static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
1599 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1600 if (off == (int16_t)off) {
1601 tcg_out_insn(s, RI, BRC, cc, off);
1602 } else if (off == (int32_t)off) {
1603 tcg_out_insn(s, RIL, BRCL, cc, off);
1605 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1606 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1610 static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
1613 tgen_gotoi(s, cc, l->u.value_ptr);
1614 } else if (USE_LONG_BRANCHES) {
1615 tcg_out16(s, RIL_BRCL | (cc << 4));
1616 tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, l, 2);
1619 tcg_out16(s, RI_BRC | (cc << 4));
1620 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, 2);
1625 static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1626 TCGReg r1, TCGReg r2, TCGLabel *l)
1628 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1629 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1631 tcg_out16(s, cc << 12 | (opc & 0xff));
1634 static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1635 TCGReg r1, int i2, TCGLabel *l)
1637 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1638 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1640 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1643 static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1644 TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
1648 if (HAVE_FACILITY(GEN_INST_EXT)) {
1649 bool is_unsigned = is_unsigned_cond(c);
1653 cc = tcg_cond_to_s390_cond[c];
1656 opc = (type == TCG_TYPE_I32
1657 ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1658 : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1659 tgen_compare_branch(s, opc, cc, r1, c2, l);
1663 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1664 If the immediate we've been given does not fit that range, we'll
1665 fall back to separate compare and branch instructions using the
1666 larger comparison range afforded by COMPARE IMMEDIATE. */
1667 if (type == TCG_TYPE_I32) {
1670 in_range = (uint32_t)c2 == (uint8_t)c2;
1673 in_range = (int32_t)c2 == (int8_t)c2;
1678 in_range = (uint64_t)c2 == (uint8_t)c2;
1681 in_range = (int64_t)c2 == (int8_t)c2;
1685 tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
1690 cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
1691 tgen_branch(s, cc, l);
1694 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
1696 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1697 if (off == (int32_t)off) {
1698 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1700 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1701 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1705 static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
1706 TCGReg base, TCGReg index, int disp)
1708 switch (opc & (MO_SSIZE | MO_BSWAP)) {
1710 tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1713 tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1716 case MO_UW | MO_BSWAP:
1717 /* swapped unsigned halfword load with upper bits zeroed */
1718 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1719 tgen_ext16u(s, TCG_TYPE_I64, data, data);
1722 tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1725 case MO_SW | MO_BSWAP:
1726 /* swapped sign-extended halfword load */
1727 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1728 tgen_ext16s(s, TCG_TYPE_I64, data, data);
1731 tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1734 case MO_UL | MO_BSWAP:
1735 /* swapped unsigned int load with upper bits zeroed */
1736 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1737 tgen_ext32u(s, data, data);
1740 tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1743 case MO_SL | MO_BSWAP:
1744 /* swapped sign-extended int load */
1745 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1746 tgen_ext32s(s, data, data);
1749 tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1752 case MO_UQ | MO_BSWAP:
1753 tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1756 tcg_out_insn(s, RXY, LG, data, base, index, disp);
1764 static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data,
1765 TCGReg base, TCGReg index, int disp)
1767 switch (opc & (MO_SIZE | MO_BSWAP)) {
1769 if (disp >= 0 && disp < 0x1000) {
1770 tcg_out_insn(s, RX, STC, data, base, index, disp);
1772 tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1776 case MO_UW | MO_BSWAP:
1777 tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1780 if (disp >= 0 && disp < 0x1000) {
1781 tcg_out_insn(s, RX, STH, data, base, index, disp);
1783 tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1787 case MO_UL | MO_BSWAP:
1788 tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1791 if (disp >= 0 && disp < 0x1000) {
1792 tcg_out_insn(s, RX, ST, data, base, index, disp);
1794 tcg_out_insn(s, RXY, STY, data, base, index, disp);
1798 case MO_UQ | MO_BSWAP:
1799 tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1802 tcg_out_insn(s, RXY, STG, data, base, index, disp);
1810 #if defined(CONFIG_SOFTMMU)
1811 /* We're expecting to use a 20-bit negative offset on the tlb memory ops. */
1812 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1813 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 19));
1815 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1816 addend into R2. Returns a register with the santitized guest address. */
1817 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc,
1818 int mem_index, bool is_ld)
1820 unsigned s_bits = opc & MO_SIZE;
1821 unsigned a_bits = get_alignment_bits(opc);
1822 unsigned s_mask = (1 << s_bits) - 1;
1823 unsigned a_mask = (1 << a_bits) - 1;
1824 int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1825 int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1826 int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1830 tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
1831 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1832 tcg_out_insn(s, RXY, NG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, mask_off);
1833 tcg_out_insn(s, RXY, AG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, table_off);
1835 /* For aligned accesses, we check the first byte and include the alignment
1836 bits within the address. For unaligned access, we check that we don't
1837 cross pages using the address of the last byte of the access. */
1838 a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
1839 tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
1840 if (HAVE_FACILITY(GEN_INST_EXT) && a_off == 0) {
1841 tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
1843 tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
1844 tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
1848 ofs = offsetof(CPUTLBEntry, addr_read);
1850 ofs = offsetof(CPUTLBEntry, addr_write);
1852 if (TARGET_LONG_BITS == 32) {
1853 tcg_out_insn(s, RX, C, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1855 tcg_out_insn(s, RXY, CG, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1858 tcg_out_insn(s, RXY, LG, TCG_REG_R2, TCG_REG_R2, TCG_REG_NONE,
1859 offsetof(CPUTLBEntry, addend));
1861 if (TARGET_LONG_BITS == 32) {
1862 tgen_ext32u(s, TCG_REG_R3, addr_reg);
1868 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, MemOpIdx oi,
1869 TCGReg data, TCGReg addr,
1870 tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
1872 TCGLabelQemuLdst *label = new_ldst_label(s);
1874 label->is_ld = is_ld;
1876 label->datalo_reg = data;
1877 label->addrlo_reg = addr;
1878 label->raddr = tcg_splitwx_to_rx(raddr);
1879 label->label_ptr[0] = label_ptr;
1882 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1884 TCGReg addr_reg = lb->addrlo_reg;
1885 TCGReg data_reg = lb->datalo_reg;
1886 MemOpIdx oi = lb->oi;
1887 MemOp opc = get_memop(oi);
1889 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1890 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1894 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1895 if (TARGET_LONG_BITS == 64) {
1896 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1898 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, oi);
1899 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R5, (uintptr_t)lb->raddr);
1900 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)]);
1901 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1903 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1907 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1909 TCGReg addr_reg = lb->addrlo_reg;
1910 TCGReg data_reg = lb->datalo_reg;
1911 MemOpIdx oi = lb->oi;
1912 MemOp opc = get_memop(oi);
1914 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1915 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1919 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1920 if (TARGET_LONG_BITS == 64) {
1921 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1923 switch (opc & MO_SIZE) {
1925 tgen_ext8u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1928 tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1931 tgen_ext32u(s, TCG_REG_R4, data_reg);
1934 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1939 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
1940 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
1941 tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1943 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1947 static void tcg_out_test_alignment(TCGContext *s, bool is_ld,
1948 TCGReg addrlo, unsigned a_bits)
1950 unsigned a_mask = (1 << a_bits) - 1;
1951 TCGLabelQemuLdst *l = new_ldst_label(s);
1954 l->addrlo_reg = addrlo;
1956 /* We are expecting a_bits to max out at 7, much lower than TMLL. */
1957 tcg_debug_assert(a_bits < 16);
1958 tcg_out_insn(s, RI, TMLL, addrlo, a_mask);
1960 tcg_out16(s, RI_BRC | (7 << 4)); /* CC in {1,2,3} */
1961 l->label_ptr[0] = s->code_ptr;
1964 l->raddr = tcg_splitwx_to_rx(s->code_ptr);
1967 static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
1969 if (!patch_reloc(l->label_ptr[0], R_390_PC16DBL,
1970 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1974 tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_R3, l->addrlo_reg);
1975 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1977 /* "Tail call" to the helper, with the return address back inline. */
1978 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R14, (uintptr_t)l->raddr);
1979 tgen_gotoi(s, S390_CC_ALWAYS, (const void *)(l->is_ld ? helper_unaligned_ld
1980 : helper_unaligned_st));
1984 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1986 return tcg_out_fail_alignment(s, l);
1989 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1991 return tcg_out_fail_alignment(s, l);
1994 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1995 TCGReg *index_reg, tcg_target_long *disp)
1997 if (TARGET_LONG_BITS == 32) {
1998 tgen_ext32u(s, TCG_TMP0, *addr_reg);
1999 *addr_reg = TCG_TMP0;
2001 if (guest_base < 0x80000) {
2002 *index_reg = TCG_REG_NONE;
2005 *index_reg = TCG_GUEST_BASE_REG;
2009 #endif /* CONFIG_SOFTMMU */
2011 static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
2014 MemOp opc = get_memop(oi);
2015 #ifdef CONFIG_SOFTMMU
2016 unsigned mem_index = get_mmuidx(oi);
2017 tcg_insn_unit *label_ptr;
2020 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 1);
2022 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
2023 label_ptr = s->code_ptr;
2026 tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
2028 add_qemu_ldst_label(s, 1, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
2031 tcg_target_long disp;
2032 unsigned a_bits = get_alignment_bits(opc);
2035 tcg_out_test_alignment(s, true, addr_reg, a_bits);
2037 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
2038 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
2042 static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
2045 MemOp opc = get_memop(oi);
2046 #ifdef CONFIG_SOFTMMU
2047 unsigned mem_index = get_mmuidx(oi);
2048 tcg_insn_unit *label_ptr;
2051 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 0);
2053 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
2054 label_ptr = s->code_ptr;
2057 tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
2059 add_qemu_ldst_label(s, 0, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
2062 tcg_target_long disp;
2063 unsigned a_bits = get_alignment_bits(opc);
2066 tcg_out_test_alignment(s, false, addr_reg, a_bits);
2068 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
2069 tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
2073 # define OP_32_64(x) \
2074 case glue(glue(INDEX_op_,x),_i32): \
2075 case glue(glue(INDEX_op_,x),_i64)
2077 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
2078 const TCGArg args[TCG_MAX_OP_ARGS],
2079 const int const_args[TCG_MAX_OP_ARGS])
2085 case INDEX_op_exit_tb:
2086 /* Reuse the zeroing that exists for goto_ptr. */
2089 tgen_gotoi(s, S390_CC_ALWAYS, tcg_code_gen_epilogue);
2091 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, a0);
2092 tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
2096 case INDEX_op_goto_tb:
2098 if (s->tb_jmp_insn_offset) {
2100 * branch displacement must be aligned for atomic patching;
2101 * see if we need to add extra nop before branch
2103 if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
2106 tcg_debug_assert(!USE_REG_TB);
2107 tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
2108 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
2111 /* load address stored at s->tb_jmp_target_addr + a0 */
2112 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_REG_TB,
2113 tcg_splitwx_to_rx(s->tb_jmp_target_addr + a0));
2115 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_TB);
2117 set_jmp_reset_offset(s, a0);
2119 /* For the unlinked path of goto_tb, we need to reset
2120 TCG_REG_TB to the beginning of this TB. */
2122 int ofs = -tcg_current_code_size(s);
2123 /* All TB are restricted to 64KiB by unwind info. */
2124 tcg_debug_assert(ofs == sextract64(ofs, 0, 20));
2125 tcg_out_insn(s, RXY, LAY, TCG_REG_TB,
2126 TCG_REG_TB, TCG_REG_NONE, ofs);
2130 case INDEX_op_goto_ptr:
2133 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, a0);
2135 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, a0);
2139 /* ??? LLC (RXY format) is only present with the extended-immediate
2140 facility, whereas LLGC is always present. */
2141 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
2145 /* ??? LB is no smaller than LGB, so no point to using it. */
2146 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
2150 /* ??? LLH (RXY format) is only present with the extended-immediate
2151 facility, whereas LLGH is always present. */
2152 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
2155 case INDEX_op_ld16s_i32:
2156 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
2159 case INDEX_op_ld_i32:
2160 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2164 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
2165 TCG_REG_NONE, args[2]);
2169 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
2170 TCG_REG_NONE, args[2]);
2173 case INDEX_op_st_i32:
2174 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2177 case INDEX_op_add_i32:
2178 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
2179 if (const_args[2]) {
2182 if (a2 == (int16_t)a2) {
2183 tcg_out_insn(s, RI, AHI, a0, a2);
2186 if (HAVE_FACILITY(EXT_IMM)) {
2187 tcg_out_insn(s, RIL, AFI, a0, a2);
2191 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2192 } else if (a0 == a1) {
2193 tcg_out_insn(s, RR, AR, a0, a2);
2195 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2198 case INDEX_op_sub_i32:
2199 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
2200 if (const_args[2]) {
2203 } else if (a0 == a1) {
2204 tcg_out_insn(s, RR, SR, a0, a2);
2206 tcg_out_insn(s, RRF, SRK, a0, a1, a2);
2210 case INDEX_op_and_i32:
2211 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
2212 if (const_args[2]) {
2213 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
2214 tgen_andi(s, TCG_TYPE_I32, a0, a2);
2215 } else if (a0 == a1) {
2216 tcg_out_insn(s, RR, NR, a0, a2);
2218 tcg_out_insn(s, RRF, NRK, a0, a1, a2);
2221 case INDEX_op_or_i32:
2222 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
2223 if (const_args[2]) {
2224 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
2225 tgen_ori(s, TCG_TYPE_I32, a0, a2);
2226 } else if (a0 == a1) {
2227 tcg_out_insn(s, RR, OR, a0, a2);
2229 tcg_out_insn(s, RRF, ORK, a0, a1, a2);
2232 case INDEX_op_xor_i32:
2233 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
2234 if (const_args[2]) {
2235 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
2236 tgen_xori(s, TCG_TYPE_I32, a0, a2);
2237 } else if (a0 == a1) {
2238 tcg_out_insn(s, RR, XR, args[0], args[2]);
2240 tcg_out_insn(s, RRF, XRK, a0, a1, a2);
2244 case INDEX_op_neg_i32:
2245 tcg_out_insn(s, RR, LCR, args[0], args[1]);
2248 case INDEX_op_mul_i32:
2249 if (const_args[2]) {
2250 if ((int32_t)args[2] == (int16_t)args[2]) {
2251 tcg_out_insn(s, RI, MHI, args[0], args[2]);
2253 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
2256 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
2260 case INDEX_op_div2_i32:
2261 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
2263 case INDEX_op_divu2_i32:
2264 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
2267 case INDEX_op_shl_i32:
2271 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
2273 if (const_args[2]) {
2274 tcg_out_sh32(s, op, a0, TCG_REG_NONE, a2);
2276 tcg_out_sh32(s, op, a0, a2, 0);
2279 /* Using tcg_out_sh64 here for the format; it is a 32-bit shift. */
2280 if (const_args[2]) {
2281 tcg_out_sh64(s, op2, a0, a1, TCG_REG_NONE, a2);
2283 tcg_out_sh64(s, op2, a0, a1, a2, 0);
2287 case INDEX_op_shr_i32:
2291 case INDEX_op_sar_i32:
2296 case INDEX_op_rotl_i32:
2297 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
2298 if (const_args[2]) {
2299 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
2301 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
2304 case INDEX_op_rotr_i32:
2305 if (const_args[2]) {
2306 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
2307 TCG_REG_NONE, (32 - args[2]) & 31);
2309 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2310 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
2314 case INDEX_op_ext8s_i32:
2315 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
2317 case INDEX_op_ext16s_i32:
2318 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
2320 case INDEX_op_ext8u_i32:
2321 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
2323 case INDEX_op_ext16u_i32:
2324 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
2327 case INDEX_op_bswap16_i32:
2328 a0 = args[0], a1 = args[1], a2 = args[2];
2329 tcg_out_insn(s, RRE, LRVR, a0, a1);
2330 if (a2 & TCG_BSWAP_OS) {
2331 tcg_out_sh32(s, RS_SRA, a0, TCG_REG_NONE, 16);
2333 tcg_out_sh32(s, RS_SRL, a0, TCG_REG_NONE, 16);
2336 case INDEX_op_bswap16_i64:
2337 a0 = args[0], a1 = args[1], a2 = args[2];
2338 tcg_out_insn(s, RRE, LRVGR, a0, a1);
2339 if (a2 & TCG_BSWAP_OS) {
2340 tcg_out_sh64(s, RSY_SRAG, a0, a0, TCG_REG_NONE, 48);
2342 tcg_out_sh64(s, RSY_SRLG, a0, a0, TCG_REG_NONE, 48);
2346 case INDEX_op_bswap32_i32:
2347 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
2349 case INDEX_op_bswap32_i64:
2350 a0 = args[0], a1 = args[1], a2 = args[2];
2351 tcg_out_insn(s, RRE, LRVR, a0, a1);
2352 if (a2 & TCG_BSWAP_OS) {
2353 tgen_ext32s(s, a0, a0);
2354 } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
2355 tgen_ext32u(s, a0, a0);
2359 case INDEX_op_add2_i32:
2360 if (const_args[4]) {
2361 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
2363 tcg_out_insn(s, RR, ALR, args[0], args[4]);
2365 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
2367 case INDEX_op_sub2_i32:
2368 if (const_args[4]) {
2369 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
2371 tcg_out_insn(s, RR, SLR, args[0], args[4]);
2373 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
2377 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
2380 case INDEX_op_brcond_i32:
2381 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
2382 args[1], const_args[1], arg_label(args[3]));
2384 case INDEX_op_setcond_i32:
2385 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
2386 args[2], const_args[2]);
2388 case INDEX_op_movcond_i32:
2389 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
2390 args[2], const_args[2], args[3], const_args[3]);
2393 case INDEX_op_qemu_ld_i32:
2394 /* ??? Technically we can use a non-extending instruction. */
2395 case INDEX_op_qemu_ld_i64:
2396 tcg_out_qemu_ld(s, args[0], args[1], args[2]);
2398 case INDEX_op_qemu_st_i32:
2399 case INDEX_op_qemu_st_i64:
2400 tcg_out_qemu_st(s, args[0], args[1], args[2]);
2403 case INDEX_op_ld16s_i64:
2404 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
2406 case INDEX_op_ld32u_i64:
2407 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
2409 case INDEX_op_ld32s_i64:
2410 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
2412 case INDEX_op_ld_i64:
2413 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2416 case INDEX_op_st32_i64:
2417 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2419 case INDEX_op_st_i64:
2420 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2423 case INDEX_op_add_i64:
2424 a0 = args[0], a1 = args[1], a2 = args[2];
2425 if (const_args[2]) {
2428 if (a2 == (int16_t)a2) {
2429 tcg_out_insn(s, RI, AGHI, a0, a2);
2432 if (HAVE_FACILITY(EXT_IMM)) {
2433 if (a2 == (int32_t)a2) {
2434 tcg_out_insn(s, RIL, AGFI, a0, a2);
2436 } else if (a2 == (uint32_t)a2) {
2437 tcg_out_insn(s, RIL, ALGFI, a0, a2);
2439 } else if (-a2 == (uint32_t)-a2) {
2440 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2445 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2446 } else if (a0 == a1) {
2447 tcg_out_insn(s, RRE, AGR, a0, a2);
2449 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2452 case INDEX_op_sub_i64:
2453 a0 = args[0], a1 = args[1], a2 = args[2];
2454 if (const_args[2]) {
2457 } else if (a0 == a1) {
2458 tcg_out_insn(s, RRE, SGR, a0, a2);
2460 tcg_out_insn(s, RRF, SGRK, a0, a1, a2);
2464 case INDEX_op_and_i64:
2465 a0 = args[0], a1 = args[1], a2 = args[2];
2466 if (const_args[2]) {
2467 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2468 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2469 } else if (a0 == a1) {
2470 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2472 tcg_out_insn(s, RRF, NGRK, a0, a1, a2);
2475 case INDEX_op_or_i64:
2476 a0 = args[0], a1 = args[1], a2 = args[2];
2477 if (const_args[2]) {
2478 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2479 tgen_ori(s, TCG_TYPE_I64, a0, a2);
2480 } else if (a0 == a1) {
2481 tcg_out_insn(s, RRE, OGR, a0, a2);
2483 tcg_out_insn(s, RRF, OGRK, a0, a1, a2);
2486 case INDEX_op_xor_i64:
2487 a0 = args[0], a1 = args[1], a2 = args[2];
2488 if (const_args[2]) {
2489 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2490 tgen_xori(s, TCG_TYPE_I64, a0, a2);
2491 } else if (a0 == a1) {
2492 tcg_out_insn(s, RRE, XGR, a0, a2);
2494 tcg_out_insn(s, RRF, XGRK, a0, a1, a2);
2498 case INDEX_op_neg_i64:
2499 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2501 case INDEX_op_bswap64_i64:
2502 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2505 case INDEX_op_mul_i64:
2506 if (const_args[2]) {
2507 if (args[2] == (int16_t)args[2]) {
2508 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2510 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2513 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2517 case INDEX_op_div2_i64:
2518 /* ??? We get an unnecessary sign-extension of the dividend
2519 into R3 with this definition, but as we do in fact always
2520 produce both quotient and remainder using INDEX_op_div_i64
2521 instead requires jumping through even more hoops. */
2522 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2524 case INDEX_op_divu2_i64:
2525 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2527 case INDEX_op_mulu2_i64:
2528 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2531 case INDEX_op_shl_i64:
2534 if (const_args[2]) {
2535 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2537 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2540 case INDEX_op_shr_i64:
2543 case INDEX_op_sar_i64:
2547 case INDEX_op_rotl_i64:
2548 if (const_args[2]) {
2549 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2550 TCG_REG_NONE, args[2]);
2552 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2555 case INDEX_op_rotr_i64:
2556 if (const_args[2]) {
2557 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2558 TCG_REG_NONE, (64 - args[2]) & 63);
2560 /* We can use the smaller 32-bit negate because only the
2561 low 6 bits are examined for the rotate. */
2562 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2563 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2567 case INDEX_op_ext8s_i64:
2568 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2570 case INDEX_op_ext16s_i64:
2571 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2573 case INDEX_op_ext_i32_i64:
2574 case INDEX_op_ext32s_i64:
2575 tgen_ext32s(s, args[0], args[1]);
2577 case INDEX_op_ext8u_i64:
2578 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2580 case INDEX_op_ext16u_i64:
2581 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2583 case INDEX_op_extu_i32_i64:
2584 case INDEX_op_ext32u_i64:
2585 tgen_ext32u(s, args[0], args[1]);
2588 case INDEX_op_add2_i64:
2589 if (const_args[4]) {
2590 if ((int64_t)args[4] >= 0) {
2591 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2593 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2596 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2598 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2600 case INDEX_op_sub2_i64:
2601 if (const_args[4]) {
2602 if ((int64_t)args[4] >= 0) {
2603 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2605 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2608 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2610 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2613 case INDEX_op_brcond_i64:
2614 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2615 args[1], const_args[1], arg_label(args[3]));
2617 case INDEX_op_setcond_i64:
2618 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2619 args[2], const_args[2]);
2621 case INDEX_op_movcond_i64:
2622 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2623 args[2], const_args[2], args[3], const_args[3]);
2627 a0 = args[0], a1 = args[1], a2 = args[2];
2628 if (const_args[1]) {
2629 tgen_deposit(s, a0, a2, args[3], args[4], 1);
2631 /* Since we can't support "0Z" as a constraint, we allow a1 in
2632 any register. Fix things up as if a matching constraint. */
2634 TCGType type = (opc == INDEX_op_deposit_i64);
2636 tcg_out_mov(s, type, TCG_TMP0, a2);
2639 tcg_out_mov(s, type, a0, a1);
2641 tgen_deposit(s, a0, a2, args[3], args[4], 0);
2646 tgen_extract(s, args[0], args[1], args[2], args[3]);
2649 case INDEX_op_clz_i64:
2650 tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2654 /* The host memory model is quite strong, we simply need to
2655 serialize the instruction stream. */
2656 if (args[0] & TCG_MO_ST_LD) {
2657 tcg_out_insn(s, RR, BCR, HAVE_FACILITY(FAST_BCR_SER) ? 14 : 15, 0);
2661 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2662 case INDEX_op_mov_i64:
2663 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2669 static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
2670 TCGReg dst, TCGReg src)
2672 if (is_general_reg(src)) {
2673 /* Replicate general register into two MO_64. */
2674 tcg_out_insn(s, VRRf, VLVGP, dst, src, src);
2675 if (vece == MO_64) {
2681 * Recall that the "standard" integer, within a vector, is the
2682 * rightmost element of the leftmost doubleword, a-la VLLEZ.
2684 tcg_out_insn(s, VRIc, VREP, dst, (8 >> vece) - 1, src, vece);
2688 static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
2689 TCGReg dst, TCGReg base, intptr_t offset)
2691 tcg_out_vrx_mem(s, VRX_VLREP, dst, base, TCG_REG_NONE, offset, vece);
2695 static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
2696 TCGReg dst, int64_t val)
2698 int i, mask, msb, lsb;
2700 /* Look for int16_t elements. */
2701 if (vece <= MO_16 ||
2702 (vece == MO_32 ? (int32_t)val : val) == (int16_t)val) {
2703 tcg_out_insn(s, VRIa, VREPI, dst, val, vece);
2707 /* Look for bit masks. */
2708 if (vece == MO_32) {
2709 if (risbg_mask((int32_t)val)) {
2710 /* Handle wraparound by swapping msb and lsb. */
2711 if ((val & 0x80000001u) == 0x80000001u) {
2712 msb = 32 - ctz32(~val);
2713 lsb = clz32(~val) - 1;
2716 lsb = 31 - ctz32(val);
2718 tcg_out_insn(s, VRIb, VGM, dst, msb, lsb, MO_32);
2722 if (risbg_mask(val)) {
2723 /* Handle wraparound by swapping msb and lsb. */
2724 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
2725 /* Handle wraparound by swapping msb and lsb. */
2726 msb = 64 - ctz64(~val);
2727 lsb = clz64(~val) - 1;
2730 lsb = 63 - ctz64(val);
2732 tcg_out_insn(s, VRIb, VGM, dst, msb, lsb, MO_64);
2737 /* Look for all bytes 0x00 or 0xff. */
2738 for (i = mask = 0; i < 8; i++) {
2739 uint8_t byte = val >> (i * 8);
2742 } else if (byte != 0) {
2747 tcg_out_insn(s, VRIa, VGBM, dst, mask * 0x0101, 0);
2751 /* Otherwise, stuff it in the constant pool. */
2752 tcg_out_insn(s, RIL, LARL, TCG_TMP0, 0);
2753 new_pool_label(s, val, R_390_PC32DBL, s->code_ptr - 2, 2);
2754 tcg_out_insn(s, VRX, VLREP, dst, TCG_TMP0, TCG_REG_NONE, 0, MO_64);
2757 static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
2758 unsigned vecl, unsigned vece,
2759 const TCGArg args[TCG_MAX_OP_ARGS],
2760 const int const_args[TCG_MAX_OP_ARGS])
2762 TCGType type = vecl + TCG_TYPE_V64;
2763 TCGArg a0 = args[0], a1 = args[1], a2 = args[2];
2766 case INDEX_op_ld_vec:
2767 tcg_out_ld(s, type, a0, a1, a2);
2769 case INDEX_op_st_vec:
2770 tcg_out_st(s, type, a0, a1, a2);
2772 case INDEX_op_dupm_vec:
2773 tcg_out_dupm_vec(s, type, vece, a0, a1, a2);
2776 case INDEX_op_abs_vec:
2777 tcg_out_insn(s, VRRa, VLP, a0, a1, vece);
2779 case INDEX_op_neg_vec:
2780 tcg_out_insn(s, VRRa, VLC, a0, a1, vece);
2782 case INDEX_op_not_vec:
2783 tcg_out_insn(s, VRRc, VNO, a0, a1, a1, 0);
2786 case INDEX_op_add_vec:
2787 tcg_out_insn(s, VRRc, VA, a0, a1, a2, vece);
2789 case INDEX_op_sub_vec:
2790 tcg_out_insn(s, VRRc, VS, a0, a1, a2, vece);
2792 case INDEX_op_and_vec:
2793 tcg_out_insn(s, VRRc, VN, a0, a1, a2, 0);
2795 case INDEX_op_andc_vec:
2796 tcg_out_insn(s, VRRc, VNC, a0, a1, a2, 0);
2798 case INDEX_op_mul_vec:
2799 tcg_out_insn(s, VRRc, VML, a0, a1, a2, vece);
2801 case INDEX_op_or_vec:
2802 tcg_out_insn(s, VRRc, VO, a0, a1, a2, 0);
2804 case INDEX_op_orc_vec:
2805 tcg_out_insn(s, VRRc, VOC, a0, a1, a2, 0);
2807 case INDEX_op_xor_vec:
2808 tcg_out_insn(s, VRRc, VX, a0, a1, a2, 0);
2810 case INDEX_op_nand_vec:
2811 tcg_out_insn(s, VRRc, VNN, a0, a1, a2, 0);
2813 case INDEX_op_nor_vec:
2814 tcg_out_insn(s, VRRc, VNO, a0, a1, a2, 0);
2816 case INDEX_op_eqv_vec:
2817 tcg_out_insn(s, VRRc, VNX, a0, a1, a2, 0);
2820 case INDEX_op_shli_vec:
2821 tcg_out_insn(s, VRSa, VESL, a0, a2, TCG_REG_NONE, a1, vece);
2823 case INDEX_op_shri_vec:
2824 tcg_out_insn(s, VRSa, VESRL, a0, a2, TCG_REG_NONE, a1, vece);
2826 case INDEX_op_sari_vec:
2827 tcg_out_insn(s, VRSa, VESRA, a0, a2, TCG_REG_NONE, a1, vece);
2829 case INDEX_op_rotli_vec:
2830 tcg_out_insn(s, VRSa, VERLL, a0, a2, TCG_REG_NONE, a1, vece);
2832 case INDEX_op_shls_vec:
2833 tcg_out_insn(s, VRSa, VESL, a0, 0, a2, a1, vece);
2835 case INDEX_op_shrs_vec:
2836 tcg_out_insn(s, VRSa, VESRL, a0, 0, a2, a1, vece);
2838 case INDEX_op_sars_vec:
2839 tcg_out_insn(s, VRSa, VESRA, a0, 0, a2, a1, vece);
2841 case INDEX_op_rotls_vec:
2842 tcg_out_insn(s, VRSa, VERLL, a0, 0, a2, a1, vece);
2844 case INDEX_op_shlv_vec:
2845 tcg_out_insn(s, VRRc, VESLV, a0, a1, a2, vece);
2847 case INDEX_op_shrv_vec:
2848 tcg_out_insn(s, VRRc, VESRLV, a0, a1, a2, vece);
2850 case INDEX_op_sarv_vec:
2851 tcg_out_insn(s, VRRc, VESRAV, a0, a1, a2, vece);
2853 case INDEX_op_rotlv_vec:
2854 tcg_out_insn(s, VRRc, VERLLV, a0, a1, a2, vece);
2857 case INDEX_op_smin_vec:
2858 tcg_out_insn(s, VRRc, VMN, a0, a1, a2, vece);
2860 case INDEX_op_smax_vec:
2861 tcg_out_insn(s, VRRc, VMX, a0, a1, a2, vece);
2863 case INDEX_op_umin_vec:
2864 tcg_out_insn(s, VRRc, VMNL, a0, a1, a2, vece);
2866 case INDEX_op_umax_vec:
2867 tcg_out_insn(s, VRRc, VMXL, a0, a1, a2, vece);
2870 case INDEX_op_bitsel_vec:
2871 tcg_out_insn(s, VRRe, VSEL, a0, a1, a2, args[3]);
2874 case INDEX_op_cmp_vec:
2875 switch ((TCGCond)args[3]) {
2877 tcg_out_insn(s, VRRc, VCEQ, a0, a1, a2, vece);
2880 tcg_out_insn(s, VRRc, VCH, a0, a1, a2, vece);
2883 tcg_out_insn(s, VRRc, VCHL, a0, a1, a2, vece);
2886 g_assert_not_reached();
2890 case INDEX_op_s390_vuph_vec:
2891 tcg_out_insn(s, VRRa, VUPH, a0, a1, vece);
2893 case INDEX_op_s390_vupl_vec:
2894 tcg_out_insn(s, VRRa, VUPL, a0, a1, vece);
2896 case INDEX_op_s390_vpks_vec:
2897 tcg_out_insn(s, VRRc, VPKS, a0, a1, a2, vece);
2900 case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov. */
2901 case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec. */
2903 g_assert_not_reached();
2907 int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
2910 case INDEX_op_abs_vec:
2911 case INDEX_op_add_vec:
2912 case INDEX_op_and_vec:
2913 case INDEX_op_andc_vec:
2914 case INDEX_op_bitsel_vec:
2915 case INDEX_op_eqv_vec:
2916 case INDEX_op_nand_vec:
2917 case INDEX_op_neg_vec:
2918 case INDEX_op_nor_vec:
2919 case INDEX_op_not_vec:
2920 case INDEX_op_or_vec:
2921 case INDEX_op_orc_vec:
2922 case INDEX_op_rotli_vec:
2923 case INDEX_op_rotls_vec:
2924 case INDEX_op_rotlv_vec:
2925 case INDEX_op_sari_vec:
2926 case INDEX_op_sars_vec:
2927 case INDEX_op_sarv_vec:
2928 case INDEX_op_shli_vec:
2929 case INDEX_op_shls_vec:
2930 case INDEX_op_shlv_vec:
2931 case INDEX_op_shri_vec:
2932 case INDEX_op_shrs_vec:
2933 case INDEX_op_shrv_vec:
2934 case INDEX_op_smax_vec:
2935 case INDEX_op_smin_vec:
2936 case INDEX_op_sub_vec:
2937 case INDEX_op_umax_vec:
2938 case INDEX_op_umin_vec:
2939 case INDEX_op_xor_vec:
2941 case INDEX_op_cmp_vec:
2942 case INDEX_op_cmpsel_vec:
2943 case INDEX_op_rotrv_vec:
2945 case INDEX_op_mul_vec:
2946 return vece < MO_64;
2947 case INDEX_op_ssadd_vec:
2948 case INDEX_op_sssub_vec:
2949 return vece < MO_64 ? -1 : 0;
2955 static bool expand_vec_cmp_noinv(TCGType type, unsigned vece, TCGv_vec v0,
2956 TCGv_vec v1, TCGv_vec v2, TCGCond cond)
2958 bool need_swap = false, need_inv = false;
2976 need_swap = need_inv = true;
2979 g_assert_not_reached();
2983 cond = tcg_invert_cond(cond);
2987 t1 = v1, v1 = v2, v2 = t1;
2988 cond = tcg_swap_cond(cond);
2991 vec_gen_4(INDEX_op_cmp_vec, type, vece, tcgv_vec_arg(v0),
2992 tcgv_vec_arg(v1), tcgv_vec_arg(v2), cond);
2997 static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0,
2998 TCGv_vec v1, TCGv_vec v2, TCGCond cond)
3000 if (expand_vec_cmp_noinv(type, vece, v0, v1, v2, cond)) {
3001 tcg_gen_not_vec(vece, v0, v0);
3005 static void expand_vec_cmpsel(TCGType type, unsigned vece, TCGv_vec v0,
3006 TCGv_vec c1, TCGv_vec c2,
3007 TCGv_vec v3, TCGv_vec v4, TCGCond cond)
3009 TCGv_vec t = tcg_temp_new_vec(type);
3011 if (expand_vec_cmp_noinv(type, vece, t, c1, c2, cond)) {
3012 /* Invert the sense of the compare by swapping arguments. */
3013 tcg_gen_bitsel_vec(vece, v0, t, v4, v3);
3015 tcg_gen_bitsel_vec(vece, v0, t, v3, v4);
3017 tcg_temp_free_vec(t);
3020 static void expand_vec_sat(TCGType type, unsigned vece, TCGv_vec v0,
3021 TCGv_vec v1, TCGv_vec v2, TCGOpcode add_sub_opc)
3023 TCGv_vec h1 = tcg_temp_new_vec(type);
3024 TCGv_vec h2 = tcg_temp_new_vec(type);
3025 TCGv_vec l1 = tcg_temp_new_vec(type);
3026 TCGv_vec l2 = tcg_temp_new_vec(type);
3028 tcg_debug_assert (vece < MO_64);
3030 /* Unpack with sign-extension. */
3031 vec_gen_2(INDEX_op_s390_vuph_vec, type, vece,
3032 tcgv_vec_arg(h1), tcgv_vec_arg(v1));
3033 vec_gen_2(INDEX_op_s390_vuph_vec, type, vece,
3034 tcgv_vec_arg(h2), tcgv_vec_arg(v2));
3036 vec_gen_2(INDEX_op_s390_vupl_vec, type, vece,
3037 tcgv_vec_arg(l1), tcgv_vec_arg(v1));
3038 vec_gen_2(INDEX_op_s390_vupl_vec, type, vece,
3039 tcgv_vec_arg(l2), tcgv_vec_arg(v2));
3041 /* Arithmetic on a wider element size. */
3042 vec_gen_3(add_sub_opc, type, vece + 1, tcgv_vec_arg(h1),
3043 tcgv_vec_arg(h1), tcgv_vec_arg(h2));
3044 vec_gen_3(add_sub_opc, type, vece + 1, tcgv_vec_arg(l1),
3045 tcgv_vec_arg(l1), tcgv_vec_arg(l2));
3047 /* Pack with saturation. */
3048 vec_gen_3(INDEX_op_s390_vpks_vec, type, vece + 1,
3049 tcgv_vec_arg(v0), tcgv_vec_arg(h1), tcgv_vec_arg(l1));
3051 tcg_temp_free_vec(h1);
3052 tcg_temp_free_vec(h2);
3053 tcg_temp_free_vec(l1);
3054 tcg_temp_free_vec(l2);
3057 void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
3061 TCGv_vec v0, v1, v2, v3, v4, t0;
3064 v0 = temp_tcgv_vec(arg_temp(a0));
3065 v1 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
3066 v2 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
3069 case INDEX_op_cmp_vec:
3070 expand_vec_cmp(type, vece, v0, v1, v2, va_arg(va, TCGArg));
3073 case INDEX_op_cmpsel_vec:
3074 v3 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
3075 v4 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
3076 expand_vec_cmpsel(type, vece, v0, v1, v2, v3, v4, va_arg(va, TCGArg));
3079 case INDEX_op_rotrv_vec:
3080 t0 = tcg_temp_new_vec(type);
3081 tcg_gen_neg_vec(vece, t0, v2);
3082 tcg_gen_rotlv_vec(vece, v0, v1, t0);
3083 tcg_temp_free_vec(t0);
3086 case INDEX_op_ssadd_vec:
3087 expand_vec_sat(type, vece, v0, v1, v2, INDEX_op_add_vec);
3089 case INDEX_op_sssub_vec:
3090 expand_vec_sat(type, vece, v0, v1, v2, INDEX_op_sub_vec);
3094 g_assert_not_reached();
3099 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
3102 case INDEX_op_goto_ptr:
3105 case INDEX_op_ld8u_i32:
3106 case INDEX_op_ld8u_i64:
3107 case INDEX_op_ld8s_i32:
3108 case INDEX_op_ld8s_i64:
3109 case INDEX_op_ld16u_i32:
3110 case INDEX_op_ld16u_i64:
3111 case INDEX_op_ld16s_i32:
3112 case INDEX_op_ld16s_i64:
3113 case INDEX_op_ld_i32:
3114 case INDEX_op_ld32u_i64:
3115 case INDEX_op_ld32s_i64:
3116 case INDEX_op_ld_i64:
3117 return C_O1_I1(r, r);
3119 case INDEX_op_st8_i32:
3120 case INDEX_op_st8_i64:
3121 case INDEX_op_st16_i32:
3122 case INDEX_op_st16_i64:
3123 case INDEX_op_st_i32:
3124 case INDEX_op_st32_i64:
3125 case INDEX_op_st_i64:
3126 return C_O0_I2(r, r);
3128 case INDEX_op_add_i32:
3129 case INDEX_op_add_i64:
3130 case INDEX_op_shl_i64:
3131 case INDEX_op_shr_i64:
3132 case INDEX_op_sar_i64:
3133 case INDEX_op_rotl_i32:
3134 case INDEX_op_rotl_i64:
3135 case INDEX_op_rotr_i32:
3136 case INDEX_op_rotr_i64:
3137 case INDEX_op_clz_i64:
3138 case INDEX_op_setcond_i32:
3139 case INDEX_op_setcond_i64:
3140 return C_O1_I2(r, r, ri);
3142 case INDEX_op_sub_i32:
3143 case INDEX_op_sub_i64:
3144 case INDEX_op_and_i32:
3145 case INDEX_op_and_i64:
3146 case INDEX_op_or_i32:
3147 case INDEX_op_or_i64:
3148 case INDEX_op_xor_i32:
3149 case INDEX_op_xor_i64:
3150 return (HAVE_FACILITY(DISTINCT_OPS)
3152 : C_O1_I2(r, 0, ri));
3154 case INDEX_op_mul_i32:
3155 /* If we have the general-instruction-extensions, then we have
3156 MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
3157 have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
3158 return (HAVE_FACILITY(GEN_INST_EXT)
3160 : C_O1_I2(r, 0, rI));
3162 case INDEX_op_mul_i64:
3163 return (HAVE_FACILITY(GEN_INST_EXT)
3165 : C_O1_I2(r, 0, rI));
3167 case INDEX_op_shl_i32:
3168 case INDEX_op_shr_i32:
3169 case INDEX_op_sar_i32:
3170 return (HAVE_FACILITY(DISTINCT_OPS)
3172 : C_O1_I2(r, 0, ri));
3174 case INDEX_op_brcond_i32:
3175 case INDEX_op_brcond_i64:
3176 return C_O0_I2(r, ri);
3178 case INDEX_op_bswap16_i32:
3179 case INDEX_op_bswap16_i64:
3180 case INDEX_op_bswap32_i32:
3181 case INDEX_op_bswap32_i64:
3182 case INDEX_op_bswap64_i64:
3183 case INDEX_op_neg_i32:
3184 case INDEX_op_neg_i64:
3185 case INDEX_op_ext8s_i32:
3186 case INDEX_op_ext8s_i64:
3187 case INDEX_op_ext8u_i32:
3188 case INDEX_op_ext8u_i64:
3189 case INDEX_op_ext16s_i32:
3190 case INDEX_op_ext16s_i64:
3191 case INDEX_op_ext16u_i32:
3192 case INDEX_op_ext16u_i64:
3193 case INDEX_op_ext32s_i64:
3194 case INDEX_op_ext32u_i64:
3195 case INDEX_op_ext_i32_i64:
3196 case INDEX_op_extu_i32_i64:
3197 case INDEX_op_extract_i32:
3198 case INDEX_op_extract_i64:
3199 return C_O1_I1(r, r);
3201 case INDEX_op_qemu_ld_i32:
3202 case INDEX_op_qemu_ld_i64:
3203 return C_O1_I1(r, L);
3204 case INDEX_op_qemu_st_i64:
3205 case INDEX_op_qemu_st_i32:
3206 return C_O0_I2(L, L);
3208 case INDEX_op_deposit_i32:
3209 case INDEX_op_deposit_i64:
3210 return C_O1_I2(r, rZ, r);
3212 case INDEX_op_movcond_i32:
3213 case INDEX_op_movcond_i64:
3214 return (HAVE_FACILITY(LOAD_ON_COND2)
3215 ? C_O1_I4(r, r, ri, rI, 0)
3216 : C_O1_I4(r, r, ri, r, 0));
3218 case INDEX_op_div2_i32:
3219 case INDEX_op_div2_i64:
3220 case INDEX_op_divu2_i32:
3221 case INDEX_op_divu2_i64:
3222 return C_O2_I3(b, a, 0, 1, r);
3224 case INDEX_op_mulu2_i64:
3225 return C_O2_I2(b, a, 0, r);
3227 case INDEX_op_add2_i32:
3228 case INDEX_op_sub2_i32:
3229 return (HAVE_FACILITY(EXT_IMM)
3230 ? C_O2_I4(r, r, 0, 1, ri, r)
3231 : C_O2_I4(r, r, 0, 1, r, r));
3233 case INDEX_op_add2_i64:
3234 case INDEX_op_sub2_i64:
3235 return (HAVE_FACILITY(EXT_IMM)
3236 ? C_O2_I4(r, r, 0, 1, rA, r)
3237 : C_O2_I4(r, r, 0, 1, r, r));
3239 case INDEX_op_st_vec:
3240 return C_O0_I2(v, r);
3241 case INDEX_op_ld_vec:
3242 case INDEX_op_dupm_vec:
3243 return C_O1_I1(v, r);
3244 case INDEX_op_dup_vec:
3245 return C_O1_I1(v, vr);
3246 case INDEX_op_abs_vec:
3247 case INDEX_op_neg_vec:
3248 case INDEX_op_not_vec:
3249 case INDEX_op_rotli_vec:
3250 case INDEX_op_sari_vec:
3251 case INDEX_op_shli_vec:
3252 case INDEX_op_shri_vec:
3253 case INDEX_op_s390_vuph_vec:
3254 case INDEX_op_s390_vupl_vec:
3255 return C_O1_I1(v, v);
3256 case INDEX_op_add_vec:
3257 case INDEX_op_sub_vec:
3258 case INDEX_op_and_vec:
3259 case INDEX_op_andc_vec:
3260 case INDEX_op_or_vec:
3261 case INDEX_op_orc_vec:
3262 case INDEX_op_xor_vec:
3263 case INDEX_op_nand_vec:
3264 case INDEX_op_nor_vec:
3265 case INDEX_op_eqv_vec:
3266 case INDEX_op_cmp_vec:
3267 case INDEX_op_mul_vec:
3268 case INDEX_op_rotlv_vec:
3269 case INDEX_op_rotrv_vec:
3270 case INDEX_op_shlv_vec:
3271 case INDEX_op_shrv_vec:
3272 case INDEX_op_sarv_vec:
3273 case INDEX_op_smax_vec:
3274 case INDEX_op_smin_vec:
3275 case INDEX_op_umax_vec:
3276 case INDEX_op_umin_vec:
3277 case INDEX_op_s390_vpks_vec:
3278 return C_O1_I2(v, v, v);
3279 case INDEX_op_rotls_vec:
3280 case INDEX_op_shls_vec:
3281 case INDEX_op_shrs_vec:
3282 case INDEX_op_sars_vec:
3283 return C_O1_I2(v, v, r);
3284 case INDEX_op_bitsel_vec:
3285 return C_O1_I3(v, v, v, v);
3288 g_assert_not_reached();
3293 * Mainline glibc added HWCAP_S390_VX before it was kernel abi.
3294 * Some distros have fixed this up locally, others have not.
3296 #ifndef HWCAP_S390_VXRS
3297 #define HWCAP_S390_VXRS 2048
3300 static void query_s390_facilities(void)
3302 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
3304 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
3305 is present on all 64-bit systems, but let's check for it anyway. */
3306 if (hwcap & HWCAP_S390_STFLE) {
3307 register int r0 __asm__("0") = ARRAY_SIZE(s390_facilities) - 1;
3308 register void *r1 __asm__("1") = s390_facilities;
3311 asm volatile(".word 0xb2b0,0x1000"
3312 : "=r"(r0) : "r"(r0), "r"(r1) : "memory", "cc");
3316 * Use of vector registers requires os support beyond the facility bit.
3317 * If the kernel does not advertise support, disable the facility bits.
3318 * There is nothing else we currently care about in the 3rd word, so
3319 * disable VECTOR with one store.
3321 if (!(hwcap & HWCAP_S390_VXRS)) {
3322 s390_facilities[2] = 0;
3326 static void tcg_target_init(TCGContext *s)
3328 query_s390_facilities();
3330 tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
3331 tcg_target_available_regs[TCG_TYPE_I64] = 0xffff;
3332 if (HAVE_FACILITY(VECTOR)) {
3333 tcg_target_available_regs[TCG_TYPE_V64] = 0xffffffff00000000ull;
3334 tcg_target_available_regs[TCG_TYPE_V128] = 0xffffffff00000000ull;
3337 tcg_target_call_clobber_regs = 0;
3338 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
3339 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
3340 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
3341 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
3342 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
3343 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
3344 /* The r6 register is technically call-saved, but it's also a parameter
3345 register, so it can get killed by setup for the qemu_st helper. */
3346 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
3347 /* The return register can be considered call-clobbered. */
3348 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
3350 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V0);
3351 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V1);
3352 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V2);
3353 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V3);
3354 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V4);
3355 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V5);
3356 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V6);
3357 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V7);
3358 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V16);
3359 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V17);
3360 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V18);
3361 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V19);
3362 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V20);
3363 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V21);
3364 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V22);
3365 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V23);
3366 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V24);
3367 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V25);
3368 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V26);
3369 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V27);
3370 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V28);
3371 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V29);
3372 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V30);
3373 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V31);
3375 s->reserved_regs = 0;
3376 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
3377 /* XXX many insns can't be used with R0, so we better avoid it for now */
3378 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
3379 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
3381 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
3385 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
3386 + TCG_STATIC_CALL_ARGS_SIZE \
3387 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
3389 static void tcg_target_qemu_prologue(TCGContext *s)
3391 /* stmg %r6,%r15,48(%r15) (save registers) */
3392 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
3394 /* aghi %r15,-frame_size */
3395 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
3397 tcg_set_frame(s, TCG_REG_CALL_STACK,
3398 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
3399 CPU_TEMP_BUF_NLONGS * sizeof(long));
3401 #ifndef CONFIG_SOFTMMU
3402 if (guest_base >= 0x80000) {
3403 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
3404 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
3408 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
3410 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB,
3411 tcg_target_call_iarg_regs[1]);
3414 /* br %r3 (go to TB) */
3415 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
3418 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
3419 * and fall through to the rest of the epilogue.
3421 tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
3422 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
3425 tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
3427 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
3428 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
3431 /* br %r14 (return) */
3432 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
3435 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
3437 memset(p, 0x07, count * sizeof(tcg_insn_unit));
3442 uint8_t fde_def_cfa[4];
3443 uint8_t fde_reg_ofs[18];
3446 /* We're expecting a 2 byte uleb128 encoded value. */
3447 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
3449 #define ELF_HOST_MACHINE EM_S390
3451 static const DebugFrame debug_frame = {
3452 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
3455 .h.cie.code_align = 1,
3456 .h.cie.data_align = 8, /* sleb128 8 */
3457 .h.cie.return_column = TCG_REG_R14,
3459 /* Total FDE size does not include the "len" member. */
3460 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
3463 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
3464 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
3468 0x86, 6, /* DW_CFA_offset, %r6, 48 */
3469 0x87, 7, /* DW_CFA_offset, %r7, 56 */
3470 0x88, 8, /* DW_CFA_offset, %r8, 64 */
3471 0x89, 9, /* DW_CFA_offset, %r92, 72 */
3472 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
3473 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
3474 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
3475 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
3476 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
3480 void tcg_register_jit(const void *buf, size_t buf_size)
3482 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));