This is the mail archive of the gcc@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]

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


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