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