mirror of
https://github.com/irmen/prog8.git
synced 2024-12-01 00:50:00 +00:00
improve detection of register re-use in parameters
This commit is contained in:
parent
cc53d698bf
commit
18e37accf9
@ -451,66 +451,49 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val regCounts = mutableMapOf<CpuRegister, Int>().withDefault { 0 }
|
val regsUsed = mutableListOf<RegisterOrPair>()
|
||||||
val statusflagCounts = mutableMapOf<Statusflag, Int>().withDefault { 0 }
|
val statusflagUsed = mutableListOf<Statusflag>()
|
||||||
fun countRegisters(from: Iterable<RegisterOrStatusflag>) {
|
fun countRegisters(from: Iterable<RegisterOrStatusflag>) {
|
||||||
regCounts.clear()
|
regsUsed.clear()
|
||||||
statusflagCounts.clear()
|
statusflagUsed.clear()
|
||||||
for(p in from) {
|
for(p in from) {
|
||||||
when(p.registerOrPair) {
|
when(p.registerOrPair) {
|
||||||
RegisterOrPair.A -> regCounts[CpuRegister.A]=regCounts.getValue(CpuRegister.A)+1
|
null -> {
|
||||||
RegisterOrPair.X -> regCounts[CpuRegister.X]=regCounts.getValue(CpuRegister.X)+1
|
if (p.statusflag != null)
|
||||||
RegisterOrPair.Y -> regCounts[CpuRegister.Y]=regCounts.getValue(CpuRegister.Y)+1
|
statusflagUsed += p.statusflag!!
|
||||||
|
}
|
||||||
RegisterOrPair.AX -> {
|
RegisterOrPair.AX -> {
|
||||||
regCounts[CpuRegister.A]=regCounts.getValue(CpuRegister.A)+1
|
regsUsed += RegisterOrPair.A
|
||||||
regCounts[CpuRegister.X]=regCounts.getValue(CpuRegister.X)+1
|
regsUsed += RegisterOrPair.X
|
||||||
}
|
}
|
||||||
RegisterOrPair.AY -> {
|
RegisterOrPair.AY -> {
|
||||||
regCounts[CpuRegister.A]=regCounts.getValue(CpuRegister.A)+1
|
regsUsed += RegisterOrPair.A
|
||||||
regCounts[CpuRegister.Y]=regCounts.getValue(CpuRegister.Y)+1
|
regsUsed += RegisterOrPair.Y
|
||||||
}
|
}
|
||||||
RegisterOrPair.XY -> {
|
RegisterOrPair.XY -> {
|
||||||
regCounts[CpuRegister.X]=regCounts.getValue(CpuRegister.X)+1
|
regsUsed += RegisterOrPair.X
|
||||||
regCounts[CpuRegister.Y]=regCounts.getValue(CpuRegister.Y)+1
|
regsUsed += RegisterOrPair.Y
|
||||||
}
|
|
||||||
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> { /* no sensible way to count this */ }
|
|
||||||
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 -> { /* no sensible way to count this */ }
|
|
||||||
null -> {
|
|
||||||
val statusf = p.statusflag
|
|
||||||
if (statusf != null)
|
|
||||||
statusflagCounts[statusf] = statusflagCounts.getValue(statusf) + 1
|
|
||||||
}
|
}
|
||||||
|
else -> regsUsed += p.registerOrPair!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
countRegisters(subroutine.asmParameterRegisters)
|
countRegisters(subroutine.asmParameterRegisters)
|
||||||
if(regCounts.any{it.value>1})
|
if(regsUsed.size != regsUsed.toSet().size)
|
||||||
err("a register is used multiple times in the parameters")
|
err("a register is used multiple times in the parameters")
|
||||||
if(statusflagCounts.any{it.value>1})
|
if(statusflagUsed.size != statusflagUsed.toSet().size)
|
||||||
err("a status flag is used multiple times in the parameters")
|
err("a status flag is used multiple times in the parameters")
|
||||||
|
|
||||||
countRegisters(subroutine.asmReturnvaluesRegisters)
|
countRegisters(subroutine.asmReturnvaluesRegisters)
|
||||||
if(regCounts.any{it.value>1})
|
if(regsUsed.size != regsUsed.toSet().size)
|
||||||
err("a register is used multiple times in the return values")
|
err("a register is used multiple times in the return values")
|
||||||
if(statusflagCounts.any{it.value>1})
|
if(statusflagUsed.size != statusflagUsed.toSet().size)
|
||||||
err("a status flag is used multiple times in the return values")
|
err("a status flag is used multiple times in the return values")
|
||||||
|
|
||||||
if(subroutine.asmClobbers.intersect(regCounts.keys).isNotEmpty())
|
for(reg in subroutine.asmClobbers) {
|
||||||
|
if(regsUsed.contains(RegisterOrPair.fromCpuRegister(reg)))
|
||||||
err("a return register is also in the clobber list")
|
err("a return register is also in the clobber list")
|
||||||
|
}
|
||||||
|
|
||||||
if(subroutine.statements.any{it !is InlineAssembly})
|
if(subroutine.statements.any{it !is InlineAssembly})
|
||||||
err("asmsub can only contain inline assembly (%asm)")
|
err("asmsub can only contain inline assembly (%asm)")
|
||||||
|
@ -3,31 +3,34 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
const long foo2 = $123456
|
foo(42)
|
||||||
cx16.r0 = $ffff
|
bar(9999,55)
|
||||||
cx16.r1 = $ea31
|
|
||||||
txt.print_uwbin(cx16.r1 << 7, true)
|
|
||||||
txt.nl()
|
|
||||||
txt.print_uwhex(cx16.r0 ^ cx16.r1, true)
|
|
||||||
txt.nl()
|
|
||||||
txt.print_ubhex(^cx16.r0, true)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_uwhex(<<cx16.r0, false)
|
|
||||||
txt.nl()
|
|
||||||
txt.print_ubhex(^foo2, true)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_uwhex(<<foo2, false)
|
|
||||||
txt.nl()
|
|
||||||
txt.print_ubhex(bankof(foo2), true)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_uwhex(foo2 &$ffff, false)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
test(1,2,3)
|
||||||
|
test2(1)
|
||||||
|
}
|
||||||
|
|
||||||
txt.print_ubhex(msw(foo2), true)
|
sub foo(ubyte arg) {
|
||||||
txt.spc()
|
txt.print_ub(arg)
|
||||||
txt.print_uwhex(lsw(foo2), false)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
}
|
||||||
|
|
||||||
|
sub bar(uword arg, ubyte arg2) {
|
||||||
|
txt.print_uw(arg)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ub(arg2)
|
||||||
|
txt.nl()
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub test(ubyte a1 @R1, ubyte a2 @R1, ubyte a3 @R2) { ; TODO should give register reuse error
|
||||||
|
%asm {{
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub test2(uword a1 @AY) clobbers(A, X) -> ubyte @X {
|
||||||
|
%asm {{
|
||||||
|
rts
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user