dcavalca / rpms / qemu

Forked from rpms/qemu a year ago
Clone

Blame 0093-tcg-sparc-Preserve-branch-destinations-during-retran.patch

5544c1
From 2cbc27913eb9eb7cdc4a41fc6efafccf3db7ebe6 Mon Sep 17 00:00:00 2001
5544c1
From: Richard Henderson <rth@twiddle.net>
5544c1
Date: Fri, 21 Sep 2012 11:00:23 -0700
5544c1
Subject: [PATCH] tcg-sparc: Preserve branch destinations during retranslation
5544c1
5544c1
Signed-off-by: Richard Henderson <rth@twiddle.net>
5544c1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
5544c1
---
5544c1
 tcg/sparc/tcg-target.c | 19 +++++++++++--------
5544c1
 1 file changed, 11 insertions(+), 8 deletions(-)
5544c1
5544c1
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
5544c1
index 1db0c9d..876da4f 100644
5544c1
--- a/tcg/sparc/tcg-target.c
5544c1
+++ b/tcg/sparc/tcg-target.c
5544c1
@@ -488,30 +488,33 @@ static inline void tcg_out_nop(TCGContext *s)
5544c1
 static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index)
5544c1
 {
5544c1
     TCGLabel *l = &s->labels[label_index];
5544c1
+    uint32_t off22;
5544c1
 
5544c1
     if (l->has_value) {
5544c1
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2)
5544c1
-                      | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr)));
5544c1
+        off22 = INSN_OFF22(l->u.value - (unsigned long)s->code_ptr);
5544c1
     } else {
5544c1
+        /* Make sure to preserve destinations during retranslation.  */
5544c1
+        off22 = *(uint32_t *)s->code_ptr & INSN_OFF22(-1);
5544c1
         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0);
5544c1
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0));
5544c1
     }
5544c1
+    tcg_out32(s, INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | off22);
5544c1
 }
5544c1
 
5544c1
 #if TCG_TARGET_REG_BITS == 64
5544c1
 static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index)
5544c1
 {
5544c1
     TCGLabel *l = &s->labels[label_index];
5544c1
+    uint32_t off19;
5544c1
 
5544c1
     if (l->has_value) {
5544c1
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
5544c1
-                      (0x5 << 19) |
5544c1
-                      INSN_OFF19(l->u.value - (unsigned long)s->code_ptr)));
5544c1
+        off19 = INSN_OFF19(l->u.value - (unsigned long)s->code_ptr);
5544c1
     } else {
5544c1
+        /* Make sure to preserve destinations during retranslation.  */
5544c1
+        off19 = *(uint32_t *)s->code_ptr & INSN_OFF19(-1);
5544c1
         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label_index, 0);
5544c1
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
5544c1
-                      (0x5 << 19) | 0));
5544c1
     }
5544c1
+    tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
5544c1
+                  (0x5 << 19) | off19));
5544c1
 }
5544c1
 #endif
5544c1
 
5544c1
-- 
5544c1
1.7.12.1
5544c1