mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
fix 6502 code for zp pointer lookup clobbering registers.
This commit is contained in:
parent
24944ad49e
commit
73ec8c31ad
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
|
Loading…
Reference in New Issue
Block a user