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:
parent
a8f62f44d8
commit
cf728c2a2a
|
@ -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
|
||||||
|
yields {IND_RC_W, fp, SL_OFFSET}
|
||||||
|
pat lxl $1==2
|
||||||
|
uses REG={IND_RC_W, fp, SL_OFFSET}
|
||||||
|
yields {IND_RC_W, %a, SL_OFFSET}
|
||||||
|
pat lxl $1==3
|
||||||
|
uses REG={IND_RC_W, fp, SL_OFFSET}, reusing %a, REG
|
||||||
|
gen move {IND_RC_W, %a, SL_OFFSET}, %b
|
||||||
|
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
|
||||||
|
mtspr ctr, %b
|
||||||
|
1:
|
||||||
|
lwz %a, {IND_RC_W, %a, SL_OFFSET}
|
||||||
|
bdnz {LABEL, "1b"}
|
||||||
|
yields %a
|
||||||
|
|
||||||
pat lxl $1==1 /* Load caller's FP */
|
pat dch /* Dynamic chain: LB -> caller's LB */
|
||||||
leaving
|
|
||||||
lxl 0
|
|
||||||
dch
|
|
||||||
|
|
||||||
pat dch /* FP -> caller FP */
|
|
||||||
with REG
|
with REG
|
||||||
uses reusing %1, REG
|
yields {IND_RC_W, %1, FP_OFFSET}
|
||||||
gen
|
|
||||||
lwz %a, {IND_RC_W, %1, FP_OFFSET}
|
|
||||||
yields %a
|
|
||||||
|
|
||||||
pat lpb /* Convert FP to argument address */
|
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
|
||||||
|
|
Loading…
Reference in a new issue