qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed
@ 2010-05-06 15:50 Richard Henderson
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 1/5] tcg: Initialize the prologue after GUEST_BASE is fixed Richard Henderson
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Richard Henderson @ 2010-05-06 15:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

By doing this we can make any number of decisions about code generation
during the prologue.  For instance, we can decide whether or not to
reserve a register to hold the value of GUEST_BASE.

This fixes a latent bug in the two ppc ports in that GUEST_BASE was 
being loaded as an immediate before the final value of GUEST_BASE is
computed.

This also fixes some register reservation problems I noticed in the
ia64 port, while trying to decide which register to use for holding
GUEST_BASE across the TB.


r~



Richard Henderson (5):
  tcg: Initialize the prologue after GUEST_BASE is fixed.
  tcg-hppa: Load GUEST_BASE as an immediate.
  tcg-ia64: Fix some register usage issues.
  tcg-ia64: Load GUEST_BASE into a register.
  tcg-ppc: Conditionally reserve TCG_GUEST_BASE_REG.

 bsd-user/main.c        |    9 ++-
 exec.c                 |    5 +
 linux-user/main.c      |    9 ++-
 tcg/hppa/tcg-target.c  |   12 +--
 tcg/ia64/tcg-target.c  |  199 +++++++++++++++++++++++++++++++-----------------
 tcg/ppc/tcg-target.c   |    8 +-
 tcg/ppc64/tcg-target.c |    9 +-
 tcg/tcg.c              |    3 +
 tcg/tcg.h              |    1 +
 9 files changed, 167 insertions(+), 88 deletions(-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 1/5] tcg: Initialize the prologue after GUEST_BASE is fixed.
  2010-05-06 15:50 [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Richard Henderson
@ 2010-05-06 15:50 ` Richard Henderson
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 2/5] tcg-hppa: Load GUEST_BASE as an immediate Richard Henderson
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2010-05-06 15:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

This will allow backends to make intelligent choices about how
to implement GUEST_BASE.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 bsd-user/main.c   |    9 ++++++++-
 exec.c            |    5 +++++
 linux-user/main.c |    9 ++++++++-
 tcg/tcg.c         |    3 +++
 tcg/tcg.h         |    1 +
 5 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index b1c438d..05cc3d9 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -30,7 +30,7 @@
 #include "qemu-common.h"
 /* For tb_lock */
 #include "exec-all.h"
-
+#include "tcg.h"
 #include "qemu-timer.h"
 #include "envlist.h"
 
@@ -970,6 +970,13 @@ int main(int argc, char **argv)
     syscall_init();
     signal_init();
 
+#if defined(CONFIG_USE_GUEST_BASE)
+    /* Now that we've loaded the binary, GUEST_BASE is fixed.  Delay
+       generating the prologue until now so that the prologue can take
+       the real value of GUEST_BASE into account.  */
+    tcg_prologue_init(&tcg_ctx);
+#endif
+
     /* build Task State */
     memset(ts, 0, sizeof(TaskState));
     init_task_state(ts);
diff --git a/exec.c b/exec.c
index 95b92f7..f417bb6 100644
--- a/exec.c
+++ b/exec.c
@@ -574,6 +574,11 @@ void cpu_exec_init_all(unsigned long tb_size)
 #if !defined(CONFIG_USER_ONLY)
     io_mem_init();
 #endif
+#if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
+    /* There's no guest base to take into account, so go ahead and
+       initialize the prologue now.  */
+    tcg_prologue_init(&tcg_ctx);
+#endif
 }
 
 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
diff --git a/linux-user/main.c b/linux-user/main.c
index eafcfc1..331cc30 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -31,7 +31,7 @@
 #include "cache-utils.h"
 /* For tb_lock */
 #include "exec-all.h"
-
+#include "tcg.h"
 #include "qemu-timer.h"
 #include "envlist.h"
 
@@ -2984,6 +2984,13 @@ int main(int argc, char **argv, char **envp)
     syscall_init();
     signal_init();
 
+#if defined(CONFIG_USE_GUEST_BASE)
+    /* Now that we've loaded the binary, GUEST_BASE is fixed.  Delay
+       generating the prologue until now so that the prologue can take
+       the real value of GUEST_BASE into account.  */
+    tcg_prologue_init(&tcg_ctx);
+#endif
+
 #if defined(TARGET_I386)
     cpu_x86_set_cpl(env, 3);
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 53da2c4..9105266 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -240,7 +240,10 @@ void tcg_context_init(TCGContext *s)
     }
     
     tcg_target_init(s);
+}
 
+void tcg_prologue_init(TCGContext *s)
+{
     /* init global prologue and epilogue */
     s->code_buf = code_gen_prologue;
     s->code_ptr = s->code_buf;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 166c889..bab13cd 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -346,6 +346,7 @@ static inline void *tcg_malloc(int size)
 }
 
 void tcg_context_init(TCGContext *s);
+void tcg_prologue_init(TCGContext *s);
 void tcg_func_start(TCGContext *s);
 
 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
-- 
1.7.0.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 2/5] tcg-hppa: Load GUEST_BASE as an immediate.
  2010-05-06 15:50 [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Richard Henderson
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 1/5] tcg: Initialize the prologue after GUEST_BASE is fixed Richard Henderson
@ 2010-05-06 15:50 ` Richard Henderson
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 3/5] tcg-ia64: Fix some register usage issues Richard Henderson
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2010-05-06 15:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

