231231end enum
232232
233233'' type for tracking the spilled registers
234- type ASM64_SPILLVREG
234+ type ASM64_SAVEDREG
235235 id as long '' unique id for debugging messages only
236- sdvreg as long '' the id of the real register spilled???
236+ sdvreg as long '' the id of the real register spilled??? KREGFREE = FREE
237237 sdoffset as long '' offset into the spilled registers for current stackframe
238238 spilbranch1 as long '' depends ctx.labelbranch2 for tracking spilled registers in second branch???
239239end type
@@ -332,7 +332,7 @@ dim shared as long reghandle(KREGUPPER+2)
332332
333333type ASM64_REGROOM
334334 status as long '' KROOMFREE, KROOMMARKED, KROOMUSED
335- vreg as ASM64_SPILLVREG ptr '' pointer to the spilled vreg
335+ vreg as ASM64_SAVEDREG ptr '' pointer to the spilled vreg
336336end type
337337
338338dim shared as ASM64_REGROOM regroom(KREGUPPER+ 2 )
@@ -1337,8 +1337,26 @@ end sub
13371337''===========================
13381338''spilling registers on stack
13391339''===========================
1340- private sub reg_spilling( byval regspilled as long )
1340+ private function asm64_spillREG( byval regspilled as long ) as ASM64_SAVEDREG ptr
1341+
1342+ dim as ASM64_SAVEDREG ptr v = any
13411343
1344+ '' re-use an existing location?
1345+ if ( ctx.vreg_count > 0 ) then
1346+ v = flistGetHead( @ctx.spillvregs )
1347+ while ( v <> NULL )
1348+ if ( v->sdvreg = KREGFREE ) then
1349+ '' keep previous id
1350+ '' keep previous sdoffset
1351+ v->sdvreg = reghandle(regspilled)
1352+ v->spilbranch1 = false
1353+ return v
1354+ end if
1355+ v = flistGetNext( v )
1356+ wend
1357+ end if
1358+
1359+ '' store the spilled register to a new location
13421360 ctx.stk+= 8
13431361 asm_info( "stk20=" +Str(ctx.stk))
13441362 if ctx.stkspil<> 0 then
@@ -1348,16 +1366,28 @@ private sub reg_spilling(byval regspilled as long)
13481366 end if
13491367 end if
13501368
1351- '' store current virtual register
1352- '' TODO: alloc of VREG should be a procedure
1353- dim as ASM64_SPILLVREG ptr v = any
1369+ '' allocate a new item on the spilled vregs list
13541370 v = flistNewItem( @ctx.spillvregs )
1371+
1372+ '' unique id is per procedure and is reset at the end of each proc
13551373 ctx.vreg_count += 1
13561374 v->id = ctx.vreg_count
1375+
1376+ '' store location and vreg spilled,
13571377 v->sdoffset = -ctx.stk
13581378 v->sdvreg = reghandle(regspilled)
13591379 v->spilbranch1 = false
13601380
1381+ return v
1382+
1383+ end function
1384+
1385+
1386+ private sub reg_spilling( byval regspilled as long )
1387+
1388+ dim as ASM64_SAVEDREG ptr v = asm64_spillREG( regspilled )
1389+ assert( v )
1390+
13611391 ''store register
13621392 asm_info( "spilled register=" +*regstrq(regspilled)+ " saved vreg=" +str(reghandle(regspilled))+ " room=" +str(v->id))
13631393 asm_code( "mov QWORD PTR " +str(v->sdoffset)+ "[rbp], " +*regstrq(regspilled))
@@ -1524,7 +1554,7 @@ private sub reg_branch(byval label as FBSYMBOL ptr )
15241554 elseif label=ctx.labeljump then
15251555 if ( ctx.vreg_count > 0 ) then
15261556 ''restoring registers spilled in the second branch
1527- dim v as ASM64_SPILLVREG ptr = any
1557+ dim v as ASM64_SAVEDREG ptr = any
15281558 v = flistGetHead( @ctx.spillvregs )
15291559 while ( v <> NULL )
15301560 if ( v->spilbranch1 ) then
@@ -1552,12 +1582,14 @@ function reg_findreal(byval vreg as long) as long
15521582 ''searching in spilled register list
15531583 'asm_info("virtual register not found extend to spilled register list")
15541584
1555- dim v as ASM64_SPILLVREG ptr = NULL
1585+ dim v as ASM64_SAVEDREG ptr = NULL
15561586 if ( ctx.vreg_count > 0 ) then
15571587 v = flistGetHead( @ctx.spillvregs )
15581588 while ( v <> NULL )
1559- 'asm_info("iroom="+str(iroom)+" "+str(v->sdvreg)+" "+str(vreg))
1560- if v->sdvreg=vreg then exit while
1589+ 'asm_info("iroom="+str(v->id)+" "+str(v->sdvreg)+" "+str(vreg))
1590+ if ( v->sdvreg=vreg ) then
1591+ exit while
1592+ end if
15611593 v = flistGetNext( v )
15621594 wend
15631595 end if
@@ -1790,7 +1822,13 @@ end sub
17901822
17911823private sub _init( )
17921824
1793- flistInit( @ctx.spillvregs, 2048 , sizeof( ASM64_SPILLVREG ) )
1825+ '' allocate space for 256 spilled registers - the size
1826+ '' will automatically grow if needed. If there are many spilled
1827+ '' registers, then either the procedure is extremely complex, or
1828+ '' more likely there is an opportunity to optimize the AST so
1829+ '' that results are not saved unecessarily.
1830+
1831+ flistInit( @ctx.spillvregs, 256 , sizeof( ASM64_SAVEDREG ) )
17941832
17951833 irhlInit( )
17961834 '' IR_OPT_CPUSELFBOPS disabled, to prevent AST from producing self-ops.
0 commit comments