mirror of git://gcc.gnu.org/git/gcc.git
mips.c (mips_global_pointer): Check call_really_used_regs instead of call_used_regs.
gcc/ * config/mips/mips.c (mips_global_pointer): Check call_really_used_regs instead of call_used_regs. (mips_save_reg_p): Likewise. Save all call-saved registers if current_function_saves_all_registers. Fix indentation. No longer treat $18 as a special case. (compute_frame_size): Guard FPR loop with TARGET_HARD_FLOAT. gcc/testsuite/ * gcc.target/mips/call-saved-1.c: New test. * gcc.target/mips/call-saved-2.c: Likewise. * gcc.target/mips/call-saved-3.c: Likewise. * gcc.target/mips/mips.exp (setup_mips_tests): Set mips_gp64 instead of mips_mips64. Set mips_fp64 too. (is_gp32_flag): Return true for -mips1 and -mips2. (dg-mips-options): Use mips_gp64 instead of mips_mips64. From-SVN: r128347
This commit is contained in:
parent
7d8bed7be6
commit
04910611bd
|
|
@ -1,3 +1,12 @@
|
||||||
|
2007-09-10 Richard Sandiford <richard@codesourcery.com>
|
||||||
|
|
||||||
|
* config/mips/mips.c (mips_global_pointer): Check
|
||||||
|
call_really_used_regs instead of call_used_regs.
|
||||||
|
(mips_save_reg_p): Likewise. Save all call-saved registers
|
||||||
|
if current_function_saves_all_registers. Fix indentation.
|
||||||
|
No longer treat $18 as a special case.
|
||||||
|
(compute_frame_size): Guard FPR loop with TARGET_HARD_FLOAT.
|
||||||
|
|
||||||
2007-09-10 Richard Sandiford <richard@codesourcery.com>
|
2007-09-10 Richard Sandiford <richard@codesourcery.com>
|
||||||
|
|
||||||
* config/mips/mips.h (MIPS_ARCH_FLOAT_SPEC): New macro.
|
* config/mips/mips.h (MIPS_ARCH_FLOAT_SPEC): New macro.
|
||||||
|
|
|
||||||
|
|
@ -6852,7 +6852,7 @@ mips_global_pointer (void)
|
||||||
if (TARGET_CALL_SAVED_GP && current_function_is_leaf)
|
if (TARGET_CALL_SAVED_GP && current_function_is_leaf)
|
||||||
for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
|
for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
|
||||||
if (!df_regs_ever_live_p (regno)
|
if (!df_regs_ever_live_p (regno)
|
||||||
&& call_used_regs[regno]
|
&& call_really_used_regs[regno]
|
||||||
&& !fixed_regs[regno]
|
&& !fixed_regs[regno]
|
||||||
&& regno != PIC_FUNCTION_ADDR_REGNUM)
|
&& regno != PIC_FUNCTION_ADDR_REGNUM)
|
||||||
return regno;
|
return regno;
|
||||||
|
|
@ -6918,43 +6918,33 @@ mips_save_reg_p (unsigned int regno)
|
||||||
return TARGET_CALL_SAVED_GP && cfun->machine->global_pointer == regno;
|
return TARGET_CALL_SAVED_GP && cfun->machine->global_pointer == regno;
|
||||||
|
|
||||||
/* Check call-saved registers. */
|
/* Check call-saved registers. */
|
||||||
if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
|
if ((current_function_saves_all_registers || df_regs_ever_live_p (regno))
|
||||||
|
&& !call_really_used_regs[regno])
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Save both registers in an FPR pair if either one is used. This is
|
/* Save both registers in an FPR pair if either one is used. This is
|
||||||
needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd
|
needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd
|
||||||
register to be used without the even register. */
|
register to be used without the even register. */
|
||||||
if (FP_REG_P (regno)
|
if (FP_REG_P (regno)
|
||||||
&& MAX_FPRS_PER_FMT == 2
|
&& MAX_FPRS_PER_FMT == 2
|
||||||
&& df_regs_ever_live_p (regno + 1)
|
&& df_regs_ever_live_p (regno + 1)
|
||||||
&& !call_used_regs[regno + 1])
|
&& !call_really_used_regs[regno + 1])
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* We need to save the old frame pointer before setting up a new one. */
|
/* We need to save the old frame pointer before setting up a new one. */
|
||||||
if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
|
if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* We need to save the incoming return address if it is ever clobbered
|
/* We need to save the incoming return address if it is ever clobbered
|
||||||
within the function. */
|
within the function, if __builtin_eh_return is being used to set a
|
||||||
if (regno == GP_REG_FIRST + 31 && df_regs_ever_live_p (regno))
|
different return address, or if a stub is being used to return a
|
||||||
|
value in FPRs. */
|
||||||
|
if (regno == GP_REG_FIRST + 31
|
||||||
|
&& (df_regs_ever_live_p (regno)
|
||||||
|
|| current_function_calls_eh_return
|
||||||
|
|| mips16_cfun_returns_in_fpr_p ()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (TARGET_MIPS16)
|
|
||||||
{
|
|
||||||
/* $18 is a special case in mips16 code. It may be used to call
|
|
||||||
a function which returns a floating point value, but it is
|
|
||||||
marked in call_used_regs. */
|
|
||||||
if (regno == GP_REG_FIRST + 18 && df_regs_ever_live_p (regno))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* $31 is also a special case. It will be used to copy a return
|
|
||||||
value into the floating point registers if the return value is
|
|
||||||
floating point. */
|
|
||||||
if (regno == GP_REG_FIRST + 31
|
|
||||||
&& mips16_cfun_returns_in_fpr_p ())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7124,16 +7114,15 @@ compute_frame_size (HOST_WIDE_INT size)
|
||||||
|
|
||||||
/* This loop must iterate over the same space as its companion in
|
/* This loop must iterate over the same space as its companion in
|
||||||
mips_for_each_saved_reg. */
|
mips_for_each_saved_reg. */
|
||||||
for (regno = (FP_REG_LAST - MAX_FPRS_PER_FMT + 1);
|
if (TARGET_HARD_FLOAT)
|
||||||
regno >= FP_REG_FIRST;
|
for (regno = (FP_REG_LAST - MAX_FPRS_PER_FMT + 1);
|
||||||
regno -= MAX_FPRS_PER_FMT)
|
regno >= FP_REG_FIRST;
|
||||||
{
|
regno -= MAX_FPRS_PER_FMT)
|
||||||
if (mips_save_reg_p (regno))
|
if (mips_save_reg_p (regno))
|
||||||
{
|
{
|
||||||
fp_reg_size += MAX_FPRS_PER_FMT * UNITS_PER_FPREG;
|
fp_reg_size += MAX_FPRS_PER_FMT * UNITS_PER_FPREG;
|
||||||
fmask |= ((1 << MAX_FPRS_PER_FMT) - 1) << (regno - FP_REG_FIRST);
|
fmask |= ((1 << MAX_FPRS_PER_FMT) - 1) << (regno - FP_REG_FIRST);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
|
gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
|
||||||
total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
|
total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,13 @@
|
||||||
|
2007-09-10 Richard Sandiford <richard@codesourcery.com>
|
||||||
|
|
||||||
|
* gcc.target/mips/call-saved-1.c: New test.
|
||||||
|
* gcc.target/mips/call-saved-2.c: Likewise.
|
||||||
|
* gcc.target/mips/call-saved-3.c: Likewise.
|
||||||
|
* gcc.target/mips/mips.exp (setup_mips_tests): Set mips_gp64
|
||||||
|
instead of mips_mips64. Set mips_fp64 too.
|
||||||
|
(is_gp32_flag): Return true for -mips1 and -mips2.
|
||||||
|
(dg-mips-options): Use mips_gp64 instead of mips_mips64.
|
||||||
|
|
||||||
2007-09-10 Jakub Jelinek <jakub@redhat.com>
|
2007-09-10 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* g++.dg/ext/va-arg-pack-1.C: New test.
|
* g++.dg/ext/va-arg-pack-1.C: New test.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* Check that we save all call-saved GPRs in a MIPS16 __builtin_eh_return
|
||||||
|
function. */
|
||||||
|
/* { dg-mips-options "-mips2 -mips16 -mno-abicalls" } */
|
||||||
|
|
||||||
|
void bar (void);
|
||||||
|
void
|
||||||
|
foo (int x)
|
||||||
|
{
|
||||||
|
__builtin_unwind_init ();
|
||||||
|
__builtin_eh_return (x, bar);
|
||||||
|
}
|
||||||
|
/* { dg-final { scan-assembler "\\\$16" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$17" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$18" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$19" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$20" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$21" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$22" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$23" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$(30|fp)" } } */
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
/* Check that we save non-MIPS16 GPRs if they are explicitly clobbered. */
|
||||||
|
/* { dg-mips-options "-mips2 -mips16 -mno-abicalls -O2" } */
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (void)
|
||||||
|
{
|
||||||
|
asm volatile ("" ::: "$19", "$23", "$24", "$30");
|
||||||
|
}
|
||||||
|
/* { dg-final { scan-assembler-not "\\\$16" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\\\$17" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\\\$18" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$19" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\\\$20" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\\\$21" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\\\$22" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$23" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\\\$24" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$(30|fp)" } } */
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* Check that we save all call-saved GPRs in a MIPS16 __builtin_setjmp
|
||||||
|
function. */
|
||||||
|
/* { dg-mips-options "-mips2 -mips16 -mno-abicalls -O2" } */
|
||||||
|
|
||||||
|
void bar (void);
|
||||||
|
extern int buf[];
|
||||||
|
void
|
||||||
|
foo (int x)
|
||||||
|
{
|
||||||
|
if (__builtin_setjmp (buf) == 0)
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
/* { dg-final { scan-assembler "\\\$16" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$17" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$18" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$19" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$20" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$21" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$22" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$23" } } */
|
||||||
|
/* { dg-final { scan-assembler "\\\$(30|fp)" } } */
|
||||||
|
|
@ -31,7 +31,8 @@ load_lib gcc-dg.exp
|
||||||
# $mips_isa: the ISA level specified by __mips
|
# $mips_isa: the ISA level specified by __mips
|
||||||
# $mips_arch: the architecture specified by _MIPS_ARCH
|
# $mips_arch: the architecture specified by _MIPS_ARCH
|
||||||
# $mips_mips16: true if MIPS16 mode is selected
|
# $mips_mips16: true if MIPS16 mode is selected
|
||||||
# $mips_mips64: true if 64-bit output is selected
|
# $mips_gp64: true if 64-bit output is selected
|
||||||
|
# $mips_fp64: true if 64-bit FPRs are selected
|
||||||
# $mips_float: "hard" or "soft"
|
# $mips_float: "hard" or "soft"
|
||||||
#
|
#
|
||||||
# $mips_forced_isa: true if the command line uses -march=* or -mips*
|
# $mips_forced_isa: true if the command line uses -march=* or -mips*
|
||||||
|
|
@ -44,7 +45,8 @@ proc setup_mips_tests {} {
|
||||||
global mips_isa
|
global mips_isa
|
||||||
global mips_arch
|
global mips_arch
|
||||||
global mips_mips16
|
global mips_mips16
|
||||||
global mips_mips64
|
global mips_gp64
|
||||||
|
global mips_fp64
|
||||||
global mips_float
|
global mips_float
|
||||||
|
|
||||||
global mips_forced_isa
|
global mips_forced_isa
|
||||||
|
|
@ -66,7 +68,10 @@ proc setup_mips_tests {} {
|
||||||
int mips16 = 1;
|
int mips16 = 1;
|
||||||
#endif
|
#endif
|
||||||
#ifdef __mips64
|
#ifdef __mips64
|
||||||
int mips64 = 1;
|
int gp64 = 1;
|
||||||
|
#endif
|
||||||
|
#if __mips_fpr==64
|
||||||
|
int fp64 = 1;
|
||||||
#endif
|
#endif
|
||||||
#ifdef __mips_hard_float
|
#ifdef __mips_hard_float
|
||||||
const char *float = "hard";
|
const char *float = "hard";
|
||||||
|
|
@ -81,7 +86,8 @@ proc setup_mips_tests {} {
|
||||||
regexp {isa = ([^;]*)} $output dummy mips_isa
|
regexp {isa = ([^;]*)} $output dummy mips_isa
|
||||||
regexp {arch = "([^"]*)} $output dummy mips_arch
|
regexp {arch = "([^"]*)} $output dummy mips_arch
|
||||||
set mips_mips16 [regexp {mips16 = 1} $output]
|
set mips_mips16 [regexp {mips16 = 1} $output]
|
||||||
set mips_mips64 [regexp {mips64 = 1} $output]
|
set mips_gp64 [regexp {gp64 = 1} $output]
|
||||||
|
set mips_fp64 [regexp {fp64 = 1} $output]
|
||||||
regexp {float = "([^"]*)} $output dummy mips_float
|
regexp {float = "([^"]*)} $output dummy mips_float
|
||||||
|
|
||||||
set mips_forced_isa [regexp -- {(-mips|-march)} $compiler_flags]
|
set mips_forced_isa [regexp -- {(-mips|-march)} $compiler_flags]
|
||||||
|
|
@ -96,6 +102,7 @@ proc setup_mips_tests {} {
|
||||||
proc is_gp32_flag {flag} {
|
proc is_gp32_flag {flag} {
|
||||||
switch -glob -- $flag {
|
switch -glob -- $flag {
|
||||||
-msmartmips -
|
-msmartmips -
|
||||||
|
-mips[12] -
|
||||||
-march=mips32* -
|
-march=mips32* -
|
||||||
-mgp32 { return 1 }
|
-mgp32 { return 1 }
|
||||||
default { return 0 }
|
default { return 0 }
|
||||||
|
|
@ -149,7 +156,8 @@ proc dg-mips-options {args} {
|
||||||
global mips_isa
|
global mips_isa
|
||||||
global mips_arch
|
global mips_arch
|
||||||
global mips_mips16
|
global mips_mips16
|
||||||
global mips_mips64
|
global mips_gp64
|
||||||
|
global mips_fp64
|
||||||
global mips_float
|
global mips_float
|
||||||
|
|
||||||
global mips_forced_isa
|
global mips_forced_isa
|
||||||
|
|
@ -164,13 +172,15 @@ proc dg-mips-options {args} {
|
||||||
|
|
||||||
# First handle the -mgp* options. Add an architecture option if necessary.
|
# First handle the -mgp* options. Add an architecture option if necessary.
|
||||||
foreach flag $flags {
|
foreach flag $flags {
|
||||||
if {[is_gp32_flag $flag] && $mips_mips64} {
|
if {[is_gp32_flag $flag]
|
||||||
|
&& ($mips_gp64
|
||||||
|
|| ($mips_fp64 && [lsearch $flags -mfp64] < 0)) } {
|
||||||
if {$mips_forced_abi} {
|
if {$mips_forced_abi} {
|
||||||
set matches 0
|
set matches 0
|
||||||
} else {
|
} else {
|
||||||
append flags " -mabi=32"
|
append flags " -mabi=32"
|
||||||
}
|
}
|
||||||
} elseif {$flag == "-mgp64" && !$mips_mips64} {
|
} elseif {$flag == "-mgp64" && !$mips_gp64} {
|
||||||
if {$mips_forced_abi} {
|
if {$mips_forced_abi} {
|
||||||
set matches 0
|
set matches 0
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue