IR: only put align on lsb array of split word array. tag split word arrays with split. (but this isn't actually used yet)

This commit is contained in:
Irmen de Jong 2025-01-06 02:50:54 +01:00
parent e5ff3c1ff3
commit f071c07dd9
4 changed files with 39 additions and 15 deletions

View File

@ -45,7 +45,6 @@ Future Things and Ideas
IR/VM
-----
- getting it in shape for code generation...: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
- split word arrays, both _msb and _lsb arrays are tagged with an alignment. This is not what's intended; only the one put in memory first should be aligned (the other one should follow straight after it)
- fix call() return value handling
- proper code gen for the CALLI instruction and that it (optionally) returns a word value that needs to be assigned to a reg
- implement fast code paths for TODO("inplace split....
@ -54,6 +53,7 @@ IR/VM
sub start() {
cx16.r0L = cx16.r1 as ubyte
cx16.r0sL = cx16.r1s as byte }
- do something with the 'split' tag on split word arrays
- add more optimizations in IRPeepholeOptimizer
- idea: (but LLVM IR simply keeps the variables, so not a good idea then?...): replace all scalar variables by an allocated register. Keep a table of the variable to register mapping (including the datatype)
global initialization values are simply a list of LOAD instructions.

View File

@ -4,9 +4,10 @@
main {
sub start() {
str foo = "foo"
str bar = "bar"
bool flag = true
uword @shared foobar = if flag foo else bar
uword[10] @align64 @nosplit array1
uword[10] @align64 @split array2
array1[2]++
array2[2]++
}
}

View File

@ -159,17 +159,23 @@ class IRFileReader {
return if(text.isBlank())
emptyList()
else {
val varPattern = Regex("(.+?)(\\[.+?\\])? (.+) zp=(.+) align=(.+)")
val varPattern = Regex("(?<type>.+?)(?<arrayspec>\\[.+?\\])? (?<name>.+) zp=(?<zp>.+?)\\s?(split=(?<split>.+?))?\\s?(align=(?<align>.+?))?")
val variables = mutableListOf<StStaticVariable>()
text.lineSequence().forEach { line ->
// example: uword main.start.qq2 zp=DONTCARE
val match = varPattern.matchEntire(line) ?: throw IRParseException("invalid VARIABLESNOINIT $line")
val (type, arrayspec, name, zpwish, alignment) = match.destructured
val type = match.groups["type"]!!.value
val arrayspec = match.groups["arrayspec"]?.value ?: ""
val name = match.groups["name"]!!.value
val zpwish = match.groups["zp"]!!.value
val split = match.groups["split"]?.value ?: ""
val alignment = match.groups["align"]?.value ?: ""
if('.' !in name)
throw IRParseException("unscoped name: $name")
val arraysize = if(arrayspec.isNotBlank()) arrayspec.substring(1, arrayspec.length-1).toInt() else null
val dt = parseDatatype(type, arraysize!=null)
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
val isSplit = if(split.isBlank()) false else split.toBoolean()
val align = if(alignment.isBlank()) 0u else alignment.toUInt()
val newVar = StStaticVariable(name, dt, null, null, arraysize, zp, align.toInt(), null)
variables.add(newVar)
@ -215,19 +221,26 @@ class IRFileReader {
return if(text.isBlank())
emptyList()
else {
val varPattern = Regex("(.+?)(\\[.+?\\])? (.+)=(.*?) zp=(.+) align=(.+)")
val varPattern = Regex("(?<type>.+?)(?<arrayspec>\\[.+?\\])? (?<name>.+)=(?<value>.*?) zp=(?<zp>.+?)\\s?(split=(?<split>.+?))?\\s?(align=(?<align>.+?))?")
val variables = mutableListOf<StStaticVariable>()
text.lineSequence().forEach { line ->
// examples:
// uword main.start.qq2=0 zp=REQUIRE_ZP
// ubyte[6] main.start.namestring=105,114,109,101,110,0
val match = varPattern.matchEntire(line) ?: throw IRParseException("invalid VARIABLE $line")
val (type, arrayspec, name, value, zpwish, alignment) = match.destructured
val type = match.groups["type"]!!.value
val arrayspec = match.groups["arrayspec"]?.value ?: ""
val name = match.groups["name"]!!.value
val value = match.groups["value"]!!.value
val zpwish = match.groups["zp"]!!.value
val split = match.groups["split"]?.value ?: ""
val alignment = match.groups["align"]?.value ?: ""
if('.' !in name)
throw IRParseException("unscoped varname: $name")
val arraysize = if(arrayspec.isNotBlank()) arrayspec.substring(1, arrayspec.length-1).toInt() else null
val dt = parseDatatype(type, arraysize!=null)
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
val isSplit = if(split.isBlank()) false else split.toBoolean()
val align = if(alignment.isBlank()) 0u else alignment.toUInt()
var initNumeric: Double? = null
var initArray: StArray? = null

View File

@ -233,10 +233,15 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
fun writeNoInitVar(variable: IRStStaticVariable) {
if(variable.dt.isSplitWordArray) {
// split into 2 ubyte arrays lsb+msb
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_lsb zp=${variable.zpwish} align=${variable.align}\n")
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_msb zp=${variable.zpwish} align=${variable.align}\n")
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_lsb zp=${variable.zpwish} split=true")
if(variable.align!=0)
xml.writeCharacters(" align=${variable.align}")
xml.writeCharacters("\nubyte[${variable.length}] ${variable.name}_msb zp=${variable.zpwish} split=true\n")
} else {
xml.writeCharacters("${variable.typeString} ${variable.name} zp=${variable.zpwish} align=${variable.align}\n")
xml.writeCharacters("${variable.typeString} ${variable.name} zp=${variable.zpwish}")
if(variable.align!=0)
xml.writeCharacters(" align=${variable.align}")
xml.writeCharacters("\n")
}
}
@ -272,8 +277,10 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
"@>${it.addressOfSymbol}"
}
}
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_lsb=$lsbValue zp=${variable.zpwish} align=${variable.align}\n")
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_msb=$msbValue zp=${variable.zpwish} align=${variable.align}\n")
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_lsb=$lsbValue zp=${variable.zpwish} split=true")
if(variable.align!=0)
xml.writeCharacters(" align=${variable.align}")
xml.writeCharacters("\nubyte[${variable.length}] ${variable.name}_msb=$msbValue zp=${variable.zpwish} split=true\n")
} else {
val dt = variable.dt
val value: String = when {
@ -309,7 +316,10 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
}
else -> throw InternalCompilerException("weird dt")
}
xml.writeCharacters("${variable.typeString} ${variable.name}=$value zp=${variable.zpwish} align=${variable.align}\n")
xml.writeCharacters("${variable.typeString} ${variable.name}=$value zp=${variable.zpwish}")
if(variable.align!=0)
xml.writeCharacters(" align=${variable.align}")
xml.writeCharacters("\n")
}
}