tcg-ppc64: Relax register restrictions in tcg_out_mem_long
authorRichard Henderson <rth@twiddle.net>
Tue, 25 Mar 2014 19:22:18 +0000 (12:22 -0700)
committerRichard Henderson <rth@twiddle.net>
Mon, 23 Jun 2014 14:31:14 +0000 (07:31 -0700)
In order to be able to use tcg_out_ld/st sensibly with scratch
registers, assert only when we'd incorrectly clobber a scratch.

Tested-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
tcg/ppc64/tcg-target.c

index 951a392..dbe9c5c 100644 (file)
@@ -714,10 +714,9 @@ static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
                              TCGReg base, tcg_target_long offset)
 {
     tcg_target_long orig = offset, l0, l1, extra = 0, align = 0;
+    bool is_store = false;
     TCGReg rs = TCG_REG_R2;
 
-    assert(rt != TCG_REG_R2 && base != TCG_REG_R2);
-
     switch (opi) {
     case LD: case LWA:
         align = 3;
@@ -725,19 +724,22 @@ static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
     default:
         if (rt != TCG_REG_R0) {
             rs = rt;
+            break;
         }
         break;
     case STD:
         align = 3;
-        break;
+        /* FALLTHRU */
     case STB: case STH: case STW:
+        is_store = true;
         break;
     }
 
     /* For unaligned, or very large offsets, use the indexed form.  */
     if (offset & align || offset != (int32_t)offset) {
-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, orig);
-        tcg_out32(s, opx | TAB(rt, base, TCG_REG_R2));
+        tcg_debug_assert(rs != base && (!is_store || rs != rt));
+        tcg_out_movi(s, TCG_TYPE_PTR, rs, orig);
+        tcg_out32(s, opx | TAB(rt, base, rs));
         return;
     }