This commit is contained in:
Irmen de Jong 2021-11-06 14:47:11 +01:00
parent 1605791f1b
commit 62dc824bc0
7 changed files with 100 additions and 55 deletions

View File

@ -833,6 +833,7 @@ class AsmGen(private val program: Program,
}
}
@Deprecated("avoid calling this as it generates slow evalstack based code")
internal fun translateExpression(expression: Expression) =
expressionsAsmGen.translateExpression(expression)

View File

@ -14,6 +14,7 @@ import kotlin.math.absoluteValue
internal class ExpressionsAsmGen(private val program: Program, private val asmgen: AsmGen) {
@Deprecated("avoid calling this as it generates slow evalstack based code")
internal fun translateExpression(expression:Expression) {
if (this.asmgen.options.slowCodegenWarnings) {
asmgen.errors.warn("slow stack evaluation used for expression $expression", expression.position)

View File

@ -143,18 +143,16 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
// 1. load all arguments reversed onto the stack: first arg goes last (is on top).
for (arg in stmt.args.reversed()) {
if(arg.isSimple) { // TODO FOR ALL ARG TYPES?
// note this stuff below is needed to (eventually) avoid calling asmgen.translateExpression()
// TODO but This STILL requires the translateNormalAssignment() to be fixed to avoid stack eval for expressions...
// println("*** ALT PARAM PASSING FOR ASMSUB $stmt $arg") // TODO DEBUG
val dt = arg.inferType(program).getOr(DataType.UNDEFINED)
val target = AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, dt, sub)
asmgen.assignExpressionTo(arg, target)
} else {
asmgen.translateExpression(arg) // TODO GET RID OF THIS, if the above actually produces compact code
}
}
for (arg in stmt.args.reversed())
asmgen.translateExpression(arg)
// TODO here's an alternative to the above, but for now generates bigger code due to intermediate register steps:
// for (arg in stmt.args.reversed()) {
// // note this stuff below is needed to (eventually) avoid calling asmgen.translateExpression()
// // TODO also This STILL requires the translateNormalAssignment() to be fixed to avoid stack eval for expressions...
// val dt = arg.inferType(program).getOr(DataType.UNDEFINED)
// asmgen.assignExpressionTo(arg, AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, dt, sub))
// }
var argForCarry: IndexedValue<Pair<Expression, RegisterOrStatusflag>>? = null
var argForXregister: IndexedValue<Pair<Expression, RegisterOrStatusflag>>? = null

View File

@ -33,6 +33,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
fun translateNormalAssignment(assign: AsmAssignment) {
if(assign.isAugmentable) {
augmentableAsmGen.translate(assign)
return
}
when(assign.source.kind) {
SourceStorageKind.LITERALNUMBER -> {
// simple case: assign a constant number
@ -249,6 +254,22 @@ 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")
// }
// }
else -> {
// Everything else just evaluate via the stack.
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
@ -257,7 +278,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
asmgen.translateExpression(value)
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
asmgen.signExtendStackLsb(assign.source.datatype)
assignStackValue(assign.target)
if(assign.target.kind!=TargetStorageKind.STACK || assign.target.datatype != assign.source.datatype)
assignStackValue(assign.target)
}
}
}
@ -265,7 +287,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
asmgen.assignRegister(assign.source.register!!, assign.target)
}
SourceStorageKind.STACK -> {
assignStackValue(assign.target)
if(assign.target.kind!=TargetStorageKind.STACK || assign.target.datatype != assign.source.datatype)
assignStackValue(assign.target)
}
}
}

View File

