mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
status condition couldn't properly be tested because restoring the X register clobbers the status flag
This commit is contained in:
parent
b7694686c2
commit
ddf1be2a13
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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) {
|
||||||
|
@ -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()!!)
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user