fix that if not fcall() wasn't transformed to a conditional branch instruction

This commit is contained in:
Irmen de Jong 2024-02-28 01:27:03 +01:00
parent c532e28841
commit af17f903ee
5 changed files with 44 additions and 11 deletions

View File

@ -235,7 +235,7 @@ class AsmGen6502Internal (
private val anyExprGen = AnyExprAsmGen(this)
private val assignmentAsmGen = AssignmentAsmGen(program, this, anyExprGen, allocator)
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
private val ifElseAsmgen = IfElseAsmGen(program, this, allocator, assignmentAsmGen)
private val ifElseAsmgen = IfElseAsmGen(program, symbolTable, this, allocator, assignmentAsmGen)
fun compileToAssembly(): IAssemblyProgram? {

View File

@ -1,24 +1,28 @@
package prog8.codegen.cpu6502
import prog8.code.StRomSub
import prog8.code.SymbolTable
import prog8.code.ast.*
import prog8.code.core.*
import prog8.codegen.cpu6502.assignment.AssignmentAsmGen
internal class IfElseAsmGen(private val program: PtProgram,
private val st: SymbolTable,
private val asmgen: AsmGen6502Internal,
private val allocator: VariableAllocator,
private val assignmentAsmGen: AssignmentAsmGen) {
fun translate(stmt: PtIfElse) {
require(stmt.condition.type== DataType.BOOL)
checkNotRomsubReturnsStatusReg(stmt.condition)
val jumpAfterIf = stmt.ifScope.children.singleOrNull() as? PtJump
if(stmt.condition is PtIdentifier ||
stmt.condition is PtFunctionCall ||
stmt.condition is PtBuiltinFunctionCall ||
stmt.condition is PtArrayIndexer ||
stmt.condition is PtTypeCast ||
stmt.condition is PtBuiltinFunctionCall ||
stmt.condition is PtFunctionCall ||
stmt.condition is PtMemoryByte ||
stmt.condition is PtContainmentCheck)
return fallbackTranslate(stmt, false) // the fallback code for these is optimal, so no warning.
@ -35,6 +39,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
val prefixCond = stmt.condition as? PtPrefix
if(prefixCond?.operator=="not") {
checkNotRomsubReturnsStatusReg(prefixCond.value)
assignConditionValueToRegisterAndTest(prefixCond.value)
return if(jumpAfterIf!=null)
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
@ -45,6 +50,16 @@ internal class IfElseAsmGen(private val program: PtProgram,
fallbackTranslate(stmt, true)
}
private fun checkNotRomsubReturnsStatusReg(condition: PtExpression) {
val fcall = condition as? PtFunctionCall
if(fcall!=null && fcall.type==DataType.BOOL) {
val romsub = st.lookup(fcall.name) as? StRomSub
if(romsub!=null && romsub.returns.any { it.register.statusflag!=null }) {
throw AssemblyError("if romsub() that returns a status register boolean should have been changed into a Conditional branch such as if_cc")
}
}
}
private fun assignConditionValueToRegisterAndTest(condition: PtExpression) {
asmgen.assignExpressionToRegister(condition, RegisterOrPair.A, false)
when(condition) {

View File

@ -349,6 +349,7 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
}
}
// if something_returning_Pc() -> if_cc
val binexpr = srcIf.condition as? BinaryExpression
if(binexpr!=null && binexpr.right.constValue(program)?.number==0.0) {
if(binexpr.operator=="==" || binexpr.operator=="!=") {
@ -368,6 +369,17 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
return codeForStatusflag(fcall, returnRegs[0].statusflag!!, false)
}
}
val prefix = srcIf.condition as? PrefixExpression
if(prefix!=null && prefix.operator=="not") {
val prefixedFcall = prefix.expression as? FunctionCallExpression
if (prefixedFcall != null) {
val returnRegs = prefixedFcall.target.targetSubroutine(program)?.asmReturnvaluesRegisters
if(returnRegs!=null && returnRegs.size==1 && returnRegs[0].statusflag!=null) {
return codeForStatusflag(prefixedFcall, returnRegs[0].statusflag!!, true)
}
}
}
}
val ifelse = PtIfElse(srcIf.position)

View File

@ -1,9 +1,12 @@
TODO
====
floatparse is a lot larger (if string.isdigit() -> uses rols instead of just bcc)
test if any()... code size
floatparse is slightly larger
snow is a lot larger
neofetch is larger
neofetch is sligthly larger

View File

@ -1,14 +1,17 @@
%import math
%import string
%import textio
%zeropage dontuse
%option no_sysinit
%zeropage basicsafe
main {
sub start() {
if cx16.r0s > 0
cx16.r1L++
if cx16.r0s <= 0
cx16.r1L++
if not string.isdigit(cx16.r0L)
goto done
cx16.r0L++
done:
}
}