This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR target/66824: -miamcu doesn't load FP constant into register directly


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]