implemented more optimized prefix expression codegen

This commit is contained in:
Irmen de Jong 2020-08-20 21:42:38 +02:00
parent 88d5c68b32
commit 513a68584c
3 changed files with 65 additions and 59 deletions

View File

@ -3,13 +3,12 @@ package prog8.compiler.target.c64.codegen
import prog8.ast.Program import prog8.ast.Program
import prog8.ast.base.DataType import prog8.ast.base.DataType
import prog8.ast.base.IterableDatatypes import prog8.ast.base.IterableDatatypes
import prog8.ast.expressions.BinaryExpression import prog8.ast.expressions.*
import prog8.ast.expressions.PrefixExpression
import prog8.ast.expressions.TypecastExpression
import prog8.ast.statements.AssignTarget import prog8.ast.statements.AssignTarget
import prog8.ast.statements.Assignment import prog8.ast.statements.Assignment
import prog8.compiler.AssemblyError import prog8.compiler.AssemblyError
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
import prog8.compiler.toHex
internal class AugmentableAssignmentAsmGen(private val program: Program, internal class AugmentableAssignmentAsmGen(private val program: Program,
private val assignmentAsmGen: AssignmentAsmGen, private val assignmentAsmGen: AssignmentAsmGen,
@ -98,7 +97,32 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta $name""") sta $name""")
} }
memory!=null -> { memory!=null -> {
TODO("in-place not of ubyte memory") when (memory.addressExpression) {
is NumericLiteralValue -> {
val addr = (memory.addressExpression as NumericLiteralValue).number.toHex()
asmgen.out("""
lda $addr
beq +
lda #1
+ eor #1
sta $addr""")
}
is IdentifierReference -> {
val name = asmgen.asmIdentifierName(memory.addressExpression as IdentifierReference)
asmgen.out("""
lda $name
sta ${C64Zeropage.SCRATCH_W1}
lda $name+1
sta ${C64Zeropage.SCRATCH_W1+1}
ldy #0
lda (${C64Zeropage.SCRATCH_W1}),y
beq +
lda #1
+ eor #1
sta (${C64Zeropage.SCRATCH_W1}),y""")
}
else -> throw AssemblyError("weird address value")
}
} }
arrayIdx!=null -> { arrayIdx!=null -> {
TODO("in-place not of ubyte array") TODO("in-place not of ubyte array")
@ -143,8 +167,28 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta $name""") sta $name""")
} }
memory!=null -> { memory!=null -> {
TODO("in-place invert ubyte memory") when (memory.addressExpression) {
is NumericLiteralValue -> {
val addr = (memory.addressExpression as NumericLiteralValue).number.toHex()
asmgen.out("""
lda $addr
eor #255
sta $addr""")
} }
is IdentifierReference -> {
val name = asmgen.asmIdentifierName(memory.addressExpression as IdentifierReference)
asmgen.out("""
lda $name
sta ${C64Zeropage.SCRATCH_W1}
lda $name+1
sta ${C64Zeropage.SCRATCH_W1+1}
ldy #0
lda (${C64Zeropage.SCRATCH_W1}),y
eor #255
sta (${C64Zeropage.SCRATCH_W1}),y""")
}
else -> throw AssemblyError("weird address value")
} }
arrayIdx!=null -> { arrayIdx!=null -> {
TODO("in-place invert ubyte array") TODO("in-place invert ubyte array")
} }
@ -186,12 +230,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sbc $name sbc $name
sta $name""") sta $name""")
} }
memory!=null -> { memory!=null -> throw AssemblyError("can't in-place negate memory ubyte")
TODO("in-place negate byte memory") arrayIdx!=null -> TODO("in-place negate byte array")
}
arrayIdx!=null -> {
TODO("in-place negate byte array")
}
} }
} }
DataType.WORD -> { DataType.WORD -> {

View File

@ -53,7 +53,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
else else
asmgen.out("+\tdec ${'$'}ffff\t; modified") asmgen.out("+\tdec ${'$'}ffff\t; modified")
} }
else -> throw AssemblyError("weird target type $targetMemory") else -> TODO("asmgen postincrdecr on memory expression")
} }
} }
targetArrayIdx!=null -> { targetArrayIdx!=null -> {

View File

@ -7,55 +7,21 @@ main {
sub start() { sub start() {
byte A = 99
ubyte U = $18
word B = 9999
uword W = $18f0
c64scr.print_b(A)
c64.CHROUT('\n')
A = -A
c64scr.print_b(A)
c64.CHROUT('\n')
U = ~U
c64scr.print_ubhex(U, true)
c64.CHROUT('\n')
U = not U
c64scr.print_ubhex(U, true)
c64.CHROUT('\n')
U = not U
c64scr.print_ubhex(U, true)
c64.CHROUT('\n')
c64scr.print_w(B)
c64.CHROUT('\n')
B = -B
c64scr.print_w(B)
c64.CHROUT('\n')
W = ~W
c64scr.print_uwhex(W, true)
c64.CHROUT('\n')
W = not W
c64scr.print_uwhex(W, true)
c64.CHROUT('\n')
W = not W
c64scr.print_uwhex(W, true)
c64.CHROUT('\n')
;@($d020) += @($d020) ; TODO fix compiler hang ;@($d020) += @($d020) ; TODO fix compiler hang
;@($c000+A) ++ ; TODO implement this
W += 3 uword addr = $c000
@($d020) += 3 @(addr) = $f1
c64scr.print_ubhex(@(addr), true)
W = 43210 c64.CHROUT('\n')
W = W as ubyte @(addr) = - @(addr)
c64scr.print_uw(W) c64scr.print_ubhex(@(addr), true)
c64.CHROUT('\n')
@(addr) = - @(addr)
c64scr.print_ubhex(@(addr), true)
c64.CHROUT('\n') c64.CHROUT('\n')
ubyte[] array = [1,2,3] ;@($c000) = ! @($c000)
array[1] = array[1] as ubyte ;@($c000) = ~ @($c000)
W = array[0]
} }
} }