mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
fix crash when using labels in pointerexpression lab+index
This commit is contained in:
parent
c5bfef4264
commit
f2844bdf1a
@ -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
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user