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 #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 16)
47 * For softmmu, we need to avoid conflicts with the first 3
48 * argument registers to perform the tlb lookup, and to call
49 * the helper function.
52 #define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_R2, 3)
54 #define SOFTMMU_RESERVE_REGS 0
58 /* Several places within the instruction set 0 means "no register"
59 rather than TCG_REG_R0. */
60 #define TCG_REG_NONE 0
62 /* A scratch register that may be be used throughout the backend. */
63 #define TCG_TMP0 TCG_REG_R1
65 /* A scratch register that holds a pointer to the beginning of the TB.
66 We don't need this when we have pc-relative loads with the general
67 instructions extension facility. */
68 #define TCG_REG_TB TCG_REG_R12
69 #define USE_REG_TB (!(s390_facilities & FACILITY_GEN_INST_EXT))
71 #ifndef CONFIG_SOFTMMU
72 #define TCG_GUEST_BASE_REG TCG_REG_R13
75 /* All of the following instructions are prefixed with their instruction
76 format, and are defined as 8- or 16-bit quantities, even when the two
77 halves of the 16-bit quantity may appear 32 bits apart in the insn.
78 This makes it easy to copy the values from the tables in Appendix B. */
79 typedef enum S390Opcode {
269 #ifdef CONFIG_DEBUG_TCG
270 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
271 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
272 "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
276 /* Since R6 is a potential argument register, choose it last of the
277 call-saved registers. Likewise prefer the call-clobbered registers
278 in reverse order to maximize the chance of avoiding the arguments. */
279 static const int tcg_target_reg_alloc_order[] = {
280 /* Call saved registers. */
289 /* Call clobbered registers. */
293 /* Argument registers, in reverse order of allocation. */
300 static const int tcg_target_call_iarg_regs[] = {
308 static const int tcg_target_call_oarg_regs[] = {
316 #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
317 #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
318 #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
319 #define S390_CC_NEVER 0
320 #define S390_CC_ALWAYS 15
322 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
323 static const uint8_t tcg_cond_to_s390_cond[] = {
324 [TCG_COND_EQ] = S390_CC_EQ,
325 [TCG_COND_NE] = S390_CC_NE,
326 [TCG_COND_LT] = S390_CC_LT,
327 [TCG_COND_LE] = S390_CC_LE,
328 [TCG_COND_GT] = S390_CC_GT,
329 [TCG_COND_GE] = S390_CC_GE,
330 [TCG_COND_LTU] = S390_CC_LT,
331 [TCG_COND_LEU] = S390_CC_LE,
332 [TCG_COND_GTU] = S390_CC_GT,
333 [TCG_COND_GEU] = S390_CC_GE,
336 /* Condition codes that result from a LOAD AND TEST. Here, we have no
337 unsigned instruction variation, however since the test is vs zero we
338 can re-map the outcomes appropriately. */
339 static const uint8_t tcg_cond_to_ltr_cond[] = {
340 [TCG_COND_EQ] = S390_CC_EQ,
341 [TCG_COND_NE] = S390_CC_NE,
342 [TCG_COND_LT] = S390_CC_LT,
343 [TCG_COND_LE] = S390_CC_LE,
344 [TCG_COND_GT] = S390_CC_GT,
345 [TCG_COND_GE] = S390_CC_GE,
346 [TCG_COND_LTU] = S390_CC_NEVER,
347 [TCG_COND_LEU] = S390_CC_EQ,
348 [TCG_COND_GTU] = S390_CC_NE,
349 [TCG_COND_GEU] = S390_CC_ALWAYS,
352 #ifdef CONFIG_SOFTMMU
353 static void * const qemu_ld_helpers[16] = {
354 [MO_UB] = helper_ret_ldub_mmu,
355 [MO_SB] = helper_ret_ldsb_mmu,
356 [MO_LEUW] = helper_le_lduw_mmu,
357 [MO_LESW] = helper_le_ldsw_mmu,
358 [MO_LEUL] = helper_le_ldul_mmu,
359 [MO_LESL] = helper_le_ldsl_mmu,
360 [MO_LEQ] = helper_le_ldq_mmu,
361 [MO_BEUW] = helper_be_lduw_mmu,
362 [MO_BESW] = helper_be_ldsw_mmu,
363 [MO_BEUL] = helper_be_ldul_mmu,
364 [MO_BESL] = helper_be_ldsl_mmu,
365 [MO_BEQ] = helper_be_ldq_mmu,
368 static void * const qemu_st_helpers[16] = {
369 [MO_UB] = helper_ret_stb_mmu,
370 [MO_LEUW] = helper_le_stw_mmu,
371 [MO_LEUL] = helper_le_stl_mmu,
372 [MO_LEQ] = helper_le_stq_mmu,
373 [MO_BEUW] = helper_be_stw_mmu,
374 [MO_BEUL] = helper_be_stl_mmu,
375 [MO_BEQ] = helper_be_stq_mmu,
379 static const tcg_insn_unit *tb_ret_addr;
380 uint64_t s390_facilities;
382 static bool patch_reloc(tcg_insn_unit *src_rw, int type,
383 intptr_t value, intptr_t addend)
385 const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
390 pcrel2 = (tcg_insn_unit *)value - src_rx;
394 if (pcrel2 == (int16_t)pcrel2) {
395 tcg_patch16(src_rw, pcrel2);
400 if (pcrel2 == (int32_t)pcrel2) {
401 tcg_patch32(src_rw, pcrel2);
406 if (value == sextract64(value, 0, 20)) {
407 old = *(uint32_t *)src_rw & 0xf00000ff;
408 old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
409 tcg_patch32(src_rw, old);
414 g_assert_not_reached();
419 /* Test if a constant matches the constraint. */
420 static int tcg_target_const_match(tcg_target_long val, TCGType type,
421 const TCGArgConstraint *arg_ct)
425 if (ct & TCG_CT_CONST) {
429 if (type == TCG_TYPE_I32) {
433 /* The following are mutually exclusive. */
434 if (ct & TCG_CT_CONST_S16) {
435 return val == (int16_t)val;
436 } else if (ct & TCG_CT_CONST_S32) {
437 return val == (int32_t)val;
438 } else if (ct & TCG_CT_CONST_S33) {
439 return val >= -0xffffffffll && val <= 0xffffffffll;
440 } else if (ct & TCG_CT_CONST_ZERO) {
447 /* Emit instructions according to the given instruction format. */
449 static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
451 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
454 static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
455 TCGReg r1, TCGReg r2)
457 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
460 static void tcg_out_insn_RRF(TCGContext *s, S390Opcode op,
461 TCGReg r1, TCGReg r2, int m3)
463 tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
466 static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
468 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
471 static void tcg_out_insn_RIE(TCGContext *s, S390Opcode op, TCGReg r1,
474 tcg_out16(s, (op & 0xff00) | (r1 << 4) | m3);
475 tcg_out32(s, (i2 << 16) | (op & 0xff));
478 static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
480 tcg_out16(s, op | (r1 << 4));
484 static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
485 TCGReg b2, TCGReg r3, int disp)
487 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
491 static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
492 TCGReg b2, TCGReg r3, int disp)
494 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
495 tcg_out32(s, (op & 0xff) | (b2 << 28)
496 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
499 #define tcg_out_insn_RX tcg_out_insn_RS
500 #define tcg_out_insn_RXY tcg_out_insn_RSY
502 /* Emit an opcode with "type-checking" of the format. */
503 #define tcg_out_insn(S, FMT, OP, ...) \
504 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
507 /* emit 64-bit shifts */
508 static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
509 TCGReg src, TCGReg sh_reg, int sh_imm)
511 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
514 /* emit 32-bit shifts */
515 static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
516 TCGReg sh_reg, int sh_imm)
518 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
521 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
524 if (type == TCG_TYPE_I32) {
525 tcg_out_insn(s, RR, LR, dst, src);
527 tcg_out_insn(s, RRE, LGR, dst, src);
533 static const S390Opcode lli_insns[4] = {
534 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
537 static bool maybe_out_small_movi(TCGContext *s, TCGType type,
538 TCGReg ret, tcg_target_long sval)
540 tcg_target_ulong uval = sval;
543 if (type == TCG_TYPE_I32) {
544 uval = (uint32_t)sval;
545 sval = (int32_t)sval;
548 /* Try all 32-bit insns that can load it in one go. */
549 if (sval >= -0x8000 && sval < 0x8000) {
550 tcg_out_insn(s, RI, LGHI, ret, sval);
554 for (i = 0; i < 4; i++) {
555 tcg_target_long mask = 0xffffull << i*16;
556 if ((uval & mask) == uval) {
557 tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
565 /* load a register with an immediate value */
566 static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
567 tcg_target_long sval, bool in_prologue)
569 tcg_target_ulong uval;
571 /* Try all 32-bit insns that can load it in one go. */
572 if (maybe_out_small_movi(s, type, ret, sval)) {
577 if (type == TCG_TYPE_I32) {
578 uval = (uint32_t)sval;
579 sval = (int32_t)sval;
582 /* Try all 48-bit insns that can load it in one go. */
583 if (s390_facilities & FACILITY_EXT_IMM) {
584 if (sval == (int32_t)sval) {
585 tcg_out_insn(s, RIL, LGFI, ret, sval);
588 if (uval <= 0xffffffff) {
589 tcg_out_insn(s, RIL, LLILF, ret, uval);
592 if ((uval & 0xffffffff) == 0) {
593 tcg_out_insn(s, RIL, LLIHF, ret, uval >> 32);
598 /* Try for PC-relative address load. For odd addresses,
599 attempt to use an offset from the start of the TB. */
600 if ((sval & 1) == 0) {
601 ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1;
602 if (off == (int32_t)off) {
603 tcg_out_insn(s, RIL, LARL, ret, off);
606 } else if (USE_REG_TB && !in_prologue) {
607 ptrdiff_t off = tcg_tbrel_diff(s, (void *)sval);
608 if (off == sextract64(off, 0, 20)) {
609 /* This is certain to be an address within TB, and therefore
610 OFF will be negative; don't try RX_LA. */
611 tcg_out_insn(s, RXY, LAY, ret, TCG_REG_TB, TCG_REG_NONE, off);
616 /* A 32-bit unsigned value can be loaded in 2 insns. And given
617 that LLILL, LLIHL, LLILF above did not succeed, we know that
618 both insns are required. */
619 if (uval <= 0xffffffff) {
620 tcg_out_insn(s, RI, LLILL, ret, uval);
621 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
625 /* Otherwise, stuff it in the constant pool. */
626 if (s390_facilities & FACILITY_GEN_INST_EXT) {
627 tcg_out_insn(s, RIL, LGRL, ret, 0);
628 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
629 } else if (USE_REG_TB && !in_prologue) {
630 tcg_out_insn(s, RXY, LG, ret, TCG_REG_TB, TCG_REG_NONE, 0);
631 new_pool_label(s, sval, R_390_20, s->code_ptr - 2,
632 tcg_tbrel_diff(s, NULL));
634 TCGReg base = ret ? ret : TCG_TMP0;
635 tcg_out_insn(s, RIL, LARL, base, 0);
636 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
637 tcg_out_insn(s, RXY, LG, ret, base, TCG_REG_NONE, 0);
641 static void tcg_out_movi(TCGContext *s, TCGType type,
642 TCGReg ret, tcg_target_long sval)
644 tcg_out_movi_int(s, type, ret, sval, false);
647 /* Emit a load/store type instruction. Inputs are:
648 DATA: The register to be loaded or stored.
649 BASE+OFS: The effective address.
650 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
651 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
653 static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
654 TCGReg data, TCGReg base, TCGReg index,
657 if (ofs < -0x80000 || ofs >= 0x80000) {
658 /* Combine the low 20 bits of the offset with the actual load insn;
659 the high 44 bits must come from an immediate load. */
660 tcg_target_long low = ((ofs & 0xfffff) ^ 0x80000) - 0x80000;
661 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - low);
664 /* If we were already given an index register, add it in. */
665 if (index != TCG_REG_NONE) {
666 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
671 if (opc_rx && ofs >= 0 && ofs < 0x1000) {
672 tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
674 tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
679 /* load data without address translation or endianness conversion */
680 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
681 TCGReg base, intptr_t ofs)
683 if (type == TCG_TYPE_I32) {
684 tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
686 tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
690 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
691 TCGReg base, intptr_t ofs)
693 if (type == TCG_TYPE_I32) {
694 tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
696 tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
700 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
701 TCGReg base, intptr_t ofs)
706 /* load data from an absolute host address */
707 static void tcg_out_ld_abs(TCGContext *s, TCGType type,
708 TCGReg dest, const void *abs)
710 intptr_t addr = (intptr_t)abs;
712 if ((s390_facilities & FACILITY_GEN_INST_EXT) && !(addr & 1)) {
713 ptrdiff_t disp = tcg_pcrel_diff(s, abs) >> 1;
714 if (disp == (int32_t)disp) {
715 if (type == TCG_TYPE_I32) {
716 tcg_out_insn(s, RIL, LRL, dest, disp);
718 tcg_out_insn(s, RIL, LGRL, dest, disp);
724 ptrdiff_t disp = tcg_tbrel_diff(s, abs);
725 if (disp == sextract64(disp, 0, 20)) {
726 tcg_out_ld(s, type, dest, TCG_REG_TB, disp);
731 tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
732 tcg_out_ld(s, type, dest, dest, addr & 0xffff);
735 static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
736 int msb, int lsb, int ofs, int z)
739 tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src);
740 tcg_out16(s, (msb << 8) | (z << 7) | lsb);
741 tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff));
744 static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
746 if (s390_facilities & FACILITY_EXT_IMM) {
747 tcg_out_insn(s, RRE, LGBR, dest, src);
751 if (type == TCG_TYPE_I32) {
753 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
755 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
757 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
759 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
760 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
764 static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
766 if (s390_facilities & FACILITY_EXT_IMM) {
767 tcg_out_insn(s, RRE, LLGCR, dest, src);
772 tcg_out_movi(s, type, TCG_TMP0, 0xff);
775 tcg_out_movi(s, type, dest, 0xff);
777 if (type == TCG_TYPE_I32) {
778 tcg_out_insn(s, RR, NR, dest, src);
780 tcg_out_insn(s, RRE, NGR, dest, src);
784 static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
786 if (s390_facilities & FACILITY_EXT_IMM) {
787 tcg_out_insn(s, RRE, LGHR, dest, src);
791 if (type == TCG_TYPE_I32) {
793 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
795 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
797 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
799 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
800 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
804 static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
806 if (s390_facilities & FACILITY_EXT_IMM) {
807 tcg_out_insn(s, RRE, LLGHR, dest, src);
812 tcg_out_movi(s, type, TCG_TMP0, 0xffff);
815 tcg_out_movi(s, type, dest, 0xffff);
817 if (type == TCG_TYPE_I32) {
818 tcg_out_insn(s, RR, NR, dest, src);
820 tcg_out_insn(s, RRE, NGR, dest, src);
824 static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
826 tcg_out_insn(s, RRE, LGFR, dest, src);
829 static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
831 tcg_out_insn(s, RRE, LLGFR, dest, src);
834 /* Accept bit patterns like these:
839 Copied from gcc sources. */
840 static inline bool risbg_mask(uint64_t c)
843 /* We don't change the number of transitions by inverting,
844 so make sure we start with the LSB zero. */
848 /* Reject all zeros or all ones. */
852 /* Find the first transition. */
854 /* Invert to look for a second transition. */
856 /* Erase the first transition. */
858 /* Find the second transition, if any. */
860 /* Match if all the bits are 1's, or if c is zero. */
864 static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
867 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
868 /* Achieve wraparound by swapping msb and lsb. */
869 msb = 64 - ctz64(~val);
870 lsb = clz64(~val) - 1;
873 lsb = 63 - ctz64(val);
875 tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
878 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
880 static const S390Opcode ni_insns[4] = {
881 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
883 static const S390Opcode nif_insns[2] = {
886 uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
889 /* Look for the zero-extensions. */
890 if ((val & valid) == 0xffffffff) {
891 tgen_ext32u(s, dest, dest);
894 if (s390_facilities & FACILITY_EXT_IMM) {
895 if ((val & valid) == 0xff) {
896 tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
899 if ((val & valid) == 0xffff) {
900 tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
905 /* Try all 32-bit insns that can perform it in one go. */
906 for (i = 0; i < 4; i++) {
907 tcg_target_ulong mask = ~(0xffffull << i*16);
908 if (((val | ~valid) & mask) == mask) {
909 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
914 /* Try all 48-bit insns that can perform it in one go. */
915 if (s390_facilities & FACILITY_EXT_IMM) {
916 for (i = 0; i < 2; i++) {
917 tcg_target_ulong mask = ~(0xffffffffull << i*32);
918 if (((val | ~valid) & mask) == mask) {
919 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
924 if ((s390_facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) {
925 tgen_andi_risbg(s, dest, dest, val);
929 /* Use the constant pool if USE_REG_TB, but not for small constants. */
931 if (!maybe_out_small_movi(s, type, TCG_TMP0, val)) {
932 tcg_out_insn(s, RXY, NG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
933 new_pool_label(s, val & valid, R_390_20, s->code_ptr - 2,
934 tcg_tbrel_diff(s, NULL));
938 tcg_out_movi(s, type, TCG_TMP0, val);
940 if (type == TCG_TYPE_I32) {
941 tcg_out_insn(s, RR, NR, dest, TCG_TMP0);
943 tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
947 static void tgen_ori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
949 static const S390Opcode oi_insns[4] = {
950 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
952 static const S390Opcode oif_insns[2] = {
958 /* Look for no-op. */
959 if (unlikely(val == 0)) {
963 /* Try all 32-bit insns that can perform it in one go. */
964 for (i = 0; i < 4; i++) {
965 tcg_target_ulong mask = (0xffffull << i*16);
966 if ((val & mask) != 0 && (val & ~mask) == 0) {
967 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
972 /* Try all 48-bit insns that can perform it in one go. */
973 if (s390_facilities & FACILITY_EXT_IMM) {
974 for (i = 0; i < 2; i++) {
975 tcg_target_ulong mask = (0xffffffffull << i*32);
976 if ((val & mask) != 0 && (val & ~mask) == 0) {
977 tcg_out_insn_RIL(s, oif_insns[i], dest, val >> i*32);
983 /* Use the constant pool if USE_REG_TB, but not for small constants. */
984 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
985 if (type == TCG_TYPE_I32) {
986 tcg_out_insn(s, RR, OR, dest, TCG_TMP0);
988 tcg_out_insn(s, RRE, OGR, dest, TCG_TMP0);
990 } else if (USE_REG_TB) {
991 tcg_out_insn(s, RXY, OG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
992 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
993 tcg_tbrel_diff(s, NULL));
995 /* Perform the OR via sequential modifications to the high and
996 low parts. Do this via recursion to handle 16-bit vs 32-bit
997 masks in each half. */
998 tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
999 tgen_ori(s, type, dest, val & 0x00000000ffffffffull);
1000 tgen_ori(s, type, dest, val & 0xffffffff00000000ull);
1004 static void tgen_xori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
1006 /* Try all 48-bit insns that can perform it in one go. */
1007 if (s390_facilities & FACILITY_EXT_IMM) {
1008 if ((val & 0xffffffff00000000ull) == 0) {
1009 tcg_out_insn(s, RIL, XILF, dest, val);
1012 if ((val & 0x00000000ffffffffull) == 0) {
1013 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1018 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1019 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1020 if (type == TCG_TYPE_I32) {
1021 tcg_out_insn(s, RR, XR, dest, TCG_TMP0);
1023 tcg_out_insn(s, RRE, XGR, dest, TCG_TMP0);
1025 } else if (USE_REG_TB) {
1026 tcg_out_insn(s, RXY, XG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1027 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
1028 tcg_tbrel_diff(s, NULL));
1030 /* Perform the xor by parts. */
1031 tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
1032 if (val & 0xffffffff) {
1033 tcg_out_insn(s, RIL, XILF, dest, val);
1035 if (val > 0xffffffff) {
1036 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1041 static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1042 TCGArg c2, bool c2const, bool need_carry)
1044 bool is_unsigned = is_unsigned_cond(c);
1049 if (!(is_unsigned && need_carry)) {
1050 if (type == TCG_TYPE_I32) {
1051 tcg_out_insn(s, RR, LTR, r1, r1);
1053 tcg_out_insn(s, RRE, LTGR, r1, r1);
1055 return tcg_cond_to_ltr_cond[c];
1059 if (!is_unsigned && c2 == (int16_t)c2) {
1060 op = (type == TCG_TYPE_I32 ? RI_CHI : RI_CGHI);
1061 tcg_out_insn_RI(s, op, r1, c2);
1065 if (s390_facilities & FACILITY_EXT_IMM) {
1066 if (type == TCG_TYPE_I32) {
1067 op = (is_unsigned ? RIL_CLFI : RIL_CFI);
1068 tcg_out_insn_RIL(s, op, r1, c2);
1070 } else if (c2 == (is_unsigned ? (TCGArg)(uint32_t)c2 : (TCGArg)(int32_t)c2)) {
1071 op = (is_unsigned ? RIL_CLGFI : RIL_CGFI);
1072 tcg_out_insn_RIL(s, op, r1, c2);
1077 /* Use the constant pool, but not for small constants. */
1078 if (maybe_out_small_movi(s, type, TCG_TMP0, c2)) {
1080 /* fall through to reg-reg */
1081 } else if (USE_REG_TB) {
1082 if (type == TCG_TYPE_I32) {
1083 op = (is_unsigned ? RXY_CLY : RXY_CY);
1084 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1085 new_pool_label(s, (uint32_t)c2, R_390_20, s->code_ptr - 2,
1086 4 - tcg_tbrel_diff(s, NULL));
1088 op = (is_unsigned ? RXY_CLG : RXY_CG);
1089 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1090 new_pool_label(s, c2, R_390_20, s->code_ptr - 2,
1091 tcg_tbrel_diff(s, NULL));
1095 if (type == TCG_TYPE_I32) {
1096 op = (is_unsigned ? RIL_CLRL : RIL_CRL);
1097 tcg_out_insn_RIL(s, op, r1, 0);
1098 new_pool_label(s, (uint32_t)c2, R_390_PC32DBL,
1099 s->code_ptr - 2, 2 + 4);
1101 op = (is_unsigned ? RIL_CLGRL : RIL_CGRL);
1102 tcg_out_insn_RIL(s, op, r1, 0);
1103 new_pool_label(s, c2, R_390_PC32DBL, s->code_ptr - 2, 2);
1109 if (type == TCG_TYPE_I32) {
1110 op = (is_unsigned ? RR_CLR : RR_CR);
1111 tcg_out_insn_RR(s, op, r1, c2);
1113 op = (is_unsigned ? RRE_CLGR : RRE_CGR);
1114 tcg_out_insn_RRE(s, op, r1, c2);
1118 return tcg_cond_to_s390_cond[c];
1121 static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
1122 TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
1127 /* With LOC2, we can always emit the minimum 3 insns. */
1128 if (s390_facilities & FACILITY_LOAD_ON_COND2) {
1129 /* Emit: d = 0, d = (cc ? 1 : d). */
1130 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1131 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1132 tcg_out_insn(s, RIE, LOCGHI, dest, 1, cc);
1136 have_loc = (s390_facilities & FACILITY_LOAD_ON_COND) != 0;
1138 /* For HAVE_LOC, only the paths through GTU/GT/LEU/LE are smaller. */
1142 /* X != 0 is X > 0. */
1143 if (c2const && c2 == 0) {
1144 cond = TCG_COND_GTU;
1152 /* The result of a compare has CC=2 for GT and CC=3 unused.
1153 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1154 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1155 tcg_out_movi(s, type, dest, 0);
1156 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1160 /* X == 0 is X <= 0. */
1161 if (c2const && c2 == 0) {
1162 cond = TCG_COND_LEU;
1170 /* As above, but we're looking for borrow, or !carry.
1171 The second insn computes d - d - borrow, or -1 for true
1172 and 0 for false. So we must mask to 1 bit afterward. */
1173 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1174 tcg_out_insn(s, RRE, SLBGR, dest, dest);
1175 tgen_andi(s, type, dest, 1);
1182 /* Swap operands so that we can use LEU/GTU/GT/LE. */
1187 tcg_out_movi(s, type, TCG_TMP0, c2);
1196 cond = tcg_swap_cond(cond);
1200 g_assert_not_reached();
1203 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1205 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1206 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1207 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1208 tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);
1210 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1211 tcg_out_movi(s, type, dest, 1);
1212 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1213 tcg_out_movi(s, type, dest, 0);
1217 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
1218 TCGReg c1, TCGArg c2, int c2const,
1219 TCGArg v3, int v3const)
1222 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1223 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1225 tcg_out_insn(s, RIE, LOCGHI, dest, v3, cc);
1227 tcg_out_insn(s, RRF, LOCGR, dest, v3, cc);
1230 c = tcg_invert_cond(c);
1231 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1233 /* Emit: if (cc) goto over; dest = r3; over: */
1234 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1235 tcg_out_insn(s, RRE, LGR, dest, v3);
1239 static void tgen_clz(TCGContext *s, TCGReg dest, TCGReg a1,
1240 TCGArg a2, int a2const)
1242 /* Since this sets both R and R+1, we have no choice but to store the
1243 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1244 QEMU_BUILD_BUG_ON(TCG_TMP0 != TCG_REG_R1);
1245 tcg_out_insn(s, RRE, FLOGR, TCG_REG_R0, a1);
1247 if (a2const && a2 == 64) {
1248 tcg_out_mov(s, TCG_TYPE_I64, dest, TCG_REG_R0);
1251 tcg_out_movi(s, TCG_TYPE_I64, dest, a2);
1253 tcg_out_mov(s, TCG_TYPE_I64, dest, a2);
1255 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1256 /* Emit: if (one bit found) dest = r0. */
1257 tcg_out_insn(s, RRF, LOCGR, dest, TCG_REG_R0, 2);
1259 /* Emit: if (no one bit found) goto over; dest = r0; over: */
1260 tcg_out_insn(s, RI, BRC, 8, (4 + 4) >> 1);
1261 tcg_out_insn(s, RRE, LGR, dest, TCG_REG_R0);
1266 static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
1267 int ofs, int len, int z)
1269 int lsb = (63 - ofs);
1270 int msb = lsb - (len - 1);
1271 tcg_out_risbg(s, dest, src, msb, lsb, ofs, z);
1274 static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
1277 tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
1280 static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
1282 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1283 if (off == (int16_t)off) {
1284 tcg_out_insn(s, RI, BRC, cc, off);
1285 } else if (off == (int32_t)off) {
1286 tcg_out_insn(s, RIL, BRCL, cc, off);
1288 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1289 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1293 static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
1296 tgen_gotoi(s, cc, l->u.value_ptr);
1297 } else if (USE_LONG_BRANCHES) {
1298 tcg_out16(s, RIL_BRCL | (cc << 4));
1299 tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, l, 2);
1302 tcg_out16(s, RI_BRC | (cc << 4));
1303 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, 2);
1308 static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1309 TCGReg r1, TCGReg r2, TCGLabel *l)
1311 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1312 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1314 tcg_out16(s, cc << 12 | (opc & 0xff));
1317 static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1318 TCGReg r1, int i2, TCGLabel *l)
1320 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1321 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1323 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1326 static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1327 TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
1331 if (s390_facilities & FACILITY_GEN_INST_EXT) {
1332 bool is_unsigned = is_unsigned_cond(c);
1336 cc = tcg_cond_to_s390_cond[c];
1339 opc = (type == TCG_TYPE_I32
1340 ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1341 : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1342 tgen_compare_branch(s, opc, cc, r1, c2, l);
1346 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1347 If the immediate we've been given does not fit that range, we'll
1348 fall back to separate compare and branch instructions using the
1349 larger comparison range afforded by COMPARE IMMEDIATE. */
1350 if (type == TCG_TYPE_I32) {
1353 in_range = (uint32_t)c2 == (uint8_t)c2;
1356 in_range = (int32_t)c2 == (int8_t)c2;
1361 in_range = (uint64_t)c2 == (uint8_t)c2;
1364 in_range = (int64_t)c2 == (int8_t)c2;
1368 tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
1373 cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
1374 tgen_branch(s, cc, l);
1377 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
1379 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1380 if (off == (int32_t)off) {
1381 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1383 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1384 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1388 static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
1389 TCGReg base, TCGReg index, int disp)
1391 switch (opc & (MO_SSIZE | MO_BSWAP)) {
1393 tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1396 tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1399 case MO_UW | MO_BSWAP:
1400 /* swapped unsigned halfword load with upper bits zeroed */
1401 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1402 tgen_ext16u(s, TCG_TYPE_I64, data, data);
1405 tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1408 case MO_SW | MO_BSWAP:
1409 /* swapped sign-extended halfword load */
1410 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1411 tgen_ext16s(s, TCG_TYPE_I64, data, data);
1414 tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1417 case MO_UL | MO_BSWAP:
1418 /* swapped unsigned int load with upper bits zeroed */
1419 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1420 tgen_ext32u(s, data, data);
1423 tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1426 case MO_SL | MO_BSWAP:
1427 /* swapped sign-extended int load */
1428 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1429 tgen_ext32s(s, data, data);
1432 tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1435 case MO_Q | MO_BSWAP:
1436 tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1439 tcg_out_insn(s, RXY, LG, data, base, index, disp);
1447 static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data,
1448 TCGReg base, TCGReg index, int disp)
1450 switch (opc & (MO_SIZE | MO_BSWAP)) {
1452 if (disp >= 0 && disp < 0x1000) {
1453 tcg_out_insn(s, RX, STC, data, base, index, disp);
1455 tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1459 case MO_UW | MO_BSWAP:
1460 tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1463 if (disp >= 0 && disp < 0x1000) {
1464 tcg_out_insn(s, RX, STH, data, base, index, disp);
1466 tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1470 case MO_UL | MO_BSWAP:
1471 tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1474 if (disp >= 0 && disp < 0x1000) {
1475 tcg_out_insn(s, RX, ST, data, base, index, disp);
1477 tcg_out_insn(s, RXY, STY, data, base, index, disp);
1481 case MO_Q | MO_BSWAP:
1482 tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1485 tcg_out_insn(s, RXY, STG, data, base, index, disp);
1493 #if defined(CONFIG_SOFTMMU)
1494 #include "../tcg-ldst.c.inc"
1496 /* We're expecting to use a 20-bit negative offset on the tlb memory ops. */
1497 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1498 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 19));
1500 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1501 addend into R2. Returns a register with the santitized guest address. */
1502 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc,
1503 int mem_index, bool is_ld)
1505 unsigned s_bits = opc & MO_SIZE;
1506 unsigned a_bits = get_alignment_bits(opc);
1507 unsigned s_mask = (1 << s_bits) - 1;
1508 unsigned a_mask = (1 << a_bits) - 1;
1509 int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1510 int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1511 int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1515 tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
1516 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1517 tcg_out_insn(s, RXY, NG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, mask_off);
1518 tcg_out_insn(s, RXY, AG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, table_off);
1520 /* For aligned accesses, we check the first byte and include the alignment
1521 bits within the address. For unaligned access, we check that we don't
1522 cross pages using the address of the last byte of the access. */
1523 a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
1524 tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
1525 if ((s390_facilities & FACILITY_GEN_INST_EXT) && a_off == 0) {
1526 tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
1528 tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
1529 tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
1533 ofs = offsetof(CPUTLBEntry, addr_read);
1535 ofs = offsetof(CPUTLBEntry, addr_write);
1537 if (TARGET_LONG_BITS == 32) {
1538 tcg_out_insn(s, RX, C, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1540 tcg_out_insn(s, RXY, CG, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1543 tcg_out_insn(s, RXY, LG, TCG_REG_R2, TCG_REG_R2, TCG_REG_NONE,
1544 offsetof(CPUTLBEntry, addend));
1546 if (TARGET_LONG_BITS == 32) {
1547 tgen_ext32u(s, TCG_REG_R3, addr_reg);
1553 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1554 TCGReg data, TCGReg addr,
1555 tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
1557 TCGLabelQemuLdst *label = new_ldst_label(s);
1559 label->is_ld = is_ld;
1561 label->datalo_reg = data;
1562 label->addrlo_reg = addr;
1563 label->raddr = tcg_splitwx_to_rx(raddr);
1564 label->label_ptr[0] = label_ptr;
1567 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1569 TCGReg addr_reg = lb->addrlo_reg;
1570 TCGReg data_reg = lb->datalo_reg;
1571 TCGMemOpIdx oi = lb->oi;
1572 MemOp opc = get_memop(oi);
1574 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1575 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1579 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1580 if (TARGET_LONG_BITS == 64) {
1581 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1583 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, oi);
1584 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R5, (uintptr_t)lb->raddr);
1585 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)]);
1586 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1588 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1592 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1594 TCGReg addr_reg = lb->addrlo_reg;
1595 TCGReg data_reg = lb->datalo_reg;
1596 TCGMemOpIdx oi = lb->oi;
1597 MemOp opc = get_memop(oi);
1599 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1600 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1604 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1605 if (TARGET_LONG_BITS == 64) {
1606 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1608 switch (opc & MO_SIZE) {
1610 tgen_ext8u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1613 tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1616 tgen_ext32u(s, TCG_REG_R4, data_reg);
1619 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1624 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
1625 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
1626 tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1628 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1632 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1633 TCGReg *index_reg, tcg_target_long *disp)
1635 if (TARGET_LONG_BITS == 32) {
1636 tgen_ext32u(s, TCG_TMP0, *addr_reg);
1637 *addr_reg = TCG_TMP0;
1639 if (guest_base < 0x80000) {
1640 *index_reg = TCG_REG_NONE;
1643 *index_reg = TCG_GUEST_BASE_REG;
1647 #endif /* CONFIG_SOFTMMU */
1649 static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1652 MemOp opc = get_memop(oi);
1653 #ifdef CONFIG_SOFTMMU
1654 unsigned mem_index = get_mmuidx(oi);
1655 tcg_insn_unit *label_ptr;
1658 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 1);
1660 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1661 label_ptr = s->code_ptr;
1664 tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1666 add_qemu_ldst_label(s, 1, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1669 tcg_target_long disp;
1671 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1672 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1676 static void tcg_out_qemu_st(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, 0);
1687 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1688 label_ptr = s->code_ptr;
1691 tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1693 add_qemu_ldst_label(s, 0, 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_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1703 # define OP_32_64(x) \
1704 case glue(glue(INDEX_op_,x),_i32): \
1705 case glue(glue(INDEX_op_,x),_i64)
1707 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1708 const TCGArg *args, const int *const_args)
1714 case INDEX_op_exit_tb:
1715 /* Reuse the zeroing that exists for goto_ptr. */
1718 tgen_gotoi(s, S390_CC_ALWAYS, tcg_code_gen_epilogue);
1720 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, a0);
1721 tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
1725 case INDEX_op_goto_tb:
1727 if (s->tb_jmp_insn_offset) {
1729 * branch displacement must be aligned for atomic patching;
1730 * see if we need to add extra nop before branch
1732 if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
1735 tcg_debug_assert(!USE_REG_TB);
1736 tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
1737 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1740 /* load address stored at s->tb_jmp_target_addr + a0 */
1741 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_REG_TB,
1742 tcg_splitwx_to_rx(s->tb_jmp_target_addr + a0));
1744 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_TB);
1746 set_jmp_reset_offset(s, a0);
1748 /* For the unlinked path of goto_tb, we need to reset
1749 TCG_REG_TB to the beginning of this TB. */
1751 int ofs = -tcg_current_code_size(s);
1752 /* All TB are restricted to 64KiB by unwind info. */
1753 tcg_debug_assert(ofs == sextract64(ofs, 0, 20));
1754 tcg_out_insn(s, RXY, LAY, TCG_REG_TB,
1755 TCG_REG_TB, TCG_REG_NONE, ofs);
1759 case INDEX_op_goto_ptr:
1762 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, a0);
1764 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, a0);
1768 /* ??? LLC (RXY format) is only present with the extended-immediate
1769 facility, whereas LLGC is always present. */
1770 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1774 /* ??? LB is no smaller than LGB, so no point to using it. */
1775 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1779 /* ??? LLH (RXY format) is only present with the extended-immediate
1780 facility, whereas LLGH is always present. */
1781 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1784 case INDEX_op_ld16s_i32:
1785 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1788 case INDEX_op_ld_i32:
1789 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1793 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1794 TCG_REG_NONE, args[2]);
1798 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1799 TCG_REG_NONE, args[2]);
1802 case INDEX_op_st_i32:
1803 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1806 case INDEX_op_add_i32:
1807 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1808 if (const_args[2]) {
1811 if (a2 == (int16_t)a2) {
1812 tcg_out_insn(s, RI, AHI, a0, a2);
1815 if (s390_facilities & FACILITY_EXT_IMM) {
1816 tcg_out_insn(s, RIL, AFI, a0, a2);
1820 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1821 } else if (a0 == a1) {
1822 tcg_out_insn(s, RR, AR, a0, a2);
1824 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1827 case INDEX_op_sub_i32:
1828 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1829 if (const_args[2]) {
1832 } else if (a0 == a1) {
1833 tcg_out_insn(s, RR, SR, a0, a2);
1835 tcg_out_insn(s, RRF, SRK, a0, a1, a2);
1839 case INDEX_op_and_i32:
1840 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1841 if (const_args[2]) {
1842 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1843 tgen_andi(s, TCG_TYPE_I32, a0, a2);
1844 } else if (a0 == a1) {
1845 tcg_out_insn(s, RR, NR, a0, a2);
1847 tcg_out_insn(s, RRF, NRK, a0, a1, a2);
1850 case INDEX_op_or_i32:
1851 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1852 if (const_args[2]) {
1853 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1854 tgen_ori(s, TCG_TYPE_I32, a0, a2);
1855 } else if (a0 == a1) {
1856 tcg_out_insn(s, RR, OR, a0, a2);
1858 tcg_out_insn(s, RRF, ORK, a0, a1, a2);
1861 case INDEX_op_xor_i32:
1862 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1863 if (const_args[2]) {
1864 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1865 tgen_xori(s, TCG_TYPE_I32, a0, a2);
1866 } else if (a0 == a1) {
1867 tcg_out_insn(s, RR, XR, args[0], args[2]);
1869 tcg_out_insn(s, RRF, XRK, a0, a1, a2);
1873 case INDEX_op_neg_i32:
1874 tcg_out_insn(s, RR, LCR, args[0], args[1]);
1877 case INDEX_op_mul_i32:
1878 if (const_args[2]) {
1879 if ((int32_t)args[2] == (int16_t)args[2]) {
1880 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1882 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1885 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1889 case INDEX_op_div2_i32:
1890 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1892 case INDEX_op_divu2_i32:
1893 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1896 case INDEX_op_shl_i32:
1900 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1902 if (const_args[2]) {
1903 tcg_out_sh32(s, op, a0, TCG_REG_NONE, a2);
1905 tcg_out_sh32(s, op, a0, a2, 0);
1908 /* Using tcg_out_sh64 here for the format; it is a 32-bit shift. */
1909 if (const_args[2]) {
1910 tcg_out_sh64(s, op2, a0, a1, TCG_REG_NONE, a2);
1912 tcg_out_sh64(s, op2, a0, a1, a2, 0);
1916 case INDEX_op_shr_i32:
1920 case INDEX_op_sar_i32:
1925 case INDEX_op_rotl_i32:
1926 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1927 if (const_args[2]) {
1928 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1930 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1933 case INDEX_op_rotr_i32:
1934 if (const_args[2]) {
1935 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1936 TCG_REG_NONE, (32 - args[2]) & 31);
1938 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1939 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1943 case INDEX_op_ext8s_i32:
1944 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1946 case INDEX_op_ext16s_i32:
1947 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1949 case INDEX_op_ext8u_i32:
1950 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1952 case INDEX_op_ext16u_i32:
1953 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1957 /* The TCG bswap definition requires bits 0-47 already be zero.
1958 Thus we don't need the G-type insns to implement bswap16_i64. */
1959 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1960 tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1963 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1966 case INDEX_op_add2_i32:
1967 if (const_args[4]) {
1968 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
1970 tcg_out_insn(s, RR, ALR, args[0], args[4]);
1972 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
1974 case INDEX_op_sub2_i32:
1975 if (const_args[4]) {
1976 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
1978 tcg_out_insn(s, RR, SLR, args[0], args[4]);
1980 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
1984 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
1987 case INDEX_op_brcond_i32:
1988 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1989 args[1], const_args[1], arg_label(args[3]));
1991 case INDEX_op_setcond_i32:
1992 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1993 args[2], const_args[2]);
1995 case INDEX_op_movcond_i32:
1996 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
1997 args[2], const_args[2], args[3], const_args[3]);
2000 case INDEX_op_qemu_ld_i32:
2001 /* ??? Technically we can use a non-extending instruction. */
2002 case INDEX_op_qemu_ld_i64:
2003 tcg_out_qemu_ld(s, args[0], args[1], args[2]);
2005 case INDEX_op_qemu_st_i32:
2006 case INDEX_op_qemu_st_i64:
2007 tcg_out_qemu_st(s, args[0], args[1], args[2]);
2010 case INDEX_op_ld16s_i64:
2011 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
2013 case INDEX_op_ld32u_i64:
2014 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
2016 case INDEX_op_ld32s_i64:
2017 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
2019 case INDEX_op_ld_i64:
2020 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2023 case INDEX_op_st32_i64:
2024 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2026 case INDEX_op_st_i64:
2027 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2030 case INDEX_op_add_i64:
2031 a0 = args[0], a1 = args[1], a2 = args[2];
2032 if (const_args[2]) {
2035 if (a2 == (int16_t)a2) {
2036 tcg_out_insn(s, RI, AGHI, a0, a2);
2039 if (s390_facilities & FACILITY_EXT_IMM) {
2040 if (a2 == (int32_t)a2) {
2041 tcg_out_insn(s, RIL, AGFI, a0, a2);
2043 } else if (a2 == (uint32_t)a2) {
2044 tcg_out_insn(s, RIL, ALGFI, a0, a2);
2046 } else if (-a2 == (uint32_t)-a2) {
2047 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2052 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2053 } else if (a0 == a1) {
2054 tcg_out_insn(s, RRE, AGR, a0, a2);
2056 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2059 case INDEX_op_sub_i64:
2060 a0 = args[0], a1 = args[1], a2 = args[2];
2061 if (const_args[2]) {
2064 } else if (a0 == a1) {
2065 tcg_out_insn(s, RRE, SGR, a0, a2);
2067 tcg_out_insn(s, RRF, SGRK, a0, a1, a2);
2071 case INDEX_op_and_i64:
2072 a0 = args[0], a1 = args[1], a2 = args[2];
2073 if (const_args[2]) {
2074 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2075 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2076 } else if (a0 == a1) {
2077 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2079 tcg_out_insn(s, RRF, NGRK, a0, a1, a2);
2082 case INDEX_op_or_i64:
2083 a0 = args[0], a1 = args[1], a2 = args[2];
2084 if (const_args[2]) {
2085 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2086 tgen_ori(s, TCG_TYPE_I64, a0, a2);
2087 } else if (a0 == a1) {
2088 tcg_out_insn(s, RRE, OGR, a0, a2);
2090 tcg_out_insn(s, RRF, OGRK, a0, a1, a2);
2093 case INDEX_op_xor_i64:
2094 a0 = args[0], a1 = args[1], a2 = args[2];
2095 if (const_args[2]) {
2096 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2097 tgen_xori(s, TCG_TYPE_I64, a0, a2);
2098 } else if (a0 == a1) {
2099 tcg_out_insn(s, RRE, XGR, a0, a2);
2101 tcg_out_insn(s, RRF, XGRK, a0, a1, a2);
2105 case INDEX_op_neg_i64:
2106 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2108 case INDEX_op_bswap64_i64:
2109 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2112 case INDEX_op_mul_i64:
2113 if (const_args[2]) {
2114 if (args[2] == (int16_t)args[2]) {
2115 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2117 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2120 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2124 case INDEX_op_div2_i64:
2125 /* ??? We get an unnecessary sign-extension of the dividend
2126 into R3 with this definition, but as we do in fact always
2127 produce both quotient and remainder using INDEX_op_div_i64
2128 instead requires jumping through even more hoops. */
2129 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2131 case INDEX_op_divu2_i64:
2132 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2134 case INDEX_op_mulu2_i64:
2135 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2138 case INDEX_op_shl_i64:
2141 if (const_args[2]) {
2142 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2144 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2147 case INDEX_op_shr_i64:
2150 case INDEX_op_sar_i64:
2154 case INDEX_op_rotl_i64:
2155 if (const_args[2]) {
2156 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2157 TCG_REG_NONE, args[2]);
2159 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2162 case INDEX_op_rotr_i64:
2163 if (const_args[2]) {
2164 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2165 TCG_REG_NONE, (64 - args[2]) & 63);
2167 /* We can use the smaller 32-bit negate because only the
2168 low 6 bits are examined for the rotate. */
2169 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2170 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2174 case INDEX_op_ext8s_i64:
2175 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2177 case INDEX_op_ext16s_i64:
2178 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2180 case INDEX_op_ext_i32_i64:
2181 case INDEX_op_ext32s_i64:
2182 tgen_ext32s(s, args[0], args[1]);
2184 case INDEX_op_ext8u_i64:
2185 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2187 case INDEX_op_ext16u_i64:
2188 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2190 case INDEX_op_extu_i32_i64:
2191 case INDEX_op_ext32u_i64:
2192 tgen_ext32u(s, args[0], args[1]);
2195 case INDEX_op_add2_i64:
2196 if (const_args[4]) {
2197 if ((int64_t)args[4] >= 0) {
2198 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2200 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2203 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2205 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2207 case INDEX_op_sub2_i64:
2208 if (const_args[4]) {
2209 if ((int64_t)args[4] >= 0) {
2210 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2212 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2215 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2217 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2220 case INDEX_op_brcond_i64:
2221 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2222 args[1], const_args[1], arg_label(args[3]));
2224 case INDEX_op_setcond_i64:
2225 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2226 args[2], const_args[2]);
2228 case INDEX_op_movcond_i64:
2229 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2230 args[2], const_args[2], args[3], const_args[3]);
2234 a0 = args[0], a1 = args[1], a2 = args[2];
2235 if (const_args[1]) {
2236 tgen_deposit(s, a0, a2, args[3], args[4], 1);
2238 /* Since we can't support "0Z" as a constraint, we allow a1 in
2239 any register. Fix things up as if a matching constraint. */
2241 TCGType type = (opc == INDEX_op_deposit_i64);
2243 tcg_out_mov(s, type, TCG_TMP0, a2);
2246 tcg_out_mov(s, type, a0, a1);
2248 tgen_deposit(s, a0, a2, args[3], args[4], 0);
2253 tgen_extract(s, args[0], args[1], args[2], args[3]);
2256 case INDEX_op_clz_i64:
2257 tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2261 /* The host memory model is quite strong, we simply need to
2262 serialize the instruction stream. */
2263 if (args[0] & TCG_MO_ST_LD) {
2264 tcg_out_insn(s, RR, BCR,
2265 s390_facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
2269 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2270 case INDEX_op_mov_i64:
2271 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2277 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
2280 case INDEX_op_goto_ptr:
2283 case INDEX_op_ld8u_i32:
2284 case INDEX_op_ld8u_i64:
2285 case INDEX_op_ld8s_i32:
2286 case INDEX_op_ld8s_i64:
2287 case INDEX_op_ld16u_i32:
2288 case INDEX_op_ld16u_i64:
2289 case INDEX_op_ld16s_i32:
2290 case INDEX_op_ld16s_i64:
2291 case INDEX_op_ld_i32:
2292 case INDEX_op_ld32u_i64:
2293 case INDEX_op_ld32s_i64:
2294 case INDEX_op_ld_i64:
2295 return C_O1_I1(r, r);
2297 case INDEX_op_st8_i32:
2298 case INDEX_op_st8_i64:
2299 case INDEX_op_st16_i32:
2300 case INDEX_op_st16_i64:
2301 case INDEX_op_st_i32:
2302 case INDEX_op_st32_i64:
2303 case INDEX_op_st_i64:
2304 return C_O0_I2(r, r);
2306 case INDEX_op_add_i32:
2307 case INDEX_op_add_i64:
2308 case INDEX_op_shl_i64:
2309 case INDEX_op_shr_i64:
2310 case INDEX_op_sar_i64:
2311 case INDEX_op_rotl_i32:
2312 case INDEX_op_rotl_i64:
2313 case INDEX_op_rotr_i32:
2314 case INDEX_op_rotr_i64:
2315 case INDEX_op_clz_i64:
2316 case INDEX_op_setcond_i32:
2317 case INDEX_op_setcond_i64:
2318 return C_O1_I2(r, r, ri);
2320 case INDEX_op_sub_i32:
2321 case INDEX_op_sub_i64:
2322 case INDEX_op_and_i32:
2323 case INDEX_op_and_i64:
2324 case INDEX_op_or_i32:
2325 case INDEX_op_or_i64:
2326 case INDEX_op_xor_i32:
2327 case INDEX_op_xor_i64:
2328 return (s390_facilities & FACILITY_DISTINCT_OPS
2330 : C_O1_I2(r, 0, ri));
2332 case INDEX_op_mul_i32:
2333 /* If we have the general-instruction-extensions, then we have
2334 MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
2335 have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
2336 return (s390_facilities & FACILITY_GEN_INST_EXT
2338 : C_O1_I2(r, 0, rI));
2340 case INDEX_op_mul_i64:
2341 return (s390_facilities & FACILITY_GEN_INST_EXT
2343 : C_O1_I2(r, 0, rI));
2345 case INDEX_op_shl_i32:
2346 case INDEX_op_shr_i32:
2347 case INDEX_op_sar_i32:
2348 return (s390_facilities & FACILITY_DISTINCT_OPS
2350 : C_O1_I2(r, 0, ri));
2352 case INDEX_op_brcond_i32:
2353 case INDEX_op_brcond_i64:
2354 return C_O0_I2(r, ri);
2356 case INDEX_op_bswap16_i32:
2357 case INDEX_op_bswap16_i64:
2358 case INDEX_op_bswap32_i32:
2359 case INDEX_op_bswap32_i64:
2360 case INDEX_op_bswap64_i64:
2361 case INDEX_op_neg_i32:
2362 case INDEX_op_neg_i64:
2363 case INDEX_op_ext8s_i32:
2364 case INDEX_op_ext8s_i64:
2365 case INDEX_op_ext8u_i32:
2366 case INDEX_op_ext8u_i64:
2367 case INDEX_op_ext16s_i32:
2368 case INDEX_op_ext16s_i64:
2369 case INDEX_op_ext16u_i32:
2370 case INDEX_op_ext16u_i64:
2371 case INDEX_op_ext32s_i64:
2372 case INDEX_op_ext32u_i64:
2373 case INDEX_op_ext_i32_i64:
2374 case INDEX_op_extu_i32_i64:
2375 case INDEX_op_extract_i32:
2376 case INDEX_op_extract_i64:
2377 return C_O1_I1(r, r);
2379 case INDEX_op_qemu_ld_i32:
2380 case INDEX_op_qemu_ld_i64:
2381 return C_O1_I1(r, L);
2382 case INDEX_op_qemu_st_i64:
2383 case INDEX_op_qemu_st_i32:
2384 return C_O0_I2(L, L);
2386 case INDEX_op_deposit_i32:
2387 case INDEX_op_deposit_i64:
2388 return C_O1_I2(r, rZ, r);
2390 case INDEX_op_movcond_i32:
2391 case INDEX_op_movcond_i64:
2392 return (s390_facilities & FACILITY_LOAD_ON_COND2
2393 ? C_O1_I4(r, r, ri, rI, 0)
2394 : C_O1_I4(r, r, ri, r, 0));
2396 case INDEX_op_div2_i32:
2397 case INDEX_op_div2_i64:
2398 case INDEX_op_divu2_i32:
2399 case INDEX_op_divu2_i64:
2400 return C_O2_I3(b, a, 0, 1, r);
2402 case INDEX_op_mulu2_i64:
2403 return C_O2_I2(b, a, 0, r);
2405 case INDEX_op_add2_i32:
2406 case INDEX_op_sub2_i32:
2407 return (s390_facilities & FACILITY_EXT_IMM
2408 ? C_O2_I4(r, r, 0, 1, ri, r)
2409 : C_O2_I4(r, r, 0, 1, r, r));
2411 case INDEX_op_add2_i64:
2412 case INDEX_op_sub2_i64:
2413 return (s390_facilities & FACILITY_EXT_IMM
2414 ? C_O2_I4(r, r, 0, 1, rA, r)
2415 : C_O2_I4(r, r, 0, 1, r, r));
2418 g_assert_not_reached();
2422 static void query_s390_facilities(void)
2424 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2426 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2427 is present on all 64-bit systems, but let's check for it anyway. */
2428 if (hwcap & HWCAP_S390_STFLE) {
2429 register int r0 __asm__("0");
2430 register void *r1 __asm__("1");
2433 r1 = &s390_facilities;
2434 asm volatile(".word 0xb2b0,0x1000"
2435 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2439 static void tcg_target_init(TCGContext *s)
2441 query_s390_facilities();
2443 tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
2444 tcg_target_available_regs[TCG_TYPE_I64] = 0xffff;
2446 tcg_target_call_clobber_regs = 0;
2447 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2448 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2449 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2450 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2451 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2452 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2453 /* The r6 register is technically call-saved, but it's also a parameter
2454 register, so it can get killed by setup for the qemu_st helper. */
2455 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2456 /* The return register can be considered call-clobbered. */
2457 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2459 s->reserved_regs = 0;
2460 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2461 /* XXX many insns can't be used with R0, so we better avoid it for now */
2462 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2463 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2465 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
2469 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2470 + TCG_STATIC_CALL_ARGS_SIZE \
2471 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2473 static void tcg_target_qemu_prologue(TCGContext *s)
2475 /* stmg %r6,%r15,48(%r15) (save registers) */
2476 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2478 /* aghi %r15,-frame_size */
2479 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
2481 tcg_set_frame(s, TCG_REG_CALL_STACK,
2482 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2483 CPU_TEMP_BUF_NLONGS * sizeof(long));
2485 #ifndef CONFIG_SOFTMMU
2486 if (guest_base >= 0x80000) {
2487 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
2488 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2492 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2494 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB,
2495 tcg_target_call_iarg_regs[1]);
2498 /* br %r3 (go to TB) */
2499 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2502 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2503 * and fall through to the rest of the epilogue.
2505 tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
2506 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
2509 tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
2511 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2512 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2515 /* br %r14 (return) */
2516 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2519 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
2521 memset(p, 0x07, count * sizeof(tcg_insn_unit));
2526 uint8_t fde_def_cfa[4];
2527 uint8_t fde_reg_ofs[18];
2530 /* We're expecting a 2 byte uleb128 encoded value. */
2531 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2533 #define ELF_HOST_MACHINE EM_S390
2535 static const DebugFrame debug_frame = {
2536 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2539 .h.cie.code_align = 1,
2540 .h.cie.data_align = 8, /* sleb128 8 */
2541 .h.cie.return_column = TCG_REG_R14,
2543 /* Total FDE size does not include the "len" member. */
2544 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2547 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
2548 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2552 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2553 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2554 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2555 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2556 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2557 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2558 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2559 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2560 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2564 void tcg_register_jit(const void *buf, size_t buf_size)
2566 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));