don't require carry parameter Pc to asmsubs to be last

This commit is contained in:
Irmen de Jong 2021-02-20 02:27:57 +01:00
parent 2aa39757b4
commit 0ed3d951a7
5 changed files with 25 additions and 12 deletions

View File

@ -351,10 +351,6 @@ internal class AstChecker(private val program: Program,
if(statusFlagsNoCarry.isNotEmpty())
err("can only use Carry as status flag parameter")
val carryParameter = subroutine.asmParameterRegisters.singleOrNull { it.statusflag==Statusflag.Pc }
if(carryParameter!=null && carryParameter !== subroutine.asmParameterRegisters.last())
err("carry parameter has to come last")
} else {
// Pass-by-reference datatypes can not occur as parameters to a subroutine directly
// Instead, their reference (address) should be passed (as an UWORD).

View File

@ -91,11 +91,15 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
when {
stmt.args.all {isNoClobberRisk(it)} -> {
// There's no risk of clobbering for these simple argument types. Optimize the register loading directly from these values.
// register assignment order: 1) cx16 virtual word registers, 2) actual CPU registers, 3) CPU Carry status flag.
val argsInfo = sub.parameters.withIndex().zip(stmt.args).zip(sub.asmParameterRegisters)
val (cx16virtualRegsArgsInfo, otherRegsArgsInfo) = argsInfo.partition { it.second.registerOrPair in Cx16VirtualRegisters }
for(arg in cx16virtualRegsArgsInfo)
val (cx16virtualRegs, args2) = argsInfo.partition { it.second.registerOrPair in Cx16VirtualRegisters }
val (cpuRegs, statusRegs) = args2.partition { it.second.registerOrPair!=null }
for(arg in cx16virtualRegs)
argumentViaRegister(sub, arg.first.first, arg.first.second)
for(arg in otherRegsArgsInfo)
for(arg in cpuRegs)
argumentViaRegister(sub, arg.first.first, arg.first.second)
for(arg in statusRegs)
argumentViaRegister(sub, arg.first.first, arg.first.second)
}
else -> {

View File

@ -2,9 +2,10 @@
TODO
====
- don't require carry parameter Pc to asmsubs to be last; sort this out yourself like with the R0-R15 registers
- make blocks without explicit memory address, word-aligned in the assembly.
- add sound to the cx16 tehtriz
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
- refactor the asmgen into their own submodule?
- refactor the compiler optimizers into their own submodule?

View File

@ -40,6 +40,6 @@ vtui $1000 {
romsub $1023 = pet2scr(ubyte char @A) -> ubyte @A
romsub $1026 = scr2pet(ubyte char @A) -> ubyte @A
romsub $1029 = border(ubyte mode @A, ubyte width @R1, ubyte height @R2, ubyte colors @X) clobbers(Y) ; NOTE: mode 6 means 'custom' characters taken from r3 - r6
romsub $102c = save_rect(ubyte vbank @A, uword address @R0, ubyte width @R1, ubyte height @R2, ubyte ramtype @Pc) clobbers(A, X, Y)
romsub $102f = rest_rect(ubyte vbank @A, uword address @R0, ubyte width @R1, ubyte height @R2, ubyte ramtype @Pc) clobbers(A, X, Y)
romsub $102c = save_rect(ubyte ramtype @Pc, ubyte vbank @A, uword address @R0, ubyte width @R1, ubyte height @R2) clobbers(A, X, Y)
romsub $102f = rest_rect(ubyte ramtype @Pc, ubyte vbank @A, uword address @R0, ubyte width @R1, ubyte height @R2) clobbers(A, X, Y)
}

View File

@ -5,8 +5,20 @@
main {
sub start() {
ubyte rr = bla(1,true,2)
txt.print_ub(rr)
txt.nl()
rr = bla(1,false,2)
txt.print_ub(rr)
}
uword zzz=memory("derp", 2000)
txt.print("hello")
asmsub bla(ubyte aa @A, ubyte cc @Pc, ubyte bb @Y) -> ubyte @A{
%asm {{
bcc +
lda #10
bne end
+ lda #20
end rts
}}
}
}