mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
vm: codegen uses INCM/DECM if possible
This commit is contained in:
parent
517cf61d11
commit
a7df828932
@ -507,53 +507,53 @@ class CodeGen(internal val program: PtProgram,
|
||||
|
||||
private fun translate(postIncrDecr: PtPostIncrDecr): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
val operation = when(postIncrDecr.operator) {
|
||||
"++" -> Opcode.INC
|
||||
"--" -> Opcode.DEC
|
||||
val operationMem: Opcode
|
||||
val operationRegister: Opcode
|
||||
when(postIncrDecr.operator) {
|
||||
"++" -> {
|
||||
operationMem = Opcode.INCM
|
||||
operationRegister = Opcode.INC
|
||||
}
|
||||
"--" -> {
|
||||
operationMem = Opcode.DECM
|
||||
operationRegister = Opcode.DEC
|
||||
}
|
||||
else -> throw AssemblyError("weird operator")
|
||||
}
|
||||
val ident = postIncrDecr.target.identifier
|
||||
val memory = postIncrDecr.target.memory
|
||||
val array = postIncrDecr.target.array
|
||||
val vmDt = vmType(postIncrDecr.target.type)
|
||||
val resultReg = vmRegisters.nextFree()
|
||||
if(ident!=null) {
|
||||
val address = allocations.get(ident.targetName)
|
||||
code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1=resultReg, value = address)
|
||||
code += VmCodeInstruction(operation, vmDt, reg1=resultReg)
|
||||
code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1=resultReg, value = address)
|
||||
code += VmCodeInstruction(operationMem, vmDt, value = address)
|
||||
} else if(memory!=null) {
|
||||
if(memory.address is PtNumber) {
|
||||
val address = (memory.address as PtNumber).number.toInt()
|
||||
code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1 = resultReg, value = address)
|
||||
code += VmCodeInstruction(operation, vmDt, reg1 = resultReg)
|
||||
code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultReg, value=address)
|
||||
code += VmCodeInstruction(operationMem, vmDt, value = address)
|
||||
} else {
|
||||
val incReg = vmRegisters.nextFree()
|
||||
val addressReg = vmRegisters.nextFree()
|
||||
code += expressionEval.translateExpression(memory.address, addressReg, -1)
|
||||
code += VmCodeInstruction(Opcode.LOADI, vmDt, reg1 = resultReg, reg2 = addressReg)
|
||||
code += VmCodeInstruction(operation, vmDt, reg1 = resultReg)
|
||||
code += VmCodeInstruction(Opcode.STOREI, vmDt, reg1 = resultReg, reg2 = addressReg)
|
||||
code += VmCodeInstruction(Opcode.LOADI, vmDt, reg1 = incReg, reg2 = addressReg)
|
||||
code += VmCodeInstruction(operationRegister, vmDt, reg1 = incReg)
|
||||
code += VmCodeInstruction(Opcode.STOREI, vmDt, reg1 = incReg, reg2 = addressReg)
|
||||
}
|
||||
} else if (array!=null) {
|
||||
val variable = array.variable.targetName
|
||||
var variableAddr = allocations.get(variable)
|
||||
val itemsize = program.memsizer.memorySize(array.type)
|
||||
val fixedIndex = constIntValue(array.index)
|
||||
val memOp = when(postIncrDecr.operator) {
|
||||
"++" -> Opcode.INCM
|
||||
"--" -> Opcode.DECM
|
||||
else -> throw AssemblyError("weird operator")
|
||||
}
|
||||
if(fixedIndex!=null) {
|
||||
variableAddr += fixedIndex*itemsize
|
||||
code += VmCodeInstruction(memOp, vmDt, value=variableAddr)
|
||||
code += VmCodeInstruction(operationMem, vmDt, value=variableAddr)
|
||||
} else {
|
||||
val incReg = vmRegisters.nextFree()
|
||||
val indexReg = vmRegisters.nextFree()
|
||||
code += expressionEval.translateExpression(array.index, indexReg, -1)
|
||||
code += VmCodeInstruction(Opcode.LOADX, vmDt, reg1=resultReg, reg2=indexReg, value=variableAddr)
|
||||
code += VmCodeInstruction(operation, vmDt, reg1=resultReg)
|
||||
code += VmCodeInstruction(Opcode.STOREX, vmDt, reg1=resultReg, reg2=indexReg, value=variableAddr)
|
||||
code += VmCodeInstruction(Opcode.LOADX, vmDt, reg1=incReg, reg2=indexReg, value=variableAddr)
|
||||
code += VmCodeInstruction(operationRegister, vmDt, reg1=incReg)
|
||||
code += VmCodeInstruction(Opcode.STOREX, vmDt, reg1=incReg, reg2=indexReg, value=variableAddr)
|
||||
}
|
||||
} else
|
||||
throw AssemblyError("weird assigntarget")
|
||||
|
@ -173,7 +173,6 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
|
||||
private fun translate(expr: PtPrefix, resultRegister: Int): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
// TODO if the value is a variable or memory read, use memory-versions of the opcodes instead of using intermediary register
|
||||
code += translateExpression(expr.value, resultRegister, -1)
|
||||
val vmDt = codeGen.vmType(expr.type)
|
||||
when(expr.operator) {
|
||||
|
@ -3,7 +3,8 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- vm: use more instructions in codegen: branching
|
||||
- vm: use more instructions in codegen: branching, don't use the conditional set instructions here
|
||||
- vm: get rid of all the conditional set instructions
|
||||
- vm: add more instructions operating directly on memory instead of only registers?
|
||||
- in-place modifiying functions (rol, ror, ..) don't accept a memory address but require a memory-read expression. that is weird.
|
||||
- complete the Inliner
|
||||
|
@ -25,10 +25,24 @@ main {
|
||||
|
||||
ubyte @shared value = inline_candidate()
|
||||
|
||||
ubyte lowb = $31
|
||||
ubyte lowb = 4
|
||||
ubyte highb = $ea
|
||||
uword result = mkword(highb, lowb)
|
||||
txt.print_uwhex(result, true)
|
||||
|
||||
if lowb==3
|
||||
lowb++
|
||||
|
||||
if lowb!=3
|
||||
lowb++
|
||||
|
||||
if lowb==3
|
||||
lowb++
|
||||
else
|
||||
lowb--
|
||||
|
||||
if lowb!=3
|
||||
lowb++
|
||||
else
|
||||
lowb--
|
||||
|
||||
; txt.print_ub(inline_candidate())
|
||||
; txt.nl()
|
||||
|
@ -184,8 +184,8 @@ enum class Opcode {
|
||||
BSTPOS,
|
||||
BZ,
|
||||
BNZ,
|
||||
BEQ,
|
||||
BNE,
|
||||
BEQ, // TODO not used in codegen??? == nonzero
|
||||
BNE, // TODO not used in codegen??? != nonzero
|
||||
BLT, // TODO not used in codegen??? <
|
||||
BLTS, // TODO not used in codegen??? <
|
||||
BGT, // TODO not used in codegen??? >
|
||||
|
Loading…
Reference in New Issue
Block a user