qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: thuth@redhat.com, david@gibson.dropbear.id.au,
	mark.cave-ayland@ilande.co.uk
Subject: [Qemu-devel] [PATCH 2/2] tcg: Fix allocation of indirect_base registers
Date: Fri, 17 Jun 2016 22:03:27 -0700	[thread overview]
Message-ID: <1466226207-23581-3-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1466226207-23581-1-git-send-email-rth@twiddle.net>

When the number of available registers is low, we need to be
prepared for TS to overlap MEM_BASE.

This fixes the Sparc64 OpenBIOS boot on i686.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/tcg.c | 68 +++++++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 21 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 154ffe8..6c26ee4 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1743,32 +1743,71 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs,
     tcg_abort();
 }
 
+/* Mark a temporary as dead.  */
+static void temp_dead(TCGContext *s, TCGTemp *ts)
+{
+    if (ts->fixed_reg) {
+        return;
+    }
+    if (ts->val_type == TEMP_VAL_REG) {
+        s->reg_to_temp[ts->reg] = NULL;
+    }
+    ts->val_type = (temp_idx(s, ts) < s->nb_globals || ts->temp_local
+                    ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
+}
+
 /* Make sure the temporary is in a register.  If needed, allocate the register
    from DESIRED while avoiding ALLOCATED.  */
 static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
                       TCGRegSet allocated_regs)
 {
-    TCGReg reg;
+    TCGReg reg, base_reg;
+    TCGTemp *base;
 
     switch (ts->val_type) {
     case TEMP_VAL_REG:
         return;
+
     case TEMP_VAL_CONST:
         reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
         tcg_out_movi(s, ts->type, reg, ts->val);
         ts->mem_coherent = 0;
         break;
+
     case TEMP_VAL_MEM:
-        reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
-        if (ts->indirect_reg) {
-            tcg_regset_set_reg(allocated_regs, reg);
-            temp_load(s, ts->mem_base,
-                      tcg_target_available_regs[TCG_TYPE_PTR],
-                      allocated_regs);
+        base = ts->mem_base;
+        base_reg = base->reg;
+        if (ts->indirect_reg && base->val_type != TEMP_VAL_REG) {
+            TCGRegSet reg_avail = desired_regs & ~allocated_regs;
+            TCGRegSet base_avail = (tcg_target_available_regs[TCG_TYPE_PTR]
+                                    & ~allocated_regs);
+            if (is_power_of_2(reg_avail)) {
+                /* There is only one register available for TS.  If there are
+                   other available registers for BASE, make sure we pick one
+                   of them.  Otherwise BASE and TS will share a reg.  */
+                TCGRegSet avail = base_avail & ~reg_avail;
+                if (avail) {
+                    base_avail = avail;
+                }
+                temp_load(s, base, base_avail, allocated_regs);
+                base_reg = base->reg;
+            } else {
+                temp_load(s, base, base_avail, allocated_regs);
+                base_reg = base->reg;
+                tcg_regset_reset_reg(allocated_regs, base_reg);
+            }
         }
-        tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
+
+        reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
+        tcg_out_ld(s, ts->type, reg, base_reg, ts->mem_offset);
         ts->mem_coherent = 1;
+
+        /* If the registers overlap, zap the info from BASE.  */
+        if (reg == base_reg) {
+            temp_dead(s, base);
+        }
         break;
+
     case TEMP_VAL_DEAD:
     default:
         tcg_abort();
@@ -1778,19 +1817,6 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
     s->reg_to_temp[reg] = ts;
 }
 
-/* mark a temporary as dead. */
-static inline void temp_dead(TCGContext *s, TCGTemp *ts)
-{
-    if (ts->fixed_reg) {
-        return;
-    }
-    if (ts->val_type == TEMP_VAL_REG) {
-        s->reg_to_temp[ts->reg] = NULL;
-    }
-    ts->val_type = (temp_idx(s, ts) < s->nb_globals || ts->temp_local
-                    ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
-}
-
 /* sync a temporary to memory. 'allocated_regs' is used in case a
    temporary registers needs to be allocated to store a constant. */
 static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
-- 
2.5.5

  parent reply	other threads:[~2016-06-18  5:03 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-18  5:03 [Qemu-devel] [PATCH 0/2] tcg: Fix i686 booting sparc64 openbios Richard Henderson
2016-06-18  5:03 ` [Qemu-devel] [PATCH 1/2] tcg: Fix name for high-half register Richard Henderson
2016-06-20  0:11   ` David Gibson
2016-06-18  5:03 ` Richard Henderson [this message]
2016-06-20  8:07 ` [Qemu-devel] [PATCH 0/2] tcg: Fix i686 booting sparc64 openbios Thomas Huth
2016-06-20 19:32 ` Mark Cave-Ayland

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=1466226207-23581-3-git-send-email-rth@twiddle.net \
    --to=rth@twiddle.net \
    --cc=david@gibson.dropbear.id.au \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@redhat.com \
    /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).