mirror of
https://github.com/irmen/prog8.git
synced 2025-01-03 06:29:54 +00:00
fix that if not fcall() wasn't transformed to a conditional branch instruction
This commit is contained in:
parent
c532e28841
commit
af17f903ee
@ -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? {
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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:
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user