vm: more optimal code when array index is constant value

This commit is contained in:
Irmen de Jong 2022-04-05 00:19:37 +02:00
parent 2b7c09e6ee
commit d78bfcc35c
3 changed files with 21 additions and 20 deletions

View File

@ -138,15 +138,20 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val vmDt = codeGen.vmType(arrayIx.type) val vmDt = codeGen.vmType(arrayIx.type)
val code = VmCodeChunk() val code = VmCodeChunk()
val idxReg = codeGen.vmRegisters.nextFree() val idxReg = codeGen.vmRegisters.nextFree()
// TODO: optimized code when the index is a constant value
code += translateExpression(arrayIx.index, idxReg)
if(eltSize>1) {
val factorReg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=factorReg, value=eltSize)
code += VmCodeInstruction(Opcode.MUL, VmDataType.BYTE, reg1=idxReg, reg2=idxReg, reg3=factorReg)
}
val arrayLocation = codeGen.allocations.get(arrayIx.variable.targetName) val arrayLocation = codeGen.allocations.get(arrayIx.variable.targetName)
code += VmCodeInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, value = arrayLocation) if(arrayIx.index is PtNumber) {
// optimized code when index is known - just calculate the memory address here
val memOffset = (arrayIx.index as PtNumber).number.toInt() * eltSize
code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, value=arrayLocation+memOffset)
} else {
code += translateExpression(arrayIx.index, idxReg)
if(eltSize>1) {
val factorReg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=factorReg, value=eltSize)
code += VmCodeInstruction(Opcode.MUL, VmDataType.BYTE, reg1=idxReg, reg2=idxReg, reg3=factorReg)
}
code += VmCodeInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, value = arrayLocation)
}
return code return code
} }

View File

@ -7,13 +7,9 @@
main { main {
sub start() { sub start() {
ubyte counter uword[] array = [1111,2222,3333,4444,5555]
repeat 256 { txt.print_uw(array[3])
txt.print_ub(counter)
txt.spc()
counter ++
}
txt.nl() txt.nl()
; a "pixelshader": ; a "pixelshader":

View File

@ -588,7 +588,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
if(right==0.toUByte()) 0xffu if(right==0.toUByte()) 0xffu
else left % right else left % right
} }
else -> TODO("operator byte $operator") else -> throw IllegalArgumentException("operator byte $operator")
} }
registers.setUB(reg1, result.toUByte()) registers.setUB(reg1, result.toUByte())
} }
@ -608,7 +608,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
if(right==0.toUShort()) 0xffffu if(right==0.toUShort()) 0xffffu
else left % right else left % right
} }
else -> TODO("operator word $operator") else -> throw IllegalArgumentException("operator word $operator")
} }
registers.setUW(reg1, result.toUShort()) registers.setUW(reg1, result.toUShort())
} }
@ -624,7 +624,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
private fun InsEXT(i: Instruction) { private fun InsEXT(i: Instruction) {
when(i.type!!){ when(i.type!!){
VmDataType.BYTE -> registers.setUW(i.reg1!!, registers.getUB(i.reg1).toUShort()) VmDataType.BYTE -> registers.setUW(i.reg1!!, registers.getUB(i.reg1).toUShort())
VmDataType.WORD -> TODO("ext.w requires 32 bits registers") VmDataType.WORD -> TODO("ext.w not yet supported, requires 32 bits registers")
} }
pc++ pc++
} }
@ -632,7 +632,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
private fun InsEXTS(i: Instruction) { private fun InsEXTS(i: Instruction) {
when(i.type!!){ when(i.type!!){
VmDataType.BYTE -> registers.setSW(i.reg1!!, registers.getSB(i.reg1).toShort()) VmDataType.BYTE -> registers.setSW(i.reg1!!, registers.getSB(i.reg1).toShort())
VmDataType.WORD -> TODO("ext.w requires 32 bits registers") VmDataType.WORD -> TODO("exts.w not yet supported, requires 32 bits registers")
} }
pc++ pc++
} }
@ -716,7 +716,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
val newValue = value.toUByte()*256u + (value.toInt() ushr 8).toUInt() val newValue = value.toUByte()*256u + (value.toInt() ushr 8).toUInt()
registers.setUW(i.reg1, newValue.toUShort()) registers.setUW(i.reg1, newValue.toUShort())
} }
VmDataType.WORD -> TODO("swap.w requires 32-bits registers") VmDataType.WORD -> TODO("swap.w not yet supported, requires 32-bits registers")
} }
pc++ pc++
} }
@ -728,7 +728,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
val lsb = registers.getUB(i.reg3!!) val lsb = registers.getUB(i.reg3!!)
registers.setUW(i.reg1!!, ((msb.toInt() shl 8) or lsb.toInt()).toUShort()) registers.setUW(i.reg1!!, ((msb.toInt() shl 8) or lsb.toInt()).toUShort())
} }
VmDataType.WORD -> TODO("swap.w requires 32-bits registers") VmDataType.WORD -> TODO("concat.w not yet supported, requires 32-bits registers")
} }
pc++ pc++
} }