@ -1724,7 +1724,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
private fun inplaceBooleanNot(target: AsmAssignTarget, dt: DataType) {
internal fun inplaceBooleanNot(target: AsmAssignTarget, dt: DataType) {
when (dt) {
DataType.UBYTE -> {
when (target.kind) {
@ -1768,9 +1768,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
}
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place not of ubyte array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg not")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack not")
TargetStorageKind.REGISTER -> TODO("missing codegen for byte reg not")
TargetStorageKind.STACK -> TODO("missing codegen for byte stack not")
else -> throw AssemblyError("missing codegen for in-place not of ubyte ${target.kind}")
}
}
DataType.UWORD -> {
@ -1786,17 +1786,17 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
lsr a
sta ${target.asmVarname}+1""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for uword-memory not")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place not of uword array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg not")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack 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}")
}
}
else -> throw AssemblyError("boolean-not of invalid type")
}
}
private fun inplaceInvert(target: AsmAssignTarget, dt: DataType) {
internal fun inplaceInvert(target: AsmAssignTarget, dt: DataType) {
when (dt) {
DataType.UBYTE -> {
when (target.kind) {
@ -1831,9 +1831,16 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
}
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place invert ubyte array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg invert")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack invert")
TargetStorageKind.REGISTER -> {
when(target.register!!) {
RegisterOrPair.A -> asmgen.out(" eor #255")
RegisterOrPair.X -> asmgen.out(" txa | eor #255 | tax")
RegisterOrPair.Y -> asmgen.out(" tya | eor #255 | tay")
else -> throw AssemblyError("invalid reg dt for byte invert")
}
}
TargetStorageKind.STACK -> TODO("missing codegen for byte stack invert")
else -> throw AssemblyError("missing codegen for in-place invert ubyte for ${target.kind}")
}
}
DataType.UWORD -> {
@ -1847,17 +1854,27 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
eor #255
sta ${target.asmVarname}+1""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for uword-memory invert")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place invert uword array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg invert")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack invert")
TargetStorageKind.REGISTER -> {
when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" pha | txa | eor #255 | tax | pla | eor #255")
RegisterOrPair.AY -> asmgen.out(" pha | tya | eor #255 | tay | pla | eor #255")
RegisterOrPair.XY -> asmgen.out(" txa | eor #255 | tax | tya | eor #255 | tay")
in Cx16VirtualRegisters -> {
TODO("codegen for cx16 word register invert")
}
else -> throw AssemblyError("invalid reg dt for word invert")
}
}
TargetStorageKind.MEMORY -> TODO("no asm gen for uword-memory invert")
TargetStorageKind.STACK -> TODO("missing codegen for word stack invert")
else -> throw AssemblyError("missing codegen for in-place invert uword for ${target.kind}")
}
}
else -> throw AssemblyError("invert of invalid type")
}
}
private fun inplaceNegate(target: AsmAssignTarget, dt: DataType) {
internal fun inplaceNegate(target: AsmAssignTarget, dt: DataType) {
when (dt) {
DataType.BYTE -> {
when (target.kind) {
@ -1868,10 +1885,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sbc ${target.asmVarname}
sta ${target.asmVarname}""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("can't in-place negate memory ubyte")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place negate byte array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg negate")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack negate")
TargetStorageKind.REGISTER -> TODO("missing codegen for byte reg negate")
TargetStorageKind.MEMORY -> TODO("can't in-place negate memory ubyte")
TargetStorageKind.STACK -> TODO("missing codegen for byte stack negate")
else -> throw AssemblyError("missing codegen for in-place negate byte array")
}
}
DataType.WORD -> {
@ -1886,10 +1903,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sbc ${target.asmVarname}+1
sta ${target.asmVarname}+1""")
}
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place negate word array")
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for word memory negate")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg negate")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack negate")
TargetStorageKind.REGISTER -> TODO("missing codegen for word reg negate")
TargetStorageKind.MEMORY -> TODO("no asm gen for word memory negate")
TargetStorageKind.STACK -> TODO("missing codegen for word stack negate")
else -> throw AssemblyError("missing codegen for in-place negate word array")
}
}
DataType.FLOAT -> {
@ -1902,9 +1919,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta ${target.asmVarname}+1
""")
}
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place negate float array")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack float negate")
else -> throw AssemblyError("weird target kind for float")
TargetStorageKind.REGISTER -> TODO("missing codegen for float reg negate")
TargetStorageKind.MEMORY -> TODO("missing codegen for float memory negate")
TargetStorageKind.STACK -> TODO("missing codegen for stack float negate")
else -> throw AssemblyError("weird target kind for inplace negate float ${target.kind}")
}
}
else -> throw AssemblyError("negate of invalid type")

View File

@ -244,8 +244,8 @@ internal class AstChecker(private val program: Program,
if(subroutine.name in BuiltinFunctions)
err("cannot redefine a built-in function")
if(subroutine.parameters.size>16)
err("subroutines are limited to 16 parameters")
if(subroutine.parameters.size>6 && !subroutine.isAsmSubroutine)
errors.warn("subroutine has a large number of parameters, this slows down code execution a lot", subroutine.position)
val uniqueNames = subroutine.parameters.asSequence().map { it.name }.toSet()
if(uniqueNames.size!=subroutine.parameters.size)

View File

@ -4,22 +4,26 @@
main {
sub start() {
; uword xx=$2000
uword xx=$2000
@(~xx) *= 2
; ubyte yy=$30
; ubyte zz=9
; ; sys.memset(xx+200, yy*2, zz+yy)
; sys.memset(xx+200, yy*2, ~yy)
;
; @($c030) = 10
; @($c000+yy) *= 2
; @(~xx) *= 2
; txt.print_ub(@($c030))
;
; float f1 = 1111.11
; float f2 = 2222.22
; float[] fa = [2222.22, 3333.33]
;
; swap(f1, fa[1])
; floats.print_f(f1)
; txt.nl()
; floats.print_f(fa[1])
float f1 = 1111.11
float f2 = 2222.22
float[] fa = [2222.22, 3333.33]
swap(f1, fa[1])
floats.print_f(f1)
txt.nl()
floats.print_f(fa[1])
}
}