fix 6502 code for zp pointer lookup clobbering registers.

This commit is contained in:
Irmen de Jong 2024-02-07 22:09:04 +01:00
parent 24944ad49e
commit 73ec8c31ad
3 changed files with 33 additions and 25 deletions

View File

@ -400,7 +400,7 @@ class AsmGen6502Internal (
} else { } else {
return if (allocator.isZpVar((target as PtNamedNode).scopedName)) { return if (allocator.isZpVar((target as PtNamedNode).scopedName)) {
// pointervar is already in the zero page, no need to copy // pointervar is already in the zero page, no need to copy
out(" ldy #0 | lda ($sourceName),y") loadAFromZpPointerVar(sourceName, true)
sourceName sourceName
} else { } else {
out(""" out("""
@ -448,18 +448,26 @@ class AsmGen6502Internal (
} }
} }
internal fun storeAIntoZpPointerVar(zpPointerVar: String) { internal fun storeAIntoZpPointerVar(zpPointerVar: String, keepY: Boolean) {
if (isTargetCpu(CpuType.CPU65c02)) if (isTargetCpu(CpuType.CPU65c02))
out(" sta ($zpPointerVar)") out(" sta ($zpPointerVar)")
else else {
out(" ldy #0 | sta ($zpPointerVar),y") if(keepY)
out(" sty P8ZP_SCRATCH_REG | ldy #0 | sta ($zpPointerVar),y | ldy P8ZP_SCRATCH_REG")
else
out(" ldy #0 | sta ($zpPointerVar),y")
}
} }
internal fun loadAFromZpPointerVar(zpPointerVar: String) { internal fun loadAFromZpPointerVar(zpPointerVar: String, keepY: Boolean) {
if (isTargetCpu(CpuType.CPU65c02)) if (isTargetCpu(CpuType.CPU65c02))
out(" lda ($zpPointerVar)") out(" lda ($zpPointerVar)")
else else {
out(" ldy #0 | lda ($zpPointerVar),y") if(keepY)
out(" sty P8ZP_SCRATCH_REG | ldy #0 | lda ($zpPointerVar),y | php | ldy P8ZP_SCRATCH_REG | plp")
else
out(" ldy #0 | lda ($zpPointerVar),y")
}
} }
private fun fixNameSymbols(name: String): String { private fun fixNameSymbols(name: String): String {

View File

@ -129,7 +129,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
SourceStorageKind.MEMORY -> { SourceStorageKind.MEMORY -> {
fun assignViaExprEval(expression: PtExpression) { fun assignViaExprEval(expression: PtExpression) {
assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD) assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2") asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2", false)
assignRegisterByte(assign.target, CpuRegister.A, false, true) assignRegisterByte(assign.target, CpuRegister.A, false, true)
} }
@ -2037,7 +2037,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
fun assignViaExprEval(addressExpression: PtExpression) { fun assignViaExprEval(addressExpression: PtExpression) {
asmgen.assignExpressionToVariable(addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD) asmgen.assignExpressionToVariable(addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2") asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2", false)
asmgen.out(" ldy #0") asmgen.out(" ldy #0")
assignRegisterpairWord(target, RegisterOrPair.AY) assignRegisterpairWord(target, RegisterOrPair.AY)
} }
@ -3880,14 +3880,14 @@ internal class AssignmentAsmGen(private val program: PtProgram,
when(addressExpr) { when(addressExpr) {
is PtNumber, is PtIdentifier -> { is PtNumber, is PtIdentifier -> {
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD) assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2", false)
} }
else -> { else -> {
// same as above but we need to save the A register // same as above but we need to save the A register
asmgen.out(" pha") asmgen.out(" pha")
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD) assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.out(" pla") asmgen.out(" pla")
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2", false)
} }
} }
} }
@ -3989,7 +3989,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
lda (P8ZP_SCRATCH_W2),y lda (P8ZP_SCRATCH_W2),y
eor #255""") eor #255""")
} }
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2", false)
} }
} }
} }

View File

@ -957,7 +957,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
"<", "<=", ">", ">=" -> TODO("byte-var-to-pointer comparisons") "<", "<=", ">", ">=" -> TODO("byte-var-to-pointer comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator") else -> throw AssemblyError("invalid operator for in-place modification $operator")
} }
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
private fun inplacemodificationBytePointerWithLiteralval(pointervar: PtIdentifier, operator: String, value: Int) { private fun inplacemodificationBytePointerWithLiteralval(pointervar: PtIdentifier, operator: String, value: Int) {
@ -971,7 +971,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
} else { } else {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" clc | adc #$value") asmgen.out(" clc | adc #$value")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
} }
"-" -> { "-" -> {
@ -982,7 +982,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
} else { } else {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" sec | sbc #$value") asmgen.out(" sec | sbc #$value")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
} }
"*" -> { "*" -> {
@ -991,50 +991,50 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
asmgen.out(" jsr math.mul_byte_${value}") asmgen.out(" jsr math.mul_byte_${value}")
else else
asmgen.out(" ldy #$value | jsr math.multiply_bytes") asmgen.out(" ldy #$value | jsr math.multiply_bytes")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
"/" -> { "/" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
if(value==0) if(value==0)
throw AssemblyError("division by zero") throw AssemblyError("division by zero")
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya") asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
"%" -> { "%" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
if(value==0) if(value==0)
throw AssemblyError("division by zero") throw AssemblyError("division by zero")
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm") asmgen.out(" ldy #$value | jsr math.divmod_ub_asm")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
"<<" -> { "<<" -> {
if (value > 0) { if (value > 0) {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
repeat(value) { asmgen.out(" asl a") } repeat(value) { asmgen.out(" asl a") }
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
} }
">>" -> { ">>" -> {
if (value > 0) { if (value > 0) {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
repeat(value) { asmgen.out(" lsr a") } repeat(value) { asmgen.out(" lsr a") }
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
} }
"&" -> { "&" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" and #$value") asmgen.out(" and #$value")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
"|"-> { "|"-> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" ora #$value") asmgen.out(" ora #$value")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
"^" -> { "^" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" eor #$value") asmgen.out(" eor #$value")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
"==" -> { "==" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
@ -1045,7 +1045,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
beq ++ beq ++
+ lda #1 + lda #1
+""") +""")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
"!=" -> { "!=" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
@ -1056,7 +1056,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
beq ++ beq ++
+ lda #1 + lda #1
+""") +""")
asmgen.storeAIntoZpPointerVar(sourceName) asmgen.storeAIntoZpPointerVar(sourceName, false)
} }
// pretty uncommon, who's going to assign a comparison boolean expresion to a pointer?: // pretty uncommon, who's going to assign a comparison boolean expresion to a pointer?:
"<", "<=", ">", ">=" -> TODO("byte-litval-to-pointer comparisons") "<", "<=", ">", ">=" -> TODO("byte-litval-to-pointer comparisons")