IR: add SEC,CLC,SEI,CLI instructions for the sys function calls.

This commit is contained in:
Irmen de Jong
2024-07-14 21:01:19 +02:00
parent 69f953fd9b
commit d5adb85e5b
7 changed files with 95 additions and 7 deletions
@@ -458,6 +458,28 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
// special case, these should be inlined, or even use specialized instructions. Instead of doing a normal subroutine call.
return translateStackFunctions(fcall, callTarget)
}
when(callTarget.scopedName) {
"sys.clear_carry" -> {
val chunk = mutableListOf<IRCodeChunkBase>()
addInstr(chunk, IRInstruction(Opcode.CLC), null)
return ExpressionCodeResult(chunk, IRDataType.BYTE, -1, -1)
}
"sys.set_carry" -> {
val chunk = mutableListOf<IRCodeChunkBase>()
addInstr(chunk, IRInstruction(Opcode.SEC), null)
return ExpressionCodeResult(chunk, IRDataType.BYTE, -1, -1)
}
"sys.clear_irqd" -> {
val chunk = mutableListOf<IRCodeChunkBase>()
addInstr(chunk, IRInstruction(Opcode.CLI), null)
return ExpressionCodeResult(chunk, IRDataType.BYTE, -1, -1)
}
"sys.set_irqd" -> {
val chunk = mutableListOf<IRCodeChunkBase>()
addInstr(chunk, IRInstruction(Opcode.SEI), null)
return ExpressionCodeResult(chunk, IRDataType.BYTE, -1, -1)
}
}
when (callTarget) {
is StSub -> {
@@ -263,6 +263,24 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) {
}
}
}
if(ins.opcode== Opcode.SEI || ins.opcode== Opcode.CLI) {
if(idx < chunk.instructions.size-1) {
val insAfter = chunk.instructions[idx+1]
if(insAfter.opcode == ins.opcode) {
chunk.instructions.removeAt(idx)
changed = true
}
else if(ins.opcode== Opcode.SEI && insAfter.opcode== Opcode.CLI) {
chunk.instructions.removeAt(idx)
changed = true
}
else if(ins.opcode== Opcode.CLI && insAfter.opcode== Opcode.SEI) {
chunk.instructions.removeAt(idx)
changed = true
}
}
}
}
return changed
}
+35 -4
View File
@@ -80,21 +80,52 @@ class TestIRPeepholeOpt: FunSpec({
instr[1].opcode shouldBe Opcode.INC
}
test("remove double sec/clc") {
test("remove double sec/clc/sei/cli") {
val irProg = makeIRProgram(listOf(
IRInstruction(Opcode.SEC),
IRInstruction(Opcode.SEC),
IRInstruction(Opcode.SEC),
IRInstruction(Opcode.CLC),
IRInstruction(Opcode.CLC),
IRInstruction(Opcode.CLC)
IRInstruction(Opcode.CLC),
IRInstruction(Opcode.SEI),
IRInstruction(Opcode.SEI),
IRInstruction(Opcode.SEI),
IRInstruction(Opcode.CLI),
IRInstruction(Opcode.CLI),
IRInstruction(Opcode.CLI),
))
irProg.chunks().single().instructions.size shouldBe 6
irProg.chunks().single().instructions.size shouldBe 12
val opt = IRPeepholeOptimizer(irProg)
opt.optimize(true, ErrorReporterForTests())
val instr = irProg.chunks().single().instructions
instr.size shouldBe 1
instr.size shouldBe 2
instr[0].opcode shouldBe Opcode.CLC
instr[1].opcode shouldBe Opcode.CLI
}
test("remove double sec/clc/sei/cli reversed") {
val irProg = makeIRProgram(listOf(
IRInstruction(Opcode.CLC),
IRInstruction(Opcode.CLC),
IRInstruction(Opcode.CLC),
IRInstruction(Opcode.SEC),
IRInstruction(Opcode.SEC),
IRInstruction(Opcode.SEC),
IRInstruction(Opcode.CLI),
IRInstruction(Opcode.CLI),
IRInstruction(Opcode.CLI),
IRInstruction(Opcode.SEI),
IRInstruction(Opcode.SEI),
IRInstruction(Opcode.SEI),
))
irProg.chunks().single().instructions.size shouldBe 12
val opt = IRPeepholeOptimizer(irProg)
opt.optimize(true, ErrorReporterForTests())
val instr = irProg.chunks().single().instructions
instr.size shouldBe 2
instr[0].opcode shouldBe Opcode.SEC
instr[1].opcode shouldBe Opcode.SEI
}
test("push followed by pop") {