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