optimized prefix-expression in to use stack evaluation less

This commit is contained in:
Irmen de Jong 2021-11-06 17:57:00 +01:00
parent 62dc824bc0
commit 74456d1135
3 changed files with 78 additions and 18 deletions

View File

@ -254,22 +254,21 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
}
}
// TODO OPTIMIZE PREFIX EXPRESSION:
// is PrefixExpression -> {
// // first assign the value to the target then apply the operator in place on the target.
// translateNormalAssignment(AsmAssignment(
// AsmAssignSource.fromAstSource(value.expression, program, asmgen),
// assign.target,
// false, program.memsizer, assign.position
// ))
// when(value.operator) {
// "+" -> {}
// "-" -> augmentableAsmGen.inplaceNegate(assign.target, assign.target.datatype)
// "~" -> augmentableAsmGen.inplaceInvert(assign.target, assign.target.datatype)
// "not" -> augmentableAsmGen.inplaceBooleanNot(assign.target, assign.target.datatype)
// else -> throw AssemblyError("invalid prefix operator")
// }
// }
is PrefixExpression -> {
// first assign the value to the target then apply the operator in place on the target.
translateNormalAssignment(AsmAssignment(
AsmAssignSource.fromAstSource(value.expression, program, asmgen),
assign.target,
false, program.memsizer, assign.position
))
when(value.operator) {
"+" -> {}
"-" -> augmentableAsmGen.inplaceNegate(assign.target, assign.target.datatype)
"~" -> augmentableAsmGen.inplaceInvert(assign.target, assign.target.datatype)
"not" -> augmentableAsmGen.inplaceBooleanNot(assign.target, assign.target.datatype)
else -> throw AssemblyError("invalid prefix operator")
}
}
else -> {
// Everything else just evaluate via the stack.
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,

View File

@ -1768,7 +1768,28 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
}
TargetStorageKind.REGISTER -> TODO("missing codegen for byte reg not")
TargetStorageKind.REGISTER -> {
when(target.register!!) {
RegisterOrPair.A -> asmgen.out("""
cmp #0
beq +
lda #1
+ eor #1""")
RegisterOrPair.X -> asmgen.out("""
txa
beq +
lda #1
+ eor #1
tax""")
RegisterOrPair.Y -> asmgen.out("""
tya
beq +
lda #1
+ eor #1
tay""")
else -> throw AssemblyError("invalid reg dt for byte not")
}
}
TargetStorageKind.STACK -> TODO("missing codegen for byte stack not")
else -> throw AssemblyError("missing codegen for in-place not of ubyte ${target.kind}")
}
@ -1786,8 +1807,47 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
lsr a
sta ${target.asmVarname}+1""")
}
TargetStorageKind.REGISTER -> {
when(target.register!!) {
RegisterOrPair.AX -> {
asmgen.out("""
stx P8ZP_SCRATCH_REG
ora P8ZP_SCRATCH_REG
beq +
lda #0
tax
beq ++
+ lda #1
+""")
}
RegisterOrPair.AY -> {
asmgen.out("""
sty P8ZP_SCRATCH_REG
ora P8ZP_SCRATCH_REG
beq +
lda #0
tay
beq ++
+ lda #1
+""")
}
RegisterOrPair.XY -> {
asmgen.out("""
stx P8ZP_SCRATCH_REG
tya
ora P8ZP_SCRATCH_REG
beq +
ldy #0
ldx #0
beq ++
+ ldx #1
+""")
}
in Cx16VirtualRegisters -> TODO()
else -> throw AssemblyError("invalid reg dt for word not")
}
}
TargetStorageKind.MEMORY -> TODO("no asm gen for uword-memory not")
TargetStorageKind.REGISTER -> TODO("missing codegen for word reg not")
TargetStorageKind.STACK -> TODO("missing codegen for word stack not")
else -> throw AssemblyError("missing codegen for in-place not of uword for ${target.kind}")
}

View File

@ -7,6 +7,7 @@ For next compiler release (7.2)
- [complicated?] find a way to optimize if-statement codegen so that "if var & %10000" doesn't use evalstack & subroutine call, but also that the simple case "if X {...}" remains fast
- fix the asm-labels problem (github issue #62)
- start migrating to KoTest library (github issue #70)
- optimize "if not x" / "while not x" to not actually calculate the whole "not x" value first --> transform in to "x==0" in these conditional statements?
Blocked by Commander-x16 v39 release