Fix discrepancies between devo and egcs.
authorNick Clifton <nickc@cygnus.com>
Tue, 13 Oct 1998 12:57:14 +0000 (12:57 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Tue, 13 Oct 1998 12:57:14 +0000 (12:57 +0000)
From-SVN: r23052

gcc/ChangeLog
gcc/config/v850/lib1funcs.asm
gcc/config/v850/v850.c
gcc/config/v850/v850.h
gcc/config/v850/v850.md

index 0adf8876dec027e1856a3925c14547ae5c7f3fd9..db482bc1295a63fa9ae61e1a8810630975473883 100644 (file)
@@ -1,3 +1,19 @@
+Tue Oct 13 12:51:04 1998  Nick Clifton  <nickc@cygnus.com>
+
+       * config/v850/lib1funcs.asm (_udivsi3): Add .type declaration.
+       Replace use of r5 with use of r19.
+
+       * config/v850/v850.h (LINK_POINTER_REGNUM): Define.
+
+       * config/v850/v850.c (compute_register_save_size): Allow for the
+       fact that helper functions save all registers, not just those used
+       by the function.
+       
+       Replace constant 31 with macro LINK_POINTER_REGNUM.
+
+       * config/v850/v850.md: Use 'indirect_operand' rather than
+       'memory_operand' for bit test/set/clear patterns.
+
 Tue Oct 13 11:49:14 1998  Jason Merrill  <jason@yorick.cygnus.com>
 
        * mips/iris6.h (ASM_OUTPUT_WEAK_ALIAS): Call ASM_GLOBALIZE_LABEL.
index 2787e97519a068a7269b5a442435adcbb25bd122..cb1f039fa048313cdf0b1b07e300c3c19880f8f6 100644 (file)
@@ -95,6 +95,7 @@ ___mulsi3:
 #ifdef L_udivsi3
        .text
        .global ___udivsi3
+       .type   ___udivsi3,@function
 ___udivsi3:
        mov 1,r12
        mov 0,r10
@@ -110,8 +111,8 @@ ___udivsi3:
        bnl .L12
        cmp r0,r12
        be .L8
-       mov r7,r5
-       and r13,r5
+       mov r7,r19
+       and r13,r19
        be .L4
        br .L12
 .L9:
index 092464029071e03bfe68e3a4e47859f37025be16..8afb2f3dcfc990b2bb1b8817ca287f208ef71779 100644 (file)
@@ -1398,12 +1398,12 @@ compute_register_save_size (p_reg_saved)
   int size = 0;
   int i;
   int interrupt_handler = v850_interrupt_function_p (current_function_decl);
-  int call_p = regs_ever_live[31];
+  int call_p = regs_ever_live [LINK_POINTER_REGNUM];
   long reg_saved = 0;
 
   /* Count the return pointer if we need to save it.  */
   if (profile_flag && !call_p)
-    regs_ever_live[31] = call_p = 1;
+    regs_ever_live [LINK_POINTER_REGNUM] = call_p = 1;
  
   /* Count space for the register saves.  */
   if (interrupt_handler)
@@ -1436,15 +1436,63 @@ compute_register_save_size (p_reg_saved)
            break;
          }
     }
-
   else
