This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch for loading floating point constants on IA64
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 21 Apr 2009 10:39:49 -0700 (PDT)
- Subject: Patch for loading floating point constants on IA64
- Reply-to: sje at cup dot hp dot com
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;