qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, Richard Henderson <rth@twiddle.net>
Subject: [Qemu-devel] [PULL 05/23] tcg/s390: Introduce TCG_REG_TB
Date: Thu,  7 Sep 2017 15:40:33 -0700	[thread overview]
Message-ID: <20170907224051.21518-6-richard.henderson@linaro.org> (raw)
In-Reply-To: <20170907224051.21518-1-richard.henderson@linaro.org>

From: Richard Henderson <rth@twiddle.net>

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/s390/tcg-target.h     |  2 +-
 tcg/s390/tcg-target.inc.c | 71 +++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 61 insertions(+), 12 deletions(-)

diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 52010c30cb..9c9c8cd464 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -95,7 +95,7 @@ extern uint64_t s390_facilities;
 #define TCG_TARGET_HAS_extrl_i64_i32  0
 #define TCG_TARGET_HAS_extrh_i64_i32  0
 #define TCG_TARGET_HAS_goto_ptr       1
-#define TCG_TARGET_HAS_direct_jump    1
+#define TCG_TARGET_HAS_direct_jump    (s390_facilities & FACILITY_GEN_INST_EXT)
 
 #define TCG_TARGET_HAS_div2_i64       1
 #define TCG_TARGET_HAS_rot_i64        1
diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c
index ee0dff995a..e007586315 100644
--- a/tcg/s390/tcg-target.inc.c
+++ b/tcg/s390/tcg-target.inc.c
@@ -51,6 +51,12 @@
 /* A scratch register that may be be used throughout the backend.  */
 #define TCG_TMP0        TCG_REG_R1
 
+/* A scratch register that holds a pointer to the beginning of the TB.
+   We don't need this when we have pc-relative loads with the general
+   instructions extension facility.  */
+#define TCG_REG_TB      TCG_REG_R12
+#define USE_REG_TB      (!(s390_facilities & FACILITY_GEN_INST_EXT))
+
 #ifndef CONFIG_SOFTMMU
 #define TCG_GUEST_BASE_REG TCG_REG_R13
 #endif
@@ -556,8 +562,8 @@ static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
 }
 
 /* load a register with an immediate value */
-static void tcg_out_movi(TCGContext *s, TCGType type,
-                         TCGReg ret, tcg_target_long sval)
+static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
+                             tcg_target_long sval, bool in_prologue)
 {
     static const S390Opcode lli_insns[4] = {
         RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
@@ -601,13 +607,22 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
         }
     }
 
-    /* Try for PC-relative address load.  */
+    /* Try for PC-relative address load.  For odd addresses,
+       attempt to use an offset from the start of the TB.  */
     if ((sval & 1) == 0) {
         ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1;
         if (off == (int32_t)off) {
             tcg_out_insn(s, RIL, LARL, ret, off);
             return;
         }
+    } else if (USE_REG_TB && !in_prologue) {
+        ptrdiff_t off = sval - (uintptr_t)s->code_gen_ptr;
+        if (off == sextract64(off, 0, 20)) {
+            /* This is certain to be an address within TB, and therefore
+               OFF will be negative; don't try RX_LA.  */
+            tcg_out_insn(s, RXY, LAY, ret, TCG_REG_TB, TCG_REG_NONE, off);
+            return;
+        }
     }
 
     /* If extended immediates are not present, then we may have to issue
@@ -663,6 +678,11 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
     }
 }
 
+static void tcg_out_movi(TCGContext *s, TCGType type,
+                         TCGReg ret, tcg_target_long sval)
+{
+    tcg_out_movi_int(s, type, ret, sval, false);
+}
 
 /* Emit a load/store type instruction.  Inputs are:
    DATA:     The register to be loaded or stored.
@@ -739,6 +759,13 @@ static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
             return;
         }
     }
+    if (USE_REG_TB) {
+        ptrdiff_t disp = abs - (void *)s->code_gen_ptr;
+        if (disp == sextract64(disp, 0, 20)) {
+            tcg_out_ld(s, type, dest, TCG_REG_TB, disp);
+            return;
+        }
+    }
 
     tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
     tcg_out_ld(s, type, dest, dest, addr & 0xffff);
@@ -1690,6 +1717,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         break;
 
     case INDEX_op_goto_tb:
+        a0 = args[0];
         if (s->tb_jmp_insn_offset) {
             /* branch displacement must be aligned for atomic patching;
              * see if we need to add extra nop before branch
@@ -1697,21 +1725,34 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
             if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
                 tcg_out16(s, NOP);
             }
+            tcg_debug_assert(!USE_REG_TB);
             tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
-            s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
+            s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
             s->code_ptr += 2;
         } else {
-            /* load address stored at s->tb_jmp_target_addr + args[0] */
-            tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0,
-                           s->tb_jmp_target_addr + args[0]);
+            /* load address stored at s->tb_jmp_target_addr + a0 */
+            tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_REG_TB,
+                           s->tb_jmp_target_addr + a0);
             /* and go there */
