Fix oinitialisation of frame pointer in interrupt functions.
authorNick Clifton <nickc@cambridge.redhat.com>
Sun, 24 Jun 2001 09:46:02 +0000 (09:46 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Sun, 24 Jun 2001 09:46:02 +0000 (09:46 +0000)
Fix compile time warnings

From-SVN: r43540

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.h

index b5acd57cff27396bcc0183f990414c60a8e36792..d0ad198fa1708269e55390aedfcb2a876bb213d2 100644 (file)
@@ -1,3 +1,17 @@
+2001-06-24  Nick Clifton  <nickc@cambridge.redhat.com>
+
+       * config/arm/arm.c (arm_compute_save_reg_mask): For FIQ interrupt
+       handlers examine register r0-r7, for other interrupt handlers
+       examine r0-r12.  If the interrupt handler is not a leaf function
+       save all call clobbered registers.
+       (arm_output_epilogue): If the prologue has pushed the IP register,
+       restore it here.
+       (Arm_expand_prologue): For interrupt functions that need the frame
+       pointer, push the IP register before it is corrupted.
+
+       * config/arm/arm.h (ARM_SIGN_EXTEND): Fix compile time warnings
+       about the use of signed and unsigned quantities in a conditional.
+
 2001-06-23  Richard Henderson  <rth@redhat.com>
 
        * config/alpha/crtfastmath.c: New file.
index a1ce9c0f53cfaeb6439edc5f51eb661ae81bad1f..c1f78873350e6768d903a19396af7938d87238a5 100644 (file)
@@ -43,6 +43,7 @@ Boston, MA 02111-1307, USA.  */
 #include "ggc.h"
 #include "except.h"
 #include "c-pragma.h"
+#include "integrate.h"
 #include "tm_p.h"
 
 /* Forward definitions of types.  */
@@ -6931,12 +6932,29 @@ arm_compute_save_reg_mask ()
   if (IS_VOLATILE (func_type))
     return save_reg_mask;
 
-  if (ARM_FUNC_TYPE (func_type) == ARM_FT_ISR)
+  if (IS_INTERRUPT (func_type))
     {
-      /* FIQ handlers have registers r8 - r12 banked, so
-        we only need to check r0 - r7, they must save them.  */
-      for (reg = 0; reg < 8; reg++)
-       if (regs_ever_live[reg])
+      unsigned int max_reg;
+      
+      /* Interrupt functions must not corrupt any registers,
+        even call clobbered ones.  If this is a leaf function
+        we can just examine the registers used by the RTL, but
+        otherwise we have to assume that whatever function is
+        called might clobber anything, and so we have to save
+        all the call-clobbered registers as well.  */
+      if (ARM_FUNC_TYPE (func_type) == ARM_FT_FIQ)
+       /* FIQ handlers have registers r8 - r12 banked, so
+          we only need to check r0 - r7, Normal ISRs only
+          bank r14 and r15, so ew must check up to r12.
+          r13 is the stack pointer which is always preserved,
+          so we do not need to consider it here.  */
+       max_reg = 7;
+      else
+       max_reg = 12;
+       
+      for (reg = 0; reg <= max_reg; reg++)
+       if (regs_ever_live[reg]
+           || (! current_function_is_leaf && call_used_regs [reg]))
          save_reg_mask |= (1 << reg);
     }
   else
@@ -7410,6 +7428,11 @@ arm_output_epilogue (really_return)
        saved_regs_mask &= ~ (1 << PC_REGNUM);
       
       print_multi_reg (f, "ldmea\t%r", FP_REGNUM, saved_regs_mask);
+
+      if (IS_INTERRUPT (func_type))
+       /* Interrupt handlers will have pushed the
+          IP onto the stack, so restore it now.  */
+       print_multi_reg (f, "ldmea\t%r", SP_REGNUM, 1 << IP_REGNUM);
     }
   else
     {
@@ -7783,7 +7806,15 @@ arm_expand_prologue ()
 
   if (frame_pointer_needed)
     {
-      if (IS_NESTED (func_type))
+      if (IS_INTERRUPT (func_type))
+       {
+         /* Interrupt functions must not corrupt any registers.
+            Creating a frame pointer however, corrupts the IP
+            register, so we must push it first.  */
+         insn = emit_multi_reg_push (1 << IP_REGNUM);
+         RTX_FRAME_RELATED_P (insn) = 1;
+       }
+      else if (IS_NESTED (func_type))
        {
          /* The Static chain register is the same as the IP register
             used as a scratch register during stack frame creation.
@@ -8925,7 +8956,7 @@ replace_symbols_in_block (block, orig, new)
              )
            continue;
 
-         DECL_RTL (sym) = new;
+         SET_DECL_RTL (sym, new);
        }
       
       replace_symbols_in_block (BLOCK_SUBBLOCKS (block), orig, new);
index 8cd8b93f448204968cdc16a1c22c4d3ca320ae96..ed444db8029d230d896220d984ab95977dd4bc77 100644 (file)
@@ -969,8 +969,8 @@ extern const char * structure_size_string;
    If we have to have a frame pointer we might as well make use of it.
    APCS says that the frame pointer does not need to be pushed in leaf
    functions, or simple tail call functions.  */
-#define FRAME_POINTER_REQUIRED                                         \
-  (current_function_has_nonlocal_label                                 \
+#define FRAME_POINTER_REQUIRED                                 \
+  (current_function_has_nonlocal_label                         \
    || (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()))
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
@@ -2758,12 +2758,12 @@ extern int making_const_table;
 #define HOST_UINT(x) ((unsigned HOST_WIDE_INT) x)
 #endif
 
-#define ARM_SIGN_EXTEND(x)  ((HOST_WIDE_INT)   \
-  (HOST_BITS_PER_WIDE_INT <= 32 ? (x)          \
-   : (((x) & HOST_UINT (0xffffffff)) |         \
-      (((x) & HOST_UINT (0x80000000))          \
-       ? ((~ HOST_INT (0))                     \
-         & ~ HOST_UINT(0xffffffff))            \
+#define ARM_SIGN_EXTEND(x)  ((HOST_WIDE_INT)                   \
+  (HOST_BITS_PER_WIDE_INT <= 32 ? (unsigned HOST_WIDE_INT) (x) \
+   : ((((unsigned HOST_WIDE_INT)(x)) & HOST_UINT (0xffffffff)) |\
+      ((((unsigned HOST_WIDE_INT)(x)) & HOST_UINT (0x80000000))        \
+       ? ((~ HOST_UINT (0))                                    \
+         & ~ HOST_UINT(0xffffffff))                            \
        : 0))))
 
 /* Output the address of an operand.  */