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 {
return if (allocator.isZpVar((target as PtNamedNode).scopedName)) {
// pointervar is already in the zero page, no need to copy
out(" ldy #0 | lda ($sourceName),y")
loadAFromZpPointerVar(sourceName, true)
sourceName
} else {
out("""
@ -448,19 +448,27 @@ class AsmGen6502Internal (
}
}
internal fun storeAIntoZpPointerVar(zpPointerVar: String) {
internal fun storeAIntoZpPointerVar(zpPointerVar: String, keepY: Boolean) {
if (isTargetCpu(CpuType.CPU65c02))
out(" sta ($zpPointerVar)")
else {
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))
out(" lda ($zpPointerVar)")
else {
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 {
val name2 = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names

View File

@ -129,7 +129,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
SourceStorageKind.MEMORY -> {
fun assignViaExprEval(expression: PtExpression) {
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)
}
@ -2037,7 +2037,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
fun assignViaExprEval(addressExpression: PtExpression) {
asmgen.assignExpressionToVariable(addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2")
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2", false)
asmgen.out(" ldy #0")
assignRegisterpairWord(target, RegisterOrPair.AY)
}
@ -3880,14 +3880,14 @@ internal class AssignmentAsmGen(private val program: PtProgram,
when(addressExpr) {
is PtNumber, is PtIdentifier -> {
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2")
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2", false)
}
else -> {
// same as above but we need to save the A register
asmgen.out(" pha")
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD)
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
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")
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) {
@ -971,7 +971,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
} else {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" clc | adc #$value")
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
}
"-" -> {
@ -982,7 +982,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
} else {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
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}")
else
asmgen.out(" ldy #$value | jsr math.multiply_bytes")
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
"/" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
if(value==0)
throw AssemblyError("division by zero")
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya")
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
"%" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
if(value==0)
throw AssemblyError("division by zero")
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm")
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
"<<" -> {
if (value > 0) {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
repeat(value) { asmgen.out(" asl a") }
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
}
">>" -> {
if (value > 0) {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
repeat(value) { asmgen.out(" lsr a") }
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
}
"&" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" and #$value")
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
"|"-> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" ora #$value")
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
"^" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" eor #$value")
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
"==" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
@ -1045,7 +1045,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
beq ++
+ lda #1
+""")
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
"!=" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
@ -1056,7 +1056,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
beq ++
+ lda #1
+""")
asmgen.storeAIntoZpPointerVar(sourceName)
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a pointer?:
"<", "<=", ">", ">=" -> TODO("byte-litval-to-pointer comparisons")