>> (insn 5559 5558 5560 694 pp_pack.c:2144 (set (reg:SI 1421)
>> (plus:SI (subreg:SI (reg:QI 1420) 0)
>> (const_int -32 [0xffffffe0]))) 121 {*addsi3_5200} (insn_list
>> 5558 (nil))
>> (nil))
>
>So register 1420 is being assigned to a data register. The
>constraints for addsi3_5200 permit the following alternatives:
> mem += datareg
> addrreg = addrreg + reg|constant
> addrreg = reg|constant + addrreg
> reg += mem|reg|constant
>There is no alternative which permits adding a data register and a
>constant and putting the result in an address register. So reload
>picks the alternative "addrreg = addrreg + reg|constant", and decides
>to reload register 1420 into an address register. But that fails
>because reload can't find an address register which can accept a
>QImode value.
Would it help to rearrange the constraints to have reg +=
mem|reg|constant before the addreg += ... ?
>Looking at the dump a little more, it's far from clear why register
>1421 is being put into an address register. I see that insn 5560
>wants to compare a byte value which it finds there, so it doesn't seem
>like a good fit to put 1421 into an address register.
>
>
>I don't know where else register 1421 is being used, so my tentative
>guess would be that gcc is picking an address register based on the
>constraints in addsi3_5200. Perhaps you need to change "?a" to "*a".
>After all, you probably don't want to encourage pseudos to go into the
>address registers merely because you add values to them.
1421 is only used in 5559 and 5560. from the lreg dump:
Register 1421 used 2 times across 2 insns in block 694; set 1 time; pref
DATA_REGS.
>But it is also possible that register 1421 is being put into an
>address register merely because all the data registers are taken and
>there is nothing which forces 1421 to be in a data register.
In the function S_unpack_rec, there are 190 registers to allocate, so
I'd guess everything will be in use.
>Or, you might permit an alternative "a a*r rJK" in addsi3_5200. You
>can implement that using a two instruction sequence--copy the data
>register to the address register, and then add. This is obviously not
>ideal, but it's more or less what reload would be doing anyhow.
>
>
>In general, though, I'm not sure that prohibiting QImode values in
>address registers is going to be a useful approach. After all, the
>values do fit there, and while we want to discourage it, it's not
>obvious that we want to completely prohibit it. The problem in PR
>18421 is that reload decided that it had to reload a QImode value from
>memory into an address register, but it couldn't. That is more or
>less easy to handle by defining SECONDARY_RELOAD_CLASS to indicate
>that a data register is required to move QImode values between the
>address registers and memory, and by defining reload_inqi and
>reload_outqi to do the moves.
The problem is that there is no valid QImode instruction that can move
values in/out of an address register....
This has been an ongoing problem for more than a year, and each
"fix" treats the particular bug/problem at hand. rth is the one who
recommended punting QImode out of address registers:
http://gcc.gnu.org/ml/gcc/2003-07/msg00743.html
Looking over the code, I see that PREFERRED_RELOAD_CLASS is:
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
((GET_CODE (X) == CONST_INT \
&& (unsigned) (INTVAL (X) + 0x80) < 0x100 \
&& (CLASS) != ADDR_REGS) \
? DATA_REGS \
: (GET_MODE (X) == QImode && (CLASS) != ADDR_REGS) \
? DATA_REGS \
: (GET_CODE (X) == CONST_DOUBLE \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
? ((TARGET_68881|TARGET_CFV4E) && (CLASS == FP_REGS || CLASS ==
DATA_OR_FP_REGS) \
? FP_REGS : NO_REGS) \
: (TARGET_PCREL \
&& (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \
|| GET_CODE (X) == LABEL_REF)) \
? ADDR_REGS \
: (CLASS))
Which looks like it allows QImode into ADDR_REGS instead
of insisting on DATA_REGS. Do you think this should be:
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
(((GET_CODE (X) == CONST_INT \
&& (unsigned) (INTVAL (X) + 0x80) < 0x100) \
|| GET_MODE(X) == QImode) \
? DATA_REGS \
: (GET_CODE (X) == CONST_DOUBLE \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
? ((TARGET_68881|TARGET_CFV4E) && (CLASS == FP_REGS || CLASS ==
DATA_OR_FP_REGS) \
? FP_REGS : NO_REGS) \
: (TARGET_PCREL \
&& (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \
|| GET_CODE (X) == LABEL_REF)) \
? ADDR_REGS \
: (CLASS))
--
Peter Barada
[EMAIL PROTECTED]