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

Re: MD representation of IA64 floating point operations

On Thu, 2004-07-22 at 15:06, Zack Weinberg wrote:
>   (set (match_operand:RF 0 "fr_register_operand" "=f")
>        (float_extend:RF
>          (float_truncate:SF
>            (plus:RF (match_operand:RF 1 "fr_register_operand" "%f")
>                     (match_operand:RF 2 "fr_reg_or_fp01_operand" "fG")))))

I don't like the (float_truncate:SF (plus:RF ...)) part of this.  This
implies to me that the value gets rounded twice, once to RF precision,
and once to SF precision.  This isn't correct.  The value get computed
to infinite precision, and then rounded once to the target precision. 
There is no double rounding error here, as the RTL implies.  However, we
don't have any way to represent this at the moment.  I think
  (plus:SF (reg:RF) (reg:RF))
would most accurately describe the hardware, but currently this is not
allowed as the operands of plus are supposed to have the same mode as
the plus.  Most FPUs do not have such an instruction, IA-64 is a little
unusual here that it supports it.  IA-64 allows FP operands to have any
type, and it does not round them before the operation.

But I think that is a moot point, as I think this change is unnecessary
and a bad idea.  I think you are confusing datatype with representation
here.  All gcc cares about is the datatype.  The representation is
irrelevant.  So the correct way to emit RTL for an SFmode operation is
exactly what is in the md file already.

Consider a 64-bit target that supports 32-bit operations.  We can still
define an addsi3 pattern the standard way.  It doesn't matter that we
are actually performing a 64-bit add on 64-bit registers, all that
matters is the datatypes of the inputs and outputs.  We may need
additional add patterns for special, or we might want to write addsi3
differently for other reasons, but there is no reason why you can't do
it this way.  See for instance the mips port.

If that isn't convincing, then look at the rs6000 (powerpc) port.  This
hardware always holds FP values as doubles even when rounded to single. 
The file still describes addsf3 using SFmode, without any
mention of DFmode, as the actual representation of the values doesn't

You will need a 5th FP mode, e.g. RFmode to describe the 82-bit register
format, and you will need new patterns to emit the instructions needed
by the div/sqrt/etc expanders.  But I don't see any need to change the
existing addsf3 pattern to accomplish this.  If you end up with too many
patterns, then we can look at ways to reduce the number of them, but I
am skeptical that this will be a problem.

Another issue here is what happens when pseudos get saved/restored, or
spilled to stack slots.  If you modify the addsf3 pattern as you
suggest, then suddenly all of these load/stores become
ldf.spill/stf.spill which move 16 bytes at a time.  This means that
programs will become bigger and slower for no reason.  We do need to use
the spill instructions if we have an RFmode value, but not if we have an
SFmode value, so we don't want to use RFmode unnecessarily.

Another possible issue is that someday we will want to add speculation
support.  When we have speculation, some FP values may have the NaT bit
set, and we may need or want to handle these values differently than
normal values which can not have the NaT bit set.  If we keep the SF/RF
distinction, then we have the option of using RFmode for values that
might have the NaT bit set.  These values do require the use of the
ldf.spill and stf.spill instructions, which will happen automatically
for RFmode values.

> An alternative would be equivalents of LOAD_EXTEND_OP and the like,
> for floating point modes.

Something has been done like this before for 64-bit machines that can
also hold 32-bit sign extended values in registers.  See the
se_register_operand and se_arith_operand predicates in the gcc-3.3.x
mips port.  They got dropped sometime before gcc-3.4, perhaps when the
mips backend rewrite got merged onto mainline.  This required some
machine independent support to accept SIGN_EXTEND in places where it
normally would not be accepted.  The same code could perhaps be extended
to handle FP conversion that do not change the underlying value. 
However, this is probably more trouble than it is worth unless you run
into serious problems, and I think that will be unlikely.
Jim Wilson, GNU Tools Support,

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