* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128347
138bc75d-0d04-0410-961f-
82ee72b054a4
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>
+
* config/mips/mips.h (MIPS_ARCH_FLOAT_SPEC): New macro.
* config/mips/mips.c (mips_cpu_info_table): Mention it in the
the introductory comment.
if (TARGET_CALL_SAVED_GP && current_function_is_leaf)
for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
if (!df_regs_ever_live_p (regno)
- && call_used_regs[regno]
+ && call_really_used_regs[regno]
&& !fixed_regs[regno]
&& regno != PIC_FUNCTION_ADDR_REGNUM)
return regno;
return TARGET_CALL_SAVED_GP && cfun->machine->global_pointer == regno;
/* 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;
- /* 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
- register to be used without the even register. */
- if (FP_REG_P (regno)
- && MAX_FPRS_PER_FMT == 2
- && df_regs_ever_live_p (regno + 1)
- && !call_used_regs[regno + 1])
- return true;
+ /* 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
+ register to be used without the even register. */
+ if (FP_REG_P (regno)
+ && MAX_FPRS_PER_FMT == 2
+ && df_regs_ever_live_p (regno + 1)
+ && !call_really_used_regs[regno + 1])
+ return true;
/* We need to save the old frame pointer before setting up a new one. */
if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
return true;
/* We need to save the incoming return address if it is ever clobbered
- within the function. */
- if (regno == GP_REG_FIRST + 31 && df_regs_ever_live_p (regno))
+ within the function, if __builtin_eh_return is being used to set a
+ 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;
- 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;
}
/* This loop must iterate over the same space as its companion in
mips_for_each_saved_reg. */
- for (regno = (FP_REG_LAST - MAX_FPRS_PER_FMT + 1);
- regno >= FP_REG_FIRST;
- regno -= MAX_FPRS_PER_FMT)
- {
+ if (TARGET_HARD_FLOAT)
+ for (regno = (FP_REG_LAST - MAX_FPRS_PER_FMT + 1);
+ regno >= FP_REG_FIRST;
+ regno -= MAX_FPRS_PER_FMT)
if (mips_save_reg_p (regno))
{
fp_reg_size += MAX_FPRS_PER_FMT * UNITS_PER_FPREG;
fmask |= ((1 << MAX_FPRS_PER_FMT) - 1) << (regno - FP_REG_FIRST);
}
- }
gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
+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>
* g++.dg/ext/va-arg-pack-1.C: New test.
--- /dev/null
+/* 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)" } } */
--- /dev/null
+/* 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)" } } */
--- /dev/null
+/* 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)" } } */
# $mips_isa: the ISA level specified by __mips
# $mips_arch: the architecture specified by _MIPS_ARCH
# $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_forced_isa: true if the command line uses -march=* or -mips*
global mips_isa
global mips_arch
global mips_mips16
- global mips_mips64
+ global mips_gp64
+ global mips_fp64
global mips_float
global mips_forced_isa
int mips16 = 1;
#endif
#ifdef __mips64
- int mips64 = 1;
+ int gp64 = 1;
+ #endif
+ #if __mips_fpr==64
+ int fp64 = 1;
#endif
#ifdef __mips_hard_float
const char *float = "hard";
regexp {isa = ([^;]*)} $output dummy mips_isa
regexp {arch = "([^"]*)} $output dummy mips_arch
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
set mips_forced_isa [regexp -- {(-mips|-march)} $compiler_flags]
proc is_gp32_flag {flag} {
switch -glob -- $flag {
-msmartmips -
+ -mips[12] -
-march=mips32* -
-mgp32 { return 1 }
default { return 0 }
global mips_isa
global mips_arch
global mips_mips16
- global mips_mips64
+ global mips_gp64
+ global mips_fp64
global mips_float
global mips_forced_isa
# First handle the -mgp* options. Add an architecture option if necessary.
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} {
set matches 0
} else {
append flags " -mabi=32"
}
- } elseif {$flag == "-mgp64" && !$mips_mips64} {
+ } elseif {$flag == "-mgp64" && !$mips_gp64} {
if {$mips_forced_abi} {
set matches 0
} else {