tweak vm codegen

This commit is contained in:
Irmen de Jong
2022-08-07 13:45:03 +02:00
parent 93ce74eeb1
commit 1e441c2ddf
6 changed files with 23 additions and 55 deletions
@@ -1,9 +1,7 @@
package prog8.codegen.virtual
import prog8.code.ast.*
import prog8.code.core.AssemblyError
import prog8.code.core.DataType
import prog8.code.core.SignedDatatypes
import prog8.code.core.*
import prog8.vm.Opcode
import prog8.vm.VmDataType
@@ -33,7 +31,9 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
else
fallbackAssign(assignment)
} else if(array!=null) {
// TODO in-place array element assignment?
// NOTE: naive fallback assignment here will sometimes generate code that loads the index value multiple times
// in a register. It's way too much work to optimize that here - instead, we trust that the generated IL assembly
// will be optimized later and have the double assignments removed.
fallbackAssign(assignment)
} else {
fallbackAssign(assignment)
@@ -275,15 +275,8 @@ class CodeGen(internal val program: PtProgram,
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress)
code += VmCodeLabel(loopLabel)
code += translateNode(forLoop.statements)
if(step<3) {
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
} else {
// TODO WHY THIS DISTINCTION?
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
code += addConstReg(loopvarDt, indexReg, step)
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
}
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
val branchOpcode = if(loopvar.dt in SignedDatatypes) Opcode.BLES else Opcode.BLE
code += VmCodeInstruction(branchOpcode, loopvarDt, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel)
return code
@@ -315,15 +308,8 @@ class CodeGen(internal val program: PtProgram,
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress)
code += VmCodeLabel(loopLabel)
code += translateNode(forLoop.statements)
if(step<3) {
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
} else {
// TODO WHY THIS DISTICTION ?
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
code += addConstReg(loopvarDt, indexReg, step)
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
}
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
code += if(rangeEndWrapped==0) {
VmCodeInstruction(Opcode.BNZ, loopvarDt, reg1 = indexReg, labelSymbol = loopLabel)
} else {
@@ -381,18 +367,13 @@ class CodeGen(internal val program: PtProgram,
}
else -> {
val valueReg = vmRegisters.nextFree()
val operandReg = vmRegisters.nextFree()
if(value>0) {
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=value)
code += VmCodeInstruction(Opcode.ADDR, dt, reg1 = valueReg, reg2 = operandReg) // TODO USE ADDM?
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=value)
code += VmCodeInstruction(Opcode.ADDM, dt, reg1=valueReg, value=address.toInt())
}
else {
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=-value)
code += VmCodeInstruction(Opcode.SUBR, dt, reg1 = valueReg, reg2 = operandReg) // TODO USE ADDM?
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=-value)
code += VmCodeInstruction(Opcode.SUBM, dt, reg1=valueReg, value=address.toInt())
}
}
}
@@ -172,6 +172,7 @@ class VmPeepholeOptimizer(private val vmprog: AssemblyProgram, private val alloc
// TODO: detect multiple sequential rnd with same reg1, only keep one
// TODO: detect subsequent same xors/nots/negs, remove the pairs completely as they cancel out
// TODO: detect multiple same ands, ors; only keep first
// TODO: (hard) detect multiple registers being assigned the same value (and not changed) - use only 1 of them
// ...
}
return changed