fix crash when using labels in pointerexpression lab+index

This commit is contained in:
Irmen de Jong 2021-06-10 00:44:12 +02:00
parent c5bfef4264
commit f2844bdf1a
2 changed files with 80 additions and 58 deletions

View File

@ -551,38 +551,48 @@ internal class AsmGen(private val program: Program,
internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): Pair<Boolean, String> { internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): Pair<Boolean, String> {
// returns if the pointer is already on the ZP itself or not (in the latter case SCRATCH_W1 is used as intermediary) // returns if the pointer is already on the ZP itself or not (in the latter case SCRATCH_W1 is used as intermediary)
val sourceName = asmVariableName(pointervar) val target = pointervar.targetStatement(program)
val vardecl = pointervar.targetVarDecl(program)!! when (target) {
val scopedName = vardecl.makeScopedName(vardecl.name) is Label -> {
if (isTargetCpu(CpuType.CPU65c02)) { val sourceName = asmSymbolName(pointervar)
return if (isZpVar(scopedName)) { out(" lda $sourceName")
// pointervar is already in the zero page, no need to copy return Pair(true, sourceName)
out(" lda ($sourceName)")
Pair(true, sourceName)
} else {
out("""
lda $sourceName
ldy $sourceName+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda (P8ZP_SCRATCH_W1)""")
Pair(false, sourceName)
} }
} else { is VarDecl -> {
return if (isZpVar(scopedName)) { val sourceName = asmVariableName(pointervar)
// pointervar is already in the zero page, no need to copy val scopedName = target.makeScopedName(target.name)
out(" ldy #0 | lda ($sourceName),y") if (isTargetCpu(CpuType.CPU65c02)) {
Pair(true, sourceName) return if (isZpVar(scopedName)) {
} else { // pointervar is already in the zero page, no need to copy
out(""" out(" lda ($sourceName)")
lda $sourceName Pair(true, sourceName)
ldy $sourceName+1 } else {
sta P8ZP_SCRATCH_W1 out("""
sty P8ZP_SCRATCH_W1+1 lda $sourceName
ldy #0 ldy $sourceName+1
lda (P8ZP_SCRATCH_W1),y""") sta P8ZP_SCRATCH_W1
Pair(false, sourceName) sty P8ZP_SCRATCH_W1+1
lda (P8ZP_SCRATCH_W1)""")
Pair(false, sourceName)
}
} else {
return if (isZpVar(scopedName)) {
// pointervar is already in the zero page, no need to copy
out(" ldy #0 | lda ($sourceName),y")
Pair(true, sourceName)
} else {
out("""
lda $sourceName
ldy $sourceName+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy #0
lda (P8ZP_SCRATCH_W1),y""")
Pair(false, sourceName)
}
}
} }
else -> throw AssemblyError("invalid pointervar")
} }
} }
@ -1470,38 +1480,49 @@ $label nop""")
val ptrAndIndex = pointerViaIndexRegisterPossible(expr) val ptrAndIndex = pointerViaIndexRegisterPossible(expr)
if(ptrAndIndex!=null) { if(ptrAndIndex!=null) {
val pointervar = ptrAndIndex.first as? IdentifierReference val pointervar = ptrAndIndex.first as? IdentifierReference
if(write) { val target = pointervar?.targetStatement(program)
if(pointervar!=null && isZpVar(pointervar)) { when(target) {
val saveA = evalBytevalueWillClobberA(ptrAndIndex.second) is Label -> {
if(saveA)
out(" pha")
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
if(saveA) out(" lda ${asmSymbolName(pointervar)},y")
out(" pla") return true
out(" sta (${asmSymbolName(pointervar)}),y")
} else {
// copy the pointer var to zp first
val saveA = evalBytevalueWillClobberA(ptrAndIndex.first) || evalBytevalueWillClobberA(ptrAndIndex.second)
if(saveA)
out(" pha")
assignExpressionToVariable(ptrAndIndex.first, asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
if(saveA)
out(" pla")
out(" sta (P8ZP_SCRATCH_W2),y")
} }
} else { is VarDecl, null -> {
if(pointervar!=null && isZpVar(pointervar)) { if(write) {
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) if(pointervar!=null && isZpVar(pointervar)) {
out(" lda (${asmSymbolName(pointervar)}),y") val saveA = evalBytevalueWillClobberA(ptrAndIndex.second)
} else { if(saveA)
// copy the pointer var to zp first out(" pha")
assignExpressionToVariable(ptrAndIndex.first, asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null) assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) if(saveA)
out(" lda (P8ZP_SCRATCH_W2),y") out(" pla")
out(" sta (${asmSymbolName(pointervar)}),y")
} else {
// copy the pointer var to zp first
val saveA = evalBytevalueWillClobberA(ptrAndIndex.first) || evalBytevalueWillClobberA(ptrAndIndex.second)
if(saveA)
out(" pha")
assignExpressionToVariable(ptrAndIndex.first, asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
if(saveA)
out(" pla")
out(" sta (P8ZP_SCRATCH_W2),y")
}
} else {
if(pointervar!=null && isZpVar(pointervar)) {
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
out(" lda (${asmSymbolName(pointervar)}),y")
} else {
// copy the pointer var to zp first
assignExpressionToVariable(ptrAndIndex.first, asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
out(" lda (P8ZP_SCRATCH_W2),y")
}
}
return true
} }
else -> throw AssemblyError("invalid pointervar")
} }
return true
} }
} }
return false return false

View File

@ -785,6 +785,7 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
override fun inferType(program: Program): InferredTypes.InferredType { override fun inferType(program: Program): InferredTypes.InferredType {
return when (val targetStmt = targetStatement(program)) { return when (val targetStmt = targetStatement(program)) {
is VarDecl -> InferredTypes.knownFor(targetStmt.datatype) is VarDecl -> InferredTypes.knownFor(targetStmt.datatype)
is Label -> InferredTypes.InferredType.known(DataType.UWORD)
else -> InferredTypes.InferredType.unknown() else -> InferredTypes.InferredType.unknown()
} }
} }