This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RFC: PowerPC floating point features
- From: Michael Eager <eager at eagercon dot com>
- To: GCC <gcc at gcc dot gnu dot org>
- Date: Fri, 04 Apr 2008 16:05:47 -0700
- Subject: RFC: PowerPC floating point features
Xilinx has a PowerPC 405 processor with an attached
single precision floating point processor. I have a
patch which supports this FP unit, but want to clean
it up a bit before submitting it.
There are a number of different flags which are used
to specify different FP support. I'd like to simplify
this a bit.
The current flags are
TARGET_SOFT_FLOAT
TARGET_HARD_FLOAT (== !TARGET_SOFT_FLOAT)
TARGET_FPRS
TARGET_E500_SINGLE
TARGET_E500_DOUBLE
There seems to be some overlap in meanings, leading
to confusing qualifications for instruction patterns.
It appears that !TARGET_FPRS is used to imply that the
target is an E500, since TARGET_FPRS == 0 if and only if
TARGET_E500 == 1, but TARGET_E500_{SINGLE|DOUBLE} also
imply TARGET_E500. TARGET_HARD_FLOAT is also frequently
qualified with other options which themselves are only
valid with a hardware FPU.
This is the processor/option matrix I've come up with:
| GPRS | FPRS
-------------------------------------_
Single | E500_SINGLE | Xilinx FPU
--------------------------------------
Double | E500_DOUBLE | Book E FPU
Here's what I propose:
Add TARGET_SINGLE_FLOAT and TARGET_DOUBLE_FLOAT which
indicate hardware support for these respective FP operations.
Set TARGET_SINGLE_FLOAT where TARGET_E500_SINGLE is set.
Set TARGET_DOUBLE_FLOAT where TARGET_E500_DOUBLE is set.
Replace TARGET_E500_SINGLE with (TARGET_SINGLE_FLOAT && TARGET_E500).
[Alternately this could be (TARGET_SINGLE_FLOAT && !TARGET_FPRS) but
I dislike negative logic.)
Replace TARGET_E500_DOUBLE with (TARGET_DOUBLE_FLOAT && TARGET_E500).
Replace !TARGET_HARD_FLOAT with TARGET_SOFT_FLOAT.
Replace TARGET_HARD_FLOAT with (TARGET_SINGLE_FLOAT || TARGET_DOUBLE_FLOAT)
(usually with other qualifications).
Replace TARGET_FPRS with !TARGET_E500.
Replace !TARGET_FPRS with
(TARGET_E500 && (TARGET_SINGLE_FLOAT || TARGET_DOUBLE_FLOAT).
Add -msingle-float and -mdouble-float to set TARGET_SINGLE_FLOAT
and TARGET_DOUBLE_FLOAT respectively.
Here's an example conversion:
(define_expand "negdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
"")
would become
(define_expand "negdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_DOUBLE_FLOAT"
"")
I've considered a couple variants. One (which is actually implemented
in my patch) has TARGET_DOUBLE_FLOAT imply TARGET_SINGLE_FLOAT, since
every DP FPU that is supported also supports SP operations, but I'd
prefer having the feature explicit. The other is to retain TARGET_FPRS
instead of using TARGET_E500, since this would be more feature-based
rather than processor model based.
Comments and/or suggestions?
--
Michael Eager eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306 650-325-8077