Implement lxl for PowerPC ncg.

This fixes lxl 1 (so it follows the static chain, not the dynamic
chain) and provides lxl 2 and greater.  The Modula-2 compiler uses lxl
for nested procedures, so they can access the variables of the
enclosing procedures.
This commit is contained in:
George Koehler 2017-02-13 23:22:31 -05:00
parent a8f62f44d8
commit cf728c2a2a

View file

@ -9,6 +9,7 @@ INT64 = 8
FP_OFFSET = 0 /* Offset of saved FP relative to our FP */ FP_OFFSET = 0 /* Offset of saved FP relative to our FP */
PC_OFFSET = 4 /* Offset of saved PC relative to our FP */ PC_OFFSET = 4 /* Offset of saved PC relative to our FP */
SL_OFFSET = 8 /* Offset of static link */
#define COMMENT(n) /* comment {LABEL, n} */ #define COMMENT(n) /* comment {LABEL, n} */
@ -1910,27 +1911,41 @@ PATTERNS
leaving leaving
ret 0 ret 0
pat lxl $1==0 /* Load FP */ /*
* Lexical local base: lxl 0 yields our fp, lxl n yields the
* fp of the nth statically enclosing procedure.
*/
pat lxl $1==0
leaving leaving
lor 0 lor 0
pat lxl $1==1
pat lxl $1==1 /* Load caller's FP */ yields {IND_RC_W, fp, SL_OFFSET}
leaving pat lxl $1==2
lxl 0 uses REG={IND_RC_W, fp, SL_OFFSET}
dch yields {IND_RC_W, %a, SL_OFFSET}
pat lxl $1==3
pat dch /* FP -> caller FP */ uses REG={IND_RC_W, fp, SL_OFFSET}, reusing %a, REG
with REG gen move {IND_RC_W, %a, SL_OFFSET}, %b
uses reusing %1, REG yields {IND_RC_W, %b, SL_OFFSET}
pat lxl $1>=4 && $1<=0x8000
uses REG={IND_RC_W, fp, SL_OFFSET},
REG={CONST_0000_7FFF, $1-1}
gen gen
lwz %a, {IND_RC_W, %1, FP_OFFSET} mtspr ctr, %b
1:
lwz %a, {IND_RC_W, %a, SL_OFFSET}
bdnz {LABEL, "1b"}
yields %a yields %a
pat lpb /* Convert FP to argument address */ pat dch /* Dynamic chain: LB -> caller's LB */
with REG
yields {IND_RC_W, %1, FP_OFFSET}
pat lpb /* LB -> argument base */
leaving leaving
adp EM_BSIZE adp EM_BSIZE
pat lxa /* Load caller's SP */ pat lxa /* Lexical argument base */
leaving leaving
lxl $1 lxl $1
lpb lpb
@ -1946,24 +1961,24 @@ PATTERNS
mtspr ctr, %a mtspr ctr, %a
bctr. bctr.
pat lor $1==0 /* Load FP */ pat lor $1==0 /* Load local base */
uses REG uses REG
gen gen
move fp, %a move fp, %a
yields %a yields %a
pat lor $1==1 /* Load SP */ pat lor $1==1 /* Load stack pointer */
uses REG uses REG
gen gen
move sp, %a move sp, %a
yields %a yields %a
pat str $1==0 /* Store FP */ pat str $1==0 /* Store local base */
with REG with REG
gen gen
move %1, fp move %1, fp
pat str $1==1 /* Store SP */ pat str $1==1 /* Store stack pointer */
with REG with REG
gen gen
move %1, sp move %1, sp