more optimal codegen for if statements

This commit is contained in:
Irmen de Jong 2020-09-15 00:31:44 +02:00
parent dd4a56cb5f
commit 32a7cd31da
3 changed files with 50 additions and 29 deletions

View File

@ -821,17 +821,38 @@ $save .byte 0
}
private fun translate(stmt: IfStatement) {
// TODO don't generate needless jumps/labels when the if or else block is empty
expressionsAsmGen.translateExpression(stmt.condition)
translateTestStack(stmt.condition.inferType(program).typeOrElse(DataType.STRUCT))
val elseLabel = makeLabel("if_else")
val endLabel = makeLabel("if_end")
out(" beq $elseLabel")
translate(stmt.truepart)
out(" jmp $endLabel")
out(elseLabel)
translate(stmt.elsepart)
out(endLabel)
when {
stmt.elsepart.containsNoCodeNorVars() -> {
// empty else
expressionsAsmGen.translateExpression(stmt.condition)
translateTestStack(stmt.condition.inferType(program).typeOrElse(DataType.STRUCT))
val endLabel = makeLabel("if_end")
out(" beq $endLabel")
translate(stmt.truepart)
out(endLabel)
}
stmt.truepart.containsNoCodeNorVars() -> {
// empty true part
expressionsAsmGen.translateExpression(stmt.condition)
translateTestStack(stmt.condition.inferType(program).typeOrElse(DataType.STRUCT))
val endLabel = makeLabel("if_end")
out(" bne $endLabel")
translate(stmt.elsepart)
out(endLabel)
}
else -> {
expressionsAsmGen.translateExpression(stmt.condition)
translateTestStack(stmt.condition.inferType(program).typeOrElse(DataType.STRUCT))
val elseLabel = makeLabel("if_else")
val endLabel = makeLabel("if_end")
out(" beq $elseLabel")
translate(stmt.truepart)
out(" jmp $endLabel")
out(elseLabel)
translate(stmt.elsepart)
out(endLabel)
}
}
}
private fun translateTestStack(dataType: DataType) {

View File

@ -2,15 +2,15 @@
TODO
====
- get rid of all other TODO's in the code ;-)
- gfx examples are now a few hundred bytes larger than before. Why is that, can it be fixed?
- compiler errors and warnings in standard format so the IDE shows them as clickable links; ./test.asm:2578:3: blablabla
- further optimize assignment codegeneration
- auto select correct library to import based on target, instead of having c64- and cx16- prefix variants
- get rid of all TODO's ;-)
- implement @stack for asmsub parameters
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
- aliases for imported symbols for example perhaps '%alias print = c64scr.print' ?
- investigate support for 8bitguy's Commander X16 platform https://www.commanderx16.com and https://github.com/commanderx16/x16-docs
- see if we can group some errors together for instance the (now single) errors about unidentified symbols

View File

@ -9,23 +9,23 @@ main {
sub start() {
%asm {{
sei
ldy #0
sty $1
lda #0
- sta $f000,y
iny
bne -
- lda $f000,y
sta $0400,y
iny
bne -
}}
ubyte b
if b > 15 {
b = 99
} else {
; nothing
}
repeat 60000 {
ubyte a = sin (3)
a++
if b > 15 {
; nothing
} else {
b = 99
}
if b > 15 {
; nothing
} else {
; nothing
}
;asmsub clear_screen (ubyte char @ A, ubyte color @ Y) clobbers(A) { ...}