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