ix86_split_long_move can optimize floating point constant move, which can be used to optimize SFmode move for IA MCU.
OK for trunk if there is no regression? H.J. --- gcc/ PR target/66824 * config/i386/i386.c (ix86_split_to_parts): Allow SFmode move for IA MCU. (ix86_split_long_move): Support single move. * config/i386/i386.md (FP splitter): Allow SFmode for IA MCU. gcc/testsuite/ PR target/66824 * gcc.target/i386/pr66824.c: New test. --- gcc/config/i386/i386.c | 14 +++++++++++++- gcc/config/i386/i386.md | 3 ++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e4e505c..aceeb13 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -22747,7 +22747,9 @@ ix86_split_to_parts (rtx operand, rtx *parts, machine_mode mode) size = (GET_MODE_SIZE (mode) + 4) / 8; gcc_assert (!REG_P (operand) || !MMX_REGNO_P (REGNO (operand))); - gcc_assert (size >= 2 && size <= 4); + /* For IA MCU, we can optimize SFmode load. */ + gcc_assert ((size >= 2 || (TARGET_IAMCU && mode == SFmode)) + && size <= 4); /* Optimize constant pool reference to immediates. This is used by fp moves, that force all constants to memory to allow combining. */ @@ -22825,10 +22827,14 @@ ix86_split_to_parts (rtx operand, rtx *parts, machine_mode mode) case DFmode: REAL_VALUE_TO_TARGET_DOUBLE (r, l); break; + case SFmode: + REAL_VALUE_TO_TARGET_SINGLE (r, l[0]); + goto part0; default: gcc_unreachable (); } parts[1] = gen_int_mode (l[1], SImode); +part0: parts[0] = gen_int_mode (l[0], SImode); } else @@ -22935,6 +22941,12 @@ ix86_split_long_move (rtx operands[]) nparts = ix86_split_to_parts (operands[1], part[1], GET_MODE (operands[0])); ix86_split_to_parts (operands[0], part[0], GET_MODE (operands[0])); + if (nparts == 1) + { + emit_move_insn (part[0][0], part[1][0]); + return; + } + /* When emitting push, take care for source operands on the stack. */ if (push && MEM_P (operands[1]) && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1])) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 1d43aaf..e723eab 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3507,7 +3507,8 @@ "reload_completed && (GET_MODE (operands[0]) == TFmode || GET_MODE (operands[0]) == XFmode - || GET_MODE (operands[0]) == DFmode) + || GET_MODE (operands[0]) == DFmode + || (TARGET_IAMCU && GET_MODE (operands[0]) == SFmode)) && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))" [(const_int 0)] "ix86_split_long_move (operands); DONE;") -- 2.4.3