mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
implementing Rpn optimizations 2
This commit is contained in:
parent
e8bebe5a75
commit
94c06e13f4
@ -74,6 +74,9 @@ class PtProgram(
|
||||
fun transformToRPN(originalExpr: PtBinaryExpression): PtRpn {
|
||||
fun makeRpn(expr: PtExpression): PtRpn {
|
||||
val rpn = PtRpn(expr.type, expr.position)
|
||||
if(expr is PtBinaryExpression)
|
||||
rpn.addRpnNode(transformToRPN(expr))
|
||||
else
|
||||
rpn.addRpnNode(expr)
|
||||
return rpn
|
||||
}
|
||||
|
@ -175,6 +175,7 @@ class PtRpn(type: DataType, position: Position): PtExpression(type, position) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
require(node !is PtBinaryExpression)
|
||||
children.add(node)
|
||||
node.parent = this
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ class AsmGen6502Internal (
|
||||
private val assignmentAsmGen = AssignmentAsmGen(program, symbolTable, this, allocator)
|
||||
private val expressionsAsmGen = ExpressionsAsmGen(program, this, allocator)
|
||||
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
|
||||
private val rpnAssignmentAsmGen = RpnExpressionAsmGen(program, symbolTable, this)
|
||||
|
||||
fun compileToAssembly(): IAssemblyProgram? {
|
||||
|
||||
@ -1013,8 +1012,10 @@ $repeatLabel lda $counterVar
|
||||
|
||||
when (pointerOffsetExpr) {
|
||||
is PtRpn -> {
|
||||
if(pointerOffsetExpr.children.size>3)
|
||||
if(pointerOffsetExpr.children.size>3) {
|
||||
println("TODO: RPN: too complicated pointerViaIndexRegisterPossible") // TODO RPN
|
||||
return null // expression is too complex, we need just a pointer var + index
|
||||
}
|
||||
val (leftNode, oper, rightNode) = pointerOffsetExpr.finalOperation()
|
||||
operator=oper.operator
|
||||
if (leftNode !is PtExpression || rightNode !is PtExpression) return null
|
||||
@ -2909,6 +2910,8 @@ $repeatLabel lda $counterVar
|
||||
}
|
||||
is PtRpn -> {
|
||||
val addrExpr = expr.address as PtRpn
|
||||
if(addrExpr.children.size>3)
|
||||
println("TODO: RPN: too complicated translateDirectMemReadExpressionToRegAorStack") // TODO RPN
|
||||
if(addrExpr.children.size==3 && tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
|
||||
if(pushResultOnEstack)
|
||||
out(" sta P8ESTACK_LO,x | dex")
|
||||
|
@ -682,6 +682,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println("TODO: RPN: too complicated PokeW") // TODO RPN
|
||||
}
|
||||
}
|
||||
is PtBinaryExpression -> {
|
||||
@ -763,7 +765,10 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
pla""")
|
||||
} else fallback()
|
||||
} else fallback()
|
||||
} else fallback()
|
||||
} else {
|
||||
println("TODO: RPN: too complicated PeekW") // TODO RPN
|
||||
fallback()
|
||||
}
|
||||
}
|
||||
is PtBinaryExpression -> {
|
||||
if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) {
|
||||
|
@ -248,21 +248,22 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
|
||||
private fun translateRpnExpression(expr: PtRpn) {
|
||||
// Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED!
|
||||
val oper = expr.finalOperator()
|
||||
val left = expr.finalLeftOperand() as? PtExpression
|
||||
val leftDt = oper.leftType
|
||||
val rightDt = oper.rightType
|
||||
|
||||
// comparison against zero
|
||||
if(oper.operator in ComparisonOperators) {
|
||||
if(left != null && oper.operator in ComparisonOperators) {
|
||||
if(leftDt in NumericDatatypes && rightDt in NumericDatatypes) {
|
||||
val rightVal = (expr.finalRightOperand() as PtExpression).asConstInteger()
|
||||
if(rightVal==0)
|
||||
return translateComparisonWithZero(expr.finalLeftOperand() as PtExpression, leftDt, oper.operator)
|
||||
return translateComparisonWithZero(left, leftDt, oper.operator)
|
||||
}
|
||||
}
|
||||
|
||||
// string compare
|
||||
if(leftDt==DataType.STR && rightDt==DataType.STR && oper.operator in ComparisonOperators) {
|
||||
return translateCompareStrings(expr.finalLeftOperand() as PtExpression, oper.operator, expr.finalRightOperand() as PtExpression)
|
||||
if(left!=null && leftDt==DataType.STR && rightDt==DataType.STR && oper.operator in ComparisonOperators) {
|
||||
return translateCompareStrings(left, oper.operator, expr.finalRightOperand() as PtExpression)
|
||||
}
|
||||
|
||||
// TODO: RPN: add the other optimizations that BinaryExpression has, to avoid eval stack usage
|
||||
@ -277,7 +278,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
|
||||
if(it is PtRpnOperator) {
|
||||
when(it.leftType) {
|
||||
in ByteDatatypes -> translateBinaryOperatorBytes(it.operator, it.leftType)
|
||||
in WordDatatypes -> translateBinaryOperatorWords(it.operator, it.leftType)
|
||||
in WordDatatypes, in PassByReferenceDatatypes -> translateBinaryOperatorWords(it.operator, it.leftType)
|
||||
DataType.FLOAT -> translateBinaryOperatorFloats(it.operator)
|
||||
else -> throw AssemblyError("non-numerical datatype ${it.leftType}")
|
||||
}
|
||||
@ -292,6 +293,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
|
||||
|
||||
private fun translateExpression(expr: PtBinaryExpression) {
|
||||
// Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED!
|
||||
require(!program.binaryExpressionsAreRPN)
|
||||
val leftDt = expr.left.type
|
||||
val rightDt = expr.right.type
|
||||
// see if we can apply some optimized routines still
|
||||
|
@ -146,6 +146,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
is PtRpn -> {
|
||||
val addrExpr = value.address as PtRpn
|
||||
if(addrExpr.children.size>3)
|
||||
println("TODO: RPN: too complex translateNormalAssignment") // TODO RPN
|
||||
if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
|
||||
assignRegisterByte(assign.target, CpuRegister.A)
|
||||
} else {
|
||||
@ -307,6 +309,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
assignRegisterByte(assign.target, CpuRegister.A)
|
||||
}
|
||||
is PtBinaryExpression -> {
|
||||
require(!program.binaryExpressionsAreRPN)
|
||||
if(!attemptAssignOptimizedBinexpr(value, assign)) {
|
||||
// All remaining binary expressions just evaluate via the stack for now.
|
||||
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
|
||||
@ -923,6 +926,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
is PtRpn -> {
|
||||
val addrExpr = value.address as PtRpn
|
||||
if(addrExpr.children.size>3) {
|
||||
println("TODO: RPN: too complex assignTypeCastedValue") // TODO RPN
|
||||
}
|
||||
if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
|
||||
asmgen.out(" ldy #0")
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
@ -2853,6 +2859,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.storeAIntoPointerVar(addressExpr)
|
||||
}
|
||||
addressExpr is PtRpn -> {
|
||||
if(addressExpr.children.size>3)
|
||||
println("TODO: RPN: too complex storeRegisterAInMemoryAddress $memoryAddress") // TODO RPN
|
||||
if(addressExpr.children.size!=3 || !asmgen.tryOptimizedPointerAccessWithA(addressExpr, addressExpr.finalOperator().operator, true))
|
||||
storeViaExprEval()
|
||||
}
|
||||
|
@ -9,11 +9,14 @@ main {
|
||||
|
||||
sub start() {
|
||||
test_stack.test()
|
||||
uword xx=32
|
||||
cx16.r0L = 3
|
||||
uword xx=4000
|
||||
ubyte a
|
||||
ubyte b
|
||||
ubyte c
|
||||
ubyte d
|
||||
|
||||
cx16.r0 = peekw(xx + 44)
|
||||
@(xx+44) = cx16.r0L
|
||||
cx16.r0 = peekw(a+xx+b+c+d)
|
||||
; TODO @(a+xx+b+c+d) = cx16.r0L
|
||||
|
||||
; if cx16.r0L in "derp" {
|
||||
; xx++
|
||||
|
Loading…
Reference in New Issue
Block a user