added remaining signature stuff to IRAsmSubroutine

This commit is contained in:
Irmen de Jong 2022-09-13 22:42:33 +02:00
parent 6428ced157
commit 7dd14955c1
4 changed files with 50 additions and 11 deletions

View File

@ -882,7 +882,7 @@ class CodeGen(internal val program: PtProgram,
val assembly = if(child.children.isEmpty()) "" else (child.children.single() as PtInlineAssembly).assembly
vmblock += IRAsmSubroutine(child.name, child.position, child.address,
child.clobbers,
child.parameters.map { IRAsmSubroutine.IRAsmSubParam(it.first.name, it.first.type, it.second) },
child.parameters.map { Pair(it.first.type, it.second) }, // note: the name of the asmsub param is not used anymore.
child.returnTypes.zip(child.retvalRegisters),
assembly)
}

View File

@ -240,7 +240,7 @@ class IRFileReader(outputDir: Path, programName: String) {
private val blockPattern = Regex("<BLOCK NAME=(.+) ADDRESS=(.+) ALIGN=(.+) POS=(.+)>")
private val inlineAsmPattern = Regex("<INLINEASM POS=(.+)>")
private val asmsubPattern = Regex("<ASMSUB NAME=(.+) ADDRESS=(.+) CLOBBERS=(.+) POS=(.+)>")
private val asmsubPattern = Regex("<ASMSUB NAME=(.+) ADDRESS=(.+) CLOBBERS=(.+) RETURNS=(.+) POS=(.+)>")
private val subPattern = Regex("<SUB NAME=(.+) RETURNTYPE=(.+) POS=(.+)>")
private val posPattern = Regex("\\[(.+): line (.+) col (.+)-(.+)\\]")
private val instructionPattern = Regex("""([a-z]+)(\.b|\.w|\.f)?(.*)""", RegexOption.IGNORE_CASE)
@ -290,19 +290,37 @@ class IRFileReader(outputDir: Path, programName: String) {
private fun parseAsmSubroutine(startline: String, lines: Iterator<String>): IRAsmSubroutine {
// <ASMSUB NAME=main.testasmsub ADDRESS=null CLOBBERS=A,Y POS=[examples/test.p8: line 14 col 6-11]>
val match = asmsubPattern.matchEntire(startline) ?: throw IRParseException("invalid ASMSUB")
val (scopedname, address, clobbers, pos) = match.destructured
val (scopedname, address, clobbers, returnSpec, pos) = match.destructured
// parse PARAMS
var line = lines.next()
if(line!="<PARAMS>")
throw IRParseException("missing PARAMS")
val params = mutableListOf<Pair<DataType, RegisterOrStatusflag>>()
while(true) {
line = lines.next()
if(line=="</PARAMS>")
break
val (datatype, regOrSf) = line.split(' ')
val dt = parseDatatype(datatype, datatype.contains('['))
val regsf = parseRegisterOrStatusflag(regOrSf)
params += Pair(dt, regsf)
}
line = lines.next()
val asm = parseInlineAssembly(line, lines)
while(line!="</ASMSUB>")
line = lines.next()
val clobberRegs = clobbers.split(',').map { CpuRegister.valueOf(it) }
// TODO parse this additional signature stuff once it's there.
val parameters = mutableListOf<IRAsmSubroutine.IRAsmSubParam>()
val returns = mutableListOf<Pair<DataType, RegisterOrStatusflag>>()
returnSpec.split(',').forEach{ rs ->
val (regstr, dtstr) = rs.split(':')
val dt = parseDatatype(dtstr, false)
val regsf = parseRegisterOrStatusflag(regstr)
returns.add(Pair(dt, regsf))
}
return IRAsmSubroutine(scopedname,
parsePosition(pos), if(address=="null") null else address.toUInt(),
clobberRegs.toSet(),
parameters,
params,
returns,
asm.asm)
}
@ -560,6 +578,17 @@ class IRFileReader(outputDir: Path, programName: String) {
return value.toFloat()
}
private fun parseRegisterOrStatusflag(regs: String): RegisterOrStatusflag {
var reg: RegisterOrPair? = null
var sf: Statusflag? = null
try {
reg = RegisterOrPair.valueOf(regs)
} catch (x: IllegalArgumentException) {
sf = Statusflag.valueOf(regs)
}
return RegisterOrStatusflag(reg, sf)
}
private fun parsePosition(strpos: String): Position {
// example: "[library:/prog8lib/virtual/textio.p8: line 5 col 2-4]"
val match = posPattern.matchEntire(strpos) ?: throw IRParseException("invalid Position")

View File

@ -57,8 +57,18 @@ class IRFileWriter(private val irProgram: IRProgram) {
}
block.asmSubroutines.forEach {
val clobbers = it.clobbers.joinToString(",")
out.write("<ASMSUB NAME=${it.name} ADDRESS=${it.address} CLOBBERS=$clobbers POS=${it.position}>\n")
// TODO rest of the signature: RETURNS = it.returns
val returns = it.returns.map { (dt, reg) ->
if(reg.registerOrPair!=null) "${reg.registerOrPair}:${dt.toString().lowercase()}"
else "${reg.statusflag}:${dt.toString().lowercase()}"
}.joinToString(",")
out.write("<ASMSUB NAME=${it.name} ADDRESS=${it.address} CLOBBERS=$clobbers RETURNS=$returns POS=${it.position}>\n")
out.write("<PARAMS>\n")
it.parameters.forEach { (dt, regOrSf) ->
val reg = if(regOrSf.registerOrPair!=null) regOrSf.registerOrPair.toString()
else regOrSf.statusflag.toString()
out.write("${dt.toString().lowercase()} $reg\n")
}
out.write("</PARAMS>\n")
out.write("<INLINEASM POS=${it.position}>\n")
out.write(it.assembly.trimStart('\n').trimEnd(' ', '\n'))
out.write("\n</INLINEASM>\n</ASMSUB>\n")

View File

@ -35,8 +35,10 @@ PROGRAM:
SUB
SUB
ASMSUB
PARAMS
INLINEASM
ASMSUB
PARAMS
INLINEASM
...
BLOCK
@ -104,7 +106,7 @@ class IRAsmSubroutine(val name: String,
val position: Position,
val address: UInt?,
val clobbers: Set<CpuRegister>,
val parameters: List<IRAsmSubParam>,
val parameters: List<Pair<DataType, RegisterOrStatusflag>>,
val returns: List<Pair<DataType, RegisterOrStatusflag>>,
val assembly: String) {
val lines = mutableListOf<IRCodeLine>()
@ -115,8 +117,6 @@ class IRAsmSubroutine(val name: String,
if(name.startsWith("main.main."))
throw IllegalArgumentException("subroutine name invalid main prefix: $name")
}
class IRAsmSubParam(val name: String, val dt: DataType, val reg: RegisterOrStatusflag)
}
sealed class IRCodeLine