On 11/04/2011 10:09 PM, DJ Delorie wrote: > The problem I'm trying to solve with that is that there's only one > segment register (ES) so you only need to force an operand non-far if > *both* operands are far. Not sure if the function is implemented that > way, but I coded the expanders that way.
Ah, I missed that. No, the generic code only looks at a single predicate at a time. If you're looking at two, then you do have to take care of it yourself. >>> if (CONST_INT_P (operand1) && ! IN_RANGE (INTVAL (operand1), (-1 << 8) >>> + 1, (1 << 8) - 1)) >>> FAIL; >> >> Huh? This would be an assert, not a FAIL. But why have it? >> >> It sounds like something that should have been caught way up >> the chain... > > "should" he says ;-) Indeed. I'll go so far as to say that it's a generic bug that needs fixing. I don't suppose this triggers during a normal build? If so, please file a bug and cc me. >>> (define_expand "addsi3" >>> [(set (match_operand:SI 0 "register_operand" "=&v") >>> (plus:SI (match_operand:SI 1 "nonmemory_operand" "vi") >>> (match_operand 2 "nonmemory_operand" "vi"))) >>> ] >>> "" >>> "if (!nonmemory_operand (operands[1], SImode)) >>> operands[1] = force_reg (SImode, operands[1]); >>> if (!nonmemory_operand (operands[1], SImode)) >>> operands[2] = force_reg (SImode, operands[2]);" >>> ) >> >> Drop the register constrains in the expander. Use register_operand >> in the expander and drop the force_reg bits. > > The pattern *does* accept immediates as-is. Not sure why that extra > check is in there, though... might be that parts of gcc call > gen_addsi3() without checking the predicates first. I've seen it do > that for moves. Yes, I suppose that's possible. Especially given add's use inside reload. > Yes, it's just like alloca() - it detects a stack shrink in the next > call to the library function and frees up any stubs that are "off the > stack". The call in the epilogue is to increase the odds of properly > detecting such a case, since we know at that point it's out of scope. Excellent. r~