re PR target/35802 (MIPS64: Unable to find a register to spill in class ‘V1_REG...
authorRichard Sandiford <rdsandiford@googlemail.com>
Wed, 9 Jul 2008 20:03:40 +0000 (20:03 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 9 Jul 2008 20:03:40 +0000 (20:03 +0000)
gcc/
PR target/35802
* config/mips/mips.h (reg_class): Remove V1_REG.
(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
* config/mips/mips.c (mips_regno_to_class): Map $3 to M16_NA_REGS
instead of V1_REGS.
(mips_get_tp): New function.
(mips_legitimize_tls_address): Use it.
* config/mips/constraints.md (v): Delete.
* config/mips/mips.md (TLS_GET_TP_REGNUM): New constant.
(tls_get_tp_<mode>): Allow any GPR destination and clobber $3.
After reload, split into a move and ...
(*tls_get_tp_<mode>_split): ...this new instruction.

gcc/testsuite/
PR target/35802
* gcc.target/mips/pr35802.c: New test.

From-SVN: r137670

gcc/ChangeLog
gcc/config/mips/constraints.md
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/pr35802.c [new file with mode: 0644]

index 06cd42f..c0e874b 100644 (file)
@@ -1,3 +1,18 @@
+2008-07-09  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       PR target/35802
+       * config/mips/mips.h (reg_class): Remove V1_REG.
+       (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
+       * config/mips/mips.c (mips_regno_to_class): Map $3 to M16_NA_REGS
+       instead of V1_REGS.
+       (mips_get_tp): New function.
+       (mips_legitimize_tls_address): Use it.
+       * config/mips/constraints.md (v): Delete.
+       * config/mips/mips.md (TLS_GET_TP_REGNUM): New constant.
+       (tls_get_tp_<mode>): Allow any GPR destination and clobber $3.
+       After reload, split into a move and ...
+       (*tls_get_tp_<mode>_split): ...this new instruction.
+
 2008-07-09  David Daney  <ddaney@avtrex.com>
 
        * config/mips/driver-native.c: Include coretypes.h and tm.h.
index a387489..ee44783 100644 (file)
@@ -55,9 +55,6 @@
 (define_register_constraint "j" "PIC_FN_ADDR_REG"
   "@internal")
 
-(define_register_constraint "v" "V1_REG"
-  "@internal")
-
 (define_register_constraint "y" "GR_REGS"
   "Equivalent to @code{r}; retained for backwards compatibility.")
 
index e8d51bc..3bbae44 100644 (file)
@@ -479,7 +479,7 @@ static const char *mips_hi_relocs[NUM_SYMBOL_TYPES];
 
 /* Index R is the smallest register class that contains register R.  */
 const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = {
-  LEA_REGS,    LEA_REGS,       M16_NA_REGS,    V1_REG,
+  LEA_REGS,    LEA_REGS,       M16_NA_REGS,    M16_NA_REGS,
   M16_REGS,    M16_REGS,       M16_REGS,       M16_REGS,
   LEA_REGS,    LEA_REGS,       LEA_REGS,       LEA_REGS,
   LEA_REGS,    LEA_REGS,       LEA_REGS,       LEA_REGS,
@@ -2465,6 +2465,21 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
   return insn;
 }
 
+/* Return a pseudo register that contains the current thread pointer.  */
+
+static rtx
+mips_get_tp (void)
+{
+  rtx tp;
+
+  tp = gen_reg_rtx (Pmode);
+  if (Pmode == DImode)
+    emit_insn (gen_tls_get_tp_di (tp));
+  else
+    emit_insn (gen_tls_get_tp_si (tp));
+  return tp;
+}
+
 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
    its address.  The return value will be both a valid address and a valid
    SET_SRC (either a REG or a LO_SUM).  */
@@ -2472,7 +2487,7 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
 static rtx
 mips_legitimize_tls_address (rtx loc)
 {
-  rtx dest, insn, v0, v1, tmp1, tmp2, eqv;
+  rtx dest, insn, v0, tp, tmp1, tmp2, eqv;
   enum tls_model model;
 
   if (TARGET_MIPS16)
@@ -2514,31 +2529,20 @@ mips_legitimize_tls_address (rtx loc)
       break;
 
     case TLS_MODEL_INITIAL_EXEC:
-      v1 = gen_rtx_REG (Pmode, GP_RETURN + 1);
+      tp = mips_get_tp ();
       tmp1 = gen_reg_rtx (Pmode);
       tmp2 = mips_unspec_address (loc, SYMBOL_GOTTPREL);
       if (Pmode == DImode)
-       {
-         emit_insn (gen_tls_get_tp_di (v1));
-         emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2));
-       }
+       emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2));
       else
-       {
-         emit_insn (gen_tls_get_tp_si (v1));
-         emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2));
-       }
+       emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2));
       dest = gen_reg_rtx (Pmode);
-      emit_insn (gen_add3_insn (dest, tmp1, v1));
+      emit_insn (gen_add3_insn (dest, tmp1, tp));
       break;
 
     case TLS_MODEL_LOCAL_EXEC:
