mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
optimize for loops over non const range, without translateExpression()
This commit is contained in:
parent
ee724eb4f1
commit
afd155ac4f
@ -1,20 +1,16 @@
|
|||||||
package prog8.compiler.target.c64.codegen
|
package prog8.compiler.target.c64.codegen
|
||||||
|
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
|
import prog8.ast.base.ArrayElementTypes
|
||||||
import prog8.ast.base.DataType
|
import prog8.ast.base.DataType
|
||||||
|
import prog8.ast.base.RegisterOrPair
|
||||||
import prog8.ast.expressions.IdentifierReference
|
import prog8.ast.expressions.IdentifierReference
|
||||||
import prog8.ast.expressions.RangeExpr
|
import prog8.ast.expressions.RangeExpr
|
||||||
import prog8.ast.statements.ForLoop
|
import prog8.ast.statements.ForLoop
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource
|
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget
|
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignment
|
|
||||||
import prog8.compiler.target.c64.codegen.assignment.TargetStorageKind
|
|
||||||
import prog8.compiler.toHex
|
import prog8.compiler.toHex
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
// todo reduce use of stack eval translateExpression()
|
|
||||||
|
|
||||||
internal class ForLoopsAsmGen(private val program: Program, private val asmgen: AsmGen) {
|
internal class ForLoopsAsmGen(private val program: Program, private val asmgen: AsmGen) {
|
||||||
|
|
||||||
internal fun translate(stmt: ForLoop) {
|
internal fun translate(stmt: ForLoop) {
|
||||||
@ -53,23 +49,17 @@ internal class ForLoopsAsmGen(private val program: Program, private val asmgen:
|
|||||||
val incdec = if(stepsize==1) "inc" else "dec"
|
val incdec = if(stepsize==1) "inc" else "dec"
|
||||||
// loop over byte range via loopvar
|
// loop over byte range via loopvar
|
||||||
val varname = asmgen.asmVariableName(stmt.loopVar)
|
val varname = asmgen.asmVariableName(stmt.loopVar)
|
||||||
asmgen.translateExpression(range.to)
|
asmgen.assignExpressionToVariable(range.from, varname, ArrayElementTypes.getValue(iterableDt), null)
|
||||||
asmgen.translateExpression(range.from)
|
asmgen.assignExpressionToVariable(range.to, "$modifiedLabel+1", ArrayElementTypes.getValue(iterableDt), null)
|
||||||
|
asmgen.out(loopLabel)
|
||||||
|
asmgen.translate(stmt.body)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
|
||||||
lda P8ESTACK_LO,x
|
|
||||||
sta $varname
|
|
||||||
lda P8ESTACK_LO+1,x
|
|
||||||
sta $modifiedLabel+1
|
|
||||||
$loopLabel""")
|
|
||||||
asmgen.translate(stmt.body)
|
|
||||||
asmgen.out("""
|
|
||||||
lda $varname
|
lda $varname
|
||||||
$modifiedLabel cmp #0 ; modified
|
$modifiedLabel cmp #0 ; modified
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
$incdec $varname
|
$incdec $varname
|
||||||
jmp $loopLabel
|
jmp $loopLabel
|
||||||
$endLabel inx""")
|
$endLabel""")
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -77,18 +67,11 @@ $endLabel inx""")
|
|||||||
|
|
||||||
// loop over byte range via loopvar
|
// loop over byte range via loopvar
|
||||||
val varname = asmgen.asmVariableName(stmt.loopVar)
|
val varname = asmgen.asmVariableName(stmt.loopVar)
|
||||||
asmgen.translateExpression(range.to)
|
asmgen.assignExpressionToVariable(range.from, varname, ArrayElementTypes.getValue(iterableDt), null)
|
||||||
asmgen.translateExpression(range.from)
|
asmgen.assignExpressionToVariable(range.to, "$modifiedLabel+1", ArrayElementTypes.getValue(iterableDt), null)
|
||||||
asmgen.out("""
|
asmgen.out(loopLabel)
|
||||||
inx
|
|
||||||
lda P8ESTACK_LO,x
|
|
||||||
sta $varname
|
|
||||||
lda P8ESTACK_LO+1,x
|
|
||||||
sta $modifiedLabel+1
|
|
||||||
$loopLabel""")
|
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
asmgen.out("""
|
asmgen.out(" lda $varname")
|
||||||
lda $varname""")
|
|
||||||
if(stepsize>0) {
|
if(stepsize>0) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
clc
|
clc
|
||||||
@ -105,8 +88,7 @@ $modifiedLabel cmp #0 ; modified
|
|||||||
$modifiedLabel cmp #0 ; modified
|
$modifiedLabel cmp #0 ; modified
|
||||||
bcs $loopLabel""")
|
bcs $loopLabel""")
|
||||||
}
|
}
|
||||||
asmgen.out("""
|
asmgen.out(endLabel)
|
||||||
$endLabel inx""")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
@ -115,13 +97,11 @@ $endLabel inx""")
|
|||||||
// words, step 1 or -1
|
// words, step 1 or -1
|
||||||
|
|
||||||
stepsize == 1 || stepsize == -1 -> {
|
stepsize == 1 || stepsize == -1 -> {
|
||||||
asmgen.translateExpression(range.to)
|
|
||||||
assignLoopvar(stmt, range)
|
|
||||||
val varname = asmgen.asmVariableName(stmt.loopVar)
|
val varname = asmgen.asmVariableName(stmt.loopVar)
|
||||||
|
assignLoopvar(stmt, range)
|
||||||
|
asmgen.assignExpressionToRegister(range.to, RegisterOrPair.AY)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda P8ESTACK_HI+1,x
|
sty $modifiedLabel+1
|
||||||
sta $modifiedLabel+1
|
|
||||||
lda P8ESTACK_LO+1,x
|
|
||||||
sta $modifiedLabel2+1
|
sta $modifiedLabel2+1
|
||||||
$loopLabel""")
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
@ -148,21 +128,17 @@ $modifiedLabel2 cmp #0 ; modified
|
|||||||
jmp $loopLabel""")
|
jmp $loopLabel""")
|
||||||
}
|
}
|
||||||
asmgen.out(endLabel)
|
asmgen.out(endLabel)
|
||||||
asmgen.out(" inx")
|
|
||||||
}
|
}
|
||||||
stepsize > 0 -> {
|
stepsize > 0 -> {
|
||||||
|
|
||||||
// (u)words, step >= 2
|
// (u)words, step >= 2
|
||||||
asmgen.translateExpression(range.to)
|
|
||||||
asmgen.out("""
|
|
||||||
lda P8ESTACK_HI+1,x
|
|
||||||
sta $modifiedLabel+1
|
|
||||||
lda P8ESTACK_LO+1,x
|
|
||||||
sta $modifiedLabel2+1
|
|
||||||
""")
|
|
||||||
assignLoopvar(stmt, range)
|
|
||||||
val varname = asmgen.asmVariableName(stmt.loopVar)
|
val varname = asmgen.asmVariableName(stmt.loopVar)
|
||||||
asmgen.out(loopLabel)
|
assignLoopvar(stmt, range)
|
||||||
|
asmgen.assignExpressionToRegister(range.to, RegisterOrPair.AY)
|
||||||
|
asmgen.out("""
|
||||||
|
sty $modifiedLabel+1
|
||||||
|
sta $modifiedLabel2+1
|
||||||
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
|
|
||||||
if (iterableDt == DataType.ARRAY_UW) {
|
if (iterableDt == DataType.ARRAY_UW) {
|
||||||
@ -181,7 +157,7 @@ $modifiedLabel2 lda #0 ; modified
|
|||||||
cmp $varname
|
cmp $varname
|
||||||
bcc $endLabel
|
bcc $endLabel
|
||||||
bcs $loopLabel
|
bcs $loopLabel
|
||||||
$endLabel inx""")
|
$endLabel""")
|
||||||
} else {
|
} else {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $varname
|
lda $varname
|
||||||
@ -198,22 +174,19 @@ $modifiedLabel lda #0 ; modified
|
|||||||
bvc +
|
bvc +
|
||||||
eor #$80
|
eor #$80
|
||||||
+ bpl $loopLabel
|
+ bpl $loopLabel
|
||||||
$endLabel inx""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|
||||||
// (u)words, step <= -2
|
// (u)words, step <= -2
|
||||||
asmgen.translateExpression(range.to)
|
|
||||||
asmgen.out("""
|
|
||||||
lda P8ESTACK_HI+1,x
|
|
||||||
sta $modifiedLabel+1
|
|
||||||
lda P8ESTACK_LO+1,x
|
|
||||||
sta $modifiedLabel2+1
|
|
||||||
""")
|
|
||||||
assignLoopvar(stmt, range)
|
|
||||||
val varname = asmgen.asmVariableName(stmt.loopVar)
|
val varname = asmgen.asmVariableName(stmt.loopVar)
|
||||||
asmgen.out(loopLabel)
|
assignLoopvar(stmt, range)
|
||||||
|
asmgen.assignExpressionToRegister(range.to, RegisterOrPair.AY)
|
||||||
|
asmgen.out("""
|
||||||
|
sty $modifiedLabel+1
|
||||||
|
sta $modifiedLabel2+1
|
||||||
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
|
|
||||||
if(iterableDt==DataType.ARRAY_UW) {
|
if(iterableDt==DataType.ARRAY_UW) {
|
||||||
@ -231,7 +204,7 @@ $modifiedLabel cmp #0 ; modified
|
|||||||
lda $varname
|
lda $varname
|
||||||
$modifiedLabel2 cmp #0 ; modified
|
$modifiedLabel2 cmp #0 ; modified
|
||||||
bcs $loopLabel
|
bcs $loopLabel
|
||||||
$endLabel inx""")
|
$endLabel""")
|
||||||
} else {
|
} else {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $varname
|
lda $varname
|
||||||
@ -249,7 +222,7 @@ $modifiedLabel sbc #0 ; modified
|
|||||||
bvc +
|
bvc +
|
||||||
eor #$80
|
eor #$80
|
||||||
+ bpl $loopLabel
|
+ bpl $loopLabel
|
||||||
$endLabel inx""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -611,10 +584,6 @@ $endLabel""")
|
|||||||
asmgen.loopEndLabels.pop()
|
asmgen.loopEndLabels.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignLoopvar(stmt: ForLoop, range: RangeExpr) {
|
private fun assignLoopvar(stmt: ForLoop, range: RangeExpr) =
|
||||||
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, stmt.loopVarDt(program).typeOrElse(DataType.STRUCT), stmt.definingSubroutine(), variableAsmName=asmgen.asmVariableName(stmt.loopVar))
|
asmgen.assignExpressionToVariable(range.from, asmgen.asmVariableName(stmt.loopVar), stmt.loopVarDt(program).typeOrElse(DataType.STRUCT), stmt.definingSubroutine())
|
||||||
val src = AsmAssignSource.fromAstSource(range.from, program, asmgen).adjustSignedUnsigned(target)
|
|
||||||
val assign = AsmAssignment(src, target, false, range.position)
|
|
||||||
asmgen.translateNormalAssignment(assign)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
115
examples/test.p8
115
examples/test.p8
@ -1,62 +1,85 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import floats
|
%import floats
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
%import test_stack
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
ubyte ub = 30
|
ubyte ub
|
||||||
byte bb = -30
|
byte bb
|
||||||
float f1
|
uword uw
|
||||||
|
word ww
|
||||||
|
|
||||||
f1 = ub
|
ubyte arrub = 10
|
||||||
floats.print_f(f1)
|
uword arruw = 10
|
||||||
txt.chrout('\n')
|
byte arrb = 10
|
||||||
f1 = bb
|
word arrw = 10
|
||||||
floats.print_f(f1)
|
|
||||||
|
test_stack.test()
|
||||||
|
|
||||||
|
for ub in 0 to arrub step 2 {
|
||||||
|
txt.print_ub(ub)
|
||||||
|
txt.chrout(',')
|
||||||
|
}
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
|
||||||
testX()
|
for ub in 5 to arrub step 2 {
|
||||||
}
|
txt.print_ub(ub)
|
||||||
|
txt.chrout(',')
|
||||||
|
}
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
sub ding(ubyte argument) -> ubyte {
|
for uw in 0 to arruw step 2 {
|
||||||
txt.chrout(' ')
|
txt.print_uw(uw)
|
||||||
return argument*2
|
txt.chrout(',')
|
||||||
}
|
}
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
sub dingw(uword argument) -> uword {
|
for uw in 5 to arruw step 2 {
|
||||||
txt.chrout(' ')
|
txt.print_uw(uw)
|
||||||
return argument*2
|
txt.chrout(',')
|
||||||
}
|
}
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
asmsub testX() {
|
for bb in 0 to arrb step 2 {
|
||||||
%asm {{
|
txt.print_b(bb)
|
||||||
stx _saveX
|
txt.chrout(',')
|
||||||
lda #13
|
}
|
||||||
jsr txt.chrout
|
txt.chrout('\n')
|
||||||
lda #'x'
|
|
||||||
jsr txt.chrout
|
for bb in -2 to arrb-2 step 2 {
|
||||||
lda #'='
|
txt.print_b(bb)
|
||||||
jsr txt.chrout
|
txt.chrout(',')
|
||||||
lda _saveX
|
}
|
||||||
jsr txt.print_ub
|
txt.chrout('\n')
|
||||||
lda #' '
|
|
||||||
jsr txt.chrout
|
for ww in 0 to arrw step 2 {
|
||||||
lda #'s'
|
txt.print_w(ww)
|
||||||
jsr txt.chrout
|
txt.chrout(',')
|
||||||
lda #'p'
|
}
|
||||||
jsr txt.chrout
|
txt.chrout('\n')
|
||||||
lda #'='
|
|
||||||
jsr txt.chrout
|
for ww in -2 to arrw-2 step 2{
|
||||||
tsx
|
txt.print_w(ww)
|
||||||
txa
|
txt.chrout(',')
|
||||||
jsr txt.print_ub
|
}
|
||||||
lda #13
|
txt.chrout('\n')
|
||||||
jsr txt.chrout
|
|
||||||
ldx _saveX
|
for bb in arrb-2 to -2 step -2 {
|
||||||
rts
|
txt.print_b(bb)
|
||||||
_saveX .byte 0
|
txt.chrout(',')
|
||||||
}}
|
}
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
for ww in arrw-2 to -2 step -2 {
|
||||||
|
txt.print_w(ww)
|
||||||
|
txt.chrout(',')
|
||||||
|
}
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
test_stack.test()
|
||||||
|
txt.chrout('\n')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
47
examples/test_stack.p8
Normal file
47
examples/test_stack.p8
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
test_stack {
|
||||||
|
|
||||||
|
asmsub test() {
|
||||||
|
%asm {{
|
||||||
|
stx _saveX
|
||||||
|
lda #13
|
||||||
|
jsr txt.chrout
|
||||||
|
lda #'-'
|
||||||
|
ldy #12
|
||||||
|
- jsr txt.chrout
|
||||||
|
dey
|
||||||
|
bne -
|
||||||
|
lda #13
|
||||||
|
jsr txt.chrout
|
||||||
|
lda #'x'
|
||||||
|
jsr txt.chrout
|
||||||
|
lda #'='
|
||||||
|
jsr txt.chrout
|
||||||
|
lda _saveX
|
||||||
|
jsr txt.print_ub
|
||||||
|
lda #' '
|
||||||
|
jsr txt.chrout
|
||||||
|
lda #'s'
|
||||||
|
jsr txt.chrout
|
||||||
|
lda #'p'
|
||||||
|
jsr txt.chrout
|
||||||
|
lda #'='
|
||||||
|
jsr txt.chrout
|
||||||
|
tsx
|
||||||
|
txa
|
||||||
|
jsr txt.print_ub
|
||||||
|
lda #13
|
||||||
|
jsr txt.chrout
|
||||||
|
lda #'-'
|
||||||
|
ldy #12
|
||||||
|
- jsr txt.chrout
|
||||||
|
dey
|
||||||
|
bne -
|
||||||
|
lda #13
|
||||||
|
jsr txt.chrout
|
||||||
|
ldx _saveX
|
||||||
|
rts
|
||||||
|
_saveX .byte 0
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user