mirror of
https://github.com/irmen/prog8.git
synced 2025-02-28 09:29:26 +00:00
some asm and some for loop asm fixed, renamed asmgen2 back to just asmgen
This commit is contained in:
parent
68df1730f5
commit
a983a896f2
@ -4,7 +4,7 @@ import prog8.ast.Module
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.processing.*
|
||||
import prog8.compiler.CompilationOptions
|
||||
import prog8.compiler.target.c64.codegen2.AnonymousScopeVarsCleanup
|
||||
import prog8.compiler.target.c64.codegen.AnonymousScopeVarsCleanup
|
||||
import prog8.optimizer.FlattenAnonymousScopesAndRemoveNops
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@ import prog8.ast.Program
|
||||
import prog8.ast.base.*
|
||||
import prog8.ast.statements.Directive
|
||||
import prog8.compiler.target.c64.MachineDefinition
|
||||
import prog8.compiler.target.c64.codegen2.AsmGen2
|
||||
import prog8.compiler.target.c64.codegen.AsmGen
|
||||
import prog8.optimizer.constantFold
|
||||
import prog8.optimizer.optimizeStatements
|
||||
import prog8.optimizer.simplifyExpressions
|
||||
@ -102,7 +102,7 @@ fun compileProgram(filepath: Path,
|
||||
// asm generation directly from the Ast, no need for intermediate code
|
||||
val zeropage = MachineDefinition.C64Zeropage(compilerOptions)
|
||||
programAst.anonscopeVarsCleanup()
|
||||
val assembly = AsmGen2(programAst, compilerOptions, zeropage).compileToAssembly(optimize)
|
||||
val assembly = AsmGen(programAst, compilerOptions, zeropage).compileToAssembly(optimize)
|
||||
assembly.assemble(compilerOptions)
|
||||
programName = assembly.name
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package prog8.compiler.target.c64.codegen2
|
||||
package prog8.compiler.target.c64.codegen
|
||||
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.AstException
|
@ -1,4 +1,4 @@
|
||||
package prog8.compiler.target.c64.codegen2
|
||||
package prog8.compiler.target.c64.codegen
|
||||
|
||||
import prog8.ast.IFunctionCall
|
||||
import prog8.ast.Node
|
||||
@ -27,7 +27,7 @@ import kotlin.math.absoluteValue
|
||||
internal class AssemblyError(msg: String) : RuntimeException(msg)
|
||||
|
||||
|
||||
internal class AsmGen2(val program: Program,
|
||||
internal class AsmGen(val program: Program,
|
||||
val options: CompilationOptions,
|
||||
val zeropage: Zeropage) {
|
||||
|
||||
@ -1065,7 +1065,8 @@ internal class AsmGen2(val program: Program,
|
||||
val counterLabel = makeLabel("for_counter")
|
||||
loopEndLabels.push(endLabel)
|
||||
loopContinueLabels.push(continueLabel)
|
||||
when (range.step.constValue(program)?.number) {
|
||||
val stepsize=range.step.constValue(program)?.number
|
||||
when (stepsize) {
|
||||
1 -> {
|
||||
when(iterableDt) {
|
||||
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||
@ -1121,17 +1122,118 @@ $endLabel""")
|
||||
}
|
||||
}
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||
TODO("loop over word range")
|
||||
translateExpression(range.to)
|
||||
out(" inc $ESTACK_LO_HEX+1,x | bne + | inc $ESTACK_HI_HEX+1,x |+ ")
|
||||
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||
val assignLoopvar = Assignment(AssignTarget(null, stmt.loopVar, null, null, stmt.loopVar!!.position),
|
||||
null, range.from, range.position)
|
||||
assignLoopvar.linkParents(stmt)
|
||||
translate(assignLoopvar)
|
||||
out(loopLabel)
|
||||
translate(stmt.body)
|
||||
out("""
|
||||
inc $varname
|
||||
bne +
|
||||
inc $varname+1
|
||||
+ lda $ESTACK_HI_HEX+1,x
|
||||
cmp $varname+1
|
||||
bne +
|
||||
lda $ESTACK_LO_HEX+1,x
|
||||
cmp $varname
|
||||
beq $endLabel
|
||||
+ jmp $loopLabel
|
||||
$endLabel inx""")
|
||||
}
|
||||
else -> throw AssemblyError("range expression can only be byte or word")
|
||||
}
|
||||
}
|
||||
-1 -> {
|
||||
TODO("non-const forloop with step -1")
|
||||
when(iterableDt){
|
||||
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||
if (stmt.loopRegister != null) {
|
||||
// loop register over range
|
||||
if(stmt.loopRegister!=Register.A)
|
||||
throw AssemblyError("can only use A")
|
||||
translateExpression(range.from)
|
||||
translateExpression(range.to)
|
||||
out("""
|
||||
inx
|
||||
lda $ESTACK_LO_HEX+1,x
|
||||
sta $loopLabel+1
|
||||
sec
|
||||
sbc $ESTACK_LO_HEX,x
|
||||
adc #0
|
||||
sta $counterLabel
|
||||
inx
|
||||
$loopLabel lda #0 ; modified""")
|
||||
translate(stmt.body)
|
||||
out("""
|
||||
$continueLabel dec $counterLabel
|
||||
beq $endLabel
|
||||
dec $loopLabel+1
|
||||
jmp $loopLabel
|
||||
$counterLabel .byte 0
|
||||
$endLabel""")
|
||||
} else {
|
||||
// loop over byte range via loopvar
|
||||
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||
translateExpression(range.from)
|
||||
translateExpression(range.to)
|
||||
out("""
|
||||
inx
|
||||
lda $ESTACK_LO_HEX+1,x
|
||||
sta $varname
|
||||
sec
|
||||
sbc $ESTACK_LO_HEX,x
|
||||
adc #0
|
||||
sta $counterLabel
|
||||
inx
|
||||
$loopLabel""")
|
||||
translate(stmt.body)
|
||||
out("""
|
||||
$continueLabel dec $counterLabel
|
||||
beq $endLabel
|
||||
dec $varname
|
||||
jmp $loopLabel
|
||||
$counterLabel .byte 0
|
||||
$endLabel""")
|
||||
}
|
||||
}
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||
translateExpression(range.to)
|
||||
out("""
|
||||
lda $ESTACK_LO_HEX+1,x
|
||||
bne +
|
||||
dec $ESTACK_HI_HEX+1,x
|
||||
+ dec $ESTACK_LO_HEX+1,x
|
||||
""")
|
||||
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||
val assignLoopvar = Assignment(AssignTarget(null, stmt.loopVar, null, null, stmt.loopVar!!.position),
|
||||
null, range.from, range.position)
|
||||
assignLoopvar.linkParents(stmt)
|
||||
translate(assignLoopvar)
|
||||
out(loopLabel)
|
||||
translate(stmt.body)
|
||||
out("""
|
||||
lda $varname
|
||||
bne +
|
||||
dec $varname+1
|
||||
+ dec $varname
|
||||
lda $ESTACK_HI_HEX+1,x
|
||||
cmp $varname+1
|
||||
bne +
|
||||
lda $ESTACK_LO_HEX+1,x
|
||||
cmp $varname
|
||||
beq $endLabel
|
||||
+ jmp $loopLabel
|
||||
$endLabel inx""")
|
||||
}
|
||||
else -> throw AssemblyError("range expression can only be byte or word")
|
||||
}
|
||||
}
|
||||
else -> when (iterableDt) {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> TODO("non-const forloop bytes")
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> TODO("non-const forloop words")
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> TODO("non-const forloop bytes, step >1: $stepsize")
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> TODO("non-const forloop words, step >1: $stepsize")
|
||||
else -> throw AssemblyError("range expression can only be byte or word")
|
||||
}
|
||||
}
|
||||
@ -1238,14 +1340,15 @@ $endLabel""")
|
||||
}
|
||||
|
||||
private fun translateForOverConstRange(stmt: ForLoop, iterableDt: DataType, range: IntProgression) {
|
||||
// TODO: optimize loop code when the range is < 256 iterations, don't need a separate counter in such cases
|
||||
val loopLabel = makeLabel("for_loop")
|
||||
val endLabel = makeLabel("for_end")
|
||||
val continueLabel = makeLabel("for_continue")
|
||||
val counterLabel = makeLabel("for_counter")
|
||||
loopEndLabels.push(endLabel)
|
||||
loopContinueLabels.push(continueLabel)
|
||||
when(iterableDt) {
|
||||
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||
val counterLabel = makeLabel("for_counter")
|
||||
if(stmt.loopRegister!=null) {
|
||||
|
||||
// loop register over range
|
||||
@ -1412,97 +1515,59 @@ $endLabel""")
|
||||
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||
when {
|
||||
range.step == 1 -> {
|
||||
// step = 1
|
||||
// word, step = 1
|
||||
val lastValue = range.last+1
|
||||
out("""
|
||||
lda #<${range.first}
|
||||
ldy #>${range.first}
|
||||
sta $varname
|
||||
sty $varname+1
|
||||
lda #${range.last - range.first + 1 and 255}
|
||||
sta $counterLabel
|
||||
$loopLabel""")
|
||||
translate(stmt.body)
|
||||
out("""
|
||||
$continueLabel dec $counterLabel
|
||||
beq $endLabel
|
||||
inc $varname
|
||||
bne $loopLabel
|
||||
$continueLabel inc $varname
|
||||
bne +
|
||||
inc $varname+1
|
||||
jmp $loopLabel
|
||||
$counterLabel .byte 0
|
||||
+ lda $varname
|
||||
cmp #<$lastValue
|
||||
bne +
|
||||
lda $varname+1
|
||||
cmp #>$lastValue
|
||||
beq $endLabel
|
||||
+ jmp $loopLabel
|
||||
$endLabel""")
|
||||
}
|
||||
range.step == -1 -> {
|
||||
// step = 1
|
||||
// word, step = 1
|
||||
val lastValue = range.last-1
|
||||
out("""
|
||||
lda #<${range.first}
|
||||
ldy #>${range.first}
|
||||
sta $varname
|
||||
sty $varname+1
|
||||
lda #${range.first - range.last + 1 and 255}
|
||||
sta $counterLabel
|
||||
$loopLabel""")
|
||||
translate(stmt.body)
|
||||
out("""
|
||||
$continueLabel dec $counterLabel
|
||||
beq $endLabel
|
||||
lda $varname
|
||||
$continueLabel lda $varname
|
||||
bne +
|
||||
dec $varname+1
|
||||
+ dec $varname
|
||||
jmp $loopLabel
|
||||
$counterLabel .byte 0
|
||||
lda $varname
|
||||
cmp #<$lastValue
|
||||
bne +
|
||||
lda $varname+1
|
||||
cmp #>$lastValue
|
||||
beq $endLabel
|
||||
+ jmp $loopLabel
|
||||
$endLabel""")
|
||||
}
|
||||
range.step >= 2 -> {
|
||||
// step >= 2
|
||||
out("""
|
||||
lda #<${range.first}
|
||||
ldy #>${range.first}
|
||||
sta $varname
|
||||
sty $varname+1
|
||||
lda #${(range.last-range.first) / range.step + 1}
|
||||
sta $counterLabel
|
||||
$loopLabel""")
|
||||
translate(stmt.body)
|
||||
out("""
|
||||
$continueLabel dec $counterLabel
|
||||
beq $endLabel
|
||||
clc
|
||||
lda $varname
|
||||
adc #<${range.step}
|
||||
sta $varname
|
||||
lda $varname+1
|
||||
adc #>${range.step}
|
||||
sta $varname+1
|
||||
jmp $loopLabel
|
||||
$counterLabel .byte 0
|
||||
$endLabel""")
|
||||
// word, step >= 2
|
||||
TODO("for, word, step>=2")
|
||||
}
|
||||
else -> {
|
||||
// step <= -2
|
||||
out("""
|
||||
lda #<${range.first}
|
||||
ldy #>${range.first}
|
||||
sta $varname
|
||||
sty $varname+1
|
||||
lda #${(range.first-range.last) / range.step.absoluteValue + 1}
|
||||
sta $counterLabel
|
||||
$loopLabel""")
|
||||
translate(stmt.body)
|
||||
out("""
|
||||
$continueLabel dec $counterLabel
|
||||
beq $endLabel
|
||||
sec
|
||||
lda $varname
|
||||
sbc #<${range.step.absoluteValue}
|
||||
sta $varname
|
||||
lda $varname+1
|
||||
sbc #>${range.step.absoluteValue}
|
||||
sta $varname+1
|
||||
jmp $loopLabel
|
||||
$counterLabel .byte 0
|
||||
$endLabel""")
|
||||
TODO("for, word, step<=-2")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2518,7 +2583,34 @@ $endLabel""")
|
||||
addressLv != null -> out(" st$registerName ${addressLv.number.toHex()}")
|
||||
addressExpr is IdentifierReference -> {
|
||||
val targetName = asmIdentifierName(addressExpr)
|
||||
out(" st$registerName $targetName")
|
||||
when(register) {
|
||||
Register.A -> out("""
|
||||
ldy $targetName
|
||||
sty ${C64Zeropage.SCRATCH_W1}
|
||||
ldy $targetName+1
|
||||
sty ${C64Zeropage.SCRATCH_W1+1}
|
||||
ldy #0
|
||||
sta (${C64Zeropage.SCRATCH_W1}),y
|
||||
""")
|
||||
Register.X -> out("""
|
||||
txa
|
||||
ldy $targetName
|
||||
sty ${C64Zeropage.SCRATCH_W1}
|
||||
ldy $targetName+1
|
||||
sty ${C64Zeropage.SCRATCH_W1+1}
|
||||
ldy #0
|
||||
sta (${C64Zeropage.SCRATCH_W1}),y
|
||||
""")
|
||||
Register.Y -> out("""
|
||||
tya
|
||||
ldy $targetName
|
||||
sty ${C64Zeropage.SCRATCH_W1}
|
||||
ldy $targetName+1
|
||||
sty ${C64Zeropage.SCRATCH_W1+1}
|
||||
ldy #0
|
||||
sta (${C64Zeropage.SCRATCH_W1}),y
|
||||
""")
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
saveRegister(register)
|
@ -1,4 +1,4 @@
|
||||
package prog8.compiler.target.c64.codegen2
|
||||
package prog8.compiler.target.c64.codegen
|
||||
|
||||
import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_HEX
|
||||
import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_PLUS1_HEX
|
@ -1,4 +1,4 @@
|
||||
package prog8.compiler.target.c64.codegen2
|
||||
package prog8.compiler.target.c64.codegen
|
||||
|
||||
import prog8.ast.IFunctionCall
|
||||
import prog8.ast.Program
|
||||
@ -21,7 +21,7 @@ import prog8.functions.FunctionSignature
|
||||
internal class BuiltinFunctionsAsmGen(private val program: Program,
|
||||
private val options: CompilationOptions,
|
||||
private val zeropage: Zeropage,
|
||||
private val asmgen: AsmGen2) {
|
||||
private val asmgen: AsmGen) {
|
||||
|
||||
internal fun translateFunctioncallExpression(fcall: FunctionCall, func: FunctionSignature) {
|
||||
translateFunctioncall(fcall, func, false)
|
@ -9,7 +9,7 @@ import prog8.ast.processing.fixupArrayDatatype
|
||||
import prog8.ast.statements.*
|
||||
import prog8.compiler.target.c64.MachineDefinition.FLOAT_MAX_NEGATIVE
|
||||
import prog8.compiler.target.c64.MachineDefinition.FLOAT_MAX_POSITIVE
|
||||
import prog8.compiler.target.c64.codegen2.AssemblyError
|
||||
import prog8.compiler.target.c64.codegen.AssemblyError
|
||||
import prog8.functions.BuiltinFunctions
|
||||
import kotlin.math.floor
|
||||
|
||||
|
@ -10,7 +10,7 @@ import prog8.ast.processing.IAstModifyingVisitor
|
||||
import prog8.ast.processing.IAstVisitor
|
||||
import prog8.ast.statements.*
|
||||
import prog8.compiler.target.c64.Petscii
|
||||
import prog8.compiler.target.c64.codegen2.AssemblyError
|
||||
import prog8.compiler.target.c64.codegen.AssemblyError
|
||||
import prog8.functions.BuiltinFunctions
|
||||
import kotlin.math.floor
|
||||
|
||||
|
@ -7,32 +7,54 @@ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
uword uw
|
||||
ubyte ub
|
||||
uword start=1027
|
||||
uword stop=2020
|
||||
uword i
|
||||
ubyte ib
|
||||
|
||||
; uw = uw>>0
|
||||
; uw = uw>>7
|
||||
ub = uw>>8 as ubyte
|
||||
A++
|
||||
uw = uw>>8
|
||||
A++
|
||||
uw = msb(uw)
|
||||
c64scr.print("\n\n\n\n\n\n\n\n")
|
||||
memset($0400, 40*25, 30)
|
||||
|
||||
; uw <<= 1
|
||||
; uw >>= 1
|
||||
;
|
||||
; ub <<= 1
|
||||
; ub >>= 1
|
||||
;
|
||||
; uw *= 2
|
||||
; ub *= 2
|
||||
ubyte ibstart = 1
|
||||
for ib in ibstart to 255-ibstart {
|
||||
@(ib+1024) = 44
|
||||
}
|
||||
|
||||
for ib in 253 to 2 step -1 {
|
||||
@(ib+1024) = 3
|
||||
}
|
||||
|
||||
ibstart = 3
|
||||
for ib in 255-ibstart to ibstart step -1 {
|
||||
@(ib+1024) = 45
|
||||
}
|
||||
|
||||
|
||||
asmsub aa(byte arg @ Y) clobbers() {
|
||||
%asm {{
|
||||
rts
|
||||
}}
|
||||
for i in 1025 to 2022 {
|
||||
@(i) = 1
|
||||
}
|
||||
|
||||
for i in 2021 to 1026 step -1 {
|
||||
@(i) = 92
|
||||
}
|
||||
|
||||
for i in start to stop {
|
||||
@(i) = 0
|
||||
}
|
||||
|
||||
for i in stop-1 to start+1 step -1 {
|
||||
@(i) = 91
|
||||
}
|
||||
|
||||
|
||||
ubyte xx=X
|
||||
c64scr.print_ub(xx)
|
||||
|
||||
|
||||
; for i in stop to start {
|
||||
; c64scr.print_uw(i)
|
||||
; c64.CHROUT(',')
|
||||
; }
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user