status condition couldn't properly be tested because restoring the X register clobbers the status flag

This commit is contained in:
Irmen de Jong 2020-12-08 22:10:12 +01:00
parent b7694686c2
commit ddf1be2a13
6 changed files with 14 additions and 38 deletions

View File

@ -134,11 +134,9 @@ io_error:
@(nameptr) = 0 @(nameptr) = 0
while c64.CHRIN() {
; read the rest of the entry until the end ; read the rest of the entry until the end
do { }
ubyte char2 = c64.CHRIN()
char2++ ; TODO fix condition test problem with ldx
} until char2==1
void c64.CHRIN() ; skip 2 bytes void c64.CHRIN() ; skip 2 bytes
void c64.CHRIN() void c64.CHRIN()

View File

@ -757,6 +757,8 @@ class Subroutine(override val name: String,
fun regXasResult() = asmReturnvaluesRegisters.any { it.registerOrPair in setOf(RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY) } fun regXasResult() = asmReturnvaluesRegisters.any { it.registerOrPair in setOf(RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY) }
fun regXasParam() = asmParameterRegisters.any { it.registerOrPair in setOf(RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY) } fun regXasParam() = asmParameterRegisters.any { it.registerOrPair in setOf(RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY) }
fun shouldPreserveStatusRegisterAfterCall() = asmReturnvaluesRegisters.any { it.statusflag != null } || shouldSaveX()
fun shouldSaveX() = CpuRegister.X in asmClobbers || regXasResult() || regXasParam()
fun amountOfRtsInAsm(): Int = statements fun amountOfRtsInAsm(): Int = statements
.asSequence() .asSequence()

View File

@ -1329,7 +1329,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
asmgen.translateBuiltinFunctionCallExpression(expression, builtinFunc, true) asmgen.translateBuiltinFunctionCallExpression(expression, builtinFunc, true)
} else { } else {
sub as Subroutine sub as Subroutine
val preserveStatusRegisterAfterCall = sub.asmReturnvaluesRegisters.any {it.statusflag!=null} val preserveStatusRegisterAfterCall = sub.shouldPreserveStatusRegisterAfterCall()
asmgen.translateFunctionCall(expression, preserveStatusRegisterAfterCall) asmgen.translateFunctionCall(expression, preserveStatusRegisterAfterCall)
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters) val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
for ((_, reg) in returns) { for ((_, reg) in returns) {

View File

@ -16,7 +16,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
internal fun translateFunctionCallStatement(stmt: IFunctionCall) { internal fun translateFunctionCallStatement(stmt: IFunctionCall) {
val sub = stmt.target.targetSubroutine(program.namespace)!! val sub = stmt.target.targetSubroutine(program.namespace)!!
val preserveStatusRegisterAfterCall = sub.asmReturnvaluesRegisters.any {it.statusflag!=null} val preserveStatusRegisterAfterCall = sub.shouldPreserveStatusRegisterAfterCall()
translateFunctionCall(stmt, preserveStatusRegisterAfterCall) translateFunctionCall(stmt, preserveStatusRegisterAfterCall)
// functioncalls no longer return results on the stack, so simply ignore the results in the registers // functioncalls no longer return results on the stack, so simply ignore the results in the registers
if(preserveStatusRegisterAfterCall) if(preserveStatusRegisterAfterCall)
@ -28,7 +28,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
// output the code to setup the parameters and perform the actual call // output the code to setup the parameters and perform the actual call
// does NOT output the code to deal with the result values! // does NOT output the code to deal with the result values!
val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}") val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}")
val saveX = CpuRegister.X in sub.asmClobbers || sub.regXasResult() || sub.regXasParam() val saveX = sub.shouldSaveX()
if(saveX) if(saveX)
asmgen.saveRegister(CpuRegister.X, preserveStatusRegisterAfterCall, (stmt as Node).definingSubroutine()!!) asmgen.saveRegister(CpuRegister.X, preserveStatusRegisterAfterCall, (stmt as Node).definingSubroutine()!!)

View File

@ -142,7 +142,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
is FunctionCall -> { is FunctionCall -> {
when (val sub = value.target.targetStatement(program.namespace)) { when (val sub = value.target.targetStatement(program.namespace)) {
is Subroutine -> { is Subroutine -> {
val preserveStatusRegisterAfterCall = sub.asmReturnvaluesRegisters.any { it.statusflag != null } val preserveStatusRegisterAfterCall = sub.shouldPreserveStatusRegisterAfterCall()
asmgen.translateFunctionCall(value, preserveStatusRegisterAfterCall) asmgen.translateFunctionCall(value, preserveStatusRegisterAfterCall)
val returnValue = sub.returntypes.zip(sub.asmReturnvaluesRegisters).single { it.second.registerOrPair!=null } val returnValue = sub.returntypes.zip(sub.asmReturnvaluesRegisters).single { it.second.registerOrPair!=null }
when (returnValue.first) { when (returnValue.first) {

View File

@ -8,36 +8,12 @@
errors { errors {
sub tofix() { sub tofix() {
repeat {
ubyte char3 = c64.CHRIN()
if_cc
break
if_z ; ; TODO fix undefined symbol:
char3 ++ ; repeat {
else ; ubyte char = c64.CHRIN()
break ; ; ...
; }
char3--
}
labeltje:
while c64.CHRIN() {
; TODO: the loop condition isn't properly tested because a ldx is in the way before the beq
}
repeat {
ubyte char2 = c64.CHRIN()
if char2==0 ; TODO condition not properly tested after optimizing because there's only a sta char2 before it (works without optimizing)
break
}
; TODO fix undefined symbol:
repeat {
ubyte char = c64.CHRIN()
; ...
}
; do { ; do {
; char = c64.CHRIN() ; TODO fix undefined symbol error, should refer to 'char' above in the subroutine's scope ; char = c64.CHRIN() ; TODO fix undefined symbol error, should refer to 'char' above in the subroutine's scope
; } until char==0 ; } until char==0