-      v1 = gen_rtx_REG (Pmode, GP_RETURN + 1);
-      if (Pmode == DImode)
-       emit_insn (gen_tls_get_tp_di (v1));
-      else
-       emit_insn (gen_tls_get_tp_si (v1));
-
-      tmp1 = mips_unspec_offset_high (NULL, v1, loc, SYMBOL_TPREL);
+      tp = mips_get_tp ();
+      tmp1 = mips_unspec_offset_high (NULL, tp, loc, SYMBOL_TPREL);
       dest = gen_rtx_LO_SUM (Pmode, tmp1,
                             mips_unspec_address (loc, SYMBOL_TPREL));
       break;
index 8518a86..c29a5e8 100644 (file)
@@ -1690,7 +1690,6 @@ enum reg_class
   T_REG,                       /* mips16 T register ($24) */
   M16_T_REGS,                  /* mips16 registers plus T register */
   PIC_FN_ADDR_REG,             /* SVR4 PIC function address register */
-  V1_REG,                      /* Register $v1 ($3) used for TLS access.  */
   LEA_REGS,                    /* Every GPR except $25 */
   GR_REGS,                     /* integer registers */
   FP_REGS,                     /* floating point registers */
@@ -1731,7 +1730,6 @@ enum reg_class
   "T_REG",                                                             \
   "M16_T_REGS",                                                                \
   "PIC_FN_ADDR_REG",                                                   \
-  "V1_REG",                                                            \
   "LEA_REGS",                                                          \
   "GR_REGS",                                                           \
   "FP_REGS",                                                           \
@@ -1775,7 +1773,6 @@ enum reg_class
   { 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* mips16 T register */ \
   { 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* mips16 and T regs */ \
   { 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* SVR4 PIC function address register */ \
-  { 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* only $v1 */ \
   { 0xfdffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* Every other GPR except $25 */   \
   { 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* integer registers */ \
   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* floating registers*/ \
index 6b2f5fa..43c47e5 100644 (file)
@@ -69,6 +69,7 @@
    
    (UNSPEC_ADDRESS_FIRST       100)
 
+   (TLS_GET_TP_REGNUM          3)
    (GOT_VERSION_REGNUM         79)
 
    ;; For MIPS Paired-Singled Floating Point Instructions.
   [(set_attr "type" "arith")
    (set_attr "extended_mips16" "yes")])
 
-; Thread-Local Storage
-
-; The TLS base pointer is accessed via "rdhwr $v1, $29".  No current
-; MIPS architecture defines this register, and no current
-; implementation provides it; instead, any OS which supports TLS is
-; expected to trap and emulate this instruction.  rdhwr is part of the
-; MIPS 32r2 specification, but we use it on any architecture because
-; we expect it to be emulated.  Use .set to force the assembler to
-; accept it.
-
-(define_insn "tls_get_tp_<mode>"
-  [(set (match_operand:P 0 "register_operand" "=v")
-       (unspec:P [(const_int 0)]
-                 UNSPEC_TLS_GET_TP))]
+;; Thread-Local Storage
+
+;; The TLS base pointer is accessed via "rdhwr $3, $29".  No current
+;; MIPS architecture defines this register, and no current
+;; implementation provides it; instead, any OS which supports TLS is
+;; expected to trap and emulate this instruction.  rdhwr is part of the
+;; MIPS 32r2 specification, but we use it on any architecture because
+;; we expect it to be emulated.  Use .set to force the assembler to
+;; accept it.
+;;
+;; We do not use a constraint to force the destination to be $3
+;; because $3 can appear explicitly as a function return value.
+;; If we leave the use of $3 implicit in the constraints until
+;; reload, we may end up making a $3 return value live across
+;; the instruction, leading to a spill failure when reloading it.
+(define_insn_and_split "tls_get_tp_<mode>"
+  [(set (match_operand:P 0 "register_operand" "=d")
+       (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
+   (clobber (reg:P TLS_GET_TP_REGNUM))]
   "HAVE_AS_TLS && !TARGET_MIPS16"
-  ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
+  "#"
+  "&& reload_completed"
+  [(set (reg:P TLS_GET_TP_REGNUM)
+       (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
+   (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
+  ""
   [(set_attr "type" "unknown")
    ; Since rdhwr always generates a trap for now, putting it in a delay
    ; slot would make the kernel's emulation of it much slower.
    (set_attr "can_delay" "no")
+   (set_attr "mode" "<MODE>")
+   (set_attr "length" "8")])
+
+(define_insn "*tls_get_tp_<mode>_split"
+  [(set (reg:P TLS_GET_TP_REGNUM)
+       (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))]
+  "HAVE_AS_TLS && !TARGET_MIPS16"
+  ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop"
+  [(set_attr "type" "unknown")
+   ; See tls_get_tp_<mode>
+   (set_attr "can_delay" "no")
    (set_attr "mode" "<MODE>")])
 \f
 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
index 196c3fa..a71c1cc 100644 (file)
@@ -1,3 +1,8 @@
+2008-07-09  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       PR target/35802
+       * gcc.target/mips/pr35802.c: New test.
+
 2008-07-09  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/36760
diff --git a/gcc/testsuite/gcc.target/mips/pr35802.c b/gcc/testsuite/gcc.target/mips/pr35802.c
new file mode 100644 (file)
index 0000000..3430098
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-mips-options "-O2 -march=74kc -mgp32" } */
+__thread int x __attribute__((tls_model("initial-exec")));
+__thread int y __attribute__((tls_model("initial-exec")));
+
+int bar (void);
+
+NOMIPS16 void
+foo (int n)
+{
+  if (n > 5)
+    {
+      y = 0;
+      do
+       x += bar ();
+      while (n--);
+    }
+}