This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Limiting the use of pointer registers

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,
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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]