qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 7/8] tcg-arm: Remove restriction on qemu_ld outpu


From: Richard Henderson
Subject: [Qemu-devel] [PATCH v2 7/8] tcg-arm: Remove restriction on qemu_ld output register
Date: Fri, 30 Aug 2013 10:47:16 -0700

The main intent of the patch is to allow the tlb addend register
to be changed, without tying that change to the constraint.  But
the most common side-effect seems to be to enable usage of ldrd
with the r0,r1 pair.

Signed-off-by: Richard Henderson <address@hidden>
---
 tcg/arm/tcg-target.c | 49 +++++++++++++++++++++++++++++--------------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index d27c365..ff331a1 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -183,15 +183,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, 
const char **pct_str)
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R14);
 #endif
         break;
-    case 'L':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
-#ifdef CONFIG_SOFTMMU
-        /* r1 is still needed to load data_reg or data_reg2,
-           so don't use it. */
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
-#endif
-        break;
 
     /* qemu_st address & data_reg */
     case 's':
@@ -1313,8 +1304,17 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, 
TCGLabelQemuLdst *lb)
         tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
         break;
     case 3:
-        tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
-        tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
+        if (data_reg != TCG_REG_R1) {
+            tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
+            tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
+        } else if (data_reg2 != TCG_REG_R0) {
+            tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
+            tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
+        } else {
+            tcg_out_mov_reg(s, COND_AL, TCG_REG_TMP, TCG_REG_R0);
+            tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
+            tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_TMP);
+        }
         break;
     }
 
@@ -1420,16 +1420,25 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, int opc)
         break;
     case 3:
         if (bswap) {
-            tcg_out_ld32_rwb(s, COND_AL, data_reg2, addend, addr_reg);
-            tcg_out_ld32_12(s, COND_AL, data_reg, addend, 4);
-            tcg_out_bswap32(s, COND_AL, data_reg2, data_reg2);
-            tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
-        } else if (use_armv6_instructions
-                   && (data_reg & 1) == 0 && data_reg2 == data_reg + 1) {
+            TCGReg t = data_reg;
+            data_reg = data_reg2;
+            data_reg2 = t;
+        }
+        if (use_armv6_instructions
+            && (data_reg & 1) == 0 && data_reg2 == data_reg + 1) {
             tcg_out_ldrd_r(s, COND_AL, data_reg, addr_reg, addend);
-        } else {
+        } else if (data_reg != addend) {
             tcg_out_ld32_rwb(s, COND_AL, data_reg, addend, addr_reg);
             tcg_out_ld32_12(s, COND_AL, data_reg2, addend, 4);
+        } else {
+            tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_TMP,
+                            addend, addr_reg, SHIFT_IMM_LSL(0));
+            tcg_out_ld32_12(s, COND_AL, data_reg, TCG_REG_TMP, 0);
+            tcg_out_ld32_12(s, COND_AL, data_reg2, TCG_REG_TMP, 4);
+        }
+        if (bswap) {
+            tcg_out_bswap32(s, COND_AL, data_reg2, data_reg2);
+            tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
         }
         break;
     }
@@ -2024,7 +2033,7 @@ static const TCGTargetOpDef arm_op_defs[] = {
     { INDEX_op_qemu_ld16u, { "r", "l" } },
     { INDEX_op_qemu_ld16s, { "r", "l" } },
     { INDEX_op_qemu_ld32, { "r", "l" } },
-    { INDEX_op_qemu_ld64, { "L", "L", "l" } },
+    { INDEX_op_qemu_ld64, { "r", "r", "l" } },
 
     { INDEX_op_qemu_st8, { "s", "s" } },
     { INDEX_op_qemu_st16, { "s", "s" } },
@@ -2036,7 +2045,7 @@ static const TCGTargetOpDef arm_op_defs[] = {
     { INDEX_op_qemu_ld16u, { "r", "l", "l" } },
     { INDEX_op_qemu_ld16s, { "r", "l", "l" } },
     { INDEX_op_qemu_ld32, { "r", "l", "l" } },
-    { INDEX_op_qemu_ld64, { "L", "L", "l", "l" } },
+    { INDEX_op_qemu_ld64, { "r", "r", "l", "l" } },
 
     { INDEX_op_qemu_st8, { "s", "s", "s" } },
     { INDEX_op_qemu_st16, { "s", "s", "s" } },
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]