Fix discrepancies between devo and egcs.
From-SVN: r23052
This commit is contained in:
parent
48ad5afd7d
commit
29a65e3dd4
5 changed files with 144 additions and 71 deletions
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
size += 4;
|
||||
reg_saved |= 1L << i;
|
||||
}
|
||||
{
|
||||
/* 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))
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -397,7 +397,7 @@
|
|||
(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))]
|
||||
|
@ -417,7 +417,7 @@
|
|||
(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" "")))]
|
||||
""
|
||||
|
@ -461,7 +461,7 @@
|
|||
(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))]
|
||||
""
|
||||
|
@ -485,7 +485,7 @@
|
|||
(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" "")))]
|
||||
""
|
||||
|
@ -534,7 +534,7 @@
|
|||
(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))]
|
||||
""
|
||||
|
@ -558,7 +558,7 @@
|
|||
(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" "")))]
|
||||
""
|
||||
|
@ -1183,42 +1183,10 @@
|
|||
[(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)
|
||||
|
@ -1233,6 +1201,18 @@
|
|||
[(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)
|
||||
|
@ -1246,6 +1226,22 @@
|
|||
[(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.
|
||||
|
@ -1254,7 +1250,7 @@
|
|||
|
||||
(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")])
|
||||
|
|
Loading…
Add table
Reference in a new issue