mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
got rid of useless opcode
This commit is contained in:
parent
c6c75c43ff
commit
eb74b8daa5
@ -43,7 +43,6 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
|||||||
optimizeVariableCopying()
|
optimizeVariableCopying()
|
||||||
optimizeMultipleSequentialLineInstrs()
|
optimizeMultipleSequentialLineInstrs()
|
||||||
optimizeCallReturnIntoJump()
|
optimizeCallReturnIntoJump()
|
||||||
optimizeRestoreXSaveXIntoRepopX()
|
|
||||||
// todo: add more optimizations to stackvm code
|
// todo: add more optimizations to stackvm code
|
||||||
|
|
||||||
optimizeRemoveNops() // must be done as the last step
|
optimizeRemoveNops() // must be done as the last step
|
||||||
@ -57,24 +56,6 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
|||||||
blk.instructions.removeIf { it.opcode== Opcode.NOP && it !is LabelInstr }
|
blk.instructions.removeIf { it.opcode== Opcode.NOP && it !is LabelInstr }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun optimizeRestoreXSaveXIntoRepopX() {
|
|
||||||
// replace rrestorex+rsavex combo by only repopX
|
|
||||||
for(blk in blocks) {
|
|
||||||
val instructionsToReplace = mutableMapOf<Int, Instruction>()
|
|
||||||
|
|
||||||
blk.instructions.asSequence().withIndex().filter {it.value.opcode!=Opcode.LINE}.windowed(2).toList().forEach {
|
|
||||||
if(it[0].value.opcode==Opcode.RRESTOREX && it[1].value.opcode==Opcode.RSAVEX) {
|
|
||||||
instructionsToReplace[it[0].index] = Instruction(Opcode.REPOPX)
|
|
||||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (rins in instructionsToReplace) {
|
|
||||||
blk.instructions[rins.key] = rins.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun optimizeCallReturnIntoJump() {
|
private fun optimizeCallReturnIntoJump() {
|
||||||
// replaces call X followed by return, by jump X
|
// replaces call X followed by return, by jump X
|
||||||
for(blk in blocks) {
|
for(blk in blocks) {
|
||||||
|
@ -261,7 +261,6 @@ enum class Opcode {
|
|||||||
RSAVEX, // save just X (the evaluation stack pointer)
|
RSAVEX, // save just X (the evaluation stack pointer)
|
||||||
RRESTORE, // restore all internal registers and status flags
|
RRESTORE, // restore all internal registers and status flags
|
||||||
RRESTOREX, // restore just X (the evaluation stack pointer)
|
RRESTOREX, // restore just X (the evaluation stack pointer)
|
||||||
REPOPX, // restore just X (the evaluation stack pointer) but store it again too (essentially not erasing the value that's saved on the stack)
|
|
||||||
|
|
||||||
NOP, // do nothing
|
NOP, // do nothing
|
||||||
BREAKPOINT, // breakpoint
|
BREAKPOINT, // breakpoint
|
||||||
|
@ -422,7 +422,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
}
|
}
|
||||||
Opcode.RSAVEX -> " sta ${C64Zeropage.SCRATCH_REG} | txa | pha | lda ${C64Zeropage.SCRATCH_REG}"
|
Opcode.RSAVEX -> " sta ${C64Zeropage.SCRATCH_REG} | txa | pha | lda ${C64Zeropage.SCRATCH_REG}"
|
||||||
Opcode.RRESTOREX -> " sta ${C64Zeropage.SCRATCH_REG} | pla | tax | lda ${C64Zeropage.SCRATCH_REG}"
|
Opcode.RRESTOREX -> " sta ${C64Zeropage.SCRATCH_REG} | pla | tax | lda ${C64Zeropage.SCRATCH_REG}"
|
||||||
Opcode.REPOPX -> " sta ${C64Zeropage.SCRATCH_REG} | pla | tax | pha | lda ${C64Zeropage.SCRATCH_REG}"
|
|
||||||
Opcode.DISCARD_BYTE -> " inx"
|
Opcode.DISCARD_BYTE -> " inx"
|
||||||
Opcode.DISCARD_WORD -> " inx"
|
Opcode.DISCARD_WORD -> " inx"
|
||||||
Opcode.DISCARD_FLOAT -> " inx | inx | inx"
|
Opcode.DISCARD_FLOAT -> " inx | inx | inx"
|
||||||
@ -969,12 +968,14 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(pattern in patterns.filter { it.sequence.size <= segment.size || (it.altSequence != null && it.altSequence.size <= segment.size)}) {
|
for(pattern in patterns.filter { it.sequence.size <= segment.size || (it.altSequence != null && it.altSequence.size <= segment.size)}) {
|
||||||
val opcodesList = opcodes.subList(0, pattern.sequence.size)
|
val opcodesList = if(pattern.sequence.size<=opcodes.size) opcodes.subList(0, pattern.sequence.size) else null
|
||||||
|
val opcodesListAlt = if(pattern.altSequence!=null && pattern.altSequence.size<=opcodes.size) opcodes.subList(0, pattern.altSequence.size) else null
|
||||||
|
|
||||||
if(pattern.sequence == opcodesList) {
|
if(pattern.sequence == opcodesList) {
|
||||||
val asm = pattern.asm(segment)
|
val asm = pattern.asm(segment)
|
||||||
if(asm!=null)
|
if(asm!=null)
|
||||||
result.add(AsmFragment(asm, pattern.sequence.size))
|
result.add(AsmFragment(asm, pattern.sequence.size))
|
||||||
} else if(pattern.altSequence == opcodesList) {
|
} else if(opcodesListAlt!=null && pattern.altSequence == opcodesListAlt) {
|
||||||
val asm = pattern.asm(segment)
|
val asm = pattern.asm(segment)
|
||||||
if(asm!=null)
|
if(asm!=null)
|
||||||
result.add(AsmFragment(asm, pattern.sequence.size))
|
result.add(AsmFragment(asm, pattern.sequence.size))
|
||||||
@ -3202,6 +3203,15 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
"""
|
"""
|
||||||
},
|
},
|
||||||
|
|
||||||
|
AsmPattern(listOf(Opcode.RRESTOREX, Opcode.LINE, Opcode.RSAVEX), listOf(Opcode.RRESTOREX, Opcode.RSAVEX)) { segment ->
|
||||||
|
"""
|
||||||
|
sta ${C64Zeropage.SCRATCH_REG}
|
||||||
|
pla
|
||||||
|
tax
|
||||||
|
pha
|
||||||
|
lda ${C64Zeropage.SCRATCH_REG}
|
||||||
|
"""
|
||||||
|
},
|
||||||
|
|
||||||
// various optimizable integer multiplications
|
// various optimizable integer multiplications
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.MUL_B), listOf(Opcode.PUSH_BYTE, Opcode.MUL_UB)) { segment ->
|
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.MUL_B), listOf(Opcode.PUSH_BYTE, Opcode.MUL_UB)) { segment ->
|
||||||
|
@ -1487,7 +1487,6 @@ class StackVm(private var traceOutputFile: String?) {
|
|||||||
}
|
}
|
||||||
Opcode.RSAVEX -> evalstack.push(variables["X"])
|
Opcode.RSAVEX -> evalstack.push(variables["X"])
|
||||||
Opcode.RRESTOREX -> variables["X"] = evalstack.pop()
|
Opcode.RRESTOREX -> variables["X"] = evalstack.pop()
|
||||||
Opcode.REPOPX -> variables["X"] = evalstack.peek()
|
|
||||||
Opcode.INLINE_ASSEMBLY -> throw VmExecutionException("stackVm doesn't support executing inline assembly code")
|
Opcode.INLINE_ASSEMBLY -> throw VmExecutionException("stackVm doesn't support executing inline assembly code")
|
||||||
Opcode.PUSH_ADDR_HEAPVAR -> {
|
Opcode.PUSH_ADDR_HEAPVAR -> {
|
||||||
val heapId = variables[ins.callLabel]!!.heapId
|
val heapId = variables[ins.callLabel]!!.heapId
|
||||||
|
Loading…
Reference in New Issue
Block a user