Now that the prologue is generated after GUEST_BASE is fixed,
we can load it as an immediate, and also avoid reserving the
register if it isn't necessary.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/hppa/tcg-target.c |   12 ++++--------
 1 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 012e486..a5f2162 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -1629,11 +1629,10 @@ void tcg_target_qemu_prologue(TCGContext *s)
     }
 
 #ifdef CONFIG_USE_GUEST_BASE
-    /* Note that GUEST_BASE can change after the prologue is generated.
-       To combat that, load the value from the variable instead of
-       embedding a constant here.  */
-    tcg_out_ld(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG,
-               TCG_REG_R0, (tcg_target_long)&guest_base);
+    if (GUEST_BASE != 0) {
+        tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
+        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+    }
 #endif
 
     /* Jump to TB, and adjust R18 to be the return address.  */
@@ -1679,9 +1678,6 @@ void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_DP);  /* data pointer */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);  /* stack pointer */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */
-#ifdef CONFIG_USE_GUEST_BASE
-    tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
-#endif
 
     tcg_add_target_add_op_defs(hppa_op_defs);
 }
-- 
1.7.0.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 3/5] tcg-ia64: Fix some register usage issues.
  2010-05-06 15:50 [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Richard Henderson
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 1/5] tcg: Initialize the prologue after GUEST_BASE is fixed Richard Henderson
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 2/5] tcg-hppa: Load GUEST_BASE as an immediate Richard Henderson
@ 2010-05-06 15:50 ` Richard Henderson
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 4/5] tcg-ia64: Load GUEST_BASE into a register Richard Henderson
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2010-05-06 15:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

(1) The output registers were not marked call-clobbered, even though
    they can be modified by called functions.
(2) The thread pointer was not marked reserved.
(3) R4-R6 are call-saved, but not saved by the prologue.  Rather than
    save them, mark them reserved so that we don't use them.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/ia64/tcg-target.c |   67 ++++++++++++++++++++++++++++++------------------
 1 files changed, 42 insertions(+), 25 deletions(-)

diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index 401dfec..acd4ce8 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -2283,39 +2283,56 @@ void tcg_target_init(TCGContext *s)
                    0xffffffffffffffffull);
     tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I64],
                    0xffffffffffffffffull);
-    tcg_regset_set(tcg_target_call_clobber_regs,
-                   (1 << TCG_REG_R8)  |
-                   (1 << TCG_REG_R9)  |
-                   (1 << TCG_REG_R10) |
-                   (1 << TCG_REG_R11) |
-                   (1 << TCG_REG_R13) |
-                   (1 << TCG_REG_R14) |
-                   (1 << TCG_REG_R15) |
-                   (1 << TCG_REG_R16) |
-                   (1 << TCG_REG_R17) |
-                   (1 << TCG_REG_R18) |
-                   (1 << TCG_REG_R19) |
-                   (1 << TCG_REG_R20) |
-                   (1 << TCG_REG_R21) |
-                   (1 << TCG_REG_R22) |
-                   (1 << TCG_REG_R23) |
-                   (1 << TCG_REG_R24) |
-                   (1 << TCG_REG_R25) |
-                   (1 << TCG_REG_R26) |
-                   (1 << TCG_REG_R27) |
-                   (1 << TCG_REG_R28) |
-                   (1 << TCG_REG_R29) |
-                   (1 << TCG_REG_R30) |
-                   (1 << TCG_REG_R31));
-    tcg_regset_clear(s->reserved_regs);
 
+    tcg_regset_clear(tcg_target_call_clobber_regs);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R15);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R16);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R17);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R18);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R19);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R20);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R21);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R22);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R23);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R24);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R25);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R26);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R27);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R28);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R29);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R30);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R31);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R56);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R57);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R58);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R59);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R60);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R61);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R62);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R63);
+
+    tcg_regset_clear(s->reserved_regs);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);   /* zero register */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);   /* global pointer */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2);   /* internal use */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R3);   /* internal use */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R12);  /* stack pointer */
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);  /* thread pointer */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R32);  /* return address */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R33);  /* PFS */
 
+    /* The following 3 are not in use, are call-saved, but *not* saved
+       by the prologue.  Therefore we cannot use them without modifying
+       the prologue.  There doesn't seem to be any good reason to use
+       these as opposed to the windowed registers.  */
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R4);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R5);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6);
+
     tcg_add_target_add_op_defs(ia64_op_defs);
 }
-- 
1.7.0.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 4/5] tcg-ia64: Load GUEST_BASE into a register.
  2010-05-06 15:50 [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Richard Henderson
                   ` (2 preceding siblings ...)
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 3/5] tcg-ia64: Fix some register usage issues Richard Henderson
@ 2010-05-06 15:50 ` Richard Henderson
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 5/5] tcg-ppc: Conditionally reserve TCG_GUEST_BASE_REG Richard Henderson
  2010-05-21 16:41 ` [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Aurelien Jarno
  5 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2010-05-06 15:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

Saves one bundle per memory operation.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/ia64/tcg-target.c |  132 ++++++++++++++++++++++++++++++++----------------
 1 files changed, 88 insertions(+), 44 deletions(-)

diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index acd4ce8..0d275e9 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -40,6 +40,12 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 };
 #endif
 
