Henri Cloetens <henri.cloetens@xxxxxxxxxx> writes: > Hello Segher, all, > > - It is indeed true subreg only works on bytes. > - So, I changed the declaration: > a. I declared all 12 condition code bits as BYTES (QI) > b. I split it in 4 CC fields (cfr below), and declared each of these > as SI. > - Then, the compare addresses the CC field in SI mode, the branch in QI > mode, and all goes well. I mean, it does not matter if I declare SI > or BI, because > the compare instruction only writes 0 or 1, and the branch > instruction tests only > for 0 or 1. > - With all goes well, I mean, gcc-9.2.0 correctly writes the CC field, > and then correctly > picks the correct subreg for the branch. > - BUT ... the test still fails. I refer here to "emit-rtl.c", function > validate_subreg() in gcc-9.2.0 > the test on line 1024. It is commented why it fails : > OSIZE is not a multiple of REGSIZE. The intend here is to have > REGSIZE as byte, but the > routine calculates REGSIZE as REGMODE_NATURAL_SIZE(imode). > I do not understand this. I mean, imode is SImode, but in the backend > description, it is > described that 4 registers of the CC field are necessary to hold an > operand of type SImode. > - Is this a bug ?, or, what did I wrong ?. Sorry if this was already suggested downthread (didn't see it), but: what's UNITS_PER_WORD on your target? Normally it's not possible to split hard registers into smaller chunks than that and still refer to each chunk using a subreg. So under the normal scheme, each individually-addressable register would need to be word_mode or bigger. But that of course leaves the composite registers being ridiculously big. Another unfortunate assumption from the old days is: case MODE_CC: /* Again, nothing more need be said. For historical reasons, the size of a CC mode is four units. */ validate_mode (m, UNSET, UNSET, UNSET, UNSET, UNSET); m->bytesize = 4; m->ncomponents = 1; m->component = 0; break; (genmodes.c). Nothing much should depend on this behaviour though. So one option might be to: - Add a new genmodes.c macro (e.g. CC_MODE_WITH_SIZE) that creates a CC mode with a specific byte size. - Create a 1-byte CC mode for the individual registers. - Create a larger CC modes for the composite forms. - Define REGMODE_NATURAL_SIZE to 1 for these CC modes (but leave it at UNITS_PER_WORD for other modes. Thanks, Richard