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
|
package prog8.compiler.target.c64.codegen
|
||||||
|
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
|
import prog8.ast.base.DataType
|
||||||
import prog8.ast.expressions.BinaryExpression
|
import prog8.ast.expressions.BinaryExpression
|
||||||
import prog8.ast.expressions.PrefixExpression
|
import prog8.ast.expressions.PrefixExpression
|
||||||
import prog8.ast.expressions.TypecastExpression
|
import prog8.ast.expressions.TypecastExpression
|
||||||
|
import prog8.ast.statements.AssignTarget
|
||||||
import prog8.ast.statements.Assignment
|
import prog8.ast.statements.Assignment
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
|
|
||||||
@ -12,23 +14,182 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
private val asmgen: AsmGen) {
|
private val asmgen: AsmGen) {
|
||||||
fun translate(assign: Assignment) {
|
fun translate(assign: Assignment) {
|
||||||
require(assign.isAugmentable)
|
require(assign.isAugmentable)
|
||||||
assignmentAsmGen.translateOtherAssignment(assign) // TODO get rid of this fallback
|
|
||||||
|
|
||||||
// when (assign.value) {
|
when (assign.value) {
|
||||||
// is PrefixExpression -> {
|
is PrefixExpression -> {
|
||||||
// TODO("aug prefix")
|
// A = -A , A = +A, A = ~A
|
||||||
// }
|
val px = assign.value as PrefixExpression
|
||||||
// is TypecastExpression -> {
|
val type = px.inferType(program).typeOrElse(DataType.STRUCT)
|
||||||
// TODO("aug typecast")
|
when(px.operator) {
|
||||||
// }
|
"+" -> {}
|
||||||
// is BinaryExpression -> {
|
"-" -> inplaceNegate(assign.target, type)
|
||||||
// TODO("aug binary")
|
"~" -> inplaceInvert(assign.target, type)
|
||||||
// }
|
"not" -> inplaceBooleanNot(assign.target, type)
|
||||||
// else -> {
|
else -> throw AssemblyError("invalid prefix operator")
|
||||||
// throw AssemblyError("invalid aug assign value type")
|
}
|
||||||
// }
|
}
|
||||||
// }
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
sub start() {
|
||||||
|
|
||||||
byte A
|
byte A = 99
|
||||||
byte B = +A
|
ubyte U = $18
|
||||||
byte C = -A
|
word B = 9999
|
||||||
uword W = 43210
|
uword W = $18f0
|
||||||
|
|
||||||
|
c64scr.print_b(A)
|
||||||
|
c64.CHROUT('\n')
|
||||||
A = -A
|
A = -A
|
||||||
|
c64scr.print_b(A)
|
||||||
c64scr.print_uw(W)
|
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
W = W as ubyte ; TODO cast(W as ubyte) as uword -> W and 255
|
U = ~U
|
||||||
c64scr.print_uw(W)
|
c64scr.print_ubhex(U, true)
|
||||||
c64.CHROUT('\n')
|
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