+#ifdef CONFIG_USE_GUEST_BASE
+#define TCG_GUEST_BASE_REG TCG_REG_R55
+#else
+#define TCG_GUEST_BASE_REG TCG_REG_R0
+#endif
+
 /* Branch registers */
 enum {
     TCG_REG_B0 = 0,
@@ -1641,9 +1647,13 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
 
 static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
 {
+    static uint64_t const opc_ld_m1[4] = {
+        OPC_LD1_M1, OPC_LD2_M1, OPC_LD4_M1, OPC_LD8_M1
+    };
+    static uint64_t const opc_sxt_i29[4] = {
+        OPC_SXT1_I29, OPC_SXT2_I29, OPC_SXT4_I29, 0
+    };
     int addr_reg, data_reg, mem_index, s_bits, bswap;
-    uint64_t opc_ld_m1[4] = { OPC_LD1_M1, OPC_LD2_M1, OPC_LD4_M1, OPC_LD8_M1 };
-    uint64_t opc_sxt_i29[8] = { OPC_SXT1_I29, OPC_SXT2_I29, OPC_SXT4_I29, 0 };
 
     data_reg = *args++;
     addr_reg = *args++;
@@ -1656,19 +1666,21 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
     bswap = 0;
 #endif
 
-    tcg_out_bundle(s, mLX,
-                   tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
-                   tcg_opc_l2 ((tcg_target_long) GUEST_BASE),
-                   tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, TCG_REG_R2,
-                               GUEST_BASE));
-
 #if TARGET_LONG_BITS == 32
-    tcg_out_bundle(s, mII,
-                   tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
-                   tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
-                               TCG_REG_R3, addr_reg),
-                   tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
-                               TCG_REG_R2, TCG_REG_R3));
+    if (GUEST_BASE != 0) {
+        tcg_out_bundle(s, mII,
+                       tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+                       tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
+                                   TCG_REG_R3, addr_reg),
+                       tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
+                                   TCG_GUEST_BASE_REG, TCG_REG_R3));
+    } else {
+        tcg_out_bundle(s, miI,
+                       tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+                       tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
+                                   TCG_REG_R2, addr_reg),
+                       tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+    }
 
     if (!bswap || s_bits == 0) {
         if (s_bits == opc) {
@@ -1724,12 +1736,20 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
         }
     }
 #else
