mirror of
https://github.com/irmen/prog8.git
synced 2025-08-10 10:25:31 +00:00
properly generate PUSH and POP instructions for push() and pop() calls in IR.
Also switch to a fork of shadowJar to avoid Gradle deprecation errors.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package prog8.codegen.intermediate
|
package prog8.codegen.intermediate
|
||||||
|
|
||||||
|
import prog8.code.StNode
|
||||||
import prog8.code.StRomSub
|
import prog8.code.StRomSub
|
||||||
import prog8.code.StSub
|
import prog8.code.StSub
|
||||||
import prog8.code.ast.*
|
import prog8.code.ast.*
|
||||||
@@ -451,7 +452,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun translate(fcall: PtFunctionCall): ExpressionCodeResult {
|
fun translate(fcall: PtFunctionCall): ExpressionCodeResult {
|
||||||
when (val callTarget = codeGen.symbolTable.flat.getValue(fcall.name)) {
|
val callTarget = codeGen.symbolTable.flat.getValue(fcall.name)
|
||||||
|
|
||||||
|
if(callTarget.scopedName in listOf("sys.push", "sys.pushw", "sys.pop", "sys.popw")) {
|
||||||
|
// special case, these should be inlined, or even use specialized instructions. Instead of doing a normal subroutine call.
|
||||||
|
return translateStackFunctions(fcall, callTarget)
|
||||||
|
}
|
||||||
|
|
||||||
|
when (callTarget) {
|
||||||
is StSub -> {
|
is StSub -> {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = callTarget.parameters.size), null)
|
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = callTarget.parameters.size), null)
|
||||||
@@ -590,6 +598,39 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun translateStackFunctions(fcall: PtFunctionCall, callTarget: StNode): ExpressionCodeResult {
|
||||||
|
val chunk = mutableListOf<IRCodeChunkBase>()
|
||||||
|
when(callTarget.scopedName) {
|
||||||
|
"sys.push" -> {
|
||||||
|
// push byte
|
||||||
|
val tr = translateExpression(fcall.args.single())
|
||||||
|
chunk += tr.chunks
|
||||||
|
addInstr(chunk, IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=tr.resultReg), null)
|
||||||
|
return ExpressionCodeResult(chunk, IRDataType.BYTE, -1, -1)
|
||||||
|
}
|
||||||
|
"sys.pushw" -> {
|
||||||
|
// push word
|
||||||
|
val tr = translateExpression(fcall.args.single())
|
||||||
|
chunk += tr.chunks
|
||||||
|
addInstr(chunk, IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1=tr.resultReg), null)
|
||||||
|
return ExpressionCodeResult(chunk, IRDataType.WORD, -1, -1)
|
||||||
|
}
|
||||||
|
"sys.pop" -> {
|
||||||
|
// pop byte
|
||||||
|
val popReg = codeGen.registers.nextFree()
|
||||||
|
addInstr(chunk, IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=popReg), null)
|
||||||
|
return ExpressionCodeResult(chunk, IRDataType.BYTE, popReg, -1)
|
||||||
|
}
|
||||||
|
"sys.popw" -> {
|
||||||
|
// pop word
|
||||||
|
val popReg = codeGen.registers.nextFree()
|
||||||
|
addInstr(chunk, IRInstruction(Opcode.POP, IRDataType.WORD, reg1=popReg), null)
|
||||||
|
return ExpressionCodeResult(chunk, IRDataType.WORD, popReg, -1)
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("unknown stack subroutine called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun callRomSubWithMultipleReturnValues(
|
private fun callRomSubWithMultipleReturnValues(
|
||||||
callTarget: StRomSub,
|
callTarget: StRomSub,
|
||||||
fcall: PtFunctionCall,
|
fcall: PtFunctionCall,
|
||||||
|
@@ -2,7 +2,8 @@ plugins {
|
|||||||
id 'java'
|
id 'java'
|
||||||
id 'application'
|
id 'application'
|
||||||
id 'org.jetbrains.kotlin.jvm'
|
id 'org.jetbrains.kotlin.jvm'
|
||||||
id 'com.github.johnrengelman.shadow' version '8.1.1'
|
// id 'com.github.johnrengelman.shadow' version '8.1.1'
|
||||||
|
id 'io.github.goooler.shadow' version '8.1.7'
|
||||||
id 'com.peterabeles.gversion' version '1.10.2'
|
id 'com.peterabeles.gversion' version '1.10.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@ import prog8.ast.statements.Assignment
|
|||||||
import prog8.code.target.C64Target
|
import prog8.code.target.C64Target
|
||||||
import prog8.code.target.Cx16Target
|
import prog8.code.target.Cx16Target
|
||||||
import prog8.code.target.VMTarget
|
import prog8.code.target.VMTarget
|
||||||
|
import prog8.intermediate.IRDataType
|
||||||
import prog8.intermediate.IRFileReader
|
import prog8.intermediate.IRFileReader
|
||||||
import prog8.intermediate.IRSubroutine
|
import prog8.intermediate.IRSubroutine
|
||||||
import prog8.intermediate.Opcode
|
import prog8.intermediate.Opcode
|
||||||
@@ -475,6 +476,34 @@ main {
|
|||||||
compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null
|
compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("push() and pop() generate correct IR instructions") {
|
||||||
|
val src="""
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
ubyte bb
|
||||||
|
uword ww
|
||||||
|
sys.push(42)
|
||||||
|
bb++
|
||||||
|
bb=sys.pop()
|
||||||
|
sys.pushw(9999)
|
||||||
|
ww++
|
||||||
|
ww=sys.popw()
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
val result = compileText(VMTarget(), true, src, writeAssembly = true)!!
|
||||||
|
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
|
||||||
|
val irProgram = IRFileReader().read(virtfile)
|
||||||
|
val start = irProgram.blocks[0].children[0] as IRSubroutine
|
||||||
|
val instructions = start.chunks.flatMap { c->c.instructions }
|
||||||
|
instructions.size shouldBe 13
|
||||||
|
instructions[3].opcode shouldBe Opcode.PUSH
|
||||||
|
instructions[3].type shouldBe IRDataType.BYTE
|
||||||
|
instructions[5].opcode shouldBe Opcode.POP
|
||||||
|
instructions[5].type shouldBe IRDataType.BYTE
|
||||||
|
instructions[8].opcode shouldBe Opcode.PUSH
|
||||||
|
instructions[8].type shouldBe IRDataType.WORD
|
||||||
|
instructions[10].opcode shouldBe Opcode.POP
|
||||||
|
instructions[10].type shouldBe IRDataType.WORD
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
@@ -7,8 +7,6 @@ https://github.com/irmen/prog8/issues/136 (string.find register order issue)
|
|||||||
|
|
||||||
optimization: for 65c02 sometimes clc adc #1 is generated, this can be optimized into inc a (always? or not? mind the carry flag!)
|
optimization: for 65c02 sometimes clc adc #1 is generated, this can be optimized into inc a (always? or not? mind the carry flag!)
|
||||||
|
|
||||||
IR: sys.push() and sys.pop() etc should be translated into PUSH/POP instructions instead of subroutine calls
|
|
||||||
|
|
||||||
if-optimization:
|
if-optimization:
|
||||||
if row == NUMQUEENS {
|
if row == NUMQUEENS {
|
||||||
print_solution()
|
print_solution()
|
||||||
|
Reference in New Issue
Block a user