mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
tweaks
This commit is contained in:
parent
1605791f1b
commit
62dc824bc0
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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])
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user