-    tcg_out_bundle(s, MmI,
-                   tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
-                               TCG_REG_R2, addr_reg),
-                   tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
-                               data_reg, TCG_REG_R2),
-                   tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+    if (GUEST_BASE != 0) {
+        tcg_out_bundle(s, MmI,
+                       tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
+                                   TCG_GUEST_BASE_REG, addr_reg),
+                       tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
+                                   data_reg, TCG_REG_R2),
+                       tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+    } else {
+        tcg_out_bundle(s, mmI,
+                       tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+                       tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
+                                   data_reg, addr_reg),
+                       tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+    }
 
     if (bswap && s_bits == 1) {
         tcg_out_bundle(s, mII,
@@ -1764,8 +1784,13 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
 
 static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
 {
+    static uint64_t const opc_st_m4[4] = {
+        OPC_ST1_M4, OPC_ST2_M4, OPC_ST4_M4, OPC_ST8_M4
+    };
     int addr_reg, data_reg, bswap;
-    uint64_t opc_st_m4[4] = { OPC_ST1_M4, OPC_ST2_M4, OPC_ST4_M4, OPC_ST8_M4 };
+#if TARGET_LONG_BITS == 64
+    uint64_t add_guest_base;
+#endif
 
     data_reg = *args++;
     addr_reg = *args++;
@@ -1776,19 +1801,22 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
     bswap = 0;
 #endif
 
-    tcg_out_bundle(s, mLX,
-                   tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
-                   tcg_opc_l2 ((tcg_target_long) GUEST_BASE),
-                   tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, TCG_REG_R2,
-                               GUEST_BASE));
-
 #if TARGET_LONG_BITS == 32
-    tcg_out_bundle(s, mII,
-                   tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
-                   tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
-                               TCG_REG_R3, addr_reg),
-                   tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
-                               TCG_REG_R2, TCG_REG_R3));
+    if (GUEST_BASE != 0) {
+        tcg_out_bundle(s, mII,
+                       tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+                       tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
+                                   TCG_REG_R3, addr_reg),
+                       tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
+                                   TCG_GUEST_BASE_REG, TCG_REG_R3));
+    } else {
+        tcg_out_bundle(s, miI,
+                       tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+                       tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
+                                   TCG_REG_R3, addr_reg),
+                       tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+    }
+
     if (bswap) {
         if (opc == 1) {
             tcg_out_bundle(s, mII,
@@ -1821,18 +1849,24 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
                    tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
                    tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
 #else
+    if (GUEST_BASE != 0) {
+        add_guest_base = tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
+                                     TCG_GUEST_BASE_REG, addr_reg);
+        addr_reg = TCG_REG_R2;
+    } else {
+        add_guest_base = tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0);
+    }
+
     if (!bswap || opc == 0) {
-        tcg_out_bundle(s, MmI,
-                       tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
-                                   TCG_REG_R2, addr_reg),
+        tcg_out_bundle(s, (GUEST_BASE ? MmI : mmI),
+                       add_guest_base,
                        tcg_opc_m4 (TCG_REG_P0, opc_st_m4[opc],
-                                   data_reg, TCG_REG_R2),
+                                   data_reg, addr_reg),
                        tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
     } else {
         if (opc == 1) {
             tcg_out_bundle(s, mII,
-                           tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
-                                       TCG_REG_R2, addr_reg),
+                           add_guest_base,
                            tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
                                        TCG_REG_R3, data_reg, 15, 15),
                            tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
@@ -1840,8 +1874,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
             data_reg = TCG_REG_R3;
         } else if (opc == 2) {
             tcg_out_bundle(s, mII,
-                           tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
-                                       TCG_REG_R2, addr_reg),
+                           add_guest_base,
                            tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
                                        TCG_REG_R3, data_reg, 31, 31),
                            tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
@@ -1849,8 +1882,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
             data_reg = TCG_REG_R3;
         } else if (opc == 3) {
             tcg_out_bundle(s, miI,
-                           tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
-                                       TCG_REG_R2, addr_reg),
+                           add_guest_base,
                            tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0),
                            tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
                                        TCG_REG_R3, data_reg, 0xb));
