mirror of
https://github.com/irmen/prog8.git
synced 2024-06-28 20:29:36 +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
|
val assembly = if(child.children.isEmpty()) "" else (child.children.single() as PtInlineAssembly).assembly
|
||||||
vmblock += IRAsmSubroutine(child.name, child.position, child.address,
|
vmblock += IRAsmSubroutine(child.name, child.position, child.address,
|
||||||
child.clobbers,
|
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),
|
child.returnTypes.zip(child.retvalRegisters),
|
||||||
assembly)
|
assembly)
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,7 @@ class IRFileReader(outputDir: Path, programName: String) {
|
||||||
|
|
||||||
private val blockPattern = Regex("<BLOCK NAME=(.+) ADDRESS=(.+) ALIGN=(.+) POS=(.+)>")
|
private val blockPattern = Regex("<BLOCK NAME=(.+) ADDRESS=(.+) ALIGN=(.+) POS=(.+)>")
|
||||||
private val inlineAsmPattern = Regex("<INLINEASM 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 subPattern = Regex("<SUB NAME=(.+) RETURNTYPE=(.+) POS=(.+)>")
|
||||||
private val posPattern = Regex("\\[(.+): line (.+) col (.+)-(.+)\\]")
|
private val posPattern = Regex("\\[(.+): line (.+) col (.+)-(.+)\\]")
|
||||||
private val instructionPattern = Regex("""([a-z]+)(\.b|\.w|\.f)?(.*)""", RegexOption.IGNORE_CASE)
|
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 {
|
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]>
|
// <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 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()
|
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)
|
val asm = parseInlineAssembly(line, lines)
|
||||||
while(line!="</ASMSUB>")
|
while(line!="</ASMSUB>")
|
||||||
line = lines.next()
|
line = lines.next()
|
||||||
val clobberRegs = clobbers.split(',').map { CpuRegister.valueOf(it) }
|
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>>()
|
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,
|
return IRAsmSubroutine(scopedname,
|
||||||
parsePosition(pos), if(address=="null") null else address.toUInt(),
|
parsePosition(pos), if(address=="null") null else address.toUInt(),
|
||||||
clobberRegs.toSet(),
|
clobberRegs.toSet(),
|
||||||
parameters,
|
params,
|
||||||
returns,
|
returns,
|
||||||
asm.asm)
|
asm.asm)
|
||||||
}
|
}
|
||||||
|
@ -560,6 +578,17 @@ class IRFileReader(outputDir: Path, programName: String) {
|
||||||
return value.toFloat()
|
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 {
|
private fun parsePosition(strpos: String): Position {
|
||||||
// example: "[library:/prog8lib/virtual/textio.p8: line 5 col 2-4]"
|
// example: "[library:/prog8lib/virtual/textio.p8: line 5 col 2-4]"
|
||||||
val match = posPattern.matchEntire(strpos) ?: throw IRParseException("invalid Position")
|
val match = posPattern.matchEntire(strpos) ?: throw IRParseException("invalid Position")
|
||||||
|
|
|
@ -57,8 +57,18 @@ class IRFileWriter(private val irProgram: IRProgram) {
|
||||||
}
|
}
|
||||||
block.asmSubroutines.forEach {
|
block.asmSubroutines.forEach {
|
||||||
val clobbers = it.clobbers.joinToString(",")
|
val clobbers = it.clobbers.joinToString(",")
|
||||||
out.write("<ASMSUB NAME=${it.name} ADDRESS=${it.address} CLOBBERS=$clobbers POS=${it.position}>\n")
|
val returns = it.returns.map { (dt, reg) ->
|
||||||
// TODO rest of the signature: RETURNS = it.returns
|
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("<INLINEASM POS=${it.position}>\n")
|
||||||
out.write(it.assembly.trimStart('\n').trimEnd(' ', '\n'))
|
out.write(it.assembly.trimStart('\n').trimEnd(' ', '\n'))
|
||||||
out.write("\n</INLINEASM>\n</ASMSUB>\n")
|
out.write("\n</INLINEASM>\n</ASMSUB>\n")
|
||||||
|
|
|
@ -35,8 +35,10 @@ PROGRAM:
|
||||||
SUB
|
SUB
|
||||||
SUB
|
SUB
|
||||||
ASMSUB
|
ASMSUB
|
||||||
|
PARAMS
|
||||||
INLINEASM
|
INLINEASM
|
||||||
ASMSUB
|
ASMSUB
|
||||||
|
PARAMS
|
||||||
INLINEASM
|
INLINEASM
|
||||||
...
|
...
|
||||||
BLOCK
|
BLOCK
|
||||||
|
@ -104,7 +106,7 @@ class IRAsmSubroutine(val name: String,
|
||||||
val position: Position,
|
val position: Position,
|
||||||
val address: UInt?,
|
val address: UInt?,
|
||||||
val clobbers: Set<CpuRegister>,
|
val clobbers: Set<CpuRegister>,
|
||||||
val parameters: List<IRAsmSubParam>,
|
val parameters: List<Pair<DataType, RegisterOrStatusflag>>,
|
||||||
val returns: List<Pair<DataType, RegisterOrStatusflag>>,
|
val returns: List<Pair<DataType, RegisterOrStatusflag>>,
|
||||||
val assembly: String) {
|
val assembly: String) {
|
||||||
val lines = mutableListOf<IRCodeLine>()
|
val lines = mutableListOf<IRCodeLine>()
|
||||||
|
@ -115,8 +117,6 @@ class IRAsmSubroutine(val name: String,
|
||||||
if(name.startsWith("main.main."))
|
if(name.startsWith("main.main."))
|
||||||
throw IllegalArgumentException("subroutine name invalid main prefix: $name")
|
throw IllegalArgumentException("subroutine name invalid main prefix: $name")
|
||||||
}
|
}
|
||||||
|
|
||||||
class IRAsmSubParam(val name: String, val dt: DataType, val reg: RegisterOrStatusflag)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class IRCodeLine
|
sealed class IRCodeLine
|
||||||
|
|
Loading…
Reference in New Issue
Block a user