mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 07:31:48 +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> {
|
||||
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)
|
||||
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> {
|
||||
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)
|
||||
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> {
|
||||
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)
|
||||
return Err(NotImplementedError("optimized memory in-place -")) // TODO
|
||||
@ -1247,9 +1315,55 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
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> {
|
||||
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)
|
||||
return Err(NotImplementedError("optimized memory in-place +")) // TODO
|
||||
@ -1293,6 +1407,27 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
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> {
|
||||
if(array!=null) {
|
||||
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> {
|
||||
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)
|
||||
return Err(NotImplementedError("optimized memory in-place xor")) // TODO
|
||||
|
@ -1,9 +1,6 @@
|
||||
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
|
||||
^^ 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
|
||||
---------------------------------------------
|
||||
|
||||
- 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.
|
||||
- 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)?
|
||||
|
@ -37,10 +37,22 @@ main {
|
||||
|
||||
ubyte @shared xx
|
||||
ubyte[3] ubarr
|
||||
uword[3] @split uwarr
|
||||
byte[3] sbarr
|
||||
bool[3] barr
|
||||
float[3] flarr
|
||||
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
|
||||
@ -58,19 +70,19 @@ main {
|
||||
; 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
|
||||
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[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
|
||||
; 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user