can now use boolean params mapped to Rx register

This commit is contained in:
Irmen de Jong 2024-12-13 20:47:03 +01:00
parent 124ec77b58
commit 1679ca79b4
5 changed files with 40 additions and 25 deletions

View File

@ -232,12 +232,11 @@ class AstPreprocessor(val program: Program,
.filter { it.name !in namesInSub && it.name !in existingAliases }
.forEach {
if (it.registerOrPair in Cx16VirtualRegisters) {
if(it.type.isInteger) {
val regname = it.registerOrPair!!.asScopedNameVirtualReg(it.type)
var alias = Alias(it.name, IdentifierReference(regname, it.position), it.position)
mods += IAstModification.InsertFirst(alias, subroutine)
if(it.type.isIntegerOrBool) {
val mappedParamVar = VarDecl.fromParameter(it)
mods += IAstModification.InsertFirst(mappedParamVar, subroutine)
} else {
errors.err("using R0-R15 as register param requires integer type", it.position)
errors.err("using R0-R15 as register param requires integer or boolean type", it.position)
}
} else
errors.err("can only use R0-R15 as register param for normal subroutines", it.position)

View File

@ -351,25 +351,21 @@ main {
errors.warnings[1] shouldContain "footgun"
}
test("reg params R0-R15 cannot be used for non integer types") {
test("reg params R0-R15 cannot be used for invalid types") {
val src="""
main {
sub func(bool flag @R1) {
if flag
return
sub func(str value @R1) {
return
}
extsub ${'$'}2000 = extok(bool flag @R0)
sub start() {
func(true)
extok(true)
}
}"""
val errors = ErrorReporterForTests(keepMessagesAfterReporting = true)
compileText(C64Target(), false, src, writeAssembly = false, errors = errors) shouldBe null
errors.errors.size shouldBe 1
errors.warnings.size shouldBe 0
errors.errors[0] shouldContain "requires integer type"
errors.errors[0] shouldContain "requires integer or boolean type"
}
})

View File

@ -258,8 +258,20 @@ class VarDecl(val type: VarDeclType,
private var autoHeapValueSequenceNumber = 0
fun fromParameter(param: SubroutineParameter): VarDecl {
val decltype: VarDeclType
val value: Expression?
if(param.registerOrPair==null) {
// regular parameter variable
decltype = VarDeclType.VAR
value = null
} else {
// parameter variable memory mapped to a R0-R15 virtual register
val regname = param.registerOrPair.asScopedNameVirtualReg(param.type)
decltype = VarDeclType.MEMORY
value = AddressOf(IdentifierReference(regname, param.position), null, param.position)
}
val dt = if(param.type.isArray) DataType.forDt(BaseDataType.UWORD) else param.type
return VarDecl(VarDeclType.VAR, VarDeclOrigin.SUBROUTINEPARAM, dt, param.zp, null, param.name, emptyList(), null,
return VarDecl(decltype, VarDeclOrigin.SUBROUTINEPARAM, dt, param.zp, null, param.name, emptyList(), value,
sharedWithAsm = false,
splitArray = false,
alignment = 0u,

View File

@ -1,10 +1,6 @@
TODO
====
@R0 parameters in normal subs are currently done via injected alias statements.
This means a bool parameter cannot be put into r0 because it is defined as a byte. (error: "using R0-R15 as register param requires integer type")
Can we inject them as regular memory mapped variables instead? &bool param = $02 (where $02 is the zp location of r0L)
...

View File

@ -3,15 +3,27 @@
%option no_sysinit
main {
sub func(bool flag @R1) {
if flag
return
sub start() {
regparams(true, 42, 9999)
}
extsub $2000 = extok(bool flag @R0)
sub regparams(bool arg1 @R0, byte arg2 @R1, uword arg3 @R2) {
txt.print_bool(arg1)
txt.nl()
txt.print_b(arg2)
txt.nl()
txt.print_uw(arg3)
txt.nl()
sub start() {
func(true)
extok(true)
cx16.r0=0
cx16.r1=$ffff
cx16.r2=11222
txt.print_bool(arg1)
txt.nl()
txt.print_b(arg2)
txt.nl()
txt.print_uw(arg3)
txt.nl()
}
}