Matthew Fortune <matthew.fort...@imgtec.com> writes:
>> Let's step back a bit.  Please explain which case you were trying to
>> handle with the specs patch.  Rejecting -msingle-float -mfp64 seems
>> fine.
>> Fiddling with the specs to stop that combination reaching the assembler
>> is what seemed odd.
>
> So, perhaps this is a 'vendor' issue too like some other debates we have
> had in this area. I presume the --with arguments are intended to
> be used to configure a single purpose toolchain that targets a specific
> ABI. So if used to construct a single-float toolchain then --with-fp=64
> would not be used. And if configured using --with-fp=64 then it is OK to
> have an error if using -msingle-float.

Yeah, it sounds like it could be a vendor issue.  IMO there are two useful
ways that a configuration can handle --with: (a) build the same multilibs
regardless of the --with option but let the --with option control the
default; or (b) deselect any multilibs that are incompatible with the
--with option.  The simple configurations like mips64*-linux-gnu and
mips64-elf do (a), but for configurations that usually have lots of
multilibs I can imagine it would make sense to do (b).  Obviously your
call for your toolchains (as long as we can avoid the ASM_SPEC magic).

> I am actually considering implications of adding support for MIPS64r6
> to GCC which I have not posted yet, sorry :-).

I don't think you're making anyone suffer from an undersupply of patches. :-)

> MIPSr6 only supports 64-bit registers which naturally leads to needing
> -mfp64. MIPSr6 does however also support a single-precision only variant.
>
> For a single purpose native toolchain then --with-fp=64 can be used xor
> --with-fpu=single to get the desired tools.

Hmm, does that really mean that an FPU that only implements S/W-format
instructions must still have 64-bit registers?  And are MTHC1 and MFHC1
therefore always supported for single-float-only FPUs?  The r6 documentation
I downloaded made it sound like 32-bit FPUs were still allowed for
S/W-only FPUs but that 64-bit FPUs are required if D/L-format
instructions are supported.

Or is this more a single-precision+MSA thing?

(Can't really respond to the later specs stuff without understanding
this part first.)

