From 52ab089615296a35d024988f9ab87e9515957dfb Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 25 Mar 2023 16:32:40 +0100 Subject: [PATCH] rpn: implement more comparisons --- .../src/prog8/codegen/cpu6502/AsmGen.kt | 2 +- .../cpu6502/assignment/AssignmentAsmGen.kt | 36 +++++++++++ .../assignment/AugmentableAssignmentAsmGen.kt | 62 ++++++++++++++++++- docs/source/todo.rst | 3 +- 4 files changed, 97 insertions(+), 6 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 19fda1f69..dcfa235cc 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -26,7 +26,7 @@ class AsmGen6502: ICodeGeneratorBackend { errors.warn("EXPERIMENTAL RPN EXPRESSION NODES ARE USED. CODE SIZE+SPEED WILL SUFFER.", Position.DUMMY) } - // printAst(program, true) { println(it) } + printAst(program, true) { println(it) } val asmgen = AsmGen6502Internal(program, symbolTable, options, errors) return asmgen.compileToAssembly() diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index bf8c514a0..aad922ddf 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -369,6 +369,42 @@ internal class AssignmentAsmGen(private val program: PtProgram, if(oper.type != value.type) throw AssemblyError("rpn node type error, expected ${value.type} got ${oper.type}") + if(value.children.size==3 && left is PtExpression && right is PtExpression) { + + // TODO re-enable after compiler errors are fixed: +// if(right.asConstInteger() == 0) { +// if(oper.operator == "==" || oper.operator=="!=") { +// when(assign.target.datatype) { +// in ByteDatatypes -> if(attemptAssignToByteCompareZeroRPN(value, assign)) return true +// else -> { +// // do nothing, this is handled by a type cast. +// } +// } +// } +// } + + if(assign.target.datatype == oper.type && oper.leftType == oper.type) { + println("TODO simple augmented assign operator into target: ${assign.position} ${oper.leftType} ${oper.operator} ${oper.rightType} -> ${oper.type}") + println(" left=$left right=$right") + //augmentableAsmGen.translate() + } else { + println("TODO augmented assign operator into target but needs tempvar: ${assign.position} ${oper.leftType} ${oper.operator} ${oper.rightType} -> ${oper.type}") + println(" left=$left right=$right") + } +// if(oper.operator in ComparisonOperators) { +// println("TODO simple comparison: ${assign.position} ${oper.leftType} ${oper.operator} ${oper.rightType} -> ${oper.type}") +// } +// else if(oper.operator in setOf("&", "|", "^", "and", "or", "xor")) { +// println("TODO simple logical: ${assign.position} ${oper.leftType} ${oper.operator} ${oper.rightType} -> ${oper.type}") +// } +// else if(oper.operator=="+" || oper.operator=="-") { +// println("TODO simple plus or minus: ${assign.position} ${oper.leftType} ${oper.operator} ${oper.rightType} -> ${oper.type}") +// } +// else if(oper.operator=="<<" || oper.operator==">>") { +// println("TODO simple bitshift: ${assign.position} ${oper.leftType} ${oper.operator} ${oper.rightType} -> ${oper.type}") +// } + } + // TODO RPN optimizations for simple cases // if(oper.operator in ComparisonOperators) { // assignRPNComparison(assign, value) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt index 619cfc53e..04d2a33ff 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt @@ -1450,7 +1450,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, sta $name+1""") } // pretty uncommon, who's going to assign a comparison boolean expresion to a word var?: - "<", "<=", ">", ">=" -> TODO("word-bytevar-to-var comparisons") + "<", "<=", ">", ">=" -> TODO("word-bytevar-to-var comparisons ${ident.position}") else -> throw AssemblyError("invalid operator for in-place modification $operator") } } @@ -1555,8 +1555,64 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, lda #0 sta $name+1""") } - // pretty uncommon, who's going to assign a comparison boolean expresion to a word var? - "<", "<=", ">", ">=" -> TODO("word-var-to-var comparisons") + "<" -> { + val compareRoutine = if(dt==DataType.UWORD) "reg_less_uw" else "reg_less_w" + asmgen.out(""" + lda $otherName + ldy $otherName+1 + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + lda $name + ldy $name+1 + jsr prog8_lib.$compareRoutine + sta $name + lda #0 + sta $name+1""") + } + ">" -> { + // a > b --> b < a + val compareRoutine = if(dt==DataType.UWORD) "reg_less_uw" else "reg_less_w" + asmgen.out(""" + lda $name + ldy $name+1 + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + lda $otherName + ldy $otherName+1 + jsr prog8_lib.$compareRoutine + sta $name + lda #0 + sta $name+1""") + } + "<=" -> { + val compareRoutine = if(dt==DataType.UWORD) "reg_lesseq_uw" else "reg_lesseq_w" + asmgen.out(""" + lda $otherName + ldy $otherName+1 + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + lda $name + ldy $name+1 + jsr prog8_lib.$compareRoutine + sta $name + lda #0 + sta $name+1""") + } + ">=" -> { + // a>=b --> b<=a + val compareRoutine = if(dt==DataType.UWORD) "reg_lesseq_uw" else "reg_lesseq_w" + asmgen.out(""" + lda $name + ldy $name+1 + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + lda $otherName + ldy $otherName+1 + jsr prog8_lib.$compareRoutine + sta $name + lda #0 + sta $name+1""") + } else -> throw AssemblyError("invalid operator for in-place modification $operator") } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index edd307623..70c167a00 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,7 +1,6 @@ TODO ==== -RPN: assembler fails selftest -RPN: examples/cx16/cobramk3-gfx.p8 crashes compiler +RPN: assembler fails selftest (something with output file name extension being wrong!) RPN: swirl is MUCH slower RPN: wizzine is slightly slower RPN: bsieve is much slower