rpn: implement more comparisons

This commit is contained in:
Irmen de Jong 2023-03-25 16:32:40 +01:00
parent 01461a196d
commit 52ab089615
4 changed files with 97 additions and 6 deletions

View File

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

View File

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

View File

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

View File

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