mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 01:49:22 +00:00
IR: optimize pointer access
This commit is contained in:
parent
8e00408e3e
commit
3c77f8a020
@ -383,18 +383,47 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
val tr = expressionEval.translateExpression(targetMemory.address)
|
val tr = expressionEval.translateExpression(targetMemory.address)
|
||||||
val addressReg = tr.resultReg
|
val addressReg = tr.resultReg
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZI, targetDt, reg1=addressReg) }
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.STOREZI, targetDt, reg1=addressReg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(targetMemory.address is PtNumber) {
|
val constAddress = targetMemory.address as? PtNumber
|
||||||
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREM, targetDt, reg1=valueRegister, address=(targetMemory.address as PtNumber).number.toInt()) }
|
if(constAddress!=null) {
|
||||||
result += chunk
|
addInstr(result, IRInstruction(Opcode.STOREM, targetDt, reg1=valueRegister, address=constAddress.number.toInt()), null)
|
||||||
} else {
|
return result
|
||||||
val tr = expressionEval.translateExpression(targetMemory.address)
|
|
||||||
val addressReg = tr.resultReg
|
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
|
||||||
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREI, targetDt, reg1=valueRegister, reg2=addressReg) }
|
|
||||||
}
|
}
|
||||||
|
val ptrWithOffset = targetMemory.address as? PtBinaryExpression
|
||||||
|
if(ptrWithOffset!=null && ptrWithOffset.operator=="+" && ptrWithOffset.left is PtIdentifier) {
|
||||||
|
if((ptrWithOffset.right as? PtNumber)?.number?.toInt() in 0..255) {
|
||||||
|
// STOREIX only works with byte index.
|
||||||
|
val ptrName = (ptrWithOffset.left as PtIdentifier).name
|
||||||
|
val offsetReg = codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=offsetReg, immediate = ptrWithOffset.right.asConstInteger())
|
||||||
|
it += IRInstruction(Opcode.STOREIX, IRDataType.BYTE, reg1=valueRegister, reg2=offsetReg, labelSymbol = ptrName)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val offsetTypecast = ptrWithOffset?.right as? PtTypeCast
|
||||||
|
if(ptrWithOffset!=null && ptrWithOffset.operator=="+" && ptrWithOffset.left is PtIdentifier
|
||||||
|
&& (ptrWithOffset.right.type in ByteDatatypes || offsetTypecast?.value?.type in ByteDatatypes)) {
|
||||||
|
// STOREIX only works with byte index.
|
||||||
|
val tr = if(offsetTypecast?.value?.type in ByteDatatypes)
|
||||||
|
expressionEval.translateExpression(offsetTypecast!!.value)
|
||||||
|
else
|
||||||
|
expressionEval.translateExpression(ptrWithOffset.right)
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
val ptrName = (ptrWithOffset.left as PtIdentifier).name
|
||||||
|
addInstr(result, IRInstruction(Opcode.STOREIX, IRDataType.BYTE, reg1=valueRegister, reg2=tr.resultReg, labelSymbol = ptrName), null)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
val tr = expressionEval.translateExpression(targetMemory.address)
|
||||||
|
val addressReg = tr.resultReg
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
addInstr(result, IRInstruction(Opcode.STOREI, targetDt, reg1=valueRegister, reg2=addressReg), null)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
@ -93,21 +93,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
ExpressionCodeResult(result, vmDt, resultRegister, -1)
|
ExpressionCodeResult(result, vmDt, resultRegister, -1)
|
||||||
}
|
}
|
||||||
is PtMemoryByte -> {
|
is PtMemoryByte -> translate(expr)
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
|
||||||
if(expr.address is PtNumber) {
|
|
||||||
val address = (expr.address as PtNumber).number.toInt()
|
|
||||||
val resultRegister = codeGen.registers.nextFree()
|
|
||||||
addInstr(result, IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1=resultRegister, address = address), null)
|
|
||||||
ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
|
||||||
} else {
|
|
||||||
val tr = translateExpression(expr.address)
|
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
|
||||||
val resultReg = codeGen.registers.nextFree()
|
|
||||||
addInstr(result, IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1=resultReg, reg2=tr.resultReg), null)
|
|
||||||
ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is PtTypeCast -> translate(expr)
|
is PtTypeCast -> translate(expr)
|
||||||
is PtPrefix -> translate(expr)
|
is PtPrefix -> translate(expr)
|
||||||
is PtArrayIndexer -> translate(expr)
|
is PtArrayIndexer -> translate(expr)
|
||||||
@ -122,6 +108,49 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun translate(mem: PtMemoryByte): ExpressionCodeResult {
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val resultRegister = codeGen.registers.nextFree()
|
||||||
|
|
||||||
|
val constAddress = mem.address as? PtNumber
|
||||||
|
if(constAddress!=null) {
|
||||||
|
addInstr(result, IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1=resultRegister, address = constAddress.number.toInt()), null)
|
||||||
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val ptrWithOffset = mem.address as? PtBinaryExpression
|
||||||
|
if(ptrWithOffset!=null && ptrWithOffset.operator=="+" && ptrWithOffset.left is PtIdentifier) {
|
||||||
|
if((ptrWithOffset.right as? PtNumber)?.number?.toInt() in 0..255) {
|
||||||
|
// LOADIX only works with byte index.
|
||||||
|
val ptrName = (ptrWithOffset.left as PtIdentifier).name
|
||||||
|
val offsetReg = codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=offsetReg, immediate = ptrWithOffset.right.asConstInteger())
|
||||||
|
it += IRInstruction(Opcode.LOADIX, IRDataType.BYTE, reg1=resultRegister, reg2=offsetReg, labelSymbol = ptrName)
|
||||||
|
}
|
||||||
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val offsetTypecast = ptrWithOffset?.right as? PtTypeCast
|
||||||
|
if(ptrWithOffset!=null && ptrWithOffset.operator=="+" && ptrWithOffset.left is PtIdentifier
|
||||||
|
&& (ptrWithOffset.right.type in ByteDatatypes || offsetTypecast?.value?.type in ByteDatatypes)) {
|
||||||
|
// LOADIX only works with byte index.
|
||||||
|
val tr = if(offsetTypecast?.value?.type in ByteDatatypes)
|
||||||
|
translateExpression(offsetTypecast!!.value)
|
||||||
|
else
|
||||||
|
translateExpression(ptrWithOffset.right)
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
val ptrName = (ptrWithOffset.left as PtIdentifier).name
|
||||||
|
addInstr(result, IRInstruction(Opcode.LOADIX, IRDataType.BYTE, reg1=resultRegister, reg2=tr.resultReg, labelSymbol = ptrName), null)
|
||||||
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val tr = translateExpression(mem.address)
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
addInstr(result, IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1=resultRegister, reg2=tr.resultReg), null)
|
||||||
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||||
|
}
|
||||||
|
|
||||||
private fun translate(check: PtContainmentCheck): ExpressionCodeResult {
|
private fun translate(check: PtContainmentCheck): ExpressionCodeResult {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
when(check.iterable.type) {
|
when(check.iterable.type) {
|
||||||
|
@ -1516,19 +1516,54 @@ class IRCodeGen(
|
|||||||
if(ident!=null) {
|
if(ident!=null) {
|
||||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = ident.name), null)
|
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = ident.name), null)
|
||||||
} else if(memory!=null) {
|
} else if(memory!=null) {
|
||||||
if(memory.address is PtNumber) {
|
val constAddress = memory.address as? PtNumber
|
||||||
val address = (memory.address as PtNumber).number.toInt()
|
if(constAddress!=null) {
|
||||||
addInstr(result, IRInstruction(operationMem, irDt, address = address), null)
|
addInstr(result, IRInstruction(operationMem, irDt, address = constAddress.number.toInt()), null)
|
||||||
} else {
|
return result
|
||||||
val tr = expressionEval.translateExpression(memory.address)
|
}
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
val ptrWithOffset = memory.address as? PtBinaryExpression
|
||||||
result += IRCodeChunk(null, null).also {
|
if(ptrWithOffset!=null && ptrWithOffset.operator=="+" && ptrWithOffset.left is PtIdentifier) {
|
||||||
|
if((ptrWithOffset.right as? PtNumber)?.number?.toInt() in 0..255) {
|
||||||
|
// LOADIX only works with byte index.
|
||||||
|
val ptrName = (ptrWithOffset.left as PtIdentifier).name
|
||||||
|
val offsetReg = registers.nextFree()
|
||||||
val incReg = registers.nextFree()
|
val incReg = registers.nextFree()
|
||||||
it += IRInstruction(Opcode.LOADI, irDt, reg1 = incReg, reg2 = tr.resultReg)
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(operationRegister, irDt, reg1 = incReg)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=offsetReg, immediate = ptrWithOffset.right.asConstInteger())
|
||||||
it += IRInstruction(Opcode.STOREI, irDt, reg1 = incReg, reg2 = tr.resultReg)
|
it += IRInstruction(Opcode.LOADIX, IRDataType.BYTE, reg1=incReg, reg2=offsetReg, labelSymbol = ptrName)
|
||||||
|
it += IRInstruction(operationRegister, irDt, reg1 = incReg)
|
||||||
|
it += IRInstruction(Opcode.STOREIX, IRDataType.BYTE, reg1=incReg, reg2=offsetReg, labelSymbol = ptrName)
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val offsetTypecast = ptrWithOffset?.right as? PtTypeCast
|
||||||
|
if(ptrWithOffset!=null && ptrWithOffset.operator=="+" && ptrWithOffset.left is PtIdentifier
|
||||||
|
&& (ptrWithOffset.right.type in ByteDatatypes || offsetTypecast?.value?.type in ByteDatatypes)) {
|
||||||
|
// LOADIX only works with byte index.
|
||||||
|
val tr = if(offsetTypecast?.value?.type in ByteDatatypes)
|
||||||
|
expressionEval.translateExpression(offsetTypecast!!.value)
|
||||||
|
else
|
||||||
|
expressionEval.translateExpression(ptrWithOffset.right)
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
val ptrName = (ptrWithOffset.left as PtIdentifier).name
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
val incReg = registers.nextFree()
|
||||||
|
it += IRInstruction(Opcode.LOADIX, IRDataType.BYTE, reg1=incReg, reg2=tr.resultReg, labelSymbol = ptrName)
|
||||||
|
it += IRInstruction(operationRegister, irDt, reg1 = incReg)
|
||||||
|
it += IRInstruction(Opcode.STOREIX, IRDataType.BYTE, reg1=incReg, reg2=tr.resultReg, labelSymbol = ptrName)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
val tr = expressionEval.translateExpression(memory.address)
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
val incReg = registers.nextFree()
|
||||||
|
it += IRInstruction(Opcode.LOADI, irDt, reg1 = incReg, reg2 = tr.resultReg)
|
||||||
|
it += IRInstruction(operationRegister, irDt, reg1 = incReg)
|
||||||
|
it += IRInstruction(Opcode.STOREI, irDt, reg1 = incReg, reg2 = tr.resultReg)
|
||||||
|
}
|
||||||
|
return result
|
||||||
} else if (array!=null) {
|
} else if (array!=null) {
|
||||||
val variable = array.variable.name
|
val variable = array.variable.name
|
||||||
val itemsize = program.memsizer.memorySize(array.type)
|
val itemsize = program.memsizer.memorySize(array.type)
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
VM textelite is now a lot larger due to the ptr[i] -> @(ptr+i) rewrite. Fix this.
|
|
||||||
|
|
||||||
(after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type.
|
(after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type.
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -11,9 +11,16 @@ main {
|
|||||||
uword @shared az = $4000
|
uword @shared az = $4000
|
||||||
ubyte @shared value = 22
|
ubyte @shared value = 22
|
||||||
|
|
||||||
cx16.r0H = value*4 + az[value]
|
az[20] = 99
|
||||||
cx16.r0L = az[value] + value*4
|
az[2000] = 99
|
||||||
|
az[value] = 99
|
||||||
|
az[cx16.r0] = 99
|
||||||
|
; cx16.r0L = az[200]
|
||||||
|
; cx16.r1L = az[2000]
|
||||||
|
; cx16.r0L = az[value]
|
||||||
|
; cx16.r0H = value*4 + az[value]
|
||||||
|
; cx16.r0L = az[value] + value*4
|
||||||
|
;
|
||||||
; @($4004) = 99
|
; @($4004) = 99
|
||||||
; az[4]--
|
; az[4]--
|
||||||
; @(az + offset)--
|
; @(az + offset)--
|
||||||
@ -26,15 +33,6 @@ main {
|
|||||||
; cx16.r0L = az[4] + value*5
|
; cx16.r0L = az[4] + value*5
|
||||||
; cx16.r1L = value*5 + az[4]
|
; cx16.r1L = value*5 + az[4]
|
||||||
|
|
||||||
; ubyte @shared idx = 1
|
|
||||||
; txt.print_w(array[idx])
|
|
||||||
; txt.nl()
|
|
||||||
; txt.print_w(-array[idx])
|
|
||||||
; txt.nl()
|
|
||||||
; array[idx] = -array[idx]
|
|
||||||
; txt.print_w(array[idx])
|
|
||||||
; txt.nl()
|
|
||||||
;
|
|
||||||
|
|
||||||
; ubyte @shared xx
|
; ubyte @shared xx
|
||||||
; ubyte[3] ubarr
|
; ubyte[3] ubarr
|
||||||
|
Loading…
Reference in New Issue
Block a user