mips.h (ELIMINABLE_REGS): Can't eliminate RETURN_ADDRESS_POINTER_REGNUM to $ra.
authorAlexandre Oliva <aoliva@redhat.com>
Mon, 18 Mar 2002 19:12:50 +0000 (19:12 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Mon, 18 Mar 2002 19:12:50 +0000 (19:12 +0000)
* config/mips/mips.h (ELIMINABLE_REGS): Can't eliminate
RETURN_ADDRESS_POINTER_REGNUM to $ra.
(CAN_ELIMINATE): Only eliminate it to $sp if a frame pointer is
not needed.  Disregard leaf_function_p().
(INITIAL_ELIMINATION_OFFSET): Adjust for elimination of rap to
mips16 frame pointer.
* config/mips/mips.md (store ra): Only to small SP offsets.
2001-08-22  Graham Stott  <grahams@redhat.com>
* config/mips/mips.h (RETURN_ADDR_RTX): For a leaf function
return a REG rtx for the return address register.

From-SVN: r50985

gcc/ChangeLog
gcc/config/mips/mips.h
gcc/config/mips/mips.md

index 615d43e08ead29817be3cdfdab6bda0abfadbbbf..429a2ff3ff21394ee503bb4fc9053b3630c61fcf 100644 (file)
@@ -1,3 +1,16 @@
+2002-03-18  Alexandre Oliva  <aoliva@redhat.com>
+
+       * config/mips/mips.h (ELIMINABLE_REGS): Can't eliminate
+       RETURN_ADDRESS_POINTER_REGNUM to $ra.
+       (CAN_ELIMINATE): Only eliminate it to $sp if a frame pointer is
+       not needed.  Disregard leaf_function_p().
+       (INITIAL_ELIMINATION_OFFSET): Adjust for elimination of rap to
+       mips16 frame pointer.
+       * config/mips/mips.md (store ra): Only to small SP offsets.
+       2001-08-22  Graham Stott  <grahams@redhat.com>
+       * config/mips/mips.h (RETURN_ADDR_RTX): For a leaf function
+       return a REG rtx for the return address register.
+
 2002-03-18  Bob Wilson  <bob.wilson@acm.org>
 
        * config/xtensa/xtensa.h (GO_IF_MODE_DEPENDENT_ADDRESS): Treat
index d72e851bbaa3f72918c27ab2ad02315061fe364d..bc09632e73fe70cf63e23c2632482bfb39e998b5 100644 (file)
@@ -2417,9 +2417,12 @@ extern enum reg_class mips_char_to_class[256];
    frame except by disassembling instructions in the prologue/epilogue.
    So currently we support only the current frame.  */
 
-#define RETURN_ADDR_RTX(count, frame)                  \
-  ((count == 0)                                                \
-   ? gen_rtx_MEM (Pmode, gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM))\
+#define RETURN_ADDR_RTX(count, frame)                                  \
+  (((count) == 0)                                                      \
+   ? (leaf_function_p ()                                               \
+      ? gen_rtx_REG (Pmode, GP_REG_FIRST + 31)                         \
+      : gen_rtx_MEM (Pmode, gen_rtx_REG (Pmode,                                \
+                                        RETURN_ADDRESS_POINTER_REGNUM))) \
    : (rtx) 0)
 
 /* Structure to be filled in by compute_frame_size with register
@@ -2483,7 +2486,6 @@ extern struct mips_frame_info current_frame_info;
  { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},               \
  { RETURN_ADDRESS_POINTER_REGNUM, GP_REG_FIRST + 30},                  \
  { RETURN_ADDRESS_POINTER_REGNUM, GP_REG_FIRST + 17},                  \
- { RETURN_ADDRESS_POINTER_REGNUM, GP_REG_FIRST + 31},                  \
  { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                                \
  { FRAME_POINTER_REGNUM, GP_REG_FIRST + 30},                           \
  { FRAME_POINTER_REGNUM, GP_REG_FIRST + 17}}
@@ -2510,10 +2512,8 @@ extern struct mips_frame_info current_frame_info;
 
 #define CAN_ELIMINATE(FROM, TO)                                                \
   (((FROM) == RETURN_ADDRESS_POINTER_REGNUM                            \
-    && ((! leaf_function_p ()                                          \
-        && ((TO) == STACK_POINTER_REGNUM                               \
-            || (TO) == HARD_FRAME_POINTER_REGNUM))                     \
-       || ((TO) == GP_REG_FIRST + 31 && leaf_function_p ())))          \
+    && (((TO) == STACK_POINTER_REGNUM && ! frame_pointer_needed)       \
+       || (TO) == HARD_FRAME_POINTER_REGNUM))                          \
    || ((FROM) != RETURN_ADDRESS_POINTER_REGNUM                         \
       && ((TO) == HARD_FRAME_POINTER_REGNUM                            \
          || ((TO) == STACK_POINTER_REGNUM && ! frame_pointer_needed    \
@@ -2553,11 +2553,11 @@ extern struct mips_frame_info current_frame_info;
      so we must add 4 bytes to the offset to get the right value.  */   \
   else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM)                     \
   {                                                                     \
-   if (leaf_function_p ())                                              \
-      (OFFSET) = 0;                                                     \
-   else (OFFSET) = current_frame_info.gp_sp_offset                      \
-              + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))      \
-                 * (BYTES_BIG_ENDIAN != 0));                            \
+    (OFFSET) = current_frame_info.gp_sp_offset                          \
+      + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))              \
+        * (BYTES_BIG_ENDIAN != 0));                                     \
+    if (TARGET_MIPS16 && (TO) != STACK_POINTER_REGNUM)                  \
+      (OFFSET) -= current_function_outgoing_args_size;                  \
   }                                                                     \
   else                                                                  \
     abort();                                                            \
@@ -4153,7 +4153,7 @@ while (0)
   "$0",   "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",                \
   "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",                \
   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",                \
-  "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "$fp",   "ra",       \
+  "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "$fp",  "ra",                \
   "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",       \
   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",      \
   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",      \
index b9490f045e01348f465b764669d501c3c8c34498..60d560b686896f0b6eca06dbdbb678bb54f0f5a5 100644 (file)
@@ -5489,22 +5489,25 @@ move\\t%0,%z4\\n\\
     }
 }")
 
-;; For mips16, we need a special case to handle storing $31 into
-;; memory, since we don't have a constraint to match $31.  This
-;; instruction can be generated by save_restore_insns.
+;; We can only store $ra directly into a small sp offset.  Should the
+;; offset be too wide, non-constant or not sp-based, leave it up to
+;; reload to choose a scratch register.
 
 (define_insn ""
-  [(set (match_operand:SI 0 "memory_operand" "=R,m")
+  [(set (mem:SI (plus:SI (reg:SI 29)
+                        (match_operand:SI 0 "small_int" "n")))
        (reg:SI 31))]
   "TARGET_MIPS16"
-  "*
-{
-  operands[1] = gen_rtx (REG, SImode, 31);
-  return mips_move_1word (operands, insn, FALSE);
-}"
+  "sw\\t$31,%0($sp)"
   [(set_attr "type"    "store")
    (set_attr "mode"    "SI")
-   (set_attr "length"  "4,8")])
+   (set_attr_alternative
+    "length"
+    [(if_then_else 
+      (lt (symbol_ref "(unsigned HOST_WIDE_INT) INTVAL (operands[0])")
+         (const_int 1024))
+      (const_int 4)
+      (const_int 8))])])
 
 ;; The difference between these two is whether or not ints are allowed
 ;; in FP registers (off by default, use -mdebugh to enable).