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
					
				
					 1 changed files with 32 additions and 17 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		
		Reference in a new issue