mirror of
https://github.com/irmen/prog8.git
synced 2025-02-27 18:29:00 +00:00
fix RPN issues
This commit is contained in:
parent
df2d7d4734
commit
a819b4a5a5
@ -1175,12 +1175,15 @@ $repeatLabel lda $counterVar
|
||||
}
|
||||
|
||||
private fun translateCompareAndJumpIfTrueRPN(expr: PtRpn, jump: PtJump) {
|
||||
val (left, oper, right) = expr.finalOperation()
|
||||
val (leftRpn, oper, right) = expr.finalOperation()
|
||||
if(oper.operator !in ComparisonOperators)
|
||||
throw AssemblyError("must be comparison expression")
|
||||
if(expr.children.size>3) {
|
||||
TODO("RPN comparison too complex ${expr.position} - split off the comparison + compare value")
|
||||
}
|
||||
val left: PtExpression = if(expr.children.size>3 || leftRpn !is PtExpression) {
|
||||
expr.children.removeLast()
|
||||
expr.children.removeLast()
|
||||
expr
|
||||
} else
|
||||
leftRpn
|
||||
|
||||
// invert the comparison, so we can reuse the JumpIfFalse code generation routines
|
||||
val invertedComparisonOperator = invertedComparisonOperator(oper.operator)
|
||||
@ -1194,23 +1197,25 @@ $repeatLabel lda $counterVar
|
||||
}
|
||||
val rightConstVal = right as? PtNumber
|
||||
if (rightConstVal!=null && rightConstVal.number == 0.0) {
|
||||
require(left is PtExpression)
|
||||
testZeroAndJump(left, invertedComparisonOperator, label)
|
||||
}
|
||||
else {
|
||||
require(left is PtExpression && right is PtExpression)
|
||||
require(right is PtExpression)
|
||||
val leftConstVal = left as? PtNumber
|
||||
testNonzeroComparisonAndJump(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal)
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateCompareAndJumpIfFalseRPN(expr: PtRpn, jumpIfFalseLabel: String) {
|
||||
val (left, oper, right) = expr.finalOperation()
|
||||
if(expr.children.size>3) {
|
||||
TODO("RPN comparison too complex ${expr.position} - split off the comparison + compare value")
|
||||
}
|
||||
val (leftRpn, oper, right) = expr.finalOperation()
|
||||
val left: PtExpression = if(expr.children.size>3 || leftRpn !is PtExpression) {
|
||||
expr.children.removeLast()
|
||||
expr.children.removeLast()
|
||||
expr
|
||||
} else
|
||||
leftRpn
|
||||
|
||||
require(left is PtExpression && right is PtExpression)
|
||||
require(right is PtExpression)
|
||||
val leftConstVal = left as? PtNumber
|
||||
val rightConstVal = right as? PtNumber
|
||||
|
||||
|
@ -202,12 +202,13 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
|
||||
asmgen.signExtendVariableLsb("P8ZP_SCRATCH_W1", value.type)
|
||||
asmgen.assignVariableToRegister("P8ZP_SCRATCH_W1", register, null, Position.DUMMY)
|
||||
} else {
|
||||
val scope = value.definingISub()
|
||||
val target: AsmAssignTarget =
|
||||
if(parameter.value.type in ByteDatatypes && (register==RegisterOrPair.AX || register == RegisterOrPair.AY || register==RegisterOrPair.XY || register in Cx16VirtualRegisters))
|
||||
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, parameter.value.type, sub, value.position, register = register)
|
||||
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, parameter.value.type, scope, value.position, register = register)
|
||||
else {
|
||||
val signed = parameter.value.type == DataType.BYTE || parameter.value.type == DataType.WORD
|
||||
AsmAssignTarget.fromRegisters(register, signed, value.position, sub, asmgen)
|
||||
AsmAssignTarget.fromRegisters(register, signed, value.position, scope, asmgen)
|
||||
}
|
||||
val src = if(value.type in PassByReferenceDatatypes) {
|
||||
if(value is PtIdentifier) {
|
||||
@ -221,7 +222,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
|
||||
} else {
|
||||
AsmAssignSource.fromAstSource(value, program, asmgen).adjustSignedUnsigned(target)
|
||||
}
|
||||
asmgen.translateNormalAssignment(AsmAssignment(src, target, program.memsizer, Position.DUMMY), sub)
|
||||
asmgen.translateNormalAssignment(AsmAssignment(src, target, program.memsizer, Position.DUMMY), scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -359,13 +359,18 @@ internal class ProgramAndVarsGen(
|
||||
|
||||
asmgen.out("; variables")
|
||||
val asmGenInfo = asmgen.subroutineExtra(sub)
|
||||
// TODO move these to BSS as well
|
||||
for((dt, name, addr) in asmGenInfo.extraVars) {
|
||||
if(addr!=null)
|
||||
asmgen.out("$name = $addr")
|
||||
else when(dt) {
|
||||
DataType.UBYTE -> asmgen.out("$name .byte 0")
|
||||
DataType.UWORD -> asmgen.out("$name .word 0")
|
||||
else -> throw AssemblyError("weird dt")
|
||||
DataType.FLOAT -> {
|
||||
require(options.compTarget.machine.FLOAT_MEM_SIZE==5)
|
||||
asmgen.out("$name .byte 0,0,0,0,0")
|
||||
}
|
||||
else -> throw AssemblyError("weird dt for extravar $dt")
|
||||
}
|
||||
}
|
||||
if(asmGenInfo.usedRegsaveA) // will probably never occur
|
||||
|
@ -366,8 +366,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
val value = assign.source.expression as PtRpn
|
||||
val (left, oper, right) = value.finalOperation()
|
||||
|
||||
// TODO RPN the fallthrough if size>3 seems to generate very inefficient code...
|
||||
if(value.children.size==3 && oper.operator in ComparisonOperators) {
|
||||
if(oper.operator in ComparisonOperators) {
|
||||
assignRPNComparison(assign, value)
|
||||
return true
|
||||
}
|
||||
@ -416,7 +415,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
val dummyNode = PtVariable(name, varDt, ZeropageWish.DONTCARE, null, null, Position.DUMMY)
|
||||
dummyNode.parent = scope
|
||||
stScope.add(StStaticVariable(name, varDt, null, null, null, null, ZeropageWish.DONTCARE, dummyNode))
|
||||
asmExtra.extraVars.add(Triple(dt, name, null))
|
||||
asmExtra.extraVars.add(Triple(varDt, name, null))
|
||||
}
|
||||
return name
|
||||
}
|
||||
@ -431,12 +430,12 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
depth-=2
|
||||
val resultVarname = evalVarName(it.type, depth)
|
||||
depth++
|
||||
require(resultVarname==leftvar)
|
||||
symbolTable.resetCachedFlat()
|
||||
if(it.operator in ComparisonOperators) {
|
||||
require(it.type == DataType.UBYTE)
|
||||
val scopeName = (scope as PtNamedNode).scopedName
|
||||
val comparison = PtRpn(DataType.UBYTE, assign.position)
|
||||
comparison.addRpnNode(PtIdentifier("$scopeName.$resultVarname", it.type, value.position))
|
||||
comparison.addRpnNode(PtIdentifier("$scopeName.$leftvar", it.type, value.position))
|
||||
comparison.addRpnNode(PtIdentifier("$scopeName.$rightvar", it.rightType, value.position))
|
||||
comparison.addRpnNode(PtRpnOperator(it.operator, it.type, it.leftType, it.rightType, it.position))
|
||||
comparison.parent = scope
|
||||
@ -445,8 +444,11 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
val normalAssign = AsmAssignment(src, target, program.memsizer, assign.position)
|
||||
assignRPNComparison(normalAssign, comparison)
|
||||
} else {
|
||||
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, DataType.UBYTE, variableAsmName = rightvar)
|
||||
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, scope, assign.position, variableAsmName = resultVarname)
|
||||
require(resultVarname==leftvar) {
|
||||
"expected result $resultVarname == leftvar $leftvar"
|
||||
}
|
||||
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, it.rightType, variableAsmName = rightvar)
|
||||
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, it.type, scope, assign.position, variableAsmName = resultVarname)
|
||||
val augAssign = AsmAugmentedAssignment(src, it.operator+"=", target, program.memsizer, assign.position)
|
||||
augmentableAsmGen.translate(augAssign, scope)
|
||||
}
|
||||
@ -534,7 +536,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun assignRPNComparison(assign: AsmAssignment, comparison: PtRpn) {
|
||||
val (left, oper, right) = comparison.finalOperation()
|
||||
val (leftRpn, oper, right) = comparison.finalOperation()
|
||||
val constRight = (right as PtExpression).asConstInteger()
|
||||
if(constRight == 0) {
|
||||
if(oper.operator == "==" || oper.operator == "!=") {
|
||||
@ -555,18 +557,19 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
|
||||
if(comparison.children.size>3) {
|
||||
TODO("RPN comparison too complex ${comparison.position}")
|
||||
}
|
||||
val left: PtExpression = if(comparison.children.size>3 || leftRpn !is PtExpression) {
|
||||
comparison.children.removeLast()
|
||||
comparison.children.removeLast()
|
||||
comparison
|
||||
} else
|
||||
leftRpn
|
||||
|
||||
require(left is PtExpression)
|
||||
val leftNum = left as? PtNumber
|
||||
val rightNum = right as? PtNumber
|
||||
val jumpIfFalseLabel = asmgen.makeLabel("cmp")
|
||||
|
||||
if(assign.target.isSameAs(left)) {
|
||||
// In-place comparison Target = Target <compare> Right
|
||||
// NOTE : this generates pretty inefficient code.... TODO RPN optimize?
|
||||
val targetDt = assign.target.datatype
|
||||
val tempVar = asmgen.getTempVarName(assign.target.datatype)
|
||||
val tempTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, targetDt, comparison.definingISub(), comparison.position, variableAsmName = tempVar)
|
||||
@ -989,9 +992,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun attemptAssignToByteCompareZeroRPN(expr: PtRpn, assign: AsmAssignment): Boolean {
|
||||
val (left, oper, right) = expr.finalOperation()
|
||||
if(expr.children.size!=3 || left !is PtExpression)
|
||||
return false
|
||||
val (leftRpn, oper, right) = expr.finalOperation()
|
||||
val left = if(expr.children.size!=3 || leftRpn !is PtExpression) {
|
||||
expr.children.removeLast()
|
||||
expr.children.removeLast()
|
||||
expr
|
||||
} else
|
||||
leftRpn
|
||||
when (oper.operator) {
|
||||
"==" -> {
|
||||
when(val dt = left.type) {
|
||||
|
@ -1,9 +1,18 @@
|
||||
TODO
|
||||
====
|
||||
RPN: examples/line-circle-txt crashes
|
||||
RPN: examples/turtlegfx crashes
|
||||
RPN: examples/maze crashes
|
||||
RPN: examples/bsieve,charset compilation crash (bit shift expression)
|
||||
RPN: cube3d-float is massive and slow
|
||||
RPN: mandelbrot is big, but seems faster
|
||||
RPN: swirl is MUCH slower, wizzine is slower
|
||||
|
||||
BRANCH: Fix the TODO RPN routines to be optimized assembly in RpnExpressionAsmGen.kt
|
||||
BRANCH: check BinExprSplitter disablement any effect for RPN?
|
||||
BRANCH: Implement RPN codegen for IR.
|
||||
RPN: Fix the TODO RPN routines to be optimized assembly in RpnExpressionAsmGen.kt
|
||||
RPN: check BinExprSplitter disablement any effect for RPN?
|
||||
RPN: Implement RPN codegen for IR.
|
||||
|
||||
- Move asmExtra vars into BSS as well, now are .byte 0 allocated
|
||||
|
||||
|
||||
For next minor release
|
||||
|
Loading…
x
Reference in New Issue
Block a user