Re: Issue with subregs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux