mirror of
https://github.com/irmen/prog8.git
synced 2025-02-13 18:31:04 +00:00
IR: implemented << and >> for split word arrays
This commit is contained in:
parent
5d33c93af9
commit
b7f47d354f
@ -513,10 +513,10 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val valueRegLsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
val valueRegMsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
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)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=valueRegLsb, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||
it += IRInstruction(Opcode.ANDM, IRDataType.BYTE, reg1=valueRegLsb, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||
it += IRInstruction(Opcode.ANDM, IRDataType.BYTE, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.next(vmDt)
|
||||
@ -527,7 +527,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("inplace word array &")
|
||||
return null // TODO("optimized inplace word array &")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place &")
|
||||
@ -550,15 +550,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
val valueRegMsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
require(vmDt==IRDataType.BYTE) { "ehh do we need a word or a byte type here?"}
|
||||
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)
|
||||
}
|
||||
throw AssemblyError("logical and on (split) word array should not happen")
|
||||
} else {
|
||||
val valueReg = codeGen.registers.next(vmDt)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
@ -568,7 +560,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("inplace word array and")
|
||||
return null // TODO("optimized inplace word array and")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place and")
|
||||
@ -613,12 +605,11 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
val valueRegMsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
require(vmDt==IRDataType.BYTE) { "ehh do we need a word or a byte type here?"}
|
||||
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)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=valueRegLsb, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||
it += IRInstruction(Opcode.ORM, IRDataType.BYTE, reg1=valueRegLsb, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||
it += IRInstruction(Opcode.ORM, IRDataType.BYTE, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.next(vmDt)
|
||||
@ -629,7 +620,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("inplace word array |")
|
||||
return null // TODO("optimized inplace word array |")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place |")
|
||||
@ -652,15 +643,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
val valueRegMsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
require(vmDt==IRDataType.BYTE) { "ehh do we need a word or a byte type here?"}
|
||||
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)
|
||||
}
|
||||
throw AssemblyError("logical or on (split) word array should not happen")
|
||||
} else {
|
||||
val valueReg = codeGen.registers.next(vmDt)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
@ -670,7 +653,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("inplace word array or")
|
||||
return null // TODO("optimized inplace word array or")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place or"")
|
||||
@ -779,7 +762,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("inplace array * non-const")
|
||||
return null // TODO("optimized inplace array * non-const")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place *"")
|
||||
@ -837,7 +820,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("inplace array -")
|
||||
return null // TODO("optimized inplace array -")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place -"")
|
||||
@ -930,7 +913,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("inplace array +")
|
||||
return null // TODO("optimized inplace array +")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place +"")
|
||||
@ -997,11 +980,35 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
|
||||
private fun operatorShiftRightInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression, signed: Boolean): IRCodeChunks? {
|
||||
if(array!=null) {
|
||||
if(array.splitWords)
|
||||
return null // TODO("optimized >> in split word array")
|
||||
else {
|
||||
return null // TODO("optimized >> in array")
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val constIndex = array.index.asConstInteger()
|
||||
val constValue = operand.asConstInteger()
|
||||
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(array.splitWords) {
|
||||
repeat(constValue) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LSRM, IRDataType.BYTE, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
it += IRInstruction(Opcode.ROXRM, IRDataType.BYTE, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constValue==1) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LSRM, vmDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.next(IRDataType.BYTE)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=valueReg, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LSRNM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("optimized >> in array")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place >>"")
|
||||
@ -1029,11 +1036,35 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
|
||||
private fun operatorShiftLeftInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks? {
|
||||
if(array!=null) {
|
||||
if(array.splitWords)
|
||||
return null // TODO("optimized << in split word array")
|
||||
else {
|
||||
return null // TODO("optimized << in array")
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val constIndex = array.index.asConstInteger()
|
||||
val constValue = operand.asConstInteger()
|
||||
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(array.splitWords) {
|
||||
repeat(constValue) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LSLM, IRDataType.BYTE, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||
it += IRInstruction(Opcode.ROXLM, IRDataType.BYTE, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constValue==1) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LSLM, vmDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.next(IRDataType.BYTE)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=valueReg, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LSLNM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("optimized << in array")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place <<"")
|
||||
@ -1067,12 +1098,11 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
val valueRegMsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
require(vmDt==IRDataType.BYTE) { "ehh do we need a word or a byte type here?"}
|
||||
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)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=valueRegLsb, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||
it += IRInstruction(Opcode.XORM, IRDataType.BYTE, reg1=valueRegLsb, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||
it += IRInstruction(Opcode.XORM, IRDataType.BYTE, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.next(vmDt)
|
||||
@ -1083,7 +1113,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
return result
|
||||
}
|
||||
return null // TODO("inplace word array xor")
|
||||
return null // TODO("optimized inplace word array xor")
|
||||
}
|
||||
if(constAddress==null && memory!=null)
|
||||
return null // TODO("optimized memory in-place xor"")
|
||||
|
@ -1,9 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- IR: implement "optimized << in array" / "optimized >> in array"
|
||||
- IR: implement "optimized << in split word array" / "optimized >> in split word array"
|
||||
|
||||
- add paypal donation button as well?
|
||||
- announce prog8 on the 6502.org site?
|
||||
|
||||
@ -51,6 +48,7 @@ IR/VM
|
||||
- getting it in shape for code generation...: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
|
||||
- add BZ and BNZ instructions? To replace CMPI #0 + Branch?
|
||||
- implement fast code paths for TODO("inplace split....
|
||||
- implement more TODOs in AssignmentGen
|
||||
- sometimes source lines end up missing in the output p8ir, for example the first assignment is gone in:
|
||||
sub start() {
|
||||
cx16.r0L = cx16.r1 as ubyte
|
||||
|
138
examples/test.p8
138
examples/test.p8
@ -4,72 +4,102 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
uword wv = %01000010_01000010
|
||||
|
||||
; expected: $8484 $4242
|
||||
sys.set_carry()
|
||||
rol(wv)
|
||||
txt.print_uwhex(wv, true)
|
||||
sys.set_carry()
|
||||
ror(wv)
|
||||
txt.print_uwhex(wv, true)
|
||||
txt.nl()
|
||||
|
||||
wv = %01000010_01000010
|
||||
sys.set_carry()
|
||||
rol2(wv)
|
||||
txt.print_uwhex(wv, true)
|
||||
sys.set_carry()
|
||||
ror2(wv)
|
||||
txt.print_uwhex(wv, true)
|
||||
txt.nl()
|
||||
|
||||
uword[] @nosplit arr = [ %01000010_01000010 , %01000010_01000010, %01000010_01000010 ]
|
||||
uword[] @split arrsplit = [ %01000010_01000010 , %01000010_01000010, %01000010_01000010 ]
|
||||
|
||||
sys.set_carry()
|
||||
rol(arr[2])
|
||||
txt.print_uwhex(arr[2], true)
|
||||
sys.set_carry()
|
||||
ror(arr[2])
|
||||
txt.print_uwhex(arr[2], true)
|
||||
txt.nl()
|
||||
sys.set_carry()
|
||||
rol2(arr[1])
|
||||
txt.print_uwhex(arr[1], true)
|
||||
sys.set_carry()
|
||||
ror2(arr[1])
|
||||
txt.print_uwhex(arr[1], true)
|
||||
ubyte[] arrb = [ %01000010 , %01000010, %01000010 ]
|
||||
|
||||
; expected $09
|
||||
arrb[2] = $12
|
||||
arrb[2] >>= 1
|
||||
txt.print_ubhex(arrb[2], true)
|
||||
txt.nl()
|
||||
|
||||
sys.set_carry()
|
||||
rol(arrsplit[2])
|
||||
txt.print_uwhex(arrsplit[2], true)
|
||||
sys.set_carry()
|
||||
ror(arrsplit[2])
|
||||
txt.print_uwhex(arrsplit[2], true)
|
||||
txt.nl()
|
||||
sys.set_carry()
|
||||
rol2(arrsplit[1])
|
||||
txt.print_uwhex(arrsplit[1], true)
|
||||
sys.set_carry()
|
||||
ror2(arrsplit[1])
|
||||
txt.print_uwhex(arrsplit[1], true)
|
||||
txt.nl()
|
||||
|
||||
|
||||
; expected $2468 $1234
|
||||
; expected $091a
|
||||
arr[2] = $1234
|
||||
arr[2] <<= 1
|
||||
txt.print_uwhex(arr[2], true)
|
||||
arr[2] >>= 1
|
||||
txt.print_uwhex(arr[2], true)
|
||||
txt.nl()
|
||||
|
||||
; expected $02
|
||||
arrb[2] = $12
|
||||
arrb[2] >>= 3
|
||||
txt.print_ubhex(arrb[2], true)
|
||||
txt.nl()
|
||||
|
||||
; expected $0246
|
||||
arr[2] = $1234
|
||||
arr[2] >>= 3
|
||||
txt.print_uwhex(arr[2], true)
|
||||
txt.nl()
|
||||
|
||||
; arr[2] >>= 1
|
||||
; txt.print_uwhex(arr[2], true)
|
||||
; txt.nl()
|
||||
|
||||
; expected $091a
|
||||
arrsplit[2] = $1234
|
||||
arrsplit[2] <<= 1
|
||||
txt.print_uwhex(arrsplit[2], true)
|
||||
arrsplit[2] >>= 1
|
||||
txt.print_uwhex(arrsplit[2], true)
|
||||
txt.nl()
|
||||
; expected $0246
|
||||
arrsplit[2] = $1234
|
||||
arrsplit[2] >>= 3
|
||||
txt.print_uwhex(arrsplit[2], true)
|
||||
txt.nl()
|
||||
|
||||
; arrsplit[2] >>= 1
|
||||
; txt.print_uwhex(arrsplit[2], true)
|
||||
; txt.nl()
|
||||
|
||||
; uword wv = %01000010_01000010
|
||||
;
|
||||
; ; expected: $8484 $4242
|
||||
; sys.set_carry()
|
||||
; rol(wv)
|
||||
; txt.print_uwhex(wv, true)
|
||||
; sys.set_carry()
|
||||
; ror(wv)
|
||||
; txt.print_uwhex(wv, true)
|
||||
; txt.nl()
|
||||
;
|
||||
; wv = %01000010_01000010
|
||||
; sys.set_carry()
|
||||
; rol2(wv)
|
||||
; txt.print_uwhex(wv, true)
|
||||
; sys.set_carry()
|
||||
; ror2(wv)
|
||||
; txt.print_uwhex(wv, true)
|
||||
; txt.nl()
|
||||
;
|
||||
; sys.set_carry()
|
||||
; rol(arr[2])
|
||||
; txt.print_uwhex(arr[2], true)
|
||||
; sys.set_carry()
|
||||
; ror(arr[2])
|
||||
; txt.print_uwhex(arr[2], true)
|
||||
; txt.nl()
|
||||
; sys.set_carry()
|
||||
; rol2(arr[1])
|
||||
; txt.print_uwhex(arr[1], true)
|
||||
; sys.set_carry()
|
||||
; ror2(arr[1])
|
||||
; txt.print_uwhex(arr[1], true)
|
||||
; txt.nl()
|
||||
;
|
||||
; sys.set_carry()
|
||||
; rol(arrsplit[2])
|
||||
; txt.print_uwhex(arrsplit[2], true)
|
||||
; sys.set_carry()
|
||||
; ror(arrsplit[2])
|
||||
; txt.print_uwhex(arrsplit[2], true)
|
||||
; txt.nl()
|
||||
; sys.set_carry()
|
||||
; rol2(arrsplit[1])
|
||||
; txt.print_uwhex(arrsplit[1], true)
|
||||
; sys.set_carry()
|
||||
; ror2(arrsplit[1])
|
||||
; txt.print_uwhex(arrsplit[1], true)
|
||||
; txt.nl()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user