Richard Sandiford <rdsandif...@googlemail.com> writes:
> Matthew Fortune <matthew.fort...@imgtec.com> writes: 
> > 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

No, the single-precision only is 32-bit registers as you would assume.

> 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?

No it is me overcomplicating things. We can deal with it as part of the
R6 patch. I have however modified the mti vendor specs to infer -mfpxx
for specific architectures rather than for everything other than mips1
to make it ready for R6.

> (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.

I haven't forgotten about this last bit but it is not very high on my list
of things to do. (I'd still rather not bother doing it as I don't see it
as sufficiently valuable but if it needs doing it will fit in eventually)

Regards,
Matthew

Reply via email to