From 9002c676390bcc5e93607d31c8a77da7651254c8 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 25 Dec 2020 12:36:11 +0100 Subject: [PATCH] cleanup of cx16 regs lists --- compiler/src/prog8/ast/base/Base.kt | 2 +- .../target/c64/codegen/FunctionCallAsmGen.kt | 93 +++++- .../codegen/assignment/AssignmentAsmGen.kt | 299 ++---------------- 3 files changed, 128 insertions(+), 266 deletions(-) diff --git a/compiler/src/prog8/ast/base/Base.kt b/compiler/src/prog8/ast/base/Base.kt index a41405d3a..126303275 100644 --- a/compiler/src/prog8/ast/base/Base.kt +++ b/compiler/src/prog8/ast/base/Base.kt @@ -151,7 +151,7 @@ val ElementArrayTypes = mapOf( DataType.UWORD to DataType.ARRAY_UW, DataType.FLOAT to DataType.ARRAY_F ) -val Cx16VirtualRegisters = setOf(RegisterOrPair.R0, RegisterOrPair.R1, RegisterOrPair.R2, RegisterOrPair.R3, +val Cx16VirtualRegisters = listOf(RegisterOrPair.R0, RegisterOrPair.R1, RegisterOrPair.R2, RegisterOrPair.R3, RegisterOrPair.R4, RegisterOrPair.R5, RegisterOrPair.R6, RegisterOrPair.R7, RegisterOrPair.R8, RegisterOrPair.R9, RegisterOrPair.R10, RegisterOrPair.R11, RegisterOrPair.R12, RegisterOrPair.R13, RegisterOrPair.R14, RegisterOrPair.R15) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt index 8212ff867..defabded9 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt @@ -59,7 +59,8 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg } } else -> { - // Risk of clobbering due to complex expression args. Work via the evaluation stack. + // Risk of clobbering due to complex expression args. Evaluate first, then assign registers. + // TODO not used yet because code is larger: registerArgsViaVirtualRegistersEvaluation(stmt, sub) registerArgsViaStackEvaluation(stmt, sub) } } @@ -75,6 +76,96 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg } } + private fun registerArgsViaVirtualRegistersEvaluation(stmt: IFunctionCall, sub: Subroutine) { + // This is called when one or more of the arguments are 'complex' and + // cannot be assigned to a cpu register easily or risk clobbering other cpu registers. + // To solve this, the expressions are first evaluated into the 'virtual registers and then loaded from there. + + // TODO not used yet; code generated here is bigger than the eval-stack based code because it always treats the virtual regs as words and also sometimes uses the stack for evaluation and then copies it to a virtual register. + + if(sub.parameters.isEmpty()) + return + + // 1. load all arguments left-to-right into the R0..R15 registers + for (vrarg in stmt.args.zip(Cx16VirtualRegisters)) { + asmgen.assignExpressionToRegister(vrarg.first, vrarg.second) + } + + // 2. Gather up the arguments in the correct registers (in specific order to not clobber earlier values) + var argForCarry: IndexedValue>? = null + var argForXregister: IndexedValue>? = null + var argForAregister: IndexedValue>? = null + + for(argi in stmt.args.zip(sub.asmParameterRegisters).withIndex()) { + val valueIsInVirtualReg = Cx16VirtualRegisters[argi.index] + val valueIsInVirtualRegAsmString = valueIsInVirtualReg.toString().toLowerCase() + when { + argi.value.second.statusflag == Statusflag.Pc -> { + require(argForCarry == null) + argForCarry = argi + } + argi.value.second.statusflag != null -> throw AssemblyError("can only use Carry as status flag parameter") + argi.value.second.registerOrPair in setOf(RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY) -> { + require(argForXregister==null) + argForXregister = argi + } + argi.value.second.registerOrPair in setOf(RegisterOrPair.A, RegisterOrPair.AY) -> { + require(argForAregister == null) + argForAregister = argi + } + argi.value.second.registerOrPair == RegisterOrPair.Y -> { + asmgen.out(" ldy cx16.$valueIsInVirtualRegAsmString") + } + argi.value.second.registerOrPair in Cx16VirtualRegisters -> { + if(argi.value.second.registerOrPair != valueIsInVirtualReg) { + asmgen.out(""" + lda cx16.$valueIsInVirtualRegAsmString + sta cx16.${argi.value.second.registerOrPair.toString().toLowerCase()} + lda cx16.$valueIsInVirtualRegAsmString+1 + sta cx16.${argi.value.second.registerOrPair.toString().toLowerCase()}+1 + """) + } + } + else -> throw AssemblyError("weird argument") + } + } + + if(argForCarry!=null) { + asmgen.out(""" + lda cx16.${Cx16VirtualRegisters[argForCarry.index].toString().toLowerCase()} + beq + + sec + bcs ++ ++ clc ++ php""") // push the status flags + } + + if(argForAregister!=null) { + when(argForAregister.value.second.registerOrPair) { + RegisterOrPair.A -> asmgen.out(" lda cx16.${Cx16VirtualRegisters[argForAregister.index].toString().toLowerCase()}") + RegisterOrPair.AY -> asmgen.out(" lda cx16.${Cx16VirtualRegisters[argForAregister.index].toString().toLowerCase()} | ldy cx16.${Cx16VirtualRegisters[argForAregister.index].toString().toLowerCase()}+1") + else -> throw AssemblyError("weird arg") + } + } + + if(argForXregister!=null) { + if(argForAregister!=null) + asmgen.out(" pha") + when(argForXregister.value.second.registerOrPair) { + RegisterOrPair.X -> asmgen.out(" ldx cx16.${Cx16VirtualRegisters[argForXregister.index].toString().toLowerCase()}") + RegisterOrPair.AX -> asmgen.out(" lda cx16.${Cx16VirtualRegisters[argForXregister.index].toString().toLowerCase()} | ldx cx16.${Cx16VirtualRegisters[argForXregister.index].toString().toLowerCase()}+1") + RegisterOrPair.XY -> asmgen.out(" ldx cx16.${Cx16VirtualRegisters[argForXregister.index].toString().toLowerCase()} | ldy cx16.${Cx16VirtualRegisters[argForXregister.index].toString().toLowerCase()}+1") + else -> throw AssemblyError("weird arg") + } + if(argForAregister!=null) + asmgen.out(" pla") + } + + if(argForCarry!=null) + asmgen.out(" plp") // set the carry flag back to correct value + } + + private fun registerArgsViaStackEvaluation(stmt: IFunctionCall, sub: Subroutine) { // this is called when one or more of the arguments are 'complex' and // cannot be assigned to a register easily or risk clobbering other registers. diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt index 4339f6c38..6153a26da 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -710,22 +710,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.Y -> asmgen.out(" inx | ldy P8ESTACK_LO,x") RegisterOrPair.AX -> asmgen.out(" inx | lda P8ESTACK_LO,x | ldx #0") RegisterOrPair.AY -> asmgen.out(" inx | lda P8ESTACK_LO,x | ldy #0") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" inx lda P8ESTACK_LO,x @@ -742,22 +727,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AX -> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}") RegisterOrPair.AY-> asmgen.out(" inx | lda P8ESTACK_LO,x | ldy P8ESTACK_HI,x") RegisterOrPair.XY-> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" inx lda P8ESTACK_LO,x @@ -806,22 +776,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AX -> asmgen.out(" lda #<$sourceName | ldx #>$sourceName") RegisterOrPair.AY -> asmgen.out(" lda #<$sourceName | ldy #>$sourceName") RegisterOrPair.XY -> asmgen.out(" ldx #<$sourceName | ldy #>$sourceName") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" lda #<$sourceName sta cx16.${target.register.toString().toLowerCase()} @@ -962,22 +917,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AX -> asmgen.out(" lda $sourceName | ldx $sourceName+1") RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy $sourceName+1") RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy $sourceName+1") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" lda $sourceName sta cx16.${target.register.toString().toLowerCase()} @@ -1150,22 +1090,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy #0") RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy #0") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" lda $sourceName sta cx16.${target.register.toString().toLowerCase()} @@ -1173,6 +1098,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen sta cx16.${target.register.toString().toLowerCase()}+1 """) } + else -> throw AssemblyError("weird register") } } TargetStorageKind.STACK -> { @@ -1295,7 +1221,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister) { - require(target.datatype in ByteDatatypes) + if(target.register !in Cx16VirtualRegisters) + require(target.datatype in ByteDatatypes) + when(target.kind) { TargetStorageKind.VARIABLE -> { asmgen.out(" st${register.name.toLowerCase()} ${target.asmVarname}") @@ -1330,28 +1258,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AX -> { asmgen.out(" ldx #0") } RegisterOrPair.XY -> { asmgen.out(" tax | ldy #0") } RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { - asmgen.out(""" - sta cx16.${target.register.toString().toLowerCase()} - ldy #0 - sty cx16.${target.register.toString().toLowerCase()}+1 - """) + in Cx16VirtualRegisters -> { + // only assign a single byte to the virtual register's Lsb + asmgen.out(" sta cx16.${target.register.toString().toLowerCase()}") } + else -> throw AssemblyError("weird register") } CpuRegister.X -> when(target.register!!) { RegisterOrPair.A -> { asmgen.out(" txa") } @@ -1361,28 +1272,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AX -> { asmgen.out(" txa | ldx #0") } RegisterOrPair.XY -> { asmgen.out(" ldy #0") } RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { - asmgen.out(""" - stx cx16.${target.register.toString().toLowerCase()} - lda #0 - sta cx16.${target.register.toString().toLowerCase()}+1 - """) + in Cx16VirtualRegisters -> { + // only assign a single byte to the virtual register's Lsb + asmgen.out(" stx cx16.${target.register.toString().toLowerCase()}") } + else -> throw AssemblyError("weird register") } CpuRegister.Y -> when(target.register!!) { RegisterOrPair.A -> { asmgen.out(" tya") } @@ -1392,27 +1286,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AX -> { asmgen.out(" tya | ldx #0") } RegisterOrPair.XY -> { asmgen.out(" tya | tax | ldy #0") } RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { - asmgen.out(""" - sty cx16.${target.register.toString().toLowerCase()} - lda #0 - sta cx16.${target.register.toString().toLowerCase()}+1 - """) } + in Cx16VirtualRegisters -> { + // only assign a single byte to the virtual register's Lsb + asmgen.out(" sty cx16.${target.register.toString().toLowerCase()}") + } + else -> throw AssemblyError("weird register") } } } @@ -1472,22 +1350,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AY -> { asmgen.out(" stx P8ZP_SCRATCH_REG | ldy P8ZP_SCRATCH_REG") } RegisterOrPair.AX -> { } RegisterOrPair.XY -> { asmgen.out(" stx P8ZP_SCRATCH_REG | ldy P8ZP_SCRATCH_REG | tax") } - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" sta cx16.${target.register.toString().toLowerCase()} stx cx16.${target.register.toString().toLowerCase()}+1 @@ -1499,22 +1362,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AY -> { } RegisterOrPair.AX -> { asmgen.out(" sty P8ZP_SCRATCH_REG | ldx P8ZP_SCRATCH_REG") } RegisterOrPair.XY -> { asmgen.out(" tax") } - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" sta cx16.${target.register.toString().toLowerCase()} sty cx16.${target.register.toString().toLowerCase()}+1 @@ -1526,22 +1374,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AY -> { asmgen.out(" txa") } RegisterOrPair.AX -> { asmgen.out(" txa | sty P8ZP_SCRATCH_REG | ldx P8ZP_SCRATCH_REG") } RegisterOrPair.XY -> { } - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" stx cx16.${target.register.toString().toLowerCase()} sty cx16.${target.register.toString().toLowerCase()}+1 @@ -1586,10 +1419,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AX -> asmgen.out(" lda #0 | tax") RegisterOrPair.AY -> asmgen.out(" lda #0 | tay") RegisterOrPair.XY -> asmgen.out(" ldx #0 | ldy #0") - RegisterOrPair.R0, RegisterOrPair.R1, RegisterOrPair.R2, RegisterOrPair.R3, - RegisterOrPair.R4, RegisterOrPair.R5, RegisterOrPair.R6, RegisterOrPair.R7, - RegisterOrPair.R8, RegisterOrPair.R9, RegisterOrPair.R10, RegisterOrPair.R11, - RegisterOrPair.R12, RegisterOrPair.R13, RegisterOrPair.R14, RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(" stz cx16.${target.register.toString().toLowerCase()} | stz cx16.${target.register.toString().toLowerCase()}+1") } else -> throw AssemblyError("invalid register for word value") @@ -1639,10 +1469,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AX -> asmgen.out(" lda #<${word.toHex()} | ldx #>${word.toHex()}") RegisterOrPair.AY -> asmgen.out(" lda #<${word.toHex()} | ldy #>${word.toHex()}") RegisterOrPair.XY -> asmgen.out(" ldx #<${word.toHex()} | ldy #>${word.toHex()}") - RegisterOrPair.R0, RegisterOrPair.R1, RegisterOrPair.R2, RegisterOrPair.R3, - RegisterOrPair.R4, RegisterOrPair.R5, RegisterOrPair.R6, RegisterOrPair.R7, - RegisterOrPair.R8, RegisterOrPair.R9, RegisterOrPair.R10, RegisterOrPair.R11, - RegisterOrPair.R12, RegisterOrPair.R13, RegisterOrPair.R14, RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" lda #<${word.toHex()} sta cx16.${target.register.toString().toLowerCase()} @@ -1692,24 +1519,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AY -> asmgen.out(" lda #0 | tay") RegisterOrPair.XY -> asmgen.out(" ldx #0 | ldy #0") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(" stz cx16.${target.register.toString().toLowerCase()} | stz cx16.${target.register.toString().toLowerCase()}+1") } + else -> throw AssemblyError("weird register") } TargetStorageKind.STACK -> { asmgen.out(" stz P8ESTACK_LO,x | dex") @@ -1745,22 +1558,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AY -> asmgen.out(" lda #${byte.toHex()} | ldy #0") RegisterOrPair.XY -> asmgen.out(" ldx #${byte.toHex()} | ldy #0") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" lda #${byte.toHex()} sta cx16.${target.register.toString().toLowerCase()} @@ -1768,6 +1566,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen sta cx16.${target.register.toString().toLowerCase()}+1 """) } + else -> throw AssemblyError("weird register") } TargetStorageKind.STACK -> { asmgen.out(""" @@ -1937,22 +1736,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AY -> asmgen.out(" lda ${address.toHex()} | ldy #0") RegisterOrPair.XY -> asmgen.out(" ldy ${address.toHex()} | ldy #0") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" lda ${address.toHex()} sta cx16.${target.register.toString().toLowerCase()} @@ -1960,6 +1744,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen sta cx16.${target.register.toString().toLowerCase()}+1 """) } + else -> throw AssemblyError("weird register") } TargetStorageKind.STACK -> { asmgen.out(""" @@ -1991,28 +1776,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen RegisterOrPair.AY -> asmgen.out(" ldy #0") RegisterOrPair.XY -> asmgen.out(" tax | ldy #0") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") - RegisterOrPair.R0, - RegisterOrPair.R1, - RegisterOrPair.R2, - RegisterOrPair.R3, - RegisterOrPair.R4, - RegisterOrPair.R5, - RegisterOrPair.R6, - RegisterOrPair.R7, - RegisterOrPair.R8, - RegisterOrPair.R9, - RegisterOrPair.R10, - RegisterOrPair.R11, - RegisterOrPair.R12, - RegisterOrPair.R13, - RegisterOrPair.R14, - RegisterOrPair.R15 -> { + in Cx16VirtualRegisters -> { asmgen.out(""" sta cx16.${target.register.toString().toLowerCase()} lda #0 sta cx16.${target.register.toString().toLowerCase()}+1 """) } + else -> throw AssemblyError("weird register") } } TargetStorageKind.STACK -> {