mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
added remaining signature stuff to IRAsmSubroutine
This commit is contained in:
parent
6428ced157
commit
7dd14955c1
@ -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)
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user