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 for loading floating point constants on IA64


This patch enables the loading of floating point constants on IA64.
Currently we load floating point constants (other than 0.0 and 1.0) from
memory and while we can't load floating point registers directly from a
constant we can put a constant in a general register and  them move that
to a floating point register.  That is how the HP and Intel compilers
load floating point constants and this patch allows GCC to do the same
thing.

I did some performance measurements and didn't see a large improvement
but in 64 bit mode (on HP-UX) I got a 0.25% improvement in SPECfp2006,
with 433.milc improving by 2.97%.  I also got a small improvement in
SPECint2006.

Tested on IA64 HP-UX and Linux with no regressions.

I plan on checking this in soon but wanted to post it first to see if
anyone has comments on it.

Steve Ellcey
sje@cup.hp.com

2009-04-21  Steve Ellcey  <sje@cup.hp.com>

	* config/ia64/ia64.md (movfs_internal): Allow flt constants.
	(movdf_internal): Ditto.
	* config/ia64/ia64.c (ia64_legitimate_constant_p): Allow
	SFmode and DFmode constants.
	(ia64_print_operand): Add 'G' format for printing
	floating point constants.


Index: config/ia64/ia64.md
===================================================================
--- config/ia64/ia64.md	(revision 146528)
+++ config/ia64/ia64.md	(working copy)
@@ -986,8 +986,8 @@ (define_expand "movsf"
 })
 
 (define_insn "movsf_internal"
-  [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
-	(match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
+  [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
+	(match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r, F"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    mov %0 = %F1
@@ -997,10 +997,11 @@ (define_insn "movsf_internal"
    setf.s %0 = %1
    mov %0 = %1
    ld4%O1 %0 = %1%P1
-   st4%Q0 %0 = %1%P0"
-  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")
+   st4%Q0 %0 = %1%P0
+   movl %0 = %G1"
+  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st,long_i")
    (set_attr "speculable1"   "yes")
-   (set_attr "speculable2"   "no,   yes,no, no,  no,  no, yes,no")])
+   (set_attr "speculable2"   "no,   yes,no, no,  no,  no, yes,no,no")])
 
 (define_expand "movdf"
   [(set (match_operand:DF 0 "general_operand" "")
@@ -1014,8 +1015,8 @@ (define_expand "movdf"
 })
 
 (define_insn "movdf_internal"
-  [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
-	(match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
+  [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
+	(match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r, F"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    mov %0 = %F1
@@ -1025,10 +1026,11 @@ (define_insn "movdf_internal"
    setf.d %0 = %1
    mov %0 = %1
    ld8%O1 %0 = %1%P1
-   st8%Q0 %0 = %1%P0"
-  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")
+   st8%Q0 %0 = %1%P0
+   movl %0 = %G1"
+  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st,long_i")
    (set_attr "speculable1"   "yes")
-   (set_attr "speculable2"   "no,   yes,no, no,  no,  no, yes,no")])
+   (set_attr "speculable2"   "no,   yes,no, no,  no,  no, yes,no,no")])
 
 ;; With no offsettable memory references, we've got to have a scratch
 ;; around to play with the second word if the variable winds up in GRs.
Index: config/ia64/ia64.c
===================================================================
--- config/ia64/ia64.c	(revision 146528)
+++ config/ia64/ia64.c	(working copy)
@@ -764,7 +764,8 @@ ia64_legitimate_constant_p (rtx x)
       return true;
 
     case CONST_DOUBLE:
-      if (GET_MODE (x) == VOIDmode)
+      if (GET_MODE (x) == VOIDmode || GET_MODE (x) == SFmode
+	  || GET_MODE (x) == DFmode)
 	return true;
       return satisfies_constraint_G (x);
 
@@ -4540,6 +4541,7 @@ ia64_print_operand_address (FILE * strea
    e    Print 64 - constant, for DImode rotates.
    F	A floating point constant 0.0 emitted as f0, or 1.0 emitted as f1, or
         a floating point register emitted normally.
+   G	A floating point constant.
    I	Invert a predicate register by adding 1.
    J    Select the proper predicate register for a condition.
    j    Select the inverse predicate register for a condition.
@@ -4627,6 +4629,24 @@ ia64_print_operand (FILE * file, rtx x, 
       fputs (str, file);
       return;
 
+    case 'G':
+      {
+	long val[4];
+	REAL_VALUE_TYPE rv;
+	REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+	real_to_target (val, &rv, GET_MODE (x));
+	if (GET_MODE (x) == SFmode)
+	  fprintf (file, "0x%08lx", val[0] & 0xffffffff);
+	else if (GET_MODE (x) == DFmode)
+	  fprintf (file, "0x%08lx%08lx", (WORDS_BIG_ENDIAN ? val[0] : val[1])
+					  & 0xffffffff,
+					 (WORDS_BIG_ENDIAN ? val[1] : val[0])
+					  & 0xffffffff);
+	else
+	  output_operand_lossage ("invalid %%G mode");
+      }
+      return;
+
     case 'I':
       fputs (reg_names [REGNO (x) + 1], file);
       return;


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