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) {
|
private fun translateCompareAndJumpIfTrueRPN(expr: PtRpn, jump: PtJump) {
|
||||||
val (left, oper, right) = expr.finalOperation()
|
val (leftRpn, oper, right) = expr.finalOperation()
|
||||||
if(oper.operator !in ComparisonOperators)
|
if(oper.operator !in ComparisonOperators)
|
||||||
throw AssemblyError("must be comparison expression")
|
throw AssemblyError("must be comparison expression")
|
||||||
if(expr.children.size>3) {
|
val left: PtExpression = if(expr.children.size>3 || leftRpn !is PtExpression) {
|
||||||
TODO("RPN comparison too complex ${expr.position} - split off the comparison + compare value")
|
expr.children.removeLast()
|
||||||
}
|
expr.children.removeLast()
|
||||||
|
expr
|
||||||
|
} else
|
||||||
|
leftRpn
|
||||||
|
|
||||||
// invert the comparison, so we can reuse the JumpIfFalse code generation routines
|
// invert the comparison, so we can reuse the JumpIfFalse code generation routines
|
||||||
val invertedComparisonOperator = invertedComparisonOperator(oper.operator)
|
val invertedComparisonOperator = invertedComparisonOperator(oper.operator)
|
||||||
@ -1194,23 +1197,25 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
val rightConstVal = right as? PtNumber
|
val rightConstVal = right as? PtNumber
|
||||||
if (rightConstVal!=null && rightConstVal.number == 0.0) {
|
if (rightConstVal!=null && rightConstVal.number == 0.0) {
|
||||||
require(left is PtExpression)
|
|
||||||
testZeroAndJump(left, invertedComparisonOperator, label)
|
testZeroAndJump(left, invertedComparisonOperator, label)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
require(left is PtExpression && right is PtExpression)
|
require(right is PtExpression)
|
||||||
val leftConstVal = left as? PtNumber
|
val leftConstVal = left as? PtNumber
|
||||||
testNonzeroComparisonAndJump(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal)
|
testNonzeroComparisonAndJump(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateCompareAndJumpIfFalseRPN(expr: PtRpn, jumpIfFalseLabel: String) {
|
private fun translateCompareAndJumpIfFalseRPN(expr: PtRpn, jumpIfFalseLabel: String) {
|
||||||
val (left, oper, right) = expr.finalOperation()
|
val (leftRpn, oper, right) = expr.finalOperation()
|
||||||
if(expr.children.size>3) {
|
val left: PtExpression = if(expr.children.size>3 || leftRpn !is PtExpression) {
|
||||||
TODO("RPN comparison too complex ${expr.position} - split off the comparison + compare value")
|
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 leftConstVal = left as? PtNumber
|
||||||
val rightConstVal = right 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.signExtendVariableLsb("P8ZP_SCRATCH_W1", value.type)
|
||||||
asmgen.assignVariableToRegister("P8ZP_SCRATCH_W1", register, null, Position.DUMMY)
|
asmgen.assignVariableToRegister("P8ZP_SCRATCH_W1", register, null, Position.DUMMY)
|
||||||
} else {
|
} else {
|
||||||
|
val scope = value.definingISub()
|
||||||
val target: AsmAssignTarget =
|
val target: AsmAssignTarget =
|
||||||
if(parameter.value.type in ByteDatatypes && (register==RegisterOrPair.AX || register == RegisterOrPair.AY || register==RegisterOrPair.XY || register in Cx16VirtualRegisters))
|
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 {
|
else {
|
||||||
val signed = parameter.value.type == DataType.BYTE || parameter.value.type == DataType.WORD
|
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) {
|
val src = if(value.type in PassByReferenceDatatypes) {
|
||||||
if(value is PtIdentifier) {
|
if(value is PtIdentifier) {
|
||||||
@ -221,7 +222,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
|
|||||||
} else {
|
} else {
|
||||||
AsmAssignSource.fromAstSource(value, program, asmgen).adjustSignedUnsigned(target)
|
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")
|
asmgen.out("; variables")
|
||||||
val asmGenInfo = asmgen.subroutineExtra(sub)
|
val asmGenInfo = asmgen.subroutineExtra(sub)
|
||||||
|
// TODO move these to BSS as well
|
||||||
for((dt, name, addr) in asmGenInfo.extraVars) {
|
for((dt, name, addr) in asmGenInfo.extraVars) {
|
||||||
if(addr!=null)
|
if(addr!=null)
|
||||||
asmgen.out("$name = $addr")
|
asmgen.out("$name = $addr")
|
||||||
else when(dt) {
|
else when(dt) {
|
||||||
DataType.UBYTE -> asmgen.out("$name .byte 0")
|
DataType.UBYTE -> asmgen.out("$name .byte 0")
|
||||||
DataType.UWORD -> asmgen.out("$name .word 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
|
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 value = assign.source.expression as PtRpn
|
||||||
val (left, oper, right) = value.finalOperation()
|
val (left, oper, right) = value.finalOperation()
|
||||||
|
|
||||||
// TODO RPN the fallthrough if size>3 seems to generate very inefficient code...
|
if(oper.operator in ComparisonOperators) {
|
||||||
if(value.children.size==3 && oper.operator in ComparisonOperators) {
|
|
||||||
assignRPNComparison(assign, value)
|
assignRPNComparison(assign, value)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -416,7 +415,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
val dummyNode = PtVariable(name, varDt, ZeropageWish.DONTCARE, null, null, Position.DUMMY)
|
val dummyNode = PtVariable(name, varDt, ZeropageWish.DONTCARE, null, null, Position.DUMMY)
|
||||||
dummyNode.parent = scope
|
dummyNode.parent = scope
|
||||||
stScope.add(StStaticVariable(name, varDt, null, null, null, null, ZeropageWish.DONTCARE, dummyNode))
|
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
|
return name
|
||||||
}
|
}
|
||||||
@ -431,12 +430,12 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
depth-=2
|
depth-=2
|
||||||
val resultVarname = evalVarName(it.type, depth)
|
val resultVarname = evalVarName(it.type, depth)
|
||||||
depth++
|
depth++
|
||||||
require(resultVarname==leftvar)
|
|
||||||
symbolTable.resetCachedFlat()
|
symbolTable.resetCachedFlat()
|
||||||
if(it.operator in ComparisonOperators) {
|
if(it.operator in ComparisonOperators) {
|
||||||
|
require(it.type == DataType.UBYTE)
|
||||||
val scopeName = (scope as PtNamedNode).scopedName
|
val scopeName = (scope as PtNamedNode).scopedName
|
||||||
val comparison = PtRpn(DataType.UBYTE, assign.position)
|
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(PtIdentifier("$scopeName.$rightvar", it.rightType, value.position))
|
||||||
comparison.addRpnNode(PtRpnOperator(it.operator, it.type, it.leftType, it.rightType, it.position))
|
comparison.addRpnNode(PtRpnOperator(it.operator, it.type, it.leftType, it.rightType, it.position))
|
||||||
comparison.parent = scope
|
comparison.parent = scope
|
||||||
@ -445,8 +444,11 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
val normalAssign = AsmAssignment(src, target, program.memsizer, assign.position)
|
val normalAssign = AsmAssignment(src, target, program.memsizer, assign.position)
|
||||||
assignRPNComparison(normalAssign, comparison)
|
assignRPNComparison(normalAssign, comparison)
|
||||||
} else {
|
} else {
|
||||||
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, DataType.UBYTE, variableAsmName = rightvar)
|
require(resultVarname==leftvar) {
|
||||||
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, scope, assign.position, variableAsmName = resultVarname)
|
"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)
|
val augAssign = AsmAugmentedAssignment(src, it.operator+"=", target, program.memsizer, assign.position)
|
||||||
augmentableAsmGen.translate(augAssign, scope)
|
augmentableAsmGen.translate(augAssign, scope)
|
||||||
}
|
}
|
||||||
@ -534,7 +536,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun assignRPNComparison(assign: AsmAssignment, comparison: PtRpn) {
|
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()
|
val constRight = (right as PtExpression).asConstInteger()
|
||||||
if(constRight == 0) {
|
if(constRight == 0) {
|
||||||
if(oper.operator == "==" || oper.operator == "!=") {
|
if(oper.operator == "==" || oper.operator == "!=") {
|
||||||
@ -555,18 +557,19 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(comparison.children.size>3) {
|
val left: PtExpression = if(comparison.children.size>3 || leftRpn !is PtExpression) {
|
||||||
TODO("RPN comparison too complex ${comparison.position}")
|
comparison.children.removeLast()
|
||||||
}
|
comparison.children.removeLast()
|
||||||
|
comparison
|
||||||
|
} else
|
||||||
|
leftRpn
|
||||||
|
|
||||||
require(left is PtExpression)
|
|
||||||
val leftNum = left as? PtNumber
|
val leftNum = left as? PtNumber
|
||||||
val rightNum = right as? PtNumber
|
val rightNum = right as? PtNumber
|
||||||
val jumpIfFalseLabel = asmgen.makeLabel("cmp")
|
val jumpIfFalseLabel = asmgen.makeLabel("cmp")
|
||||||
|
|
||||||
if(assign.target.isSameAs(left)) {
|
if(assign.target.isSameAs(left)) {
|
||||||
// In-place comparison Target = Target <compare> Right
|
// In-place comparison Target = Target <compare> Right
|
||||||
// NOTE : this generates pretty inefficient code.... TODO RPN optimize?
|
|
||||||
val targetDt = assign.target.datatype
|
val targetDt = assign.target.datatype
|
||||||
val tempVar = asmgen.getTempVarName(assign.target.datatype)
|
val tempVar = asmgen.getTempVarName(assign.target.datatype)
|
||||||
val tempTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, targetDt, comparison.definingISub(), comparison.position, variableAsmName = tempVar)
|
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 {
|
private fun attemptAssignToByteCompareZeroRPN(expr: PtRpn, assign: AsmAssignment): Boolean {
|
||||||
val (left, oper, right) = expr.finalOperation()
|
val (leftRpn, oper, right) = expr.finalOperation()
|
||||||
if(expr.children.size!=3 || left !is PtExpression)
|
val left = if(expr.children.size!=3 || leftRpn !is PtExpression) {
|
||||||
return false
|
expr.children.removeLast()
|
||||||
|
expr.children.removeLast()
|
||||||
|
expr
|
||||||
|
} else
|
||||||
|
leftRpn
|
||||||
when (oper.operator) {
|
when (oper.operator) {
|
||||||
"==" -> {
|
"==" -> {
|
||||||
when(val dt = left.type) {
|
when(val dt = left.type) {
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
TODO
|
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
|
RPN: Fix the TODO RPN routines to be optimized assembly in RpnExpressionAsmGen.kt
|
||||||
BRANCH: check BinExprSplitter disablement any effect for RPN?
|
RPN: check BinExprSplitter disablement any effect for RPN?
|
||||||
BRANCH: Implement RPN codegen for IR.
|
RPN: Implement RPN codegen for IR.
|
||||||
|
|
||||||
|
- Move asmExtra vars into BSS as well, now are .byte 0 allocated
|
||||||
|
|
||||||
|
|
||||||
For next minor release
|
For next minor release
|
||||||
|
Loading…
x
Reference in New Issue
Block a user