diff --git a/gcc/config/m68k/m68k.cc b/gcc/config/m68k/m68k.cc index 6cd45b53406..b1c9238949f 100644 --- a/gcc/config/m68k/m68k.cc +++ b/gcc/config/m68k/m68k.cc @@ -197,6 +197,7 @@ static bool m68k_modes_tieable_p (machine_mode, machine_mode); static machine_mode m68k_promote_function_mode (const_tree, machine_mode, int *, const_tree, int); static void m68k_asm_final_postscan_insn (FILE *, rtx_insn *insn, rtx [], int); +static HARD_REG_SET m68k_zero_call_used_regs (HARD_REG_SET); /* Initialize the GCC target structure. */ @@ -361,6 +362,9 @@ static void m68k_asm_final_postscan_insn (FILE *, rtx_insn *insn, rtx [], int); #undef TARGET_ASM_FINAL_POSTSCAN_INSN #define TARGET_ASM_FINAL_POSTSCAN_INSN m68k_asm_final_postscan_insn +#undef TARGET_ZERO_CALL_USED_REGS +#define TARGET_ZERO_CALL_USED_REGS m68k_zero_call_used_regs + TARGET_GNU_ATTRIBUTES (m68k_attribute_table, { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, @@ -7166,4 +7170,46 @@ m68k_promote_function_mode (const_tree type, machine_mode mode, return mode; } +/* Implement TARGET_ZERO_CALL_USED_REGS. */ + +static HARD_REG_SET +m68k_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs) +{ + rtx zero_fpreg = NULL_RTX; + + for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno)) + { + rtx reg, zero; + + if (INT_REGNO_P (regno)) + { + reg = regno_reg_rtx[regno]; + zero = CONST0_RTX (SImode); + } + else if (FP_REGNO_P (regno)) + { + reg = gen_raw_REG (SFmode, regno); + if (zero_fpreg == NULL_RTX) + { + /* On the 040/060 clearing an FP reg loads a large + immediate. To reduce code size use the first + cleared FP reg to clear remaining ones. Don't do + this on cores which use fmovecr. */ + zero = CONST0_RTX (SFmode); + if (TUNE_68040_60) + zero_fpreg = reg; + } + else + zero = zero_fpreg; + } + else + gcc_unreachable (); + + emit_move_insn (reg, zero); + } + + return need_zeroed_hardregs; +} + #include "gt-m68k.h" diff --git a/gcc/testsuite/gcc.target/m68k/pr110934.c b/gcc/testsuite/gcc.target/m68k/pr110934.c new file mode 100644 index 00000000000..8c21d46f660 --- /dev/null +++ b/gcc/testsuite/gcc.target/m68k/pr110934.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { do-options "-fzero-call-used-regs=used -fpic -O2" } */ + +extern double clobber_fp0 (void); + +void foo (void) +{ + clobber_fp0 (); +}