mirror of
https://github.com/irmen/prog8.git
synced 2024-07-09 17:29:46 +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) =
|
internal fun translateExpression(expression: Expression) =
|
||||||
expressionsAsmGen.translateExpression(expression)
|
expressionsAsmGen.translateExpression(expression)
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import kotlin.math.absoluteValue
|
|||||||
|
|
||||||
internal class ExpressionsAsmGen(private val program: Program, private val asmgen: AsmGen) {
|
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) {
|
internal fun translateExpression(expression:Expression) {
|
||||||
if (this.asmgen.options.slowCodegenWarnings) {
|
if (this.asmgen.options.slowCodegenWarnings) {
|
||||||
asmgen.errors.warn("slow stack evaluation used for expression $expression", expression.position)
|
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).
|
// 1. load all arguments reversed onto the stack: first arg goes last (is on top).
|
||||||
|
|
||||||
for (arg in stmt.args.reversed()) {
|
for (arg in stmt.args.reversed())
|
||||||
if(arg.isSimple) { // TODO FOR ALL ARG TYPES?
|
asmgen.translateExpression(arg)
|
||||||
// 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...
|
// TODO here's an alternative to the above, but for now generates bigger code due to intermediate register steps:
|
||||||
// println("*** ALT PARAM PASSING FOR ASMSUB $stmt $arg") // TODO DEBUG
|
// for (arg in stmt.args.reversed()) {
|
||||||
val dt = arg.inferType(program).getOr(DataType.UNDEFINED)
|
// // note this stuff below is needed to (eventually) avoid calling asmgen.translateExpression()
|
||||||
val target = AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, dt, sub)
|
// // TODO also This STILL requires the translateNormalAssignment() to be fixed to avoid stack eval for expressions...
|
||||||
asmgen.assignExpressionTo(arg, target)
|
// val dt = arg.inferType(program).getOr(DataType.UNDEFINED)
|
||||||
} else {
|
// asmgen.assignExpressionTo(arg, AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, dt, sub))
|
||||||
asmgen.translateExpression(arg) // TODO GET RID OF THIS, if the above actually produces compact code
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var argForCarry: IndexedValue<Pair<Expression, RegisterOrStatusflag>>? = null
|
var argForCarry: IndexedValue<Pair<Expression, RegisterOrStatusflag>>? = null
|
||||||
var argForXregister: 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) {
|
fun translateNormalAssignment(assign: AsmAssignment) {
|
||||||
|
if(assign.isAugmentable) {
|
||||||
|
augmentableAsmGen.translate(assign)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
when(assign.source.kind) {
|
when(assign.source.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> {
|
SourceStorageKind.LITERALNUMBER -> {
|
||||||
// simple case: assign a constant number
|
// 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 -> {
|
else -> {
|
||||||
// Everything else just evaluate via the stack.
|
// Everything else just evaluate via the stack.
|
||||||
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
|
// (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)
|
asmgen.translateExpression(value)
|
||||||
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
|
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
|
||||||
asmgen.signExtendStackLsb(assign.source.datatype)
|
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)
|
asmgen.assignRegister(assign.source.register!!, assign.target)
|
||||||
}
|
}
|
||||||
SourceStorageKind.STACK -> {
|
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) {
|
when (dt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
when (target.kind) {
|
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 -> TODO("missing codegen for byte reg not")
|
||||||
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg not")
|
TargetStorageKind.STACK -> TODO("missing codegen for byte stack not")
|
||||||
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack not")
|
else -> throw AssemblyError("missing codegen for in-place not of ubyte ${target.kind}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.UWORD -> {
|
DataType.UWORD -> {
|
||||||
@ -1786,17 +1786,17 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
lsr a
|
lsr a
|
||||||
sta ${target.asmVarname}+1""")
|
sta ${target.asmVarname}+1""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for uword-memory not")
|
TargetStorageKind.MEMORY -> TODO("no asm gen for uword-memory not")
|
||||||
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place not of uword array")
|
TargetStorageKind.REGISTER -> TODO("missing codegen for word reg not")
|
||||||
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg not")
|
TargetStorageKind.STACK -> TODO("missing codegen for word stack not")
|
||||||
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack not")
|
else -> throw AssemblyError("missing codegen for in-place not of uword for ${target.kind}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("boolean-not of invalid type")
|
else -> throw AssemblyError("boolean-not of invalid type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceInvert(target: AsmAssignTarget, dt: DataType) {
|
internal fun inplaceInvert(target: AsmAssignTarget, dt: DataType) {
|
||||||
when (dt) {
|
when (dt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
when (target.kind) {
|
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 -> {
|
||||||
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg invert")
|
when(target.register!!) {
|
||||||
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack invert")
|
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 -> {
|
DataType.UWORD -> {
|
||||||
@ -1847,17 +1854,27 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
eor #255
|
eor #255
|
||||||
sta ${target.asmVarname}+1""")
|
sta ${target.asmVarname}+1""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for uword-memory invert")
|
TargetStorageKind.REGISTER -> {
|
||||||
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place invert uword array")
|
when(target.register!!) {
|
||||||
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg invert")
|
RegisterOrPair.AX -> asmgen.out(" pha | txa | eor #255 | tax | pla | eor #255")
|
||||||
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack invert")
|
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")
|
else -> throw AssemblyError("invert of invalid type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceNegate(target: AsmAssignTarget, dt: DataType) {
|
internal fun inplaceNegate(target: AsmAssignTarget, dt: DataType) {
|
||||||
when (dt) {
|
when (dt) {
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
when (target.kind) {
|
when (target.kind) {
|
||||||
@ -1868,10 +1885,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sbc ${target.asmVarname}
|
sbc ${target.asmVarname}
|
||||||
sta ${target.asmVarname}""")
|
sta ${target.asmVarname}""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.MEMORY -> throw AssemblyError("can't in-place negate memory ubyte")
|
TargetStorageKind.REGISTER -> TODO("missing codegen for byte reg negate")
|
||||||
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place negate byte array")
|
TargetStorageKind.MEMORY -> TODO("can't in-place negate memory ubyte")
|
||||||
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg negate")
|
TargetStorageKind.STACK -> TODO("missing codegen for byte stack negate")
|
||||||
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack negate")
|
else -> throw AssemblyError("missing codegen for in-place negate byte array")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.WORD -> {
|
DataType.WORD -> {
|
||||||
@ -1886,10 +1903,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sbc ${target.asmVarname}+1
|
sbc ${target.asmVarname}+1
|
||||||
sta ${target.asmVarname}+1""")
|
sta ${target.asmVarname}+1""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place negate word array")
|
TargetStorageKind.REGISTER -> TODO("missing codegen for word reg negate")
|
||||||
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for word memory negate")
|
TargetStorageKind.MEMORY -> TODO("no asm gen for word memory negate")
|
||||||
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg negate")
|
TargetStorageKind.STACK -> TODO("missing codegen for word stack negate")
|
||||||
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack negate")
|
else -> throw AssemblyError("missing codegen for in-place negate word array")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
@ -1902,9 +1919,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sta ${target.asmVarname}+1
|
sta ${target.asmVarname}+1
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place negate float array")
|
TargetStorageKind.REGISTER -> TODO("missing codegen for float reg negate")
|
||||||
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack float negate")
|
TargetStorageKind.MEMORY -> TODO("missing codegen for float memory negate")
|
||||||
else -> throw AssemblyError("weird target kind for float")
|
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")
|
else -> throw AssemblyError("negate of invalid type")
|
||||||
|
@ -244,8 +244,8 @@ internal class AstChecker(private val program: Program,
|
|||||||
if(subroutine.name in BuiltinFunctions)
|
if(subroutine.name in BuiltinFunctions)
|
||||||
err("cannot redefine a built-in function")
|
err("cannot redefine a built-in function")
|
||||||
|
|
||||||
if(subroutine.parameters.size>16)
|
if(subroutine.parameters.size>6 && !subroutine.isAsmSubroutine)
|
||||||
err("subroutines are limited to 16 parameters")
|
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()
|
val uniqueNames = subroutine.parameters.asSequence().map { it.name }.toSet()
|
||||||
if(uniqueNames.size!=subroutine.parameters.size)
|
if(uniqueNames.size!=subroutine.parameters.size)
|
||||||
|
@ -4,22 +4,26 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
; uword xx=$2000
|
uword xx=$2000
|
||||||
|
|
||||||
|
@(~xx) *= 2
|
||||||
|
|
||||||
; ubyte yy=$30
|
; ubyte yy=$30
|
||||||
; ubyte zz=9
|
; ubyte zz=9
|
||||||
; ; sys.memset(xx+200, yy*2, zz+yy)
|
; sys.memset(xx+200, yy*2, ~yy)
|
||||||
;
|
;
|
||||||
; @($c030) = 10
|
; @($c030) = 10
|
||||||
; @($c000+yy) *= 2
|
; @(~xx) *= 2
|
||||||
; txt.print_ub(@($c030))
|
; 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