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-pool.c.inc"
35 /* ??? The translation blocks produced by TCG are generally small enough to
36 be entirely reachable with a 16-bit displacement. Leaving the option for
37 a 32-bit displacement here Just In Case. */
38 #define USE_LONG_BRANCHES 0
40 #define TCG_CT_CONST_S16 0x100
41 #define TCG_CT_CONST_S32 0x200
42 #define TCG_CT_CONST_S33 0x400
43 #define TCG_CT_CONST_ZERO 0x800
45 /* Several places within the instruction set 0 means "no register"
46 rather than TCG_REG_R0. */
47 #define TCG_REG_NONE 0
49 /* A scratch register that may be be used throughout the backend. */
50 #define TCG_TMP0 TCG_REG_R1
52 /* A scratch register that holds a pointer to the beginning of the TB.
53 We don't need this when we have pc-relative loads with the general
54 instructions extension facility. */
55 #define TCG_REG_TB TCG_REG_R12
56 #define USE_REG_TB (!(s390_facilities & FACILITY_GEN_INST_EXT))
58 #ifndef CONFIG_SOFTMMU
59 #define TCG_GUEST_BASE_REG TCG_REG_R13
62 /* All of the following instructions are prefixed with their instruction
63 format, and are defined as 8- or 16-bit quantities, even when the two
64 halves of the 16-bit quantity may appear 32 bits apart in the insn.
65 This makes it easy to copy the values from the tables in Appendix B. */
66 typedef enum S390Opcode {
256 #ifdef CONFIG_DEBUG_TCG
257 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
258 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
259 "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
263 /* Since R6 is a potential argument register, choose it last of the
264 call-saved registers. Likewise prefer the call-clobbered registers
265 in reverse order to maximize the chance of avoiding the arguments. */
266 static const int tcg_target_reg_alloc_order[] = {
267 /* Call saved registers. */
276 /* Call clobbered registers. */
280 /* Argument registers, in reverse order of allocation. */
287 static const int tcg_target_call_iarg_regs[] = {
295 static const int tcg_target_call_oarg_regs[] = {
303 #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
304 #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
305 #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
306 #define S390_CC_NEVER 0
307 #define S390_CC_ALWAYS 15
309 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
310 static const uint8_t tcg_cond_to_s390_cond[] = {
311 [TCG_COND_EQ] = S390_CC_EQ,
312 [TCG_COND_NE] = S390_CC_NE,
313 [TCG_COND_LT] = S390_CC_LT,
314 [TCG_COND_LE] = S390_CC_LE,
315 [TCG_COND_GT] = S390_CC_GT,
316 [TCG_COND_GE] = S390_CC_GE,
317 [TCG_COND_LTU] = S390_CC_LT,
318 [TCG_COND_LEU] = S390_CC_LE,
319 [TCG_COND_GTU] = S390_CC_GT,
320 [TCG_COND_GEU] = S390_CC_GE,
323 /* Condition codes that result from a LOAD AND TEST. Here, we have no
324 unsigned instruction variation, however since the test is vs zero we
325 can re-map the outcomes appropriately. */
326 static const uint8_t tcg_cond_to_ltr_cond[] = {
327 [TCG_COND_EQ] = S390_CC_EQ,
328 [TCG_COND_NE] = S390_CC_NE,
329 [TCG_COND_LT] = S390_CC_LT,
330 [TCG_COND_LE] = S390_CC_LE,
331 [TCG_COND_GT] = S390_CC_GT,
332 [TCG_COND_GE] = S390_CC_GE,
333 [TCG_COND_LTU] = S390_CC_NEVER,
334 [TCG_COND_LEU] = S390_CC_EQ,
335 [TCG_COND_GTU] = S390_CC_NE,
336 [TCG_COND_GEU] = S390_CC_ALWAYS,
339 #ifdef CONFIG_SOFTMMU
340 static void * const qemu_ld_helpers[16] = {
341 [MO_UB] = helper_ret_ldub_mmu,
342 [MO_SB] = helper_ret_ldsb_mmu,
343 [MO_LEUW] = helper_le_lduw_mmu,
344 [MO_LESW] = helper_le_ldsw_mmu,
345 [MO_LEUL] = helper_le_ldul_mmu,
346 [MO_LESL] = helper_le_ldsl_mmu,
347 [MO_LEQ] = helper_le_ldq_mmu,
348 [MO_BEUW] = helper_be_lduw_mmu,
349 [MO_BESW] = helper_be_ldsw_mmu,
350 [MO_BEUL] = helper_be_ldul_mmu,
351 [MO_BESL] = helper_be_ldsl_mmu,
352 [MO_BEQ] = helper_be_ldq_mmu,
355 static void * const qemu_st_helpers[16] = {
356 [MO_UB] = helper_ret_stb_mmu,
357 [MO_LEUW] = helper_le_stw_mmu,
358 [MO_LEUL] = helper_le_stl_mmu,
359 [MO_LEQ] = helper_le_stq_mmu,
360 [MO_BEUW] = helper_be_stw_mmu,
361 [MO_BEUL] = helper_be_stl_mmu,
362 [MO_BEQ] = helper_be_stq_mmu,
366 static const tcg_insn_unit *tb_ret_addr;
367 uint64_t s390_facilities;
369 static bool patch_reloc(tcg_insn_unit *src_rw, int type,
370 intptr_t value, intptr_t addend)
372 const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
377 pcrel2 = (tcg_insn_unit *)value - src_rx;
381 if (pcrel2 == (int16_t)pcrel2) {
382 tcg_patch16(src_rw, pcrel2);
387 if (pcrel2 == (int32_t)pcrel2) {
388 tcg_patch32(src_rw, pcrel2);
393 if (value == sextract64(value, 0, 20)) {
394 old = *(uint32_t *)src_rw & 0xf00000ff;
395 old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
396 tcg_patch32(src_rw, old);
401 g_assert_not_reached();
406 /* parse target specific constraints */
407 static const char *target_parse_constraint(TCGArgConstraint *ct,
408 const char *ct_str, TCGType type)
411 case 'r': /* all registers */
414 case 'L': /* qemu_ld/st constraint */
416 tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
417 tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
418 tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
420 case 'a': /* force R2 for division */
422 tcg_regset_set_reg(ct->regs, TCG_REG_R2);
424 case 'b': /* force R3 for division */
426 tcg_regset_set_reg(ct->regs, TCG_REG_R3);
429 ct->ct |= TCG_CT_CONST_S33;
432 ct->ct |= TCG_CT_CONST_S16;
435 ct->ct |= TCG_CT_CONST_S32;
438 ct->ct |= TCG_CT_CONST_ZERO;
446 /* Test if a constant matches the constraint. */
447 static int tcg_target_const_match(tcg_target_long val, TCGType type,
448 const TCGArgConstraint *arg_ct)
452 if (ct & TCG_CT_CONST) {
456 if (type == TCG_TYPE_I32) {
460 /* The following are mutually exclusive. */
461 if (ct & TCG_CT_CONST_S16) {
462 return val == (int16_t)val;
463 } else if (ct & TCG_CT_CONST_S32) {
464 return val == (int32_t)val;
465 } else if (ct & TCG_CT_CONST_S33) {
466 return val >= -0xffffffffll && val <= 0xffffffffll;
467 } else if (ct & TCG_CT_CONST_ZERO) {
474 /* Emit instructions according to the given instruction format. */
476 static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
478 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
481 static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
482 TCGReg r1, TCGReg r2)
484 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
487 static void tcg_out_insn_RRF(TCGContext *s, S390Opcode op,
488 TCGReg r1, TCGReg r2, int m3)
490 tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
493 static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
495 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
498 static void tcg_out_insn_RIE(TCGContext *s, S390Opcode op, TCGReg r1,
501 tcg_out16(s, (op & 0xff00) | (r1 << 4) | m3);
502 tcg_out32(s, (i2 << 16) | (op & 0xff));
505 static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
507 tcg_out16(s, op | (r1 << 4));
511 static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
512 TCGReg b2, TCGReg r3, int disp)
514 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
518 static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
519 TCGReg b2, TCGReg r3, int disp)
521 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
522 tcg_out32(s, (op & 0xff) | (b2 << 28)
523 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
526 #define tcg_out_insn_RX tcg_out_insn_RS
527 #define tcg_out_insn_RXY tcg_out_insn_RSY
529 /* Emit an opcode with "type-checking" of the format. */
530 #define tcg_out_insn(S, FMT, OP, ...) \
531 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
534 /* emit 64-bit shifts */
535 static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
536 TCGReg src, TCGReg sh_reg, int sh_imm)
538 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
541 /* emit 32-bit shifts */
542 static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
543 TCGReg sh_reg, int sh_imm)
545 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
548 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
551 if (type == TCG_TYPE_I32) {
552 tcg_out_insn(s, RR, LR, dst, src);
554 tcg_out_insn(s, RRE, LGR, dst, src);
560 static const S390Opcode lli_insns[4] = {
561 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
564 static bool maybe_out_small_movi(TCGContext *s, TCGType type,
565 TCGReg ret, tcg_target_long sval)
567 tcg_target_ulong uval = sval;
570 if (type == TCG_TYPE_I32) {
571 uval = (uint32_t)sval;
572 sval = (int32_t)sval;
575 /* Try all 32-bit insns that can load it in one go. */
576 if (sval >= -0x8000 && sval < 0x8000) {
577 tcg_out_insn(s, RI, LGHI, ret, sval);
581 for (i = 0; i < 4; i++) {
582 tcg_target_long mask = 0xffffull << i*16;
583 if ((uval & mask) == uval) {
584 tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
592 /* load a register with an immediate value */
593 static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
594 tcg_target_long sval, bool in_prologue)
596 tcg_target_ulong uval;
598 /* Try all 32-bit insns that can load it in one go. */
599 if (maybe_out_small_movi(s, type, ret, sval)) {
604 if (type == TCG_TYPE_I32) {
605 uval = (uint32_t)sval;
606 sval = (int32_t)sval;
609 /* Try all 48-bit insns that can load it in one go. */
610 if (s390_facilities & FACILITY_EXT_IMM) {
611 if (sval == (int32_t)sval) {
612 tcg_out_insn(s, RIL, LGFI, ret, sval);
615 if (uval <= 0xffffffff) {
616 tcg_out_insn(s, RIL, LLILF, ret, uval);
619 if ((uval & 0xffffffff) == 0) {
620 tcg_out_insn(s, RIL, LLIHF, ret, uval >> 32);
625 /* Try for PC-relative address load. For odd addresses,
626 attempt to use an offset from the start of the TB. */
627 if ((sval & 1) == 0) {
628 ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1;
629 if (off == (int32_t)off) {
630 tcg_out_insn(s, RIL, LARL, ret, off);
633 } else if (USE_REG_TB && !in_prologue) {
634 ptrdiff_t off = tcg_tbrel_diff(s, (void *)sval);
635 if (off == sextract64(off, 0, 20)) {
636 /* This is certain to be an address within TB, and therefore
637 OFF will be negative; don't try RX_LA. */
638 tcg_out_insn(s, RXY, LAY, ret, TCG_REG_TB, TCG_REG_NONE, off);
643 /* A 32-bit unsigned value can be loaded in 2 insns. And given
644 that LLILL, LLIHL, LLILF above did not succeed, we know that
645 both insns are required. */
646 if (uval <= 0xffffffff) {
647 tcg_out_insn(s, RI, LLILL, ret, uval);
648 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
652 /* Otherwise, stuff it in the constant pool. */
653 if (s390_facilities & FACILITY_GEN_INST_EXT) {
654 tcg_out_insn(s, RIL, LGRL, ret, 0);
655 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
656 } else if (USE_REG_TB && !in_prologue) {
657 tcg_out_insn(s, RXY, LG, ret, TCG_REG_TB, TCG_REG_NONE, 0);
658 new_pool_label(s, sval, R_390_20, s->code_ptr - 2,
659 tcg_tbrel_diff(s, NULL));
661 TCGReg base = ret ? ret : TCG_TMP0;
662 tcg_out_insn(s, RIL, LARL, base, 0);
663 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
664 tcg_out_insn(s, RXY, LG, ret, base, TCG_REG_NONE, 0);
668 static void tcg_out_movi(TCGContext *s, TCGType type,
669 TCGReg ret, tcg_target_long sval)
671 tcg_out_movi_int(s, type, ret, sval, false);
674 /* Emit a load/store type instruction. Inputs are:
675 DATA: The register to be loaded or stored.
676 BASE+OFS: The effective address.
677 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
678 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
680 static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
681 TCGReg data, TCGReg base, TCGReg index,
684 if (ofs < -0x80000 || ofs >= 0x80000) {
685 /* Combine the low 20 bits of the offset with the actual load insn;
686 the high 44 bits must come from an immediate load. */
687 tcg_target_long low = ((ofs & 0xfffff) ^ 0x80000) - 0x80000;
688 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - low);
691 /* If we were already given an index register, add it in. */
692 if (index != TCG_REG_NONE) {
693 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
698 if (opc_rx && ofs >= 0 && ofs < 0x1000) {
699 tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
701 tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
706 /* load data without address translation or endianness conversion */
707 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
708 TCGReg base, intptr_t ofs)
710 if (type == TCG_TYPE_I32) {
711 tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
713 tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
717 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
718 TCGReg base, intptr_t ofs)
720 if (type == TCG_TYPE_I32) {
721 tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
723 tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
727 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
728 TCGReg base, intptr_t ofs)
733 /* load data from an absolute host address */
734 static void tcg_out_ld_abs(TCGContext *s, TCGType type,
735 TCGReg dest, const void *abs)
737 intptr_t addr = (intptr_t)abs;
739 if ((s390_facilities & FACILITY_GEN_INST_EXT) && !(addr & 1)) {
740 ptrdiff_t disp = tcg_pcrel_diff(s, abs) >> 1;
741 if (disp == (int32_t)disp) {
742 if (type == TCG_TYPE_I32) {
743 tcg_out_insn(s, RIL, LRL, dest, disp);
745 tcg_out_insn(s, RIL, LGRL, dest, disp);
751 ptrdiff_t disp = tcg_tbrel_diff(s, abs);
752 if (disp == sextract64(disp, 0, 20)) {
753 tcg_out_ld(s, type, dest, TCG_REG_TB, disp);
758 tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
759 tcg_out_ld(s, type, dest, dest, addr & 0xffff);
762 static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
763 int msb, int lsb, int ofs, int z)
766 tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src);
767 tcg_out16(s, (msb << 8) | (z << 7) | lsb);
768 tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff));
771 static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
773 if (s390_facilities & FACILITY_EXT_IMM) {
774 tcg_out_insn(s, RRE, LGBR, dest, src);
778 if (type == TCG_TYPE_I32) {
780 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
782 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
784 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
786 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
787 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
791 static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
793 if (s390_facilities & FACILITY_EXT_IMM) {
794 tcg_out_insn(s, RRE, LLGCR, dest, src);
799 tcg_out_movi(s, type, TCG_TMP0, 0xff);
802 tcg_out_movi(s, type, dest, 0xff);
804 if (type == TCG_TYPE_I32) {
805 tcg_out_insn(s, RR, NR, dest, src);
807 tcg_out_insn(s, RRE, NGR, dest, src);
811 static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
813 if (s390_facilities & FACILITY_EXT_IMM) {
814 tcg_out_insn(s, RRE, LGHR, dest, src);
818 if (type == TCG_TYPE_I32) {
820 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
822 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
824 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
826 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
827 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
831 static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
833 if (s390_facilities & FACILITY_EXT_IMM) {
834 tcg_out_insn(s, RRE, LLGHR, dest, src);
839 tcg_out_movi(s, type, TCG_TMP0, 0xffff);
842 tcg_out_movi(s, type, dest, 0xffff);
844 if (type == TCG_TYPE_I32) {
845 tcg_out_insn(s, RR, NR, dest, src);
847 tcg_out_insn(s, RRE, NGR, dest, src);
851 static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
853 tcg_out_insn(s, RRE, LGFR, dest, src);
856 static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
858 tcg_out_insn(s, RRE, LLGFR, dest, src);
861 /* Accept bit patterns like these:
866 Copied from gcc sources. */
867 static inline bool risbg_mask(uint64_t c)
870 /* We don't change the number of transitions by inverting,
871 so make sure we start with the LSB zero. */
875 /* Reject all zeros or all ones. */
879 /* Find the first transition. */
881 /* Invert to look for a second transition. */
883 /* Erase the first transition. */
885 /* Find the second transition, if any. */
887 /* Match if all the bits are 1's, or if c is zero. */
891 static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
894 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
895 /* Achieve wraparound by swapping msb and lsb. */
896 msb = 64 - ctz64(~val);
897 lsb = clz64(~val) - 1;
900 lsb = 63 - ctz64(val);
902 tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
905 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
907 static const S390Opcode ni_insns[4] = {
908 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
910 static const S390Opcode nif_insns[2] = {
913 uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
916 /* Look for the zero-extensions. */
917 if ((val & valid) == 0xffffffff) {
918 tgen_ext32u(s, dest, dest);
921 if (s390_facilities & FACILITY_EXT_IMM) {
922 if ((val & valid) == 0xff) {
923 tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
926 if ((val & valid) == 0xffff) {
927 tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
932 /* Try all 32-bit insns that can perform it in one go. */
933 for (i = 0; i < 4; i++) {
934 tcg_target_ulong mask = ~(0xffffull << i*16);
935 if (((val | ~valid) & mask) == mask) {
936 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
941 /* Try all 48-bit insns that can perform it in one go. */
942 if (s390_facilities & FACILITY_EXT_IMM) {
943 for (i = 0; i < 2; i++) {
944 tcg_target_ulong mask = ~(0xffffffffull << i*32);
945 if (((val | ~valid) & mask) == mask) {
946 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
951 if ((s390_facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) {
952 tgen_andi_risbg(s, dest, dest, val);
956 /* Use the constant pool if USE_REG_TB, but not for small constants. */
958 if (!maybe_out_small_movi(s, type, TCG_TMP0, val)) {
959 tcg_out_insn(s, RXY, NG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
960 new_pool_label(s, val & valid, R_390_20, s->code_ptr - 2,
961 tcg_tbrel_diff(s, NULL));
965 tcg_out_movi(s, type, TCG_TMP0, val);
967 if (type == TCG_TYPE_I32) {
968 tcg_out_insn(s, RR, NR, dest, TCG_TMP0);
970 tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
974 static void tgen_ori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
976 static const S390Opcode oi_insns[4] = {
977 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
979 static const S390Opcode oif_insns[2] = {
985 /* Look for no-op. */
986 if (unlikely(val == 0)) {
990 /* Try all 32-bit insns that can perform it in one go. */
991 for (i = 0; i < 4; i++) {
992 tcg_target_ulong mask = (0xffffull << i*16);
993 if ((val & mask) != 0 && (val & ~mask) == 0) {
994 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
999 /* Try all 48-bit insns that can perform it in one go. */
1000 if (s390_facilities & FACILITY_EXT_IMM) {
1001 for (i = 0; i < 2; i++) {
1002 tcg_target_ulong mask = (0xffffffffull << i*32);
1003 if ((val & mask) != 0 && (val & ~mask) == 0) {
1004 tcg_out_insn_RIL(s, oif_insns[i], dest, val >> i*32);
1010 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1011 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1012 if (type == TCG_TYPE_I32) {
1013 tcg_out_insn(s, RR, OR, dest, TCG_TMP0);
1015 tcg_out_insn(s, RRE, OGR, dest, TCG_TMP0);
1017 } else if (USE_REG_TB) {
1018 tcg_out_insn(s, RXY, OG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1019 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
1020 tcg_tbrel_diff(s, NULL));
1022 /* Perform the OR via sequential modifications to the high and
1023 low parts. Do this via recursion to handle 16-bit vs 32-bit
1024 masks in each half. */
1025 tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
1026 tgen_ori(s, type, dest, val & 0x00000000ffffffffull);
1027 tgen_ori(s, type, dest, val & 0xffffffff00000000ull);
1031 static void tgen_xori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
1033 /* Try all 48-bit insns that can perform it in one go. */
1034 if (s390_facilities & FACILITY_EXT_IMM) {
1035 if ((val & 0xffffffff00000000ull) == 0) {
1036 tcg_out_insn(s, RIL, XILF, dest, val);
1039 if ((val & 0x00000000ffffffffull) == 0) {
1040 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1045 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1046 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1047 if (type == TCG_TYPE_I32) {
1048 tcg_out_insn(s, RR, XR, dest, TCG_TMP0);
1050 tcg_out_insn(s, RRE, XGR, dest, TCG_TMP0);
1052 } else if (USE_REG_TB) {
1053 tcg_out_insn(s, RXY, XG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1054 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
1055 tcg_tbrel_diff(s, NULL));
1057 /* Perform the xor by parts. */
1058 tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
1059 if (val & 0xffffffff) {
1060 tcg_out_insn(s, RIL, XILF, dest, val);
1062 if (val > 0xffffffff) {
1063 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1068 static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1069 TCGArg c2, bool c2const, bool need_carry)
1071 bool is_unsigned = is_unsigned_cond(c);
1076 if (!(is_unsigned && need_carry)) {
1077 if (type == TCG_TYPE_I32) {
1078 tcg_out_insn(s, RR, LTR, r1, r1);
1080 tcg_out_insn(s, RRE, LTGR, r1, r1);
1082 return tcg_cond_to_ltr_cond[c];
1086 if (!is_unsigned && c2 == (int16_t)c2) {
1087 op = (type == TCG_TYPE_I32 ? RI_CHI : RI_CGHI);
1088 tcg_out_insn_RI(s, op, r1, c2);
1092 if (s390_facilities & FACILITY_EXT_IMM) {
1093 if (type == TCG_TYPE_I32) {
1094 op = (is_unsigned ? RIL_CLFI : RIL_CFI);
1095 tcg_out_insn_RIL(s, op, r1, c2);
1097 } else if (c2 == (is_unsigned ? (uint32_t)c2 : (int32_t)c2)) {
1098 op = (is_unsigned ? RIL_CLGFI : RIL_CGFI);
1099 tcg_out_insn_RIL(s, op, r1, c2);
1104 /* Use the constant pool, but not for small constants. */
1105 if (maybe_out_small_movi(s, type, TCG_TMP0, c2)) {
1107 /* fall through to reg-reg */
1108 } else if (USE_REG_TB) {
1109 if (type == TCG_TYPE_I32) {
1110 op = (is_unsigned ? RXY_CLY : RXY_CY);
1111 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1112 new_pool_label(s, (uint32_t)c2, R_390_20, s->code_ptr - 2,
1113 4 - tcg_tbrel_diff(s, NULL));
1115 op = (is_unsigned ? RXY_CLG : RXY_CG);
1116 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1117 new_pool_label(s, c2, R_390_20, s->code_ptr - 2,
1118 tcg_tbrel_diff(s, NULL));
1122 if (type == TCG_TYPE_I32) {
1123 op = (is_unsigned ? RIL_CLRL : RIL_CRL);
1124 tcg_out_insn_RIL(s, op, r1, 0);
1125 new_pool_label(s, (uint32_t)c2, R_390_PC32DBL,
1126 s->code_ptr - 2, 2 + 4);
1128 op = (is_unsigned ? RIL_CLGRL : RIL_CGRL);
1129 tcg_out_insn_RIL(s, op, r1, 0);
1130 new_pool_label(s, c2, R_390_PC32DBL, s->code_ptr - 2, 2);
1136 if (type == TCG_TYPE_I32) {
1137 op = (is_unsigned ? RR_CLR : RR_CR);
1138 tcg_out_insn_RR(s, op, r1, c2);
1140 op = (is_unsigned ? RRE_CLGR : RRE_CGR);
1141 tcg_out_insn_RRE(s, op, r1, c2);
1145 return tcg_cond_to_s390_cond[c];
1148 static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
1149 TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
1154 /* With LOC2, we can always emit the minimum 3 insns. */
1155 if (s390_facilities & FACILITY_LOAD_ON_COND2) {
1156 /* Emit: d = 0, d = (cc ? 1 : d). */
1157 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1158 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1159 tcg_out_insn(s, RIE, LOCGHI, dest, 1, cc);
1163 have_loc = (s390_facilities & FACILITY_LOAD_ON_COND) != 0;
1165 /* For HAVE_LOC, only the paths through GTU/GT/LEU/LE are smaller. */
1169 /* X != 0 is X > 0. */
1170 if (c2const && c2 == 0) {
1171 cond = TCG_COND_GTU;
1179 /* The result of a compare has CC=2 for GT and CC=3 unused.
1180 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1181 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1182 tcg_out_movi(s, type, dest, 0);
1183 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1187 /* X == 0 is X <= 0. */
1188 if (c2const && c2 == 0) {
1189 cond = TCG_COND_LEU;
1197 /* As above, but we're looking for borrow, or !carry.
1198 The second insn computes d - d - borrow, or -1 for true
1199 and 0 for false. So we must mask to 1 bit afterward. */
1200 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1201 tcg_out_insn(s, RRE, SLBGR, dest, dest);
1202 tgen_andi(s, type, dest, 1);
1209 /* Swap operands so that we can use LEU/GTU/GT/LE. */
1214 tcg_out_movi(s, type, TCG_TMP0, c2);
1223 cond = tcg_swap_cond(cond);
1227 g_assert_not_reached();
1230 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1232 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1233 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1234 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1235 tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);
1237 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1238 tcg_out_movi(s, type, dest, 1);
1239 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1240 tcg_out_movi(s, type, dest, 0);
1244 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
1245 TCGReg c1, TCGArg c2, int c2const,
1246 TCGArg v3, int v3const)
1249 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1250 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1252 tcg_out_insn(s, RIE, LOCGHI, dest, v3, cc);
1254 tcg_out_insn(s, RRF, LOCGR, dest, v3, cc);
1257 c = tcg_invert_cond(c);
1258 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1260 /* Emit: if (cc) goto over; dest = r3; over: */
1261 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1262 tcg_out_insn(s, RRE, LGR, dest, v3);
1266 static void tgen_clz(TCGContext *s, TCGReg dest, TCGReg a1,
1267 TCGArg a2, int a2const)
1269 /* Since this sets both R and R+1, we have no choice but to store the
1270 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1271 QEMU_BUILD_BUG_ON(TCG_TMP0 != TCG_REG_R1);
1272 tcg_out_insn(s, RRE, FLOGR, TCG_REG_R0, a1);
1274 if (a2const && a2 == 64) {
1275 tcg_out_mov(s, TCG_TYPE_I64, dest, TCG_REG_R0);
1278 tcg_out_movi(s, TCG_TYPE_I64, dest, a2);
1280 tcg_out_mov(s, TCG_TYPE_I64, dest, a2);
1282 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1283 /* Emit: if (one bit found) dest = r0. */
1284 tcg_out_insn(s, RRF, LOCGR, dest, TCG_REG_R0, 2);
1286 /* Emit: if (no one bit found) goto over; dest = r0; over: */
1287 tcg_out_insn(s, RI, BRC, 8, (4 + 4) >> 1);
1288 tcg_out_insn(s, RRE, LGR, dest, TCG_REG_R0);
1293 static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
1294 int ofs, int len, int z)
1296 int lsb = (63 - ofs);
1297 int msb = lsb - (len - 1);
1298 tcg_out_risbg(s, dest, src, msb, lsb, ofs, z);
1301 static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
1304 tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
1307 static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
1309 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1310 if (off == (int16_t)off) {
1311 tcg_out_insn(s, RI, BRC, cc, off);
1312 } else if (off == (int32_t)off) {
1313 tcg_out_insn(s, RIL, BRCL, cc, off);
1315 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1316 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1320 static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
1323 tgen_gotoi(s, cc, l->u.value_ptr);
1324 } else if (USE_LONG_BRANCHES) {
1325 tcg_out16(s, RIL_BRCL | (cc << 4));
1326 tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, l, 2);
1329 tcg_out16(s, RI_BRC | (cc << 4));
1330 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, 2);
1335 static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1336 TCGReg r1, TCGReg r2, TCGLabel *l)
1338 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1339 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1341 tcg_out16(s, cc << 12 | (opc & 0xff));
1344 static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1345 TCGReg r1, int i2, TCGLabel *l)
1347 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1348 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1350 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1353 static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1354 TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
1358 if (s390_facilities & FACILITY_GEN_INST_EXT) {
1359 bool is_unsigned = is_unsigned_cond(c);
1363 cc = tcg_cond_to_s390_cond[c];
1366 opc = (type == TCG_TYPE_I32
1367 ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1368 : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1369 tgen_compare_branch(s, opc, cc, r1, c2, l);
1373 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1374 If the immediate we've been given does not fit that range, we'll
1375 fall back to separate compare and branch instructions using the
1376 larger comparison range afforded by COMPARE IMMEDIATE. */
1377 if (type == TCG_TYPE_I32) {
1380 in_range = (uint32_t)c2 == (uint8_t)c2;
1383 in_range = (int32_t)c2 == (int8_t)c2;
1388 in_range = (uint64_t)c2 == (uint8_t)c2;
1391 in_range = (int64_t)c2 == (int8_t)c2;
1395 tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
1400 cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
1401 tgen_branch(s, cc, l);
1404 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
1406 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1407 if (off == (int32_t)off) {
1408 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1410 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1411 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1415 static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
1416 TCGReg base, TCGReg index, int disp)
1418 switch (opc & (MO_SSIZE | MO_BSWAP)) {
1420 tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1423 tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1426 case MO_UW | MO_BSWAP:
1427 /* swapped unsigned halfword load with upper bits zeroed */
1428 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1429 tgen_ext16u(s, TCG_TYPE_I64, data, data);
1432 tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1435 case MO_SW | MO_BSWAP:
1436 /* swapped sign-extended halfword load */
1437 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1438 tgen_ext16s(s, TCG_TYPE_I64, data, data);
1441 tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1444 case MO_UL | MO_BSWAP:
1445 /* swapped unsigned int load with upper bits zeroed */
1446 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1447 tgen_ext32u(s, data, data);
1450 tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1453 case MO_SL | MO_BSWAP:
1454 /* swapped sign-extended int load */
1455 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1456 tgen_ext32s(s, data, data);
1459 tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1462 case MO_Q | MO_BSWAP:
1463 tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1466 tcg_out_insn(s, RXY, LG, data, base, index, disp);
1474 static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data,
1475 TCGReg base, TCGReg index, int disp)
1477 switch (opc & (MO_SIZE | MO_BSWAP)) {
1479 if (disp >= 0 && disp < 0x1000) {
1480 tcg_out_insn(s, RX, STC, data, base, index, disp);
1482 tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1486 case MO_UW | MO_BSWAP:
1487 tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1490 if (disp >= 0 && disp < 0x1000) {
1491 tcg_out_insn(s, RX, STH, data, base, index, disp);
1493 tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1497 case MO_UL | MO_BSWAP:
1498 tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1501 if (disp >= 0 && disp < 0x1000) {
1502 tcg_out_insn(s, RX, ST, data, base, index, disp);
1504 tcg_out_insn(s, RXY, STY, data, base, index, disp);
1508 case MO_Q | MO_BSWAP:
1509 tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1512 tcg_out_insn(s, RXY, STG, data, base, index, disp);
1520 #if defined(CONFIG_SOFTMMU)
1521 #include "../tcg-ldst.c.inc"
1523 /* We're expecting to use a 20-bit negative offset on the tlb memory ops. */
1524 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1525 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 19));
1527 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1528 addend into R2. Returns a register with the santitized guest address. */
1529 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc,
1530 int mem_index, bool is_ld)
1532 unsigned s_bits = opc & MO_SIZE;
1533 unsigned a_bits = get_alignment_bits(opc);
1534 unsigned s_mask = (1 << s_bits) - 1;
1535 unsigned a_mask = (1 << a_bits) - 1;
1536 int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1537 int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1538 int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1542 tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
1543 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1544 tcg_out_insn(s, RXY, NG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, mask_off);
1545 tcg_out_insn(s, RXY, AG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, table_off);
1547 /* For aligned accesses, we check the first byte and include the alignment
1548 bits within the address. For unaligned access, we check that we don't
1549 cross pages using the address of the last byte of the access. */
1550 a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
1551 tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
1552 if ((s390_facilities & FACILITY_GEN_INST_EXT) && a_off == 0) {
1553 tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
1555 tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
1556 tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
1560 ofs = offsetof(CPUTLBEntry, addr_read);
1562 ofs = offsetof(CPUTLBEntry, addr_write);
1564 if (TARGET_LONG_BITS == 32) {
1565 tcg_out_insn(s, RX, C, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1567 tcg_out_insn(s, RXY, CG, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1570 tcg_out_insn(s, RXY, LG, TCG_REG_R2, TCG_REG_R2, TCG_REG_NONE,
1571 offsetof(CPUTLBEntry, addend));
1573 if (TARGET_LONG_BITS == 32) {
1574 tgen_ext32u(s, TCG_REG_R3, addr_reg);
1580 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1581 TCGReg data, TCGReg addr,
1582 tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
1584 TCGLabelQemuLdst *label = new_ldst_label(s);
1586 label->is_ld = is_ld;
1588 label->datalo_reg = data;
1589 label->addrlo_reg = addr;
1590 label->raddr = tcg_splitwx_to_rx(raddr);
1591 label->label_ptr[0] = label_ptr;
1594 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1596 TCGReg addr_reg = lb->addrlo_reg;
1597 TCGReg data_reg = lb->datalo_reg;
1598 TCGMemOpIdx oi = lb->oi;
1599 MemOp opc = get_memop(oi);
1601 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1602 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1606 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1607 if (TARGET_LONG_BITS == 64) {
1608 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1610 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, oi);
1611 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R5, (uintptr_t)lb->raddr);
1612 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)]);
1613 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1615 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1619 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1621 TCGReg addr_reg = lb->addrlo_reg;
1622 TCGReg data_reg = lb->datalo_reg;
1623 TCGMemOpIdx oi = lb->oi;
1624 MemOp opc = get_memop(oi);
1626 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1627 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1631 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1632 if (TARGET_LONG_BITS == 64) {
1633 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1635 switch (opc & MO_SIZE) {
1637 tgen_ext8u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1640 tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1643 tgen_ext32u(s, TCG_REG_R4, data_reg);
1646 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1651 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
1652 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
1653 tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1655 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1659 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1660 TCGReg *index_reg, tcg_target_long *disp)
1662 if (TARGET_LONG_BITS == 32) {
1663 tgen_ext32u(s, TCG_TMP0, *addr_reg);
1664 *addr_reg = TCG_TMP0;
1666 if (guest_base < 0x80000) {
1667 *index_reg = TCG_REG_NONE;
1670 *index_reg = TCG_GUEST_BASE_REG;
1674 #endif /* CONFIG_SOFTMMU */
1676 static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1679 MemOp opc = get_memop(oi);
1680 #ifdef CONFIG_SOFTMMU
1681 unsigned mem_index = get_mmuidx(oi);
1682 tcg_insn_unit *label_ptr;
1685 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 1);
1687 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1688 label_ptr = s->code_ptr;
1691 tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1693 add_qemu_ldst_label(s, 1, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1696 tcg_target_long disp;
1698 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1699 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1703 static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1706 MemOp opc = get_memop(oi);
1707 #ifdef CONFIG_SOFTMMU
1708 unsigned mem_index = get_mmuidx(oi);
1709 tcg_insn_unit *label_ptr;
1712 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 0);
1714 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1715 label_ptr = s->code_ptr;
1718 tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1720 add_qemu_ldst_label(s, 0, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1723 tcg_target_long disp;
1725 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1726 tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1730 # define OP_32_64(x) \
1731 case glue(glue(INDEX_op_,x),_i32): \
1732 case glue(glue(INDEX_op_,x),_i64)
1734 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1735 const TCGArg *args, const int *const_args)
1741 case INDEX_op_exit_tb:
1742 /* Reuse the zeroing that exists for goto_ptr. */
1745 tgen_gotoi(s, S390_CC_ALWAYS, tcg_code_gen_epilogue);
1747 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, a0);
1748 tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
1752 case INDEX_op_goto_tb:
1754 if (s->tb_jmp_insn_offset) {
1756 * branch displacement must be aligned for atomic patching;
1757 * see if we need to add extra nop before branch
1759 if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
1762 tcg_debug_assert(!USE_REG_TB);
1763 tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
1764 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1767 /* load address stored at s->tb_jmp_target_addr + a0 */
1768 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_REG_TB,
1769 tcg_splitwx_to_rx(s->tb_jmp_target_addr + a0));
1771 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_TB);
1773 set_jmp_reset_offset(s, a0);
1775 /* For the unlinked path of goto_tb, we need to reset
1776 TCG_REG_TB to the beginning of this TB. */
1778 int ofs = -tcg_current_code_size(s);
1779 /* All TB are restricted to 64KiB by unwind info. */
1780 tcg_debug_assert(ofs == sextract64(ofs, 0, 20));
1781 tcg_out_insn(s, RXY, LAY, TCG_REG_TB,
1782 TCG_REG_TB, TCG_REG_NONE, ofs);
1786 case INDEX_op_goto_ptr:
1789 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, a0);
1791 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, a0);
1795 /* ??? LLC (RXY format) is only present with the extended-immediate
1796 facility, whereas LLGC is always present. */
1797 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1801 /* ??? LB is no smaller than LGB, so no point to using it. */
1802 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1806 /* ??? LLH (RXY format) is only present with the extended-immediate
1807 facility, whereas LLGH is always present. */
1808 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1811 case INDEX_op_ld16s_i32:
1812 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1815 case INDEX_op_ld_i32:
1816 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1820 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1821 TCG_REG_NONE, args[2]);
1825 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1826 TCG_REG_NONE, args[2]);
1829 case INDEX_op_st_i32:
1830 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1833 case INDEX_op_add_i32:
1834 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1835 if (const_args[2]) {
1838 if (a2 == (int16_t)a2) {
1839 tcg_out_insn(s, RI, AHI, a0, a2);
1842 if (s390_facilities & FACILITY_EXT_IMM) {
1843 tcg_out_insn(s, RIL, AFI, a0, a2);
1847 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1848 } else if (a0 == a1) {
1849 tcg_out_insn(s, RR, AR, a0, a2);
1851 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1854 case INDEX_op_sub_i32:
1855 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1856 if (const_args[2]) {
1859 } else if (a0 == a1) {
1860 tcg_out_insn(s, RR, SR, a0, a2);
1862 tcg_out_insn(s, RRF, SRK, a0, a1, a2);
1866 case INDEX_op_and_i32:
1867 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1868 if (const_args[2]) {
1869 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1870 tgen_andi(s, TCG_TYPE_I32, a0, a2);
1871 } else if (a0 == a1) {
1872 tcg_out_insn(s, RR, NR, a0, a2);
1874 tcg_out_insn(s, RRF, NRK, a0, a1, a2);
1877 case INDEX_op_or_i32:
1878 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1879 if (const_args[2]) {
1880 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1881 tgen_ori(s, TCG_TYPE_I32, a0, a2);
1882 } else if (a0 == a1) {
1883 tcg_out_insn(s, RR, OR, a0, a2);
1885 tcg_out_insn(s, RRF, ORK, a0, a1, a2);
1888 case INDEX_op_xor_i32:
1889 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1890 if (const_args[2]) {
1891 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1892 tgen_xori(s, TCG_TYPE_I32, a0, a2);
1893 } else if (a0 == a1) {
1894 tcg_out_insn(s, RR, XR, args[0], args[2]);
1896 tcg_out_insn(s, RRF, XRK, a0, a1, a2);
1900 case INDEX_op_neg_i32:
1901 tcg_out_insn(s, RR, LCR, args[0], args[1]);
1904 case INDEX_op_mul_i32:
1905 if (const_args[2]) {
1906 if ((int32_t)args[2] == (int16_t)args[2]) {
1907 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1909 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1912 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1916 case INDEX_op_div2_i32:
1917 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1919 case INDEX_op_divu2_i32:
1920 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1923 case INDEX_op_shl_i32:
1927 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1929 if (const_args[2]) {
1930 tcg_out_sh32(s, op, a0, TCG_REG_NONE, a2);
1932 tcg_out_sh32(s, op, a0, a2, 0);
1935 /* Using tcg_out_sh64 here for the format; it is a 32-bit shift. */
1936 if (const_args[2]) {
1937 tcg_out_sh64(s, op2, a0, a1, TCG_REG_NONE, a2);
1939 tcg_out_sh64(s, op2, a0, a1, a2, 0);
1943 case INDEX_op_shr_i32:
1947 case INDEX_op_sar_i32:
1952 case INDEX_op_rotl_i32:
1953 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1954 if (const_args[2]) {
1955 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1957 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1960 case INDEX_op_rotr_i32:
1961 if (const_args[2]) {
1962 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1963 TCG_REG_NONE, (32 - args[2]) & 31);
1965 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1966 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1970 case INDEX_op_ext8s_i32:
1971 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1973 case INDEX_op_ext16s_i32:
1974 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1976 case INDEX_op_ext8u_i32:
1977 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1979 case INDEX_op_ext16u_i32:
1980 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1984 /* The TCG bswap definition requires bits 0-47 already be zero.
1985 Thus we don't need the G-type insns to implement bswap16_i64. */
1986 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1987 tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1990 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1993 case INDEX_op_add2_i32:
1994 if (const_args[4]) {
1995 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
1997 tcg_out_insn(s, RR, ALR, args[0], args[4]);
1999 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
2001 case INDEX_op_sub2_i32:
2002 if (const_args[4]) {
2003 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
2005 tcg_out_insn(s, RR, SLR, args[0], args[4]);
2007 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
2011 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
2014 case INDEX_op_brcond_i32:
2015 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
2016 args[1], const_args[1], arg_label(args[3]));
2018 case INDEX_op_setcond_i32:
2019 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
2020 args[2], const_args[2]);
2022 case INDEX_op_movcond_i32:
2023 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
2024 args[2], const_args[2], args[3], const_args[3]);
2027 case INDEX_op_qemu_ld_i32:
2028 /* ??? Technically we can use a non-extending instruction. */
2029 case INDEX_op_qemu_ld_i64:
2030 tcg_out_qemu_ld(s, args[0], args[1], args[2]);
2032 case INDEX_op_qemu_st_i32:
2033 case INDEX_op_qemu_st_i64:
2034 tcg_out_qemu_st(s, args[0], args[1], args[2]);
2037 case INDEX_op_ld16s_i64:
2038 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
2040 case INDEX_op_ld32u_i64:
2041 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
2043 case INDEX_op_ld32s_i64:
2044 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
2046 case INDEX_op_ld_i64:
2047 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2050 case INDEX_op_st32_i64:
2051 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2053 case INDEX_op_st_i64:
2054 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2057 case INDEX_op_add_i64:
2058 a0 = args[0], a1 = args[1], a2 = args[2];
2059 if (const_args[2]) {
2062 if (a2 == (int16_t)a2) {
2063 tcg_out_insn(s, RI, AGHI, a0, a2);
2066 if (s390_facilities & FACILITY_EXT_IMM) {
2067 if (a2 == (int32_t)a2) {
2068 tcg_out_insn(s, RIL, AGFI, a0, a2);
2070 } else if (a2 == (uint32_t)a2) {
2071 tcg_out_insn(s, RIL, ALGFI, a0, a2);
2073 } else if (-a2 == (uint32_t)-a2) {
2074 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2079 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2080 } else if (a0 == a1) {
2081 tcg_out_insn(s, RRE, AGR, a0, a2);
2083 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2086 case INDEX_op_sub_i64:
2087 a0 = args[0], a1 = args[1], a2 = args[2];
2088 if (const_args[2]) {
2091 } else if (a0 == a1) {
2092 tcg_out_insn(s, RRE, SGR, a0, a2);
2094 tcg_out_insn(s, RRF, SGRK, a0, a1, a2);
2098 case INDEX_op_and_i64:
2099 a0 = args[0], a1 = args[1], a2 = args[2];
2100 if (const_args[2]) {
2101 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2102 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2103 } else if (a0 == a1) {
2104 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2106 tcg_out_insn(s, RRF, NGRK, a0, a1, a2);
2109 case INDEX_op_or_i64:
2110 a0 = args[0], a1 = args[1], a2 = args[2];
2111 if (const_args[2]) {
2112 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2113 tgen_ori(s, TCG_TYPE_I64, a0, a2);
2114 } else if (a0 == a1) {
2115 tcg_out_insn(s, RRE, OGR, a0, a2);
2117 tcg_out_insn(s, RRF, OGRK, a0, a1, a2);
2120 case INDEX_op_xor_i64:
2121 a0 = args[0], a1 = args[1], a2 = args[2];
2122 if (const_args[2]) {
2123 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2124 tgen_xori(s, TCG_TYPE_I64, a0, a2);
2125 } else if (a0 == a1) {
2126 tcg_out_insn(s, RRE, XGR, a0, a2);
2128 tcg_out_insn(s, RRF, XGRK, a0, a1, a2);
2132 case INDEX_op_neg_i64:
2133 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2135 case INDEX_op_bswap64_i64:
2136 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2139 case INDEX_op_mul_i64:
2140 if (const_args[2]) {
2141 if (args[2] == (int16_t)args[2]) {
2142 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2144 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2147 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2151 case INDEX_op_div2_i64:
2152 /* ??? We get an unnecessary sign-extension of the dividend
2153 into R3 with this definition, but as we do in fact always
2154 produce both quotient and remainder using INDEX_op_div_i64
2155 instead requires jumping through even more hoops. */
2156 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2158 case INDEX_op_divu2_i64:
2159 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2161 case INDEX_op_mulu2_i64:
2162 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2165 case INDEX_op_shl_i64:
2168 if (const_args[2]) {
2169 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2171 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2174 case INDEX_op_shr_i64:
2177 case INDEX_op_sar_i64:
2181 case INDEX_op_rotl_i64:
2182 if (const_args[2]) {
2183 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2184 TCG_REG_NONE, args[2]);
2186 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2189 case INDEX_op_rotr_i64:
2190 if (const_args[2]) {
2191 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2192 TCG_REG_NONE, (64 - args[2]) & 63);
2194 /* We can use the smaller 32-bit negate because only the
2195 low 6 bits are examined for the rotate. */
2196 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2197 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2201 case INDEX_op_ext8s_i64:
2202 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2204 case INDEX_op_ext16s_i64:
2205 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2207 case INDEX_op_ext_i32_i64:
2208 case INDEX_op_ext32s_i64:
2209 tgen_ext32s(s, args[0], args[1]);
2211 case INDEX_op_ext8u_i64:
2212 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2214 case INDEX_op_ext16u_i64:
2215 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2217 case INDEX_op_extu_i32_i64:
2218 case INDEX_op_ext32u_i64:
2219 tgen_ext32u(s, args[0], args[1]);
2222 case INDEX_op_add2_i64:
2223 if (const_args[4]) {
2224 if ((int64_t)args[4] >= 0) {
2225 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2227 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2230 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2232 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2234 case INDEX_op_sub2_i64:
2235 if (const_args[4]) {
2236 if ((int64_t)args[4] >= 0) {
2237 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2239 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2242 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2244 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2247 case INDEX_op_brcond_i64:
2248 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2249 args[1], const_args[1], arg_label(args[3]));
2251 case INDEX_op_setcond_i64:
2252 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2253 args[2], const_args[2]);
2255 case INDEX_op_movcond_i64:
2256 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2257 args[2], const_args[2], args[3], const_args[3]);
2261 a0 = args[0], a1 = args[1], a2 = args[2];
2262 if (const_args[1]) {
2263 tgen_deposit(s, a0, a2, args[3], args[4], 1);
2265 /* Since we can't support "0Z" as a constraint, we allow a1 in
2266 any register. Fix things up as if a matching constraint. */
2268 TCGType type = (opc == INDEX_op_deposit_i64);
2270 tcg_out_mov(s, type, TCG_TMP0, a2);
2273 tcg_out_mov(s, type, a0, a1);
2275 tgen_deposit(s, a0, a2, args[3], args[4], 0);
2280 tgen_extract(s, args[0], args[1], args[2], args[3]);
2283 case INDEX_op_clz_i64:
2284 tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2288 /* The host memory model is quite strong, we simply need to
2289 serialize the instruction stream. */
2290 if (args[0] & TCG_MO_ST_LD) {
2291 tcg_out_insn(s, RR, BCR,
2292 s390_facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
2296 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2297 case INDEX_op_mov_i64:
2298 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
2299 case INDEX_op_movi_i64:
2300 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2306 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
2308 static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
2309 static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
2310 static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
2311 static const TCGTargetOpDef L_L = { .args_ct_str = { "L", "L" } };
2312 static const TCGTargetOpDef r_ri = { .args_ct_str = { "r", "ri" } };
2313 static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
2314 static const TCGTargetOpDef r_0_ri = { .args_ct_str = { "r", "0", "ri" } };
2315 static const TCGTargetOpDef r_0_rI = { .args_ct_str = { "r", "0", "rI" } };
2316 static const TCGTargetOpDef r_0_rJ = { .args_ct_str = { "r", "0", "rJ" } };
2317 static const TCGTargetOpDef a2_r
2318 = { .args_ct_str = { "r", "r", "0", "1", "r", "r" } };
2319 static const TCGTargetOpDef a2_ri
2320 = { .args_ct_str = { "r", "r", "0", "1", "ri", "r" } };
2321 static const TCGTargetOpDef a2_rA
2322 = { .args_ct_str = { "r", "r", "0", "1", "rA", "r" } };
2325 case INDEX_op_goto_ptr:
2328 case INDEX_op_ld8u_i32:
2329 case INDEX_op_ld8u_i64:
2330 case INDEX_op_ld8s_i32:
2331 case INDEX_op_ld8s_i64:
2332 case INDEX_op_ld16u_i32:
2333 case INDEX_op_ld16u_i64:
2334 case INDEX_op_ld16s_i32:
2335 case INDEX_op_ld16s_i64:
2336 case INDEX_op_ld_i32:
2337 case INDEX_op_ld32u_i64:
2338 case INDEX_op_ld32s_i64:
2339 case INDEX_op_ld_i64:
2340 case INDEX_op_st8_i32:
2341 case INDEX_op_st8_i64:
2342 case INDEX_op_st16_i32:
2343 case INDEX_op_st16_i64:
2344 case INDEX_op_st_i32:
2345 case INDEX_op_st32_i64:
2346 case INDEX_op_st_i64:
2349 case INDEX_op_add_i32:
2350 case INDEX_op_add_i64:
2352 case INDEX_op_sub_i32:
2353 case INDEX_op_sub_i64:
2354 case INDEX_op_and_i32:
2355 case INDEX_op_and_i64:
2356 case INDEX_op_or_i32:
2357 case INDEX_op_or_i64:
2358 case INDEX_op_xor_i32:
2359 case INDEX_op_xor_i64:
2360 return (s390_facilities & FACILITY_DISTINCT_OPS ? &r_r_ri : &r_0_ri);
2362 case INDEX_op_mul_i32:
2363 /* If we have the general-instruction-extensions, then we have
2364 MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
2365 have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
2366 return (s390_facilities & FACILITY_GEN_INST_EXT ? &r_0_ri : &r_0_rI);
2367 case INDEX_op_mul_i64:
2368 return (s390_facilities & FACILITY_GEN_INST_EXT ? &r_0_rJ : &r_0_rI);
2370 case INDEX_op_shl_i32:
2371 case INDEX_op_shr_i32:
2372 case INDEX_op_sar_i32:
2373 return (s390_facilities & FACILITY_DISTINCT_OPS ? &r_r_ri : &r_0_ri);
2375 case INDEX_op_shl_i64:
2376 case INDEX_op_shr_i64:
2377 case INDEX_op_sar_i64:
2380 case INDEX_op_rotl_i32:
2381 case INDEX_op_rotl_i64:
2382 case INDEX_op_rotr_i32:
2383 case INDEX_op_rotr_i64:
2386 case INDEX_op_brcond_i32:
2387 case INDEX_op_brcond_i64:
2390 case INDEX_op_bswap16_i32:
2391 case INDEX_op_bswap16_i64:
2392 case INDEX_op_bswap32_i32:
2393 case INDEX_op_bswap32_i64:
2394 case INDEX_op_bswap64_i64:
2395 case INDEX_op_neg_i32:
2396 case INDEX_op_neg_i64:
2397 case INDEX_op_ext8s_i32:
2398 case INDEX_op_ext8s_i64:
2399 case INDEX_op_ext8u_i32:
2400 case INDEX_op_ext8u_i64:
2401 case INDEX_op_ext16s_i32:
2402 case INDEX_op_ext16s_i64:
2403 case INDEX_op_ext16u_i32:
2404 case INDEX_op_ext16u_i64:
2405 case INDEX_op_ext32s_i64:
2406 case INDEX_op_ext32u_i64:
2407 case INDEX_op_ext_i32_i64:
2408 case INDEX_op_extu_i32_i64:
2409 case INDEX_op_extract_i32:
2410 case INDEX_op_extract_i64:
2413 case INDEX_op_clz_i64:
2414 case INDEX_op_setcond_i32:
2415 case INDEX_op_setcond_i64:
2418 case INDEX_op_qemu_ld_i32:
2419 case INDEX_op_qemu_ld_i64:
2421 case INDEX_op_qemu_st_i64:
2422 case INDEX_op_qemu_st_i32:
2425 case INDEX_op_deposit_i32:
2426 case INDEX_op_deposit_i64:
2428 static const TCGTargetOpDef dep
2429 = { .args_ct_str = { "r", "rZ", "r" } };
2432 case INDEX_op_movcond_i32:
2433 case INDEX_op_movcond_i64:
2435 static const TCGTargetOpDef movc
2436 = { .args_ct_str = { "r", "r", "ri", "r", "0" } };
2437 static const TCGTargetOpDef movc_l
2438 = { .args_ct_str = { "r", "r", "ri", "rI", "0" } };
2439 return (s390_facilities & FACILITY_LOAD_ON_COND2 ? &movc_l : &movc);
2441 case INDEX_op_div2_i32:
2442 case INDEX_op_div2_i64:
2443 case INDEX_op_divu2_i32:
2444 case INDEX_op_divu2_i64:
2446 static const TCGTargetOpDef div2
2447 = { .args_ct_str = { "b", "a", "0", "1", "r" } };
2450 case INDEX_op_mulu2_i64:
2452 static const TCGTargetOpDef mul2
2453 = { .args_ct_str = { "b", "a", "0", "r" } };
2457 case INDEX_op_add2_i32:
2458 case INDEX_op_sub2_i32:
2459 return (s390_facilities & FACILITY_EXT_IMM ? &a2_ri : &a2_r);
2460 case INDEX_op_add2_i64:
2461 case INDEX_op_sub2_i64:
2462 return (s390_facilities & FACILITY_EXT_IMM ? &a2_rA : &a2_r);
2470 static void query_s390_facilities(void)
2472 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2474 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2475 is present on all 64-bit systems, but let's check for it anyway. */
2476 if (hwcap & HWCAP_S390_STFLE) {
2477 register int r0 __asm__("0");
2478 register void *r1 __asm__("1");
2481 r1 = &s390_facilities;
2482 asm volatile(".word 0xb2b0,0x1000"
2483 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2487 static void tcg_target_init(TCGContext *s)
2489 query_s390_facilities();
2491 tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
2492 tcg_target_available_regs[TCG_TYPE_I64] = 0xffff;
2494 tcg_target_call_clobber_regs = 0;
2495 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2496 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2497 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2498 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2499 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2500 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2501 /* The r6 register is technically call-saved, but it's also a parameter
2502 register, so it can get killed by setup for the qemu_st helper. */
2503 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2504 /* The return register can be considered call-clobbered. */
2505 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2507 s->reserved_regs = 0;
2508 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2509 /* XXX many insns can't be used with R0, so we better avoid it for now */
2510 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2511 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2513 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
2517 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2518 + TCG_STATIC_CALL_ARGS_SIZE \
2519 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2521 static void tcg_target_qemu_prologue(TCGContext *s)
2523 /* stmg %r6,%r15,48(%r15) (save registers) */
2524 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2526 /* aghi %r15,-frame_size */
2527 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
2529 tcg_set_frame(s, TCG_REG_CALL_STACK,
2530 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2531 CPU_TEMP_BUF_NLONGS * sizeof(long));
2533 #ifndef CONFIG_SOFTMMU
2534 if (guest_base >= 0x80000) {
2535 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
2536 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2540 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2542 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB,
2543 tcg_target_call_iarg_regs[1]);
2546 /* br %r3 (go to TB) */
2547 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2550 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2551 * and fall through to the rest of the epilogue.
2553 tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
2554 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
2557 tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
2559 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2560 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2563 /* br %r14 (return) */
2564 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2567 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
2569 memset(p, 0x07, count * sizeof(tcg_insn_unit));
2574 uint8_t fde_def_cfa[4];
2575 uint8_t fde_reg_ofs[18];
2578 /* We're expecting a 2 byte uleb128 encoded value. */
2579 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2581 #define ELF_HOST_MACHINE EM_S390
2583 static const DebugFrame debug_frame = {
2584 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2587 .h.cie.code_align = 1,
2588 .h.cie.data_align = 8, /* sleb128 8 */
2589 .h.cie.return_column = TCG_REG_R14,
2591 /* Total FDE size does not include the "len" member. */
2592 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2595 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
2596 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2600 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2601 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2602 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2603 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2604 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2605 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2606 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2607 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2608 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2612 void tcg_register_jit(const void *buf, size_t buf_size)
2614 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));