implementing Rpn optimizations 2

This commit is contained in:
Irmen de Jong 2023-03-18 11:04:51 +01:00
parent e8bebe5a75
commit 94c06e13f4
7 changed files with 38 additions and 13 deletions

View File

@ -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
}

View File

@ -175,6 +175,7 @@ class PtRpn(type: DataType, position: Position): PtExpression(type, position) {
}
}
else {
require(node !is PtBinaryExpression)
children.add(node)
node.parent = this
}

View File

@ -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")

View File

@ -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) {

View File

@ -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

View File

@ -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()
}

View File

@ -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++