Hi there. I'm working on a port to an architecture where the pointer registers X and Y are directly backed by small 128 byte caches. Changing one of these registers to a different memory row causes a cache load cycle, so using them for memory access is fine but using them as general purpose registers is expensive.
How can I prevent the register allocator from using these for anything but memory access? I have a register class called ADDR_REGS that contains just X and Y and one called DATA_REGS which contains the general registers R10 to R1E. GENERAL_REGS is the same as DATA_REGS. The order they appear in in reg_class is DATA_REGS, GENERAL_REGS, then ADDR_REGS. I've defined the constrains for most of the patterns to only take 'r' which prevents X or Y being used as operands for those patterns. I have to allow X and Y to be used in movsi and addsi3 to allow indirect memory addresses to be calculated. Unfortunately Pmode is SImode so I can't tell the difference between pointer and normal values in PREFERRED_RELOAD_CLASS, LIMIT_RELOAD_CLASS, or TARGET_SECONDARY_RELOAD. I tried setting REGISTER_MOVE_COST and MEMORY_MOVE_COST to 100 when the source or destination is ADDR_REGS but this didn't affect the output. I suspect that I'll have to do the same as the accumulator and hide X and Y from the register allocator. Pretend that any general register can access memory and then use post reload split to turn the patterns into X based patterns for the later phases to tidy up. One more question. The backing caches aren't coherent so X and Y can't read and write to the same 128 bytes of memory at the same time. Does GCC have any other information about the location of a pointer that I could use? Something like: * Pointer is to text memory or read only data, so it is safe to read from * Pointer 1 is in the stack and pointer 2 is in BSS, so they are definitely far apart * Pointer 1 is to to one on stack item and pointer 2 is to a stack item at least 128 bytes apart * The call stack is known and pointer 1 and pointer 2 point to different rows My fallback plan is to add a variable attribute so the programmer can mark the pointer as non overlapping and push the problem onto them. Something clever would be nice though :) Sorry for all the questions - this is quite a difficult architecture. I hope to collect all the answers and do a write up for others to use when I'm done. -- Michael