Richard Sandiford <rdsandif...@googlemail.com> writes: > Matthew Fortune <matthew.fort...@imgtec.com> writes: > > I've realised that I may need to do 'something' to prevent GCC from > loading or > > storing DFmode/DImode values to/from FPRs using pairs of SWC1/LWC1 > when using > > an unaligned address. Initial tests show that when loading from an > unaligned > > address (4-byte aligned) then GCC loads the two halves of a 64-bit > value into > > GPRs and then moves across to FPRs. This is good but I don't know if > it is > > guaranteed. > > > > From what I can tell the backend doesn't specifically deal with > loading > > unaligned data but rather the normal load/store patterns are used by > the > > middle end. As such I'm not sure there is anything to prevent direct > loads > > to FPRs by parts. > > > > Do you know one way or the other if unaligned doubles can currently be > loaded > > via pairs of lwc1 (same for store) and if so can you advise on an > approach I > > could try to prevent this for FPXX? I will try to figure this out on > my own in > > the meantime. > > The port does handle some widths of unaligned access via the > {insv,extv,extzv}misalign patterns. That's how an unaligned DImode > value will be handled on 64-bit targets. > > The MIPS *misalign patterns only handle integer modes, so for other > types of mode the target-independent code will fall back to using an > integer load followed by a subreg (or a subreg followed by an integer > store). IIRC that's how an unaligned DFmode access will be handled on > 64-bit targets. > > For modes that are larger or smaller than *misalign can handle, > the target-independent code has to split the access up into smaller > pieces and reassemble them. And these pieces have to have integer > modes. > E.g. on 32-bit targets a 4-byte-misaligned load into (reg:DF x) could be > done by loading (subreg:SI (reg:DF x) 0) and (subreg:SI (reg:DF x) 4). > The thing that prevents these individual loads from using LWC1 is > CANNOT_CHANGE_MODE_CLASS, which (among other things) makes it invalid > for any target-independent code to reduce a subreg of an FPR pair > to an individual FPR. > > [FWIW, the reason MIPS doesn't define {insv,extv,extzv}misalign for > things > like DImode on 32-bit targets is because there's no special architecture > feature than can be used. It's just a case of decomposing the access. > Since that's a general technique, we want to make the target-independent > code do it as well as possible rather than handle it in a port-specific > way.] > > So yeah, the combination of (a) STRICT_ALIGNMENT, (b) the lack of > unaligned > floating-point load/store patterns and (c) CANNOT_CHANGE_MODE_CLASS > should > guarantee what you want.
Thanks for all the details. I did not know if CANNOT_CHANGE_MODE_CLASS would give this guarantee as I am conscious of MIPS 1 having to do pairs of LWC1/SWC1 for doubles. However, if I understand the code correctly the LWC1/SWC1 pairs are generated by splits for MIPS 1 and not directly from target-independent code so CANNOT_CHANGE_MODE_CLASS does not impact that explicit splitting logic. Is that right? Regards, Matthew