Commit 29a65e3d by Nick Clifton Committed by Nick Clifton

Fix discrepancies between devo and egcs.

From-SVN: r23052
parent 48ad5afd
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> Tue Oct 13 11:49:14 1998 Jason Merrill <jason@yorick.cygnus.com>
* mips/iris6.h (ASM_OUTPUT_WEAK_ALIAS): Call ASM_GLOBALIZE_LABEL. * mips/iris6.h (ASM_OUTPUT_WEAK_ALIAS): Call ASM_GLOBALIZE_LABEL.
......
...@@ -95,6 +95,7 @@ ___mulsi3: ...@@ -95,6 +95,7 @@ ___mulsi3:
#ifdef L_udivsi3 #ifdef L_udivsi3
.text .text
.global ___udivsi3 .global ___udivsi3
.type ___udivsi3,@function
___udivsi3: ___udivsi3:
mov 1,r12 mov 1,r12
mov 0,r10 mov 0,r10
...@@ -110,8 +111,8 @@ ___udivsi3: ...@@ -110,8 +111,8 @@ ___udivsi3:
bnl .L12 bnl .L12
cmp r0,r12 cmp r0,r12
be .L8 be .L8
mov r7,r5 mov r7,r19
and r13,r5 and r13,r19
be .L4 be .L4
br .L12 br .L12
.L9: .L9:
......
...@@ -1398,12 +1398,12 @@ compute_register_save_size (p_reg_saved) ...@@ -1398,12 +1398,12 @@ compute_register_save_size (p_reg_saved)
int size = 0; int size = 0;
int i; int i;
int interrupt_handler = v850_interrupt_function_p (current_function_decl); 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; long reg_saved = 0;
/* Count the return pointer if we need to save it. */ /* Count the return pointer if we need to save it. */
if (profile_flag && !call_p) 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. */ /* Count space for the register saves. */
if (interrupt_handler) if (interrupt_handler)
...@@ -1436,15 +1436,63 @@ compute_register_save_size (p_reg_saved) ...@@ -1436,15 +1436,63 @@ compute_register_save_size (p_reg_saved)
break; break;
} }
} }
else 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; if (i == 2)
reg_saved |= 1L << i; {
} 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) if (p_reg_saved)
*p_reg_saved = reg_saved; *p_reg_saved = reg_saved;
...@@ -1486,8 +1534,10 @@ expand_prologue () ...@@ -1486,8 +1534,10 @@ expand_prologue ()
if (interrupt_handler) if (interrupt_handler)
{ {
emit_insn (gen_save_interrupt ()); emit_insn (gen_save_interrupt ());
actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE; 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; actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;
} }
...@@ -1495,7 +1545,9 @@ expand_prologue () ...@@ -1495,7 +1545,9 @@ expand_prologue ()
else if (current_function_anonymous_args) else if (current_function_anonymous_args)
{ {
if (TARGET_PROLOG_FUNCTION) if (TARGET_PROLOG_FUNCTION)
emit_insn (gen_save_r6_r9 ()); {
emit_insn (gen_save_r6_r9 ());
}
else else
{ {
offset = 0; offset = 0;
...@@ -1521,9 +1573,9 @@ expand_prologue () ...@@ -1521,9 +1573,9 @@ expand_prologue ()
/* If the return pointer is saved, the helper functions also allocate /* If the return pointer is saved, the helper functions also allocate
16 bytes of stack for arguments to be saved in. */ 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; default_stack = 16;
} }
...@@ -1563,14 +1615,14 @@ expand_prologue () ...@@ -1563,14 +1615,14 @@ expand_prologue ()
if (TARGET_V850) 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)); = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 10));
} }
offset = - default_stack; offset = - default_stack;
for (i = 0; i < num_save; i++) 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 (SET, VOIDmode,
gen_rtx (MEM, Pmode, gen_rtx (MEM, Pmode,
plus_constant (stack_pointer_rtx, offset)), plus_constant (stack_pointer_rtx, offset)),
...@@ -1584,7 +1636,7 @@ expand_prologue () ...@@ -1584,7 +1636,7 @@ expand_prologue ()
rtx insn = emit_insn (save_all); rtx insn = emit_insn (save_all);
INSN_CODE (insn) = code; INSN_CODE (insn) = code;
actual_fsize -= alloc_stack; actual_fsize -= alloc_stack;
if (TARGET_DEBUG) if (TARGET_DEBUG)
fprintf (stderr, "\ fprintf (stderr, "\
Saved %d bytes via prologue function (%d vs. %d) for function %s\n", 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", ...@@ -1602,9 +1654,10 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
if (!save_all) if (!save_all)
{ {
/* Special case interrupt functions that save all registers for a call. */ /* Special case interrupt functions that save all registers for a call. */
if (interrupt_handler && ((1L << 31) & reg_saved) != 0) if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
emit_insn (gen_save_all_interrupt ()); {
emit_insn (gen_save_all_interrupt ());
}
else else
{ {
/* If the stack is too big, allocate it in chunks so we can do the /* 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", ...@@ -1624,7 +1677,7 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
GEN_INT (-init_stack_alloc))); GEN_INT (-init_stack_alloc)));
/* Save the return pointer first. */ /* 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, emit_move_insn (gen_rtx (MEM, SImode,
plus_constant (stack_pointer_rtx, plus_constant (stack_pointer_rtx,
...@@ -1688,7 +1741,7 @@ expand_epilogue () ...@@ -1688,7 +1741,7 @@ expand_epilogue ()
if (interrupt_handler) if (interrupt_handler)
{ {
actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE; 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; actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;
} }
...@@ -1707,9 +1760,9 @@ expand_epilogue () ...@@ -1707,9 +1760,9 @@ expand_epilogue ()
/* If the return pointer is saved, the helper functions also allocate /* If the return pointer is saved, the helper functions also allocate
16 bytes of stack for arguments to be saved in. */ 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; default_stack = 16;
} }
...@@ -1832,15 +1885,18 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n", ...@@ -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 /* Special case interrupt functions that save all registers
for a call. */ for a call. */
if (interrupt_handler && ((1L << 31) & reg_saved) != 0) if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
emit_insn (gen_restore_all_interrupt ()); {
emit_insn (gen_restore_all_interrupt ());
}
else else
{ {
/* Restore registers from the beginning of the stack frame */ /* Restore registers from the beginning of the stack frame */
offset = init_stack_free - 4; offset = init_stack_free - 4;
/* Restore the return pointer first. */ /* 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], emit_move_insn (restore_regs[--num_restore],
gen_rtx (MEM, SImode, gen_rtx (MEM, SImode,
...@@ -2267,17 +2323,18 @@ construct_restore_jr (op) ...@@ -2267,17 +2323,18 @@ construct_restore_jr (op)
abort (); abort ();
/* Discover the last register to pop. */ /* Discover the last register to pop. */
if (mask & (1 << 31)) if (mask & (1 << LINK_POINTER_REGNUM))
{ {
if (stack_bytes != 16) if (stack_bytes != 16)
abort (); abort ();
last = 31; last = LINK_POINTER_REGNUM;
} }
else else
{ {
if (stack_bytes != 0) if (stack_bytes != 0)
abort (); abort ();
if ((mask & (1 << 29)) == 0) if ((mask & (1 << 29)) == 0)
abort (); abort ();
...@@ -2453,12 +2510,12 @@ construct_save_jarl (op) ...@@ -2453,12 +2510,12 @@ construct_save_jarl (op)
abort (); abort ();
/* Discover the last register to push. */ /* Discover the last register to push. */
if (mask & (1 << 31)) if (mask & (1 << LINK_POINTER_REGNUM))
{ {
if (stack_bytes != -16) if (stack_bytes != -16)
abort (); abort ();
last = 31; last = LINK_POINTER_REGNUM;
} }
else else
{ {
......
...@@ -573,6 +573,9 @@ enum reg_class ...@@ -573,6 +573,9 @@ enum reg_class
/* Base register for access to local variables of the function. */ /* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM 32 #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 /* On some machines the offset between the frame pointer and starting
offset of the automatic variables is not known until after register offset of the automatic variables is not known until after register
allocation has been done (for example, because the saved registers allocation has been done (for example, because the saved registers
......
...@@ -397,7 +397,7 @@ ...@@ -397,7 +397,7 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "*v850_clr1_2" (define_insn "*v850_clr1_2"
[(set (match_operand:HI 0 "memory_operand" "=m") [(set (match_operand:HI 0 "indirect_operand" "=m")
(subreg:HI (subreg:HI
(and:SI (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 0) 0)
(match_operand:HI 1 "not_power_of_two_operand" "")) 0))] (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
...@@ -417,7 +417,7 @@ ...@@ -417,7 +417,7 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "*v850_clr1_3" (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) (and:SI (match_dup 0)
(match_operand:SI 1 "not_power_of_two_operand" "")))] (match_operand:SI 1 "not_power_of_two_operand" "")))]
"" ""
...@@ -461,7 +461,7 @@ ...@@ -461,7 +461,7 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "*v850_set1_2" (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) (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
(match_operand 1 "power_of_two_operand" "")) 0))] (match_operand 1 "power_of_two_operand" "")) 0))]
"" ""
...@@ -485,7 +485,7 @@ ...@@ -485,7 +485,7 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "*v850_set1_3" (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) (ior:SI (match_dup 0)
(match_operand 1 "power_of_two_operand" "")))] (match_operand 1 "power_of_two_operand" "")))]
"" ""
...@@ -534,7 +534,7 @@ ...@@ -534,7 +534,7 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "*v850_not1_2" (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) (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
(match_operand 1 "power_of_two_operand" "")) 0))] (match_operand 1 "power_of_two_operand" "")) 0))]
"" ""
...@@ -558,7 +558,7 @@ ...@@ -558,7 +558,7 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "*v850_not1_3" (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) (xor:SI (match_dup 0)
(match_operand 1 "power_of_two_operand" "")))] (match_operand 1 "power_of_two_operand" "")))]
"" ""
...@@ -1183,42 +1183,10 @@ ...@@ -1183,42 +1183,10 @@
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "cc" "clobber")]) (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 ;; 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 ;; and possible a stack adjustment as well. These RTXs will be turned into
;; a suitable call to a worker function. ;; a suitable call to a worker function.
(define_insn "" (define_insn ""
[(match_parallel 0 "pattern_is_ok_for_epilogue" [(match_parallel 0 "pattern_is_ok_for_epilogue"
[(return) [(return)
...@@ -1233,6 +1201,18 @@ ...@@ -1233,6 +1201,18 @@
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "cc" "clobber")]) (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 ;; Restore r1, r4, r10, and return from the interrupt
(define_insn "restore_interrupt" (define_insn "restore_interrupt"
[(return) [(return)
...@@ -1246,6 +1226,22 @@ ...@@ -1246,6 +1226,22 @@
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "cc" "clobber")]) (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. ;; Restore all registers saved when an interrupt function makes a call.
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
;; all of memory. This blocks insns from being moved across this point. ;; all of memory. This blocks insns from being moved across this point.
...@@ -1254,7 +1250,7 @@ ...@@ -1254,7 +1250,7 @@
(define_insn "restore_all_interrupt" (define_insn "restore_all_interrupt"
[(unspec_volatile [(const_int 0)] 1)] [(unspec_volatile [(const_int 0)] 1)]
"" "TARGET_V850"
"jarl __restore_all_interrupt,r10" "jarl __restore_all_interrupt,r10"
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment