On Dec 7, 2010, at 9:51 AM, Paulo J. Matos wrote: > Ian Lance Taylor <i...@google.com> writes: > >> [snip] >> after register allocation. After the second split, no output template >> should still be "#". >> > > What do you mean by your last sentence? It somehow makes me think that > the splits work at some preprocessing level replacing/rewriting the output > template of instructions. Is that what happens?
I assume that means that the insn stream you have at this point will only match templates that don't have # in them, in other words the # insns all have patterns that no longer match (because of the splits etc. that have taken place) > > >> There are cases where a processor needs a secondary reload. You need it >> when you can not move between registers of two classes in a single >> instruction, >> > > I assume you by 'instruction' here mean a define_insn and not a single > RTL or assembler instruction. > > So, assume I have two classes M_REGS and Y_REGS and I cannot move > between them except if I go through an intermediary in C_REGS. > Do I need a secondary reload? Yes > > I wouldn't expect so cause I could write a rule that has a scratch from > C_REGS. Then I move the value from SOURCE to C_REGS and from C_REGS to > DEST. Have I misunderstood what you said? > >> and you need it when you can't load and store registers of >> any class directly to/from memory. > > That's interesting but if you can't store/load registers of any class to > and from memory how do you do it with a secondary reload anyway? "Directly" is the key word. If you have a register that can't be stored at all then it's not useable. But if it can be loaded/stored by way of another register, then you describe this with a secondary reload. Read the documentation in gccint about TARGET_SECONDARY_RELOAD, it's pretty clear, better than older documentation on the subject. That's the target hook that defines how to move things between register classes, or between register and memory, if it takes an intermediate step. The other one you might need is SECONDARY_MEMORY_NEEDED, which applies if you can't get from class X to class Y except by way of memory. You can find examples of both in the pdp11 target. TARGET_SECONDARY_RELOAD is needed because some of the floating point registers can't be loaded/stored directly (the "NO_LOAD_FPU_REGS" class). And TARGET_MEMORY_NEEDED is defined because you can't transfer directly from FPU to general registers. I think that second one is not actually needed because HARD_REGNO_MODE_OK confines values to either one or the other class of register, but it could still serve as an example for what you're looking for. paul