-            tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
+            tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_TB);
+        }
+        s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
+
+        /* For the unlinked path of goto_tb, we need to reset
+           TCG_REG_TB to the beginning of this TB.  */
+        if (USE_REG_TB) {
+            int ofs = -tcg_current_code_size(s);
+            assert(ofs == (int16_t)ofs);
+            tcg_out_insn(s, RI, AGHI, TCG_REG_TB, ofs);
         }
-        s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
         break;
 
     case INDEX_op_goto_ptr:
-        tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, args[0]);
+        a0 = args[0];
+        if (USE_REG_TB) {
+            tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, a0);
+        }
+        tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, a0);
         break;
 
     OP_32_64(ld8u):
@@ -2476,6 +2517,9 @@ static void tcg_target_init(TCGContext *s)
     /* XXX many insns can't be used with R0, so we better avoid it for now */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
+    if (USE_REG_TB) {
+        tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
+    }
 }
 
 #define FRAME_SIZE  ((int)(TCG_TARGET_CALL_STACK_OFFSET          \
@@ -2496,12 +2540,17 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 
 #ifndef CONFIG_SOFTMMU
     if (guest_base >= 0x80000) {
-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
+        tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
     }
 #endif
 
     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+    if (USE_REG_TB) {
+        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB,
+                    tcg_target_call_iarg_regs[1]);
+    }
+
     /* br %r3 (go to TB) */
     tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
 
-- 
2.13.5

  parent reply	other threads:[~2017-09-07 22:41 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-07 22:40 [Qemu-devel] [PULL 00/23] tcg constant pools and USE_DIRECT_JUMP cleanup Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 01/23] tcg: Move USE_DIRECT_JUMP discriminator to tcg/cpu/tcg-target.h Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 02/23] tcg: Rearrange ldst label tracking Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 03/23] tcg: Infrastructure for managing constant pools Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 04/23] tcg/i386: Store out-of-range call targets in constant pool Richard Henderson
2017-09-07 22:40 ` Richard Henderson [this message]
2017-09-07 22:40 ` [Qemu-devel] [PULL 06/23] tcg/s390: Fix sign of patch_reloc addend Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 07/23] tcg/s390: Use constant pool for movi Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 08/23] tcg/s390: Use constant pool for andi Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 09/23] tcg/s390: Use constant pool for ori Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 10/23] tcg/s390: Use constant pool for xori Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 11/23] tcg/s390: Use constant pool for cmpi Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 12/23] tcg/aarch64: Use constant pool for movi Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 13/23] tcg/sparc: Introduce TCG_REG_TB Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 14/23] tcg/sparc: Use constant pool for movi Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 15/23] tcg/arm: Improve tlb load for armv7 Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 16/23] tcg/arm: Tighten tlb indexing offset test Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 17/23] tcg/arm: Code rearrangement Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 18/23] tcg/arm: Extract INSN_NOP Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 19/23] tcg/arm: Use constant pool for movi Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 20/23] tcg/arm: Use constant pool for call Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 21/23] tcg/ppc: Change TCG_REG_RA to TCG_REG_TB Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 22/23] tcg/ppc: Look for shifted constants Richard Henderson
2017-09-07 22:40 ` [Qemu-devel] [PULL 23/23] tcg/ppc: Use constant pool for movi Richard Henderson
2017-09-08 11:56 ` [Qemu-devel] [PULL 00/23] tcg constant pools and USE_DIRECT_JUMP cleanup Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170907224051.21518-6-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).