mirror of
https://github.com/irmen/prog8.git
synced 2024-11-27 03:50:27 +00:00
added start of optimized in-place assignment code (for prefix expressions)
This commit is contained in:
parent
e1812ce16c
commit
cffb582568
@ -1,9 +1,11 @@
|
||||
package prog8.compiler.target.c64.codegen
|
||||
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.expressions.BinaryExpression
|
||||
import prog8.ast.expressions.PrefixExpression
|
||||
import prog8.ast.expressions.TypecastExpression
|
||||
import prog8.ast.statements.AssignTarget
|
||||
import prog8.ast.statements.Assignment
|
||||
import prog8.compiler.AssemblyError
|
||||
|
||||
@ -12,23 +14,182 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
private val asmgen: AsmGen) {
|
||||
fun translate(assign: Assignment) {
|
||||
require(assign.isAugmentable)
|
||||
|
||||
when (assign.value) {
|
||||
is PrefixExpression -> {
|
||||
// A = -A , A = +A, A = ~A
|
||||
val px = assign.value as PrefixExpression
|
||||
val type = px.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
when(px.operator) {
|
||||
"+" -> {}
|
||||
"-" -> inplaceNegate(assign.target, type)
|
||||
"~" -> inplaceInvert(assign.target, type)
|
||||
"not" -> inplaceBooleanNot(assign.target, type)
|
||||
else -> throw AssemblyError("invalid prefix operator")
|
||||
}
|
||||
}
|
||||
is TypecastExpression -> {
|
||||
println("TODO optimize typecast assignment ${assign.position}")
|
||||
assignmentAsmGen.translateOtherAssignment(assign) // TODO get rid of this fallback
|
||||
}
|
||||
is BinaryExpression -> {
|
||||
println("TODO optimize binexpr assignment ${assign.position}")
|
||||
assignmentAsmGen.translateOtherAssignment(assign) // TODO get rid of this fallback
|
||||
}
|
||||
else -> {
|
||||
throw AssemblyError("invalid aug assign value type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// when (assign.value) {
|
||||
// is PrefixExpression -> {
|
||||
// TODO("aug prefix")
|
||||
// }
|
||||
// is TypecastExpression -> {
|
||||
// TODO("aug typecast")
|
||||
// }
|
||||
// is BinaryExpression -> {
|
||||
// TODO("aug binary")
|
||||
// }
|
||||
// else -> {
|
||||
// throw AssemblyError("invalid aug assign value type")
|
||||
// }
|
||||
// }
|
||||
private fun inplaceBooleanNot(target: AssignTarget, dt: DataType) {
|
||||
val arrayIdx = target.arrayindexed
|
||||
val identifier = target.identifier
|
||||
val memory = target.memoryAddress
|
||||
|
||||
when(dt) {
|
||||
DataType.UBYTE -> {
|
||||
when {
|
||||
identifier!=null -> {
|
||||
val name = asmgen.asmIdentifierName(identifier)
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
beq +
|
||||
lda #1
|
||||
+ eor #1
|
||||
sta $name""")
|
||||
}
|
||||
memory!=null -> {
|
||||
TODO()
|
||||
}
|
||||
arrayIdx!=null -> {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
when {
|
||||
identifier!=null -> {
|
||||
val name = asmgen.asmIdentifierName(identifier)
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
ora $name+1
|
||||
beq +
|
||||
lda #1
|
||||
+ eor #1
|
||||
sta $name
|
||||
lsr a
|
||||
sta $name+1""")
|
||||
}
|
||||
memory!=null -> {
|
||||
TODO()
|
||||
}
|
||||
arrayIdx!=null -> {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> throw AssemblyError("boolean-not of invalid type")
|
||||
}
|
||||
}
|
||||
|
||||
private fun inplaceInvert(target: AssignTarget, dt: DataType) {
|
||||
val arrayIdx = target.arrayindexed
|
||||
val identifier = target.identifier
|
||||
val memory = target.memoryAddress
|
||||
|
||||
when(dt) {
|
||||
DataType.UBYTE -> {
|
||||
when {
|
||||
identifier!=null -> {
|
||||
val name = asmgen.asmIdentifierName(identifier)
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
eor #255
|
||||
sta $name""")
|
||||
}
|
||||
memory!=null -> {
|
||||
TODO()
|
||||
}
|
||||
arrayIdx!=null -> {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
when {
|
||||
identifier!=null -> {
|
||||
val name = asmgen.asmIdentifierName(identifier)
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
eor #255
|
||||
sta $name
|
||||
lda $name+1
|
||||
eor #255
|
||||
sta $name+1""")
|
||||
}
|
||||
memory!=null -> {
|
||||
TODO()
|
||||
}
|
||||
arrayIdx!=null -> {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> throw AssemblyError("invert of invalid type")
|
||||
}
|
||||
}
|
||||
|
||||
private fun inplaceNegate(target: AssignTarget, dt: DataType) {
|
||||
val arrayIdx = target.arrayindexed
|
||||
val identifier = target.identifier
|
||||
val memory = target.memoryAddress
|
||||
|
||||
when(dt) {
|
||||
DataType.BYTE -> {
|
||||
when {
|
||||
identifier!=null -> {
|
||||
val name = asmgen.asmIdentifierName(identifier)
|
||||
asmgen.out("""
|
||||
lda #0
|
||||
sec
|
||||
sbc $name
|
||||
sta $name""")
|
||||
}
|
||||
memory!=null -> {
|
||||
TODO()
|
||||
}
|
||||
arrayIdx!=null -> {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
DataType.WORD -> {
|
||||
when {
|
||||
identifier!=null -> {
|
||||
val name = asmgen.asmIdentifierName(identifier)
|
||||
asmgen.out("""
|
||||
lda #0
|
||||
sec
|
||||
sbc $name
|
||||
sta $name
|
||||
lda #0
|
||||
sbc $name+1
|
||||
sta $name+1""")
|
||||
}
|
||||
memory!=null -> {
|
||||
TODO()
|
||||
}
|
||||
arrayIdx!=null -> {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
TODO()
|
||||
}
|
||||
else -> throw AssemblyError("negate of invalid type")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,18 +7,55 @@ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
byte A
|
||||
byte B = +A
|
||||
byte C = -A
|
||||
uword W = 43210
|
||||
byte A = 99
|
||||
ubyte U = $18
|
||||
word B = 9999
|
||||
uword W = $18f0
|
||||
|
||||
c64scr.print_b(A)
|
||||
c64.CHROUT('\n')
|
||||
A = -A
|
||||
|
||||
c64scr.print_uw(W)
|
||||
c64scr.print_b(A)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
W = W as ubyte ; TODO cast(W as ubyte) as uword -> W and 255
|
||||
c64scr.print_uw(W)
|
||||
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')
|
||||
|
||||
;
|
||||
; byte B = +A
|
||||
; byte C = -A
|
||||
; uword W = 43210
|
||||
; A = -A
|
||||
;
|
||||
; c64scr.print_uw(W)
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; W = W as ubyte ; TODO cast(W as ubyte) as uword -> W and 255
|
||||
; c64scr.print_uw(W)
|
||||
; c64.CHROUT('\n')
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user