diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index d95f34d15..5ea64ef0c 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -48,11 +48,11 @@ class AsmGen6502Internal ( private val forloopsAsmGen = ForLoopsAsmGen(program, this, zeropage) private val postincrdecrAsmGen = PostIncrDecrAsmGen(program, this) private val functioncallAsmGen = FunctionCallAsmGen(program, this) - private val expressionsAsmGen = ExpressionsAsmGen(program, this, allocator) private val programGen = ProgramAndVarsGen(program, options, errors, symbolTable, functioncallAsmGen, this, allocator, zeropage) private val assignmentAsmGen = AssignmentAsmGen(program, symbolTable, this, allocator) - private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, symbolTable, this, assignmentAsmGen) - private val rpnAssignmentAsmGen = RpnExpressionAsmGen(program, symbolTable, assignmentAsmGen, this) + private val expressionsAsmGen = ExpressionsAsmGen(program, this, allocator) + private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen) + private val rpnAssignmentAsmGen = RpnExpressionAsmGen(program, symbolTable, this) fun compileToAssembly(): IAssemblyProgram? { @@ -1007,36 +1007,53 @@ $repeatLabel lda $counterVar } internal fun pointerViaIndexRegisterPossible(pointerOffsetExpr: PtExpression): Pair? { - if (pointerOffsetExpr is PtRpn) { - return rpnAssignmentAsmGen.pointerViaIndexRegisterPossible(pointerOffsetExpr) - } - else if (pointerOffsetExpr is PtBinaryExpression) { - if (pointerOffsetExpr.operator != "+") return null - val leftDt = pointerOffsetExpr.left.type - val rightDt = pointerOffsetExpr.left.type - if(leftDt == DataType.UWORD && rightDt == DataType.UBYTE) - return Pair(pointerOffsetExpr.left, pointerOffsetExpr.right) - if(leftDt == DataType.UBYTE && rightDt == DataType.UWORD) - return Pair(pointerOffsetExpr.right, pointerOffsetExpr.left) - if(leftDt == DataType.UWORD && rightDt == DataType.UWORD) { - // could be that the index was a constant numeric byte but converted to word, check that - val constIdx = pointerOffsetExpr.right as? PtNumber - if(constIdx!=null && constIdx.number.toInt()>=0 && constIdx.number.toInt()<=255) { - return Pair(pointerOffsetExpr.left, PtNumber(DataType.UBYTE, constIdx.number, constIdx.position)) - } - // could be that the index was typecasted into uword, check that - val rightTc = pointerOffsetExpr.right as? PtTypeCast - if(rightTc!=null && rightTc.value.type == DataType.UBYTE) - return Pair(pointerOffsetExpr.left, rightTc.value) - val leftTc = pointerOffsetExpr.left as? PtTypeCast - if(leftTc!=null && leftTc.value.type == DataType.UBYTE) - return Pair(pointerOffsetExpr.right, leftTc.value) + val left: PtExpression + val right: PtExpression + val operator: String + + when (pointerOffsetExpr) { + is PtRpn -> { + if(pointerOffsetExpr.children.size>3) + 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 + left = leftNode + right = rightNode } + is PtBinaryExpression -> { + operator = pointerOffsetExpr.operator + left = pointerOffsetExpr.left + right = pointerOffsetExpr.right + } + else -> return null + } + + if (operator != "+") return null + val leftDt = left.type + val rightDt = right.type + if(leftDt == DataType.UWORD && rightDt == DataType.UBYTE) + return Pair(left, right) + if(leftDt == DataType.UBYTE && rightDt == DataType.UWORD) + return Pair(right, left) + if(leftDt == DataType.UWORD && rightDt == DataType.UWORD) { + // could be that the index was a constant numeric byte but converted to word, check that + val constIdx = right as? PtNumber + if(constIdx!=null && constIdx.number.toInt()>=0 && constIdx.number.toInt()<=255) { + return Pair(left, PtNumber(DataType.UBYTE, constIdx.number, constIdx.position)) + } + // could be that the index was typecasted into uword, check that + val rightTc = right as? PtTypeCast + if(rightTc!=null && rightTc.value.type == DataType.UBYTE) + return Pair(left, rightTc.value) + val leftTc = left as? PtTypeCast + if(leftTc!=null && leftTc.value.type == DataType.UBYTE) + return Pair(right, leftTc.value) } return null } - internal fun tryOptimizedPointerAccessWithA(expr: PtBinaryExpression, write: Boolean): Boolean { + internal fun tryOptimizedPointerAccessWithA(addressExpr: PtExpression, operator: String, write: Boolean): Boolean { // optimize pointer,indexregister if possible fun evalBytevalueWillClobberA(expr: PtExpression): Boolean { @@ -1052,8 +1069,8 @@ $repeatLabel lda $counterVar } } - if(expr.operator=="+") { - val ptrAndIndex = pointerViaIndexRegisterPossible(expr) + if(operator=="+") { + val ptrAndIndex = pointerViaIndexRegisterPossible(addressExpr) if(ptrAndIndex!=null) { val pointervar = ptrAndIndex.first as? PtIdentifier val target = if(pointervar==null) null else symbolTable.lookup(pointervar.name)!!.astNode @@ -2882,7 +2899,8 @@ $repeatLabel lda $counterVar out(" sta P8ESTACK_LO,x | dex") } is PtBinaryExpression -> { - if(tryOptimizedPointerAccessWithA(expr.address as PtBinaryExpression, false)) { + val addrExpr = expr.address as PtBinaryExpression + if(tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) { if(pushResultOnEstack) out(" sta P8ESTACK_LO,x | dex") } else { @@ -2890,7 +2908,8 @@ $repeatLabel lda $counterVar } } is PtRpn -> { - if(rpnAssignmentAsmGen.tryOptimizedPointerAccessWithA(expr.address as PtRpn, false)) { + val addrExpr = expr.address as PtRpn + if(addrExpr.children.size==3 && tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) { if(pushResultOnEstack) out(" sta P8ESTACK_LO,x | dex") } else { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index c77e3ab1a..5433ac687 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -1,18 +1,14 @@ package prog8.codegen.cpu6502 -import prog8.code.SymbolTable import prog8.code.ast.* import prog8.code.core.* import prog8.codegen.cpu6502.assignment.* internal class BuiltinFunctionsAsmGen(private val program: PtProgram, - private val symbolTable: SymbolTable, private val asmgen: AsmGen6502Internal, private val assignAsmGen: AssignmentAsmGen) { - private val rpnAssignmentAsmGen = RpnExpressionAsmGen(program, symbolTable, assignAsmGen, asmgen) - internal fun translateFunctioncallExpression(fcall: PtBuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?): DataType? { return translateFunctioncall(fcall, discardResult = false, resultToStack = resultToStack, resultRegister = resultRegister) } @@ -665,7 +661,29 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, return } } - is PtRpn -> if(rpnAssignmentAsmGen.funcPokeW(fcall)) return + is PtRpn -> { + if(addrExpr.children.size==3) { + // we want just one '+' operator + val (left, oper, right) = addrExpr.finalOperation() + if(oper.operator=="+" && left is PtIdentifier && right is PtNumber) { + val varname = asmgen.asmVariableName(left) + if(asmgen.isZpVar(left)) { + // pointervar is already in the zero page, no need to copy + asmgen.saveRegisterLocal(CpuRegister.X, fcall.definingISub()!!) + asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.AX) + val index = right.number.toHex() + asmgen.out(""" + ldy #$index + sta ($varname),y + txa + iny + sta ($varname),y""") + asmgen.restoreRegisterLocal(CpuRegister.X) + return + } + } + } + } is PtBinaryExpression -> { if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) { val varname = asmgen.asmVariableName(addrExpr.left as PtIdentifier) @@ -695,6 +713,10 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, } private fun funcPeekW(fcall: PtBuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?) { + fun fallback() { + asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) + asmgen.out(" jsr prog8_lib.func_peekw") + } when(val addrExpr = fcall.args[0]) { is PtNumber -> { val addr = addrExpr.number.toHex() @@ -720,12 +742,29 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, tay pla""") } - } else { - asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) - asmgen.out(" jsr prog8_lib.func_peekw") - } + } else fallback() + } + is PtRpn -> { + if(addrExpr.children.size==3) { + // must be 3 (one '+' operator), otherwise expression is too complex for this + val (left, oper, right) = addrExpr.finalOperation() + if(oper.operator=="+" && left is PtIdentifier && right is PtNumber) { + val varname = asmgen.asmVariableName(left) + if(asmgen.isZpVar(left)) { + // pointervar is already in the zero page, no need to copy + val index = right.number.toHex() + asmgen.out(""" + ldy #$index + lda ($varname),y + pha + iny + lda ($varname),y + tay + pla""") + } else fallback() + } else fallback() + } else fallback() } - is PtRpn -> rpnAssignmentAsmGen.funcPeekW(fcall, resultToStack, resultRegister) is PtBinaryExpression -> { if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) { val varname = asmgen.asmVariableName(addrExpr.left as PtIdentifier) @@ -740,19 +779,10 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, lda ($varname),y tay pla""") - } else { - asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) - asmgen.out(" jsr prog8_lib.func_peekw") - } - } else { - asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) - asmgen.out(" jsr prog8_lib.func_peekw") - } - } - else -> { - asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) - asmgen.out(" jsr prog8_lib.func_peekw") + } else fallback() + } else fallback() } + else -> fallback() } if(resultToStack){ diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt index 5b1af0346..089fae6fb 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt @@ -25,7 +25,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram, when(expression) { is PtPrefix -> translateExpression(expression) is PtBinaryExpression -> translateExpression(expression) - is PtRpn -> translateExpression(expression) + is PtRpn -> translateRpnExpression(expression) is PtArrayIndexer -> translateExpression(expression) is PtTypeCast -> translateExpression(expression) is PtAddressOf -> translateExpression(expression) @@ -245,7 +245,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram, } } - private fun translateExpression(expr: PtRpn) { + private fun translateRpnExpression(expr: PtRpn) { // Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED! val oper = expr.finalOperator() val leftDt = oper.leftType @@ -265,6 +265,8 @@ internal class ExpressionsAsmGen(private val program: PtProgram, return translateCompareStrings(expr.finalLeftOperand() as PtExpression, oper.operator, expr.finalRightOperand() as PtExpression) } + // TODO: RPN: add the other optimizations that BinaryExpression has, to avoid eval stack usage + // any other expression if((leftDt in ByteDatatypes && rightDt !in ByteDatatypes) || (leftDt in WordDatatypes && rightDt !in WordDatatypes)) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index ee0299dd3..ef09083dd 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -9,11 +9,11 @@ import prog8.codegen.cpu6502.returnsWhatWhere internal class AssignmentAsmGen(private val program: PtProgram, - private val symbolTable: SymbolTable, + symbolTable: SymbolTable, private val asmgen: AsmGen6502Internal, private val allocator: VariableAllocator) { private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen, allocator) - private val rpnAssignmentAsmGen = RpnExpressionAsmGen(program, symbolTable, this, asmgen) + private val rpnAssignmentAsmGen = RpnExpressionAsmGen(program, symbolTable, asmgen) fun translate(assignment: PtAssignment) { val target = AsmAssignTarget.fromAstAssignment(assignment.target, assignment.definingISub(), asmgen) @@ -145,14 +145,16 @@ internal class AssignmentAsmGen(private val program: PtProgram, assignMemoryByte(assign.target, null, value.address as PtIdentifier) } is PtRpn -> { - if(rpnAssignmentAsmGen.tryOptimizedPointerAccessWithA(value.address as PtRpn, false)) { + val addrExpr = value.address as PtRpn + if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) { assignRegisterByte(assign.target, CpuRegister.A) } else { assignViaExprEval(value.address) } } is PtBinaryExpression -> { - if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpression, false)) { + val addrExpr = value.address as PtBinaryExpression + if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) { assignRegisterByte(assign.target, CpuRegister.A) } else { assignViaExprEval(value.address) @@ -313,7 +315,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, } } is PtRpn -> { - if(!rpnAssignmentAsmGen.attemptAssignOptimizedExpr(value, assign)) { + if(!rpnAssignmentAsmGen.attemptAssignOptimizedExpr(assign)) { // All remaining binary expressions just evaluate via the stack for now. // TODO: For RPN expressions this should never occur anymore and the eval stack should be removed when we achieve this // (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here, @@ -920,7 +922,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, assignMemoryByteIntoWord(target, null, value.address as PtIdentifier) } is PtRpn -> { - if(rpnAssignmentAsmGen.tryOptimizedPointerAccessWithA(value.address as PtRpn, false)) { + val addrExpr = value.address as PtRpn + if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) { asmgen.out(" ldy #0") assignRegisterpairWord(target, RegisterOrPair.AY) } else { @@ -928,7 +931,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, } } is PtBinaryExpression -> { - if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpression, false)) { + val addrExpr = value.address as PtBinaryExpression + if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) { asmgen.out(" ldy #0") assignRegisterpairWord(target, RegisterOrPair.AY) } else { @@ -2849,11 +2853,11 @@ internal class AssignmentAsmGen(private val program: PtProgram, asmgen.storeAIntoPointerVar(addressExpr) } addressExpr is PtRpn -> { - if(!rpnAssignmentAsmGen.tryOptimizedPointerAccessWithA(addressExpr, true)) + if(addressExpr.children.size!=3 || !asmgen.tryOptimizedPointerAccessWithA(addressExpr, addressExpr.finalOperator().operator, true)) storeViaExprEval() } addressExpr is PtBinaryExpression -> { - if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, true)) + if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, addressExpr.operator, true)) storeViaExprEval() } else -> storeViaExprEval() diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/RpnExpressionAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/RpnExpressionAsmGen.kt index 1b542aafd..6433e27c5 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/RpnExpressionAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/RpnExpressionAsmGen.kt @@ -1,129 +1,21 @@ package prog8.codegen.cpu6502.assignment import prog8.code.SymbolTable -import prog8.code.ast.* -import prog8.code.core.AssemblyError -import prog8.code.core.CpuRegister -import prog8.code.core.DataType -import prog8.code.core.RegisterOrPair +import prog8.code.ast.PtProgram +import prog8.code.ast.PtRpn import prog8.codegen.cpu6502.AsmGen6502Internal internal class RpnExpressionAsmGen( val program: PtProgram, val symbolTable: SymbolTable, - val assignmentAsmGen: AssignmentAsmGen, val asmgen: AsmGen6502Internal ) { - internal fun tryOptimizedPointerAccessWithA(expr: PtRpn, write: Boolean): Boolean { - // optimize pointer,indexregister if possible - - fun evalBytevalueWillClobberA(expr: PtExpression): Boolean { - val dt = expr.type - if(dt != DataType.UBYTE && dt != DataType.BYTE) - return true - return when(expr) { - is PtIdentifier -> false - is PtNumber -> false - is PtMemoryByte -> expr.address !is PtIdentifier && expr.address !is PtNumber - is PtTypeCast -> evalBytevalueWillClobberA(expr.value) - else -> true - } - } - - if(expr.finalOperator().operator=="+") { - val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(expr) - if(ptrAndIndex!=null) { - val pointervar = ptrAndIndex.first as? PtIdentifier - val target = if(pointervar==null) null else symbolTable.lookup(pointervar.name)!!.astNode - when(target) { - is PtLabel -> { - asmgen.assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) - asmgen.out(" lda ${asmgen.asmSymbolName(pointervar!!)},y") - return true - } - is IPtVariable, null -> { - if(write) { - if(pointervar!=null && asmgen.isZpVar(pointervar)) { - val saveA = evalBytevalueWillClobberA(ptrAndIndex.second) - if(saveA) - asmgen.out(" pha") - asmgen.assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) - if(saveA) - asmgen.out(" pla") - asmgen.out(" sta (${asmgen.asmSymbolName(pointervar)}),y") - } else { - // copy the pointer var to zp first - val saveA = evalBytevalueWillClobberA(ptrAndIndex.first) || evalBytevalueWillClobberA(ptrAndIndex.second) - if(saveA) - asmgen.out(" pha") - if(ptrAndIndex.second.isSimple()) { - asmgen. assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - asmgen.assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) - if(saveA) - asmgen.out(" pla") - asmgen.out(" sta (P8ZP_SCRATCH_W2),y") - } else { - asmgen.pushCpuStack(DataType.UBYTE, ptrAndIndex.second) - asmgen.assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - asmgen.restoreRegisterStack(CpuRegister.Y, true) - if(saveA) - asmgen.out(" pla") - asmgen.out(" sta (P8ZP_SCRATCH_W2),y") - } - } - } else { - if(pointervar!=null && asmgen.isZpVar(pointervar)) { - asmgen.assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) - asmgen.out(" lda (${asmgen.asmSymbolName(pointervar)}),y") - } else { - // copy the pointer var to zp first - if(ptrAndIndex.second.isSimple()) { - asmgen.assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - asmgen.assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) - asmgen.out(" lda (P8ZP_SCRATCH_W2),y") - } else { - asmgen.pushCpuStack(DataType.UBYTE, ptrAndIndex.second) - asmgen.assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - asmgen.restoreRegisterStack(CpuRegister.Y, false) - asmgen.out(" lda (P8ZP_SCRATCH_W2),y") - } - } - } - return true - } - else -> throw AssemblyError("invalid pointervar $pointervar") - } - } - } + fun attemptAssignOptimizedExpr(assign: AsmAssignment): Boolean { + val value = assign.source.expression as PtRpn + println("TODO: RPN: optimized assignment ${value.position}") // TODO RPN: optimized assignment + // NOTE: don't forgot to evaluate the rest of the RPN expr as well return false } - fun attemptAssignOptimizedExpr(expr: PtRpn, assign: AsmAssignment): Boolean { - println("TODO: RPN: optimized assignment ${expr.position}") // TODO RPN: optimized assignment - return false - } - - fun funcPeekW( - fcall: PtBuiltinFunctionCall, - resultToStack: Boolean, - resultRegister: RegisterOrPair? - ) { - println("TODO: RPN: peekw optimized pointer+index ${fcall.position}") // TODO RPN: peekw optimized pointer+index - // val (left, oper, right) = addrExpr.finalOperation() - asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) - asmgen.out(" jsr prog8_lib.func_peekw") - } - - fun funcPokeW(fcall: PtBuiltinFunctionCall): Boolean { - println("TODO: RPN: pokew optimized pointer+index ${fcall.position}") // TODO RPN: pokew optimized pointer+index - // val (left, oper, right) = addrExpr.finalOperation() - // for now: fall through - return false - } - - fun pointerViaIndexRegisterPossible(pointerOffsetExpr: PtRpn): Pair? { - TODO("RPN determine pointer+index via reg.") // however, is this ever getting called from RPN code? - } - } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 237897337..5f95ca1fa 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,7 +1,9 @@ TODO ==== -BRANCH: Fix the TODO RPN routines to be optimized assembly +BRANCH: Fix the TODO RPN routines to be optimized assembly in RpnExpressionAsmGen.kt + +Implement RPN codegen for IR. For next minor release ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/test.p8 b/examples/test.p8 index 142a726ec..e2d60ddf9 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,6 +3,8 @@ %zeropage basicsafe %option no_sysinit +; $1e4 size + main { sub start() { @@ -10,17 +12,20 @@ main { uword xx=32 cx16.r0L = 3 - if cx16.r0L in "derp" { - xx++ - } + cx16.r0 = peekw(xx + 44) + @(xx+44) = cx16.r0L - xx = xx+(3*func(xx)+xx*2*cx16.r0L) - txt.print_uw(xx) +; if cx16.r0L in "derp" { +; xx++ +; } +; +; xx = xx+(3*func(xx)+xx*2*cx16.r0L) +; txt.print_uw(xx) test_stack.test() } - sub func(uword value) -> uword { - value ++ - return value - } +; sub func(uword value) -> uword { +; value ++ +; return value +; } }