>> >> >> > diff --git a/gcc/testsuite/gcc.target/mips/call-clobbered-2.c
>> >> >> b/gcc/testsuite/gcc.target/mips/call-clobbered-2.c
>> >> >> > new file mode 100644
>> >> >> > index 0000000..f47cdda
>> >> >> > --- /dev/null
>> >> >> > +++ b/gcc/testsuite/gcc.target/mips/call-clobbered-2.c
>> >> >> > @@ -0,0 +1,21 @@
>> >> >> > +/* Check that we handle call-clobbered FPRs correctly.  */
>> >> >> > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" }
>> } */
>> >> >> > +/* { dg-options "-mabi=32 -modd-spreg -mfp32 -ffixed-f0 -
>> ffixed-f1 -
>> >> >> ffixed-f2 -ffixed-f3 -ffixed-f4 -ffixed-f5 -ffixed-f6 -ffixed-f7 -
>> >> ffixed-f8
>> >> >> -ffixed-f9 -ffixed-f10 -ffixed-f11 -ffixed-f12 -ffixed-f13 -
>> ffixed-f14 -
>> >> >> ffixed-f15 -ffixed-f16 -ffixed-f17 -ffixed-f18 -ffixed-f19 -
>> ffixed-f20 -
>> >> >> ffixed-f22 -ffixed-f24 -ffixed-f26 -ffixed-f28 -ffixed-f30" } */
>> >> >> > +
>> >> >> > +void bar (void);
>> >> >> > +float a;
>> >> >> > +float
>> >> >> > +foo ()
>> >> >> > +{
>> >> >> > +  float b = a + 1.0f;
>> >> >> > +  bar();
>> >> >> > +  return b;
>> >> >> > +}
>> >> >> > +/* { dg-final { scan-assembler-times "lwc1" 2 } } */
>> >> >> > +/* { dg-final { scan-assembler-not "swc1" } } */
>> >> >> > +/* { dg-final { scan-assembler-times "sdc1" 2 } } */
>> >> >> > +/* { dg-final { scan-assembler-not "mtc" } } */
>> >> >> > +/* { dg-final { scan-assembler-not "mfc" } } */
>> >> >> > +/* { dg-final { scan-assembler-not "mthc" } } */
>> >> >> > +/* { dg-final { scan-assembler-not "mfhc" } } */
>> >> >>
>> >> >> Why require sdc1 here?  Would Chao-Ying's patch make this use SWC1
>> and
>> >> LWC1
>> >> >> exclusively?
>> >> >
>> >> > The SDC1 instructions are for callee-saved registers. I'll add the
>> >> > check for two corresponding LDC1 instructions in the epilogue
>> though
>> >> > since I've noticed them being missing.
>> >>
>> >> I'm probably being dense, sorry, but why is SDC1 needed for -mfp32
>> >> -modd-spreg?  Can't we just save and restore the odd register?
>> >> That's technically more correct too, since we shouldn't really touch
>> >> -ffixed registers.
>> >
>> > You are correct and I am/was aware of this...
>> >
>> > GCC is saving too much of the callee-saved registers when single-
>> precision
>> > values are live in them but this is historic behaviour. The code which
>> > controls this is very complex and I'd be worried about breaking it.
>> The
>> > fix would be invasive as all the logic is honed towards the notion of
>> > 64-bit callee-saved registers.
>> 
>> But that's because it was written before separate odd spregs came along.
>> I'm not convinced the situation is as bad as you say.
>>
>> > One thing to say is that this test is
>> > a very aggressive test of ABI not normal compiler behaviour. Normally
>> > an even-numbered callee-saved register would be used first followed by
>> the
>> > odd meaning that it is rare to only use the odd register. That flips
>> the
>> > problem round to single precision data in even registers...
>> >
>> > I believe that prior to mips32 introducing odd-numbered single-
>> precision
>> > registers then GCC will have been saving and restoring using sdc1/ldc1
>> > for even-numbered registers regardless of whether they are used for
>> > single or double precision data (for mips1 it also will do pairs of
>> > lwc1/swc1).
>> 
>> Sure.  And saving and restoring both using LDC1 and SDC1 is still
>> the right thing to do if both registers are clobbered.  But if only
>> one is clobbered then we should save just that.  It's really just
>> the same principle as Chao-ying's patch, but applied to the prologue
>> and epilogue.
>> 
>> > My vote FWIW is to leave this behaviour as is, if you would like it
>> looking
>> > in to then it is a separate issue to FPXX I believe. Going forward
>> with
>> > the FPXX ABI becoming the norm then we have to save/restore 64-bit
>> registers
>> > anyway so the fix may not be of much value for end users.
>> 
>> It isn't really that separate from -modd-spreg.  We shouldn't add tests
>> for wrong output.
>
> I'm not confident that it would be the right thing to change this
> behaviour. While the test is slightly weird in that the compiler generates
> code that touches a -ffixed-reg this is just an ABI test.
>
> == Taken from MIPS ABI supplement ==
> Only registers $f20.$f30 are preserved across a function call. All other 
> float-
> ing-point registers can change across a function call. However, functions
> that use any of $f20.$f30 for single-precision operations only must still save
> and restore the corresponding odd-numbered register since the odd-num-
> bered register contents are left undefined by single-precision operations
> == end == 

Like Maciej says, this was written for MIPS I.  -modd-spreg means that
single-precision ops on even registers no longer clobber the associated
odd-numbered register.

I can't hope to match Maciej's reply on the details, but like he says,
my understanding was that this:

> ADD.D $f20, $f10, $f10
> MOV.D $f18, $f20
> SWC1 $f20, 0($sp)
> MTC1 $2, $f20
> LWC1 $f20, 0($sp)
> ADD.D $f16, $f18, $f20
> ($f16 should be 4*$f10)

really is required to work for -modd-spreg.  Specifically I thought the
LWC1 would force $f20 to be become "uninterpreted" and then the ADD.D
would need to (re)interpret the register pair as D-format.

Thanks,
Richard

Reply via email to