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 {
|
||||
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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user