-
Notifications
You must be signed in to change notification settings - Fork 32
FenceArm
For now, we're just using the 32-bit instruction set.
The ARMv7 code generator is in pretty good shape, but it's starved for registers. The first four arguments to a procedure are passed in hardware registers REG1 through REG4, but all other arguments are passed as a list in REG5. Adding two or three more argument registers should help a lot.
On Linux, which is the only OS for which we're creating an ARM public release, it should be possible to add two or three more argument registers.
For other platforms, the conservative approach taken by Lars's original register assignment is the safest way to go.
So we probably want to refactor the ARMv7 code generator, using a Linux-specific register assignment for Linux and the conservative register assignment for all other target operating systems. The code generator proper is already almost independent of the register assignment, but some conditional compilation will be needed for millicode and for the compiler; we already have some infrastructure in place for that, and this will give us incentive to clean up that infrastructure.
We should be able to build and test both register assignments under Linux.
There are 13 general purpose 32-bit registers (R0-R12) along
with three more (R13-R15) that have special names and purposes.
Based on Lars's notes in src/Asm/Fence/pass5p2-arm.sch
, the
the ARMv7 architecture reference manuals, and the
Procedure Call Standard for the ARM Architecture (AAPCS), the registers are intended to be used
as shown below. The last two columns show Larceny's existing
conservative register assignment and my proposed Linux-specific
assignment:
typical use conservative Linux-specific
r0 a1 RESULT REG0
r1 a2 SECOND REG1
r2 a3 GLOBALS REG2
r3 a4 STKP REG3
r4 v1 TMP0 REG4
r5 v2 REG0 REG5
r6 v3 REG1 REG6
r7 v4 REG2 REG7
r8 v5 REG3 REG8
r9 v6 or (static base) GLOBALS
r10 v7 REG4 RESULT
r11 v8 REG5 SECOND
r12 IP scratch TMP1 TMP0
r13 SP stack pointer STKP
r14 LR link register TMP1
r15 PC program counter
a1 through a4 are caller-save registers used to pass arguments and return results. v1 through v8 are callee-save registers, except r9 (v6) is the "platform register" that may be reserved for some special purpose. Linux apparently does not reserve register r9. The gcc compiler uses r9 as a static base register when compiling position-independent code, but that usage does not preclude other uses in code compiled by Larceny's compiler.
The AAPCS explicitly sanctions private calling conventions but also says stack invariants must be preserved. The stack must always be word-aligned (multiple of 4) and must be double-word-aligned (multiple of 8) at a "public interface"; the generic Fence code generator already guarantees double-word alignment. We'll need a red zone as well.
Some uses of SP are deprecated, but it looks as though using it as a stack pointer for Larceny's stack cache is within the intended use of the register and should be okay.
Will has built and tested experimental versions of ARM Larceny in which r9 is used as REG3 or REG4 (he's forgotten which) and r12 is used as TMP1, so that much is known to work. Using r13 (SP) as STKP will take a little more work.