@@ -1858,7 +1890,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
         }
         tcg_out_bundle(s, miI,
                        tcg_opc_m4 (TCG_REG_P0, opc_st_m4[opc],
-                                   data_reg, TCG_REG_R2),
+                                   data_reg, addr_reg),
                        tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0),
                        tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
     }
@@ -2255,6 +2287,18 @@ void tcg_target_qemu_prologue(TCGContext *s)
                                TCG_REG_B6, TCG_REG_R32, 0),
                    tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
                                TCG_REG_R32, TCG_REG_B0));
+
+    /* ??? If GUEST_BASE < 0x200000, we could load the register via
+       an ADDL in the M slot of the next bundle.  */
+    if (GUEST_BASE != 0) {
+        tcg_out_bundle(s, mlx,
+                       tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+                       tcg_opc_l2 (GUEST_BASE),
+                       tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2,
+                                   TCG_GUEST_BASE_REG, GUEST_BASE));
+        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+    }
+
     tcg_out_bundle(s, miB,
                    tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
                    tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
-- 
1.7.0.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 5/5] tcg-ppc: Conditionally reserve TCG_GUEST_BASE_REG.
  2010-05-06 15:50 [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Richard Henderson
                   ` (3 preceding siblings ...)
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 4/5] tcg-ia64: Load GUEST_BASE into a register Richard Henderson
@ 2010-05-06 15:50 ` Richard Henderson
  2010-05-21 16:41 ` [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Aurelien Jarno
  5 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2010-05-06 15:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

We need not reserve the register unless we're going to use it.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/ppc/tcg-target.c   |    8 ++++----
 tcg/ppc64/tcg-target.c |    9 ++++-----
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index ce078e4..654d244 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -933,7 +933,10 @@ void tcg_target_qemu_prologue (TCGContext *s)
     tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + LR_OFFSET));
 
 #ifdef CONFIG_USE_GUEST_BASE
-    tcg_out_movi (s, TCG_TYPE_I32, TCG_GUEST_BASE_REG, GUEST_BASE);
+    if (GUEST_BASE) {
+        tcg_out_movi (s, TCG_TYPE_I32, TCG_GUEST_BASE_REG, GUEST_BASE);
+        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+    }
 #endif
 
     tcg_out32 (s, MTSPR | RS (3) | CTR);
@@ -1914,9 +1917,6 @@ void tcg_target_init(TCGContext *s)
 #ifdef _CALL_SYSV
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
 #endif
-#ifdef CONFIG_USE_GUEST_BASE
-    tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
-#endif
 
     tcg_add_target_add_op_defs(ppc_op_defs);
 }
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 2d436a5..a1e643c 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -899,7 +899,10 @@ void tcg_target_qemu_prologue (TCGContext *s)
     tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));
 
 #ifdef CONFIG_USE_GUEST_BASE
-    tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
+    if (GUEST_BASE) {
+        tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
+        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+    }
 #endif
 
     tcg_out32 (s, MTSPR | RS (3) | CTR);
@@ -1692,9 +1695,5 @@ void tcg_target_init (TCGContext *s)
 #endif
     tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
 
-#ifdef CONFIG_USE_GUEST_BASE
-    tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
-#endif
-
     tcg_add_target_add_op_defs (ppc_op_defs);
 }
-- 
1.7.0.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed
  2010-05-06 15:50 [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Richard Henderson
                   ` (4 preceding siblings ...)
  2010-05-06 15:50 ` [Qemu-devel] [PATCH 5/5] tcg-ppc: Conditionally reserve TCG_GUEST_BASE_REG Richard Henderson
@ 2010-05-21 16:41 ` Aurelien Jarno
  5 siblings, 0 replies; 7+ messages in thread
From: Aurelien Jarno @ 2010-05-21 16:41 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Thu, May 06, 2010 at 08:50:40AM -0700, Richard Henderson wrote:
> By doing this we can make any number of decisions about code generation
> during the prologue.  For instance, we can decide whether or not to
> reserve a register to hold the value of GUEST_BASE.
> 
> This fixes a latent bug in the two ppc ports in that GUEST_BASE was 
> being loaded as an immediate before the final value of GUEST_BASE is
> computed.
> 
> This also fixes some register reservation problems I noticed in the
> ia64 port, while trying to decide which register to use for holding
> GUEST_BASE across the TB.
> 
> 
> r~
> 
> 
> 
> Richard Henderson (5):
>   tcg: Initialize the prologue after GUEST_BASE is fixed.
>   tcg-hppa: Load GUEST_BASE as an immediate.
>   tcg-ia64: Fix some register usage issues.
>   tcg-ia64: Load GUEST_BASE into a register.
>   tcg-ppc: Conditionally reserve TCG_GUEST_BASE_REG.
> 
>  bsd-user/main.c        |    9 ++-
>  exec.c                 |    5 +
>  linux-user/main.c      |    9 ++-
>  tcg/hppa/tcg-target.c  |   12 +--
>  tcg/ia64/tcg-target.c  |  199 +++++++++++++++++++++++++++++++-----------------
>  tcg/ppc/tcg-target.c   |    8 +-
>  tcg/ppc64/tcg-target.c |    9 +-
>  tcg/tcg.c              |    3 +
>  tcg/tcg.h              |    1 +
>  9 files changed, 167 insertions(+), 88 deletions(-)
> 

Thanks, applied patches 1-4.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-05-21 16:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-06 15:50 [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Richard Henderson
2010-05-06 15:50 ` [Qemu-devel] [PATCH 1/5] tcg: Initialize the prologue after GUEST_BASE is fixed Richard Henderson
2010-05-06 15:50 ` [Qemu-devel] [PATCH 2/5] tcg-hppa: Load GUEST_BASE as an immediate Richard Henderson
2010-05-06 15:50 ` [Qemu-devel] [PATCH 3/5] tcg-ia64: Fix some register usage issues Richard Henderson
2010-05-06 15:50 ` [Qemu-devel] [PATCH 4/5] tcg-ia64: Load GUEST_BASE into a register Richard Henderson
2010-05-06 15:50 ` [Qemu-devel] [PATCH 5/5] tcg-ppc: Conditionally reserve TCG_GUEST_BASE_REG Richard Henderson
2010-05-21 16:41 ` [Qemu-devel] [PATCH 0/5] tcg: Initialize prologue after guest_base fixed Aurelien Jarno

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).