This is the mail archive of the
mailing list for the GCC project.
Re: [patch] MIPS: 64bit floating point support for MIPS32R2
David Ung <email@example.com> writes:
> Richard Sandiford wrote:
>> David Ung <firstname.lastname@example.org> writes:
>>> Richard Sandiford wrote:
>>>>I'm still a little worried about that cannot_change_mode_class hunk;
>>>>do you know off-hand why it's needed?
>>>hmm. If I still recall this correctly. The check (FP_INC > 1) is no
>>>longer valid for gp32+fp64, but there still needs a
>>>reg_classes_intersect_p (FP_REGS, class) check to ensure we ain't
>>>simply converting between 32bit integer and 64bit floats. The check
>>>at the end of the function will catch 32bit -> 64bit float, but not
>>>64bit -> 32bit. It should allow pattens such as subreg:SI (reg:DF) or
>>>even the paradoxical subreg:DI (reg:SF) provided they fit. But
>>>subreg:SF (reg:DI) is a no no.
>> I'm probably being dense here, but why is it a no-no? How is it
>> different from the -mgp64 -mfp64 case?
> I am guessing here since I don't have a real example, so correct me if I am wrong,
> In -mgp32 -mfp32, if you have
> set (subreg:SF (reg:DI X) 0) (reg:SF Y)
> set (subreg:SF (reg:DI X) 4) (reg:SF Z)
> will mean allocation X to a float register eg $f0, and you get
> set (reg:SF $f0) (reg:SF Y)
> set (reg:SF $f1) (reg:SF Z)
> in -mgp32 -mfp64:
> set (reg:SF $f0) (reg:SF Y)
> set (reg:SF ???) (reg:SF Z)
> there just no patterns to match that, nor are
> set (subreg:SF (reg:DI $f0) 4) ...
> in -mgp64 -mfp64, would you even generate the above patterns?
Ah, thanks, I think I see now. It's the non-lowpart subregs you're
worried about. That's what I'd failed to grasp from the earlier
conversation. (The existing function is dealing with cases where
even lowpart subregs are invalid.)
So the issue you're dealing with is that gcc assumes that each word
of a multiword value can be accessed using SUBREGs. I suppose this
situation is the same as MMX registers on the x86, which are also
handled by CANNOT_CHANGE_MODE_CLASS.
In that case, I agree you're taking the right kind of approach,
but I don't think the patch is quite right. It's disallowing all
conversions in which one mode is bigger than a word and the other
mode isn't. It also triggers for TARGET_64BIT, where this
particular restriction doesn't apply. Does something like:
/* gcc assumes that each word of a multiword register can be accessed
individually using SUBREGs. This is not true for floating-point
registers if they are bigger than a word. */
if (UNITS_PER_FPREG > UNITS_PER_WORD
&& GET_MODE_SIZE (from) > UNITS_PER_WORD
&& GET_MODE_SIZE (to) < UNITS_PER_FPREG
&& reg_classes_intersect_p (FP_REGS, class))
in the outer scope of the function work? (Yeah, it's a bit of a mouthful.)
We'll still need to add the "&& TARGET_64BIT" to the LOAD_EXTEND_OP-related
hunk as I mentioned in passing before.
> Complex modes makes it more tricky. And O32 doesn't even defind how
> they are handled as argument / return values in 32/64 bit.
Good point. ;)
Thanks for your patience here.