-    for (i = 0; i <= 31; i++)
-      if (regs_ever_live[i] && ((! call_used_regs[i]) || i == 31))
+    {
+      /* Find the first register that needs to be saved.  */
+      for (i = 0; i <= 31; i++)
+       if (regs_ever_live[i] && ((! call_used_regs[i])
+                                 || i == LINK_POINTER_REGNUM))
+         break;
+
+      /* If it is possible that an out-of-line helper function might be
+        used to generate the prologue for the current function, then we
+        need to cover the possibility that such a helper function will
+        be used, despite the fact that there might be gaps in the list of
+        registers that need to be saved.  To detect this we note that the
+        helper functions always push at least register r29 if the link
+        register is not used, and at least registers r27 - r31 if the
+        link register is used (and provided that the function is not an
+        interrupt handler).  */
+        
+      if (TARGET_PROLOG_FUNCTION
+         && (i == 2 || i >= 20)
+         && regs_ever_live[LINK_POINTER_REGNUM] ? (i < 28) : (i < 30))
        {
-         size += 4;
-         reg_saved |= 1L << i;
-       }
+         if (i == 2)
+           {
+             size += 4;
+             reg_saved |= 1L << i;
+
+             i = 20;
+           }
 
+         /* Helper functions save all registers between the starting
+            register and the last register, regardless of whether they
+            are actually used by the function or not.  */
+         for (; i <= 29; i++)
+           {
+             size += 4;
+             reg_saved |= 1L << i;
+           }
+
+         if (regs_ever_live [LINK_POINTER_REGNUM])
+           {
+             size += 4;
+             reg_saved |= 1L << LINK_POINTER_REGNUM;
+           }
+       }
+      else
+       {
+         for (; i <= 31; i++)
+           if (regs_ever_live[i] && ((! call_used_regs[i])
+                                     || i == LINK_POINTER_REGNUM))
+             {
+               size += 4;
+               reg_saved |= 1L << i;
+             }
+       }
+    }
+  
   if (p_reg_saved)
     *p_reg_saved = reg_saved;
 
@@ -1486,8 +1534,10 @@ expand_prologue ()
   if (interrupt_handler)
     {
       emit_insn (gen_save_interrupt ());
+      
       actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;
-      if (((1L << 31) & reg_saved) != 0)
+      
+      if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
        actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;
     }
 
