On Tue, Sep 1, 2015 at 6:20 PM, DJ Delorie <d...@redhat.com> wrote: > >> It did match the first alternative (alternative 0), but it matched the >> constraints Y/Y/m. > > It shouldn't match Y as those are for near addresses (unless it's only > matching MEM==MEM), and the ones in the insn are far, but ...
Reload chooses the alternative that is the best match. When using the constraints Y/Y/m, 2 of the three operands match the constraints, so this ends up being the best match. It then tries to reload the far mem to match Y, which fails, as all it knows how to do is reload a mem address to make it match, which can't turn a far mem into a near mem. You would need some way to indicate that while Y does accept a mem, this particular mem can't be reloaded to match. We don't have a way to do that. The Y constraint gets classified as contraint type CT_MEMORY. In find_reloads, in reload.c, there is a case CT_MEMORY, and it does if (CONST_POOL_OK_P (operand_mode[i], operand) || MEM_P (operand)) badop = 0; constmemok = 1; offmemok = 1; Since the operand is a MEM, badop is set to zero. That makes this look like a good alternative. You want badop to be left alone. Also, the fact that offmemok was set means that reload thinks that any mem can be fixed by reloading the address to make it offsetable. You don't want offmemok set. Without offmemok set, it should get reloaded into a register, as reload will use the v constraint instead. Jim