mirror of
https://github.com/irmen/prog8.git
synced 2025-02-19 11:31:07 +00:00
IR: working on inplace +/-
This commit is contained in:
parent
9553248ed6
commit
e0055bc431
@ -1001,7 +1001,30 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
|
|
||||||
internal fun operatorAndInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
internal fun operatorAndInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
||||||
if(array!=null) {
|
if(array!=null) {
|
||||||
TODO("&")
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val constIndex = array.index.asConstInteger()
|
||||||
|
val constValue = operand.asConstInteger()
|
||||||
|
val eltSize = codeGen.program.memsizer.memorySize(array.type)
|
||||||
|
if(constIndex!=null && constValue!=null) {
|
||||||
|
if(array.splitWords) {
|
||||||
|
val valueRegLsb = codeGen.registers.nextFree()
|
||||||
|
val valueRegMsb = codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegLsb, immediate=constValue and 255)
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||||
|
it += IRInstruction(Opcode.ANDM, vmDt, reg1=valueRegLsb, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||||
|
it += IRInstruction(Opcode.ANDM, vmDt, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val valueReg = codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate=constValue)
|
||||||
|
it += IRInstruction(Opcode.ANDM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(result)
|
||||||
|
}
|
||||||
|
return Err(NotImplementedError("inplace word array &")) // TODO?
|
||||||
}
|
}
|
||||||
if(constAddress==null && memory!=null)
|
if(constAddress==null && memory!=null)
|
||||||
return Err(NotImplementedError("optimized memory in-place &")) // TODO
|
return Err(NotImplementedError("optimized memory in-place &")) // TODO
|
||||||
@ -1055,7 +1078,30 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
|
|
||||||
internal fun operatorOrInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
internal fun operatorOrInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
||||||
if(array!=null) {
|
if(array!=null) {
|
||||||
TODO("|")
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val constIndex = array.index.asConstInteger()
|
||||||
|
val constValue = operand.asConstInteger()
|
||||||
|
val eltSize = codeGen.program.memsizer.memorySize(array.type)
|
||||||
|
if(constIndex!=null && constValue!=null) {
|
||||||
|
if(array.splitWords) {
|
||||||
|
val valueRegLsb = codeGen.registers.nextFree()
|
||||||
|
val valueRegMsb = codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegLsb, immediate=constValue and 255)
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||||
|
it += IRInstruction(Opcode.ORM, vmDt, reg1=valueRegLsb, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||||
|
it += IRInstruction(Opcode.ORM, vmDt, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val valueReg = codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate=constValue)
|
||||||
|
it += IRInstruction(Opcode.ORM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(result)
|
||||||
|
}
|
||||||
|
return Err(NotImplementedError("inplace word array |")) // TODO?
|
||||||
}
|
}
|
||||||
if(constAddress==null && memory!=null)
|
if(constAddress==null && memory!=null)
|
||||||
return Err(NotImplementedError("optimized memory in-place |")) // TODO
|
return Err(NotImplementedError("optimized memory in-place |")) // TODO
|
||||||
@ -1203,7 +1249,29 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
|
|
||||||
internal fun operatorMinusInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
internal fun operatorMinusInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
||||||
if(array!=null) {
|
if(array!=null) {
|
||||||
TODO("-")
|
val eltSize = codeGen.program.memsizer.memorySize(array.type)
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
if(array.splitWords)
|
||||||
|
return operatorMinusInplaceSplitArray(array, operand)
|
||||||
|
if(array.usesPointerVariable) {
|
||||||
|
TODO("inplace - for pointer variable")
|
||||||
|
}
|
||||||
|
val vmDt = irType(array.type)
|
||||||
|
val constIndex = array.index.asConstInteger()
|
||||||
|
val constValue = operand.asConstInteger()
|
||||||
|
if(constIndex!=null && constValue!=null) {
|
||||||
|
if(constValue==1) {
|
||||||
|
addInstr(result, IRInstruction(Opcode.DECM, vmDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
||||||
|
} else {
|
||||||
|
val valueReg=codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate = constValue)
|
||||||
|
it += IRInstruction(Opcode.SUBM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(result)
|
||||||
|
}
|
||||||
|
return Err(NotImplementedError("inplace array -")) // TODO?
|
||||||
}
|
}
|
||||||
if(constAddress==null && memory!=null)
|
if(constAddress==null && memory!=null)
|
||||||
return Err(NotImplementedError("optimized memory in-place -")) // TODO
|
return Err(NotImplementedError("optimized memory in-place -")) // TODO
|
||||||
@ -1247,9 +1315,55 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
return Ok(result)
|
return Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun operatorMinusInplaceSplitArray(array: PtArrayIndexer, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val constIndex = array.index.asConstInteger()
|
||||||
|
val constValue = operand.asConstInteger()
|
||||||
|
if(constIndex!=null) {
|
||||||
|
val skip = codeGen.createLabelName()
|
||||||
|
if(constValue==1) {
|
||||||
|
val lsbReg = codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lsbReg, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||||
|
it += IRInstruction(Opcode.BSTNE, labelSymbol = skip)
|
||||||
|
it += IRInstruction(Opcode.DECM, IRDataType.BYTE, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||||
|
}
|
||||||
|
result += IRCodeChunk(skip, null).also {
|
||||||
|
it += IRInstruction(Opcode.DECM, IRDataType.BYTE, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||||
|
}
|
||||||
|
return Ok(result)
|
||||||
|
} else {
|
||||||
|
return Err(NotImplementedError("inplace split word array +")) // TODO?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Err(NotImplementedError("inplace split word array +")) // TODO?
|
||||||
|
}
|
||||||
|
|
||||||
internal fun operatorPlusInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
internal fun operatorPlusInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
||||||
if(array!=null) {
|
if(array!=null) {
|
||||||
TODO("+")
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
if(array.splitWords)
|
||||||
|
return operatorPlusInplaceSplitArray(array, operand)
|
||||||
|
if(array.usesPointerVariable) {
|
||||||
|
TODO("inplace + for pointer variable")
|
||||||
|
}
|
||||||
|
val eltSize = codeGen.program.memsizer.memorySize(array.type)
|
||||||
|
val elementDt = irType(array.type)
|
||||||
|
val constIndex = array.index.asConstInteger()
|
||||||
|
val constValue = operand.asConstInteger()
|
||||||
|
if(constIndex!=null && constValue!=null) {
|
||||||
|
if(constValue==1) {
|
||||||
|
addInstr(result, IRInstruction(Opcode.INCM, elementDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
||||||
|
} else {
|
||||||
|
val valueReg=codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, elementDt, reg1=valueReg, immediate = constValue)
|
||||||
|
it += IRInstruction(Opcode.ADDM, elementDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(result)
|
||||||
|
}
|
||||||
|
return Err(NotImplementedError("inplace array +")) // TODO?
|
||||||
}
|
}
|
||||||
if(constAddress==null && memory!=null)
|
if(constAddress==null && memory!=null)
|
||||||
return Err(NotImplementedError("optimized memory in-place +")) // TODO
|
return Err(NotImplementedError("optimized memory in-place +")) // TODO
|
||||||
@ -1293,6 +1407,27 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
return Ok(result)
|
return Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun operatorPlusInplaceSplitArray(array: PtArrayIndexer, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val constIndex = array.index.asConstInteger()
|
||||||
|
val constValue = operand.asConstInteger()
|
||||||
|
if(constIndex!=null) {
|
||||||
|
val skip = codeGen.createLabelName()
|
||||||
|
if(constValue==1) {
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.INCM, IRDataType.BYTE, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||||
|
it += IRInstruction(Opcode.BSTNE, labelSymbol = skip)
|
||||||
|
it += IRInstruction(Opcode.INCM, IRDataType.BYTE, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||||
|
}
|
||||||
|
result += IRCodeChunk(skip, null)
|
||||||
|
return Ok(result)
|
||||||
|
} else {
|
||||||
|
return Err(NotImplementedError("inplace split word array +")) // TODO?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Err(NotImplementedError("inplace split word array +")) // TODO?
|
||||||
|
}
|
||||||
|
|
||||||
internal fun operatorShiftRightInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression, signed: Boolean): Result<IRCodeChunks, NotImplementedError> {
|
internal fun operatorShiftRightInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression, signed: Boolean): Result<IRCodeChunks, NotImplementedError> {
|
||||||
if(array!=null) {
|
if(array!=null) {
|
||||||
TODO(">>")
|
TODO(">>")
|
||||||
@ -1349,7 +1484,30 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
|
|
||||||
internal fun operatorXorInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
internal fun operatorXorInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): Result<IRCodeChunks, NotImplementedError> {
|
||||||
if(array!=null) {
|
if(array!=null) {
|
||||||
TODO("xor")
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val constIndex = array.index.asConstInteger()
|
||||||
|
val constValue = operand.asConstInteger()
|
||||||
|
val eltSize = codeGen.program.memsizer.memorySize(array.type)
|
||||||
|
if(constIndex!=null && constValue!=null) {
|
||||||
|
if(array.splitWords) {
|
||||||
|
val valueRegLsb = codeGen.registers.nextFree()
|
||||||
|
val valueRegMsb = codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegLsb, immediate=constValue and 255)
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||||
|
it += IRInstruction(Opcode.XORM, vmDt, reg1=valueRegLsb, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||||
|
it += IRInstruction(Opcode.XORM, vmDt, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val valueReg = codeGen.registers.nextFree()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate=constValue)
|
||||||
|
it += IRInstruction(Opcode.XORM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(result)
|
||||||
|
}
|
||||||
|
return Err(NotImplementedError("inplace word array ^")) // TODO?
|
||||||
}
|
}
|
||||||
if(constAddress==null && memory!=null)
|
if(constAddress==null && memory!=null)
|
||||||
return Err(NotImplementedError("optimized memory in-place xor")) // TODO
|
return Err(NotImplementedError("optimized memory in-place xor")) // TODO
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
IR ExpressionGen: implement all in-place operators TODOs. Starting with operatorPlusInplace
|
|
||||||
|
|
||||||
|
|
||||||
maze: if cell & UP!=0 and @(celladdr(cx,cy-1)) & (WALKED|BACKTRACKED) ==0
|
maze: if cell & UP!=0 and @(celladdr(cx,cy-1)) & (WALKED|BACKTRACKED) ==0
|
||||||
^^ adding this !=0 caused a weird beq + / lda #1 / + to appear in front of the shortcircuit beq...
|
^^ adding this !=0 caused a weird beq + / lda #1 / + to appear in front of the shortcircuit beq...
|
||||||
|
|
||||||
@ -88,6 +85,7 @@ What if we were to re-introduce Structs in prog8? Some thoughts:
|
|||||||
Other language/syntax features to think about
|
Other language/syntax features to think about
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
|
- remove ++/-- (just use Pythonesque x+=1) OR make ++/-- into a postfix expression (but then we need a prefix variant of them too?) maybe via a new builtin function like postincr__w() etc?
|
||||||
- support for assigning multiple return values from romsub/asmsub to multiple variables.
|
- support for assigning multiple return values from romsub/asmsub to multiple variables.
|
||||||
- add (rom/ram)bank support to romsub. A call will then automatically switch banks, use callfar and something else when in banked ram.
|
- add (rom/ram)bank support to romsub. A call will then automatically switch banks, use callfar and something else when in banked ram.
|
||||||
challenges: how to not make this too X16 specific? How does the compiler know what bank to switch (ram/rom)?
|
challenges: how to not make this too X16 specific? How does the compiler know what bank to switch (ram/rom)?
|
||||||
|
@ -37,10 +37,22 @@ main {
|
|||||||
|
|
||||||
ubyte @shared xx
|
ubyte @shared xx
|
||||||
ubyte[3] ubarr
|
ubyte[3] ubarr
|
||||||
|
uword[3] @split uwarr
|
||||||
byte[3] sbarr
|
byte[3] sbarr
|
||||||
bool[3] barr
|
bool[3] barr
|
||||||
float[3] flarr
|
float[3] flarr
|
||||||
bool @shared bb
|
bool @shared bb
|
||||||
|
uword ptr = &ubarr
|
||||||
|
|
||||||
|
ptr[1]++
|
||||||
|
ptr[1]++
|
||||||
|
ptr[1]--
|
||||||
|
txt.print_ub(ubarr[1])
|
||||||
|
txt.nl()
|
||||||
|
ptr[1]+=4
|
||||||
|
ptr[1]-=3
|
||||||
|
txt.print_ub(ubarr[1])
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
; sbarr[1] = sbarr[1] == 0
|
; sbarr[1] = sbarr[1] == 0
|
||||||
; sbarr[1] = sbarr[1] != 0
|
; sbarr[1] = sbarr[1] != 0
|
||||||
@ -58,19 +70,19 @@ main {
|
|||||||
; sbarr[xx] = sbarr[xx] > 0
|
; sbarr[xx] = sbarr[xx] > 0
|
||||||
; sbarr[xx] = sbarr[xx] >= 0
|
; sbarr[xx] = sbarr[xx] >= 0
|
||||||
|
|
||||||
sbarr[1] = sbarr[1] == 2
|
; sbarr[1] = sbarr[1] == 2
|
||||||
sbarr[1] = sbarr[1] != 2
|
; sbarr[1] = sbarr[1] != 2
|
||||||
sbarr[1] = sbarr[1] < 2
|
; sbarr[1] = sbarr[1] < 2
|
||||||
sbarr[1] = sbarr[1] <= 2
|
; sbarr[1] = sbarr[1] <= 2
|
||||||
sbarr[1] = sbarr[1] > 2
|
; sbarr[1] = sbarr[1] > 2
|
||||||
sbarr[1] = sbarr[1] >= 2
|
; sbarr[1] = sbarr[1] >= 2
|
||||||
xx = 1
|
; xx = 1
|
||||||
sbarr[xx] = sbarr[xx] == 2
|
; sbarr[xx] = sbarr[xx] == 2
|
||||||
sbarr[xx] = sbarr[xx] != 2
|
; sbarr[xx] = sbarr[xx] != 2
|
||||||
sbarr[xx] = sbarr[xx] < 2
|
; sbarr[xx] = sbarr[xx] < 2
|
||||||
sbarr[xx] = sbarr[xx] <= 2
|
; sbarr[xx] = sbarr[xx] <= 2
|
||||||
sbarr[xx] = sbarr[xx] > 2
|
; sbarr[xx] = sbarr[xx] > 2
|
||||||
sbarr[xx] = sbarr[xx] >= 2
|
; sbarr[xx] = sbarr[xx] >= 2
|
||||||
|
|
||||||
; ubarr[1] = ubarr[1] == 2
|
; ubarr[1] = ubarr[1] == 2
|
||||||
; ubarr[1] = ubarr[1] < 2
|
; ubarr[1] = ubarr[1] < 2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user