mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
vm: more optimal code when array index is constant value
This commit is contained in:
parent
2b7c09e6ee
commit
d78bfcc35c
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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":
|
||||||
|
@ -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++
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user