@@ -1495,7 +1545,9 @@ expand_prologue ()
   else if (current_function_anonymous_args)
     {
       if (TARGET_PROLOG_FUNCTION)
-       emit_insn (gen_save_r6_r9 ());
+       {
+         emit_insn (gen_save_r6_r9 ());
+       }
       else
        {
          offset = 0;
@@ -1521,9 +1573,9 @@ expand_prologue ()
 
   /* If the return pointer is saved, the helper functions also allocate
      16 bytes of stack for arguments to be saved in.  */
-  if (((1L << 31) & reg_saved) != 0)
+  if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
     {
-      save_regs[num_save++] = gen_rtx (REG, Pmode, 31);
+      save_regs[num_save++] = gen_rtx (REG, Pmode, LINK_POINTER_REGNUM);
       default_stack = 16;
     }
 
@@ -1563,14 +1615,14 @@ expand_prologue ()
 
          if (TARGET_V850)
            {
-             XVECEXP (save_all, 0, num_save+1)
+             XVECEXP (save_all, 0, num_save + 1)
                = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 10));
            }
 
          offset = - default_stack;
          for (i = 0; i < num_save; i++)
            {
-             XVECEXP (save_all, 0, i+1)
+             XVECEXP (save_all, 0, i + 1)
                = gen_rtx (SET, VOIDmode,
                           gen_rtx (MEM, Pmode,
                                    plus_constant (stack_pointer_rtx, offset)),
@@ -1584,7 +1636,7 @@ expand_prologue ()
              rtx insn = emit_insn (save_all);
              INSN_CODE (insn) = code;
              actual_fsize -= alloc_stack;
-
+             
              if (TARGET_DEBUG)
                fprintf (stderr, "\
 Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
@@ -1602,9 +1654,10 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
   if (!save_all)
     {
       /* Special case interrupt functions that save all registers for a call.  */
-      if (interrupt_handler && ((1L << 31) & reg_saved) != 0)
-       emit_insn (gen_save_all_interrupt ());
-
+      if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
+       {
+         emit_insn (gen_save_all_interrupt ());
+       }
       else
        {
          /* If the stack is too big, allocate it in chunks so we can do the
@@ -1624,7 +1677,7 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
                                   GEN_INT (-init_stack_alloc)));
          
          /* Save the return pointer first.  */
-         if (num_save > 0 && REGNO (save_regs[num_save-1]) == 31)
+         if (num_save > 0 && REGNO (save_regs[num_save-1]) == LINK_POINTER_REGNUM)
            {
              emit_move_insn (gen_rtx (MEM, SImode,
                                       plus_constant (stack_pointer_rtx,
@@ -1688,7 +1741,7 @@ expand_epilogue ()
   if (interrupt_handler)
     {
       actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;
-      if (((1L << 31) & reg_saved) != 0)
+      if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
        actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;
     }
 
@@ -1707,9 +1760,9 @@ expand_epilogue ()
 
   /* If the return pointer is saved, the helper functions also allocate
      16 bytes of stack for arguments to be saved in.  */
-  if (((1L << 31) & reg_saved) != 0)
+  if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
     {
-      restore_regs[num_restore++] = gen_rtx (REG, Pmode, 31);
+      restore_regs[num_restore++] = gen_rtx (REG, Pmode, LINK_POINTER_REGNUM);
       default_stack = 16;
     }
 
@@ -1832,15 +1885,18 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
 
       /* Special case interrupt functions that save all registers
         for a call.  */
-      if (interrupt_handler && ((1L << 31) & reg_saved) != 0)
-       emit_insn (gen_restore_all_interrupt ());
+      if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
+       {
+         emit_insn (gen_restore_all_interrupt ());
+       }
       else
        {
          /* Restore registers from the beginning of the stack frame */
          offset = init_stack_free - 4;
 
          /* Restore the return pointer first.  */
-         if (num_restore > 0 && REGNO (restore_regs[num_restore-1]) == 31)
+         if (num_restore > 0
+             && REGNO (restore_regs [num_restore - 1]) == LINK_POINTER_REGNUM)
            {
              emit_move_insn (restore_regs[--num_restore],
                              gen_rtx (MEM, SImode,
@@ -2267,17 +2323,18 @@ construct_restore_jr (op)
     abort ();
 
   /* Discover the last register to pop.  */
-  if (mask & (1 << 31))
+  if (mask & (1 << LINK_POINTER_REGNUM))
     {
       if (stack_bytes != 16)
        abort ();
       
-      last = 31;
+      last = LINK_POINTER_REGNUM;
     }
   else
     {
       if (stack_bytes != 0)
        abort ();
+      
       if ((mask & (1 << 29)) == 0)
        abort ();
       
@@ -2453,12 +2510,12 @@ construct_save_jarl (op)
     abort ();
 
   /* Discover the last register to push.  */
-  if (mask & (1 << 31))
+  if (mask & (1 << LINK_POINTER_REGNUM))
     {
       if (stack_bytes != -16)
        abort ();
       
-      last = 31;
+      last = LINK_POINTER_REGNUM;
     }
   else
     {
index 8a417f079fc7d643d9398df241273681ddb18bca..6b9a9e2f62e5c4d781d771e0909e0e8e639d7f58 100644 (file)
@@ -573,6 +573,9 @@ enum reg_class
 /* Base register for access to local variables of the function.  */
 #define FRAME_POINTER_REGNUM 32
 
+/* Register containing return address from latest function call.  */
+#define LINK_POINTER_REGNUM 31
+     
 /* On some machines the offset between the frame pointer and starting
    offset of the automatic variables is not known until after register
    allocation has been done (for example, because the saved registers
index 0ba10ca0cc0222d95d3e9976bdfc246e10fe267a..42a95db4541404b45d57479b2e3b4f048e4ab405 100644 (file)
    (set_attr "cc" "clobber")])
 
 (define_insn "*v850_clr1_2"
-  [(set (match_operand:HI 0 "memory_operand" "=m")
+  [(set (match_operand:HI 0 "indirect_operand" "=m")
        (subreg:HI
          (and:SI (subreg:SI (match_dup 0) 0)
                  (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
    (set_attr "cc" "clobber")])
 
 (define_insn "*v850_clr1_3"
-  [(set (match_operand:SI 0 "memory_operand" "=m")
+  [(set (match_operand:SI 0 "indirect_operand" "=m")
        (and:SI (match_dup 0)
                (match_operand:SI 1 "not_power_of_two_operand" "")))]
   ""
    (set_attr "cc" "clobber")])
 
 (define_insn "*v850_set1_2"
-  [(set (match_operand:HI 0 "memory_operand" "=m")
+  [(set (match_operand:HI 0 "indirect_operand" "=m")
        (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
                           (match_operand 1 "power_of_two_operand" "")) 0))]
   ""
    (set_attr "cc" "clobber")])
 
 (define_insn "*v850_set1_3"
-  [(set (match_operand:SI 0 "memory_operand" "=m")
+  [(set (match_operand:SI 0 "indirect_operand" "=m")
        (ior:SI (match_dup 0)
                (match_operand 1 "power_of_two_operand" "")))]
   ""
    (set_attr "cc" "clobber")])
 
 (define_insn "*v850_not1_2"
-  [(set (match_operand:HI 0 "memory_operand" "=m")
+  [(set (match_operand:HI 0 "indirect_operand" "=m")
        (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
                           (match_operand 1 "power_of_two_operand" "")) 0))]
   ""
    (set_attr "cc" "clobber")])
 
 (define_insn "*v850_not1_3"
-  [(set (match_operand:SI 0 "memory_operand" "=m")
+  [(set (match_operand:SI 0 "indirect_operand" "=m")
        (xor:SI (match_dup 0)
                (match_operand 1 "power_of_two_operand" "")))]
   ""
  [(set_attr "length" "4")
   (set_attr "cc"     "clobber")])
 
-
-;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
-(define_insn "save_interrupt"
-  [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
-   (set (mem:SI (reg:SI 3)) (reg:SI 30))
-   (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
-   (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
-   (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
-  ""
-  "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
-  [(set_attr "length" "12")
-   (set_attr "cc" "clobber")])
-
-
-;; Save all registers except for the registers saved in save_interrupt when
-;; an interrupt function makes a call.
-;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
-;; all of memory.  This blocks insns from being moved across this point.
-;; This is needed because the rest of the compiler is not ready to handle
-;; insns this complicated.
-
-(define_insn "save_all_interrupt"
-  [(unspec_volatile [(const_int 0)] 0)]
-  ""
-  "jarl __save_all_interrupt,r10"
-  [(set_attr "length" "4")
-   (set_attr "cc" "clobber")])
-
-
-
-
 ;; This pattern will match a return RTX followed by any number of pop RTXs
 ;; and possible a stack adjustment as well.  These RTXs will be turned into
 ;; a suitable call to a worker function.
 
-
 (define_insn ""
 [(match_parallel 0 "pattern_is_ok_for_epilogue"
    [(return)
  [(set_attr "length" "4")
   (set_attr "cc"     "clobber")])
 
+;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
+(define_insn "save_interrupt"
+  [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
+   (set (mem:SI (reg:SI 3)) (reg:SI 30))
+   (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
+   (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
+   (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
+  "TARGET_V850"
+  "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
+  [(set_attr "length" "12")
+   (set_attr "cc" "clobber")])
+
 ;; Restore r1, r4, r10, and return from the interrupt
 (define_insn "restore_interrupt"
   [(return)
   [(set_attr "length" "4")
    (set_attr "cc" "clobber")])
 
+
+;; Save all registers except for the registers saved in save_interrupt when
+;; an interrupt function makes a call.
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory.  This blocks insns from being moved across this point.
+;; This is needed because the rest of the compiler is not ready to handle
+;; insns this complicated.
+
+(define_insn "save_all_interrupt"
+  [(unspec_volatile [(const_int 0)] 0)]
+  "TARGET_V850"
+  "jarl __save_all_interrupt,r10"
+  [(set_attr "length" "4")
+   (set_attr "cc" "clobber")])
+
+
 ;; Restore all registers saved when an interrupt function makes a call.
 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
 ;; all of memory.  This blocks insns from being moved across this point.
 
 (define_insn "restore_all_interrupt"
   [(unspec_volatile [(const_int 0)] 1)]
-  ""
+  "TARGET_V850"
   "jarl __restore_all_interrupt,r10"
   [(set_attr "length" "4")
    (set_attr "cc" "clobber")])