mirror of
https://github.com/irmen/prog8.git
synced 2025-09-12 00:24:34 +00:00
IR: fix various register type mismatches
This commit is contained in:
@@ -627,8 +627,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
result += code
|
result += code
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
if(targetArray.splitWords) {
|
if(targetArray.splitWords) {
|
||||||
it += IRInstruction(Opcode.STOREZX, IRDataType.BYTE, reg1 = indexReg, immediate = arrayLength, labelSymbol = variable+"_lsb")
|
it += IRInstruction(Opcode.STOREZX, IRDataType.BYTE, reg1 = indexReg, labelSymbol = variable+"_lsb")
|
||||||
it += IRInstruction(Opcode.STOREZX, IRDataType.BYTE, reg1 = indexReg, immediate = arrayLength, labelSymbol = variable+"_msb")
|
it += IRInstruction(Opcode.STOREZX, IRDataType.BYTE, reg1 = indexReg, labelSymbol = variable+"_msb")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it += IRInstruction(Opcode.STOREZX, targetDt, reg1=indexReg, labelSymbol = variable)
|
it += IRInstruction(Opcode.STOREZX, targetDt, reg1=indexReg, labelSymbol = variable)
|
||||||
@@ -753,7 +753,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
if(itemsize==1 || array.splitWords)
|
if(itemsize==1 || array.splitWords)
|
||||||
return Pair(result, byteIndexTr.resultReg)
|
return Pair(result, byteIndexTr.resultReg)
|
||||||
|
|
||||||
result += codeGen.multiplyByConst(DataType.UWORD, byteIndexTr.resultReg, itemsize)
|
result += codeGen.multiplyByConst(DataType.UBYTE, byteIndexTr.resultReg, itemsize)
|
||||||
return Pair(result, byteIndexTr.resultReg)
|
return Pair(result, byteIndexTr.resultReg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1317,13 +1317,18 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
IRInstruction(opc, vmDt, labelSymbol = symbol)
|
IRInstruction(opc, vmDt, labelSymbol = symbol)
|
||||||
addInstr(result, ins, null)
|
addInstr(result, ins, null)
|
||||||
} else {
|
} else {
|
||||||
val tr = expressionEval.translateExpression(operand)
|
val shiftTr = expressionEval.translateExpression(operand)
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, shiftTr, shiftTr.resultReg, -1)
|
||||||
|
var shiftReg = shiftTr.resultReg
|
||||||
|
if(vmDt==IRDataType.WORD && shiftTr.dt==IRDataType.BYTE) {
|
||||||
|
shiftReg = codeGen.registers.next(IRDataType.WORD)
|
||||||
|
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=shiftReg, reg2=shiftTr.resultReg), null)
|
||||||
|
}
|
||||||
val opc = if (signed) Opcode.ASRNM else Opcode.LSRNM
|
val opc = if (signed) Opcode.ASRNM else Opcode.LSRNM
|
||||||
val ins = if(constAddress!=null)
|
val ins = if(constAddress!=null)
|
||||||
IRInstruction(opc, vmDt, reg1 = tr.resultReg, address = constAddress)
|
IRInstruction(opc, vmDt, reg1 = shiftReg, address = constAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(opc, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
|
IRInstruction(opc, vmDt, reg1 = shiftReg, labelSymbol = symbol)
|
||||||
addInstr(result, ins, null)
|
addInstr(result, ins, null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@@ -1376,12 +1381,17 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
IRInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol)
|
IRInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol)
|
||||||
, null)
|
, null)
|
||||||
} else {
|
} else {
|
||||||
val tr = expressionEval.translateExpression(operand)
|
val shiftTr = expressionEval.translateExpression(operand)
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, shiftTr, shiftTr.resultReg, -1)
|
||||||
|
var shiftReg = shiftTr.resultReg
|
||||||
|
if(vmDt==IRDataType.WORD && shiftTr.dt==IRDataType.BYTE) {
|
||||||
|
shiftReg = codeGen.registers.next(IRDataType.WORD)
|
||||||
|
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=shiftReg, reg2=shiftTr.resultReg), null)
|
||||||
|
}
|
||||||
addInstr(result, if(constAddress!=null)
|
addInstr(result, if(constAddress!=null)
|
||||||
IRInstruction(Opcode.LSLNM, vmDt, reg1=tr.resultReg, address = constAddress)
|
IRInstruction(Opcode.LSLNM, vmDt, reg1=shiftReg, address = constAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.LSLNM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
|
IRInstruction(Opcode.LSLNM, vmDt, reg1=shiftReg, labelSymbol = symbol)
|
||||||
,null)
|
,null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
@@ -409,5 +409,68 @@ main {
|
|||||||
errors.errors.size shouldBe 0
|
errors.errors.size shouldBe 0
|
||||||
errors.warnings.size shouldBe 0
|
errors.warnings.size shouldBe 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("various array indexed assignment scenarios") {
|
||||||
|
val src="""
|
||||||
|
%import floats
|
||||||
|
%import textio
|
||||||
|
%zeropage basicsafe
|
||||||
|
|
||||||
|
main {
|
||||||
|
bool[10] barray
|
||||||
|
uword[10] @nosplit warrayns
|
||||||
|
uword[10] warray
|
||||||
|
float[10] farray
|
||||||
|
|
||||||
|
sub start() {
|
||||||
|
dump()
|
||||||
|
|
||||||
|
; ALL OK
|
||||||
|
barray[2] = true
|
||||||
|
warrayns[2] = 1234
|
||||||
|
warray[2] = 5678
|
||||||
|
farray[2] = 3.1415
|
||||||
|
dump()
|
||||||
|
|
||||||
|
; ALL OK
|
||||||
|
cx16.r0L=2
|
||||||
|
barray[cx16.r0L] = false
|
||||||
|
warrayns[cx16.r0L] = 0
|
||||||
|
warray[cx16.r0L] = 0
|
||||||
|
farray[cx16.r0L] = 0
|
||||||
|
dump()
|
||||||
|
|
||||||
|
; ALL OK
|
||||||
|
cx16.r0L=2
|
||||||
|
barray[cx16.r0L] = true
|
||||||
|
warrayns[cx16.r0L] = 1234
|
||||||
|
warray[cx16.r0L] = 5678
|
||||||
|
farray[cx16.r0L] = 3.1415
|
||||||
|
dump()
|
||||||
|
|
||||||
|
; ALL OK
|
||||||
|
barray[2] = false
|
||||||
|
warrayns[2] = 0
|
||||||
|
warray[2] = 0
|
||||||
|
farray[2] = 0.0
|
||||||
|
dump()
|
||||||
|
|
||||||
|
sub dump() {
|
||||||
|
txt.print_bool(barray[2])
|
||||||
|
txt.spc()
|
||||||
|
txt.print_uw(warrayns[2])
|
||||||
|
txt.spc()
|
||||||
|
txt.print_uw(warray[2])
|
||||||
|
txt.spc()
|
||||||
|
txt.print_f(farray[2])
|
||||||
|
txt.nl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
compileText(C64Target(), optimize=true, src, outputDir) shouldNotBe null
|
||||||
|
compileText(VMTarget(), optimize=true, src, outputDir) shouldNotBe null
|
||||||
|
compileText(C64Target(), optimize=false, src, outputDir) shouldNotBe null
|
||||||
|
compileText(VMTarget(), optimize=false, src, outputDir) shouldNotBe null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -615,4 +615,19 @@ main {
|
|||||||
compileText(C64Target(), false, src, outputDir, writeAssembly = true) shouldNotBe null
|
compileText(C64Target(), false, src, outputDir, writeAssembly = true) shouldNotBe null
|
||||||
compileText(VMTarget(), false, src, outputDir, writeAssembly = true) shouldNotBe null
|
compileText(VMTarget(), false, src, outputDir, writeAssembly = true) shouldNotBe null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("word bitshift with byte operand") {
|
||||||
|
val src="""
|
||||||
|
main{
|
||||||
|
sub start() {
|
||||||
|
cx16.r0 >>= 4
|
||||||
|
cx16.r1 <<= 4
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
|
compileText(C64Target(), false, src, outputDir) shouldNotBe null
|
||||||
|
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
|
||||||
|
compileText(C64Target(), true, src, outputDir) shouldNotBe null
|
||||||
|
compileText(VMTarget(), true, src, outputDir) shouldNotBe null
|
||||||
|
}
|
||||||
})
|
})
|
129
examples/test.p8
129
examples/test.p8
@@ -1,103 +1,56 @@
|
|||||||
%import floats
|
%import floats
|
||||||
%import textio
|
%import textio
|
||||||
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
bool[10] barray
|
||||||
|
uword[10] @nosplit warrayns
|
||||||
|
uword[10] warray
|
||||||
|
float[10] farray
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
simpleptrindexing()
|
dump()
|
||||||
|
|
||||||
struct List {
|
; ALL OK
|
||||||
float f
|
barray[2] = true
|
||||||
^^uword s
|
warrayns[2] = 1234
|
||||||
^^float fp
|
warray[2] = 5678
|
||||||
uword n
|
farray[2] = 3.1415
|
||||||
}
|
dump()
|
||||||
^^List l = List()
|
|
||||||
l.s = 2000
|
|
||||||
l.fp = 3000
|
|
||||||
|
|
||||||
pokew(2000, 1)
|
; ALL OK
|
||||||
pokew(2002, 2)
|
cx16.r0L=2
|
||||||
pokew(2004, 3)
|
barray[cx16.r0L] = false
|
||||||
pokew(2006, 4)
|
warrayns[cx16.r0L] = 0
|
||||||
pokew(2008, 5)
|
warray[cx16.r0L] = 0
|
||||||
pokef(3000, 1.111)
|
farray[cx16.r0L] = 0
|
||||||
pokef(3008, 2.222)
|
dump()
|
||||||
pokef(3016, 3.333)
|
|
||||||
pokef(3024, 4.444)
|
|
||||||
pokef(3032, 5.555)
|
|
||||||
|
|
||||||
cx16.r9L = 2
|
; ALL OK
|
||||||
|
cx16.r0L=2
|
||||||
|
barray[cx16.r0L] = true
|
||||||
|
warrayns[cx16.r0L] = 1234
|
||||||
|
warray[cx16.r0L] = 5678
|
||||||
|
farray[cx16.r0L] = 3.1415
|
||||||
|
dump()
|
||||||
|
|
||||||
lvref1()
|
; ALL OK
|
||||||
lvref2()
|
barray[2] = false
|
||||||
lvref1f()
|
warrayns[2] = 0
|
||||||
lvref2f()
|
warray[2] = 0
|
||||||
|
farray[2] = 0.0
|
||||||
|
dump()
|
||||||
|
|
||||||
ref1()
|
sub dump() {
|
||||||
ref2()
|
txt.print_bool(barray[2])
|
||||||
ref1f()
|
txt.spc()
|
||||||
ref2f()
|
txt.print_uw(warrayns[2])
|
||||||
|
txt.spc()
|
||||||
sub lvref1() {
|
txt.print_uw(warray[2])
|
||||||
l.s[2] = 3333
|
txt.spc()
|
||||||
}
|
txt.print_f(farray[2])
|
||||||
sub lvref2() {
|
|
||||||
l.s[cx16.r9L+1] = 4444
|
|
||||||
}
|
|
||||||
sub lvref1f() {
|
|
||||||
l.fp[2] = 3333.3
|
|
||||||
}
|
|
||||||
sub lvref2f() {
|
|
||||||
l.fp[cx16.r9L+1] = 4444.4
|
|
||||||
}
|
|
||||||
|
|
||||||
sub ref1() {
|
|
||||||
cx16.r0 = l.s[2]
|
|
||||||
txt.print_uw(l.s[2])
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ref2() {
|
|
||||||
cx16.r1 = l.s[cx16.r9L+1]
|
|
||||||
txt.print_uw(l.s[cx16.r9L+1])
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ref1f() {
|
|
||||||
txt.print_f(l.fp[2])
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ref2f() {
|
|
||||||
txt.print_f(l.fp[cx16.r9L+1])
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub simpleptrindexing() {
|
|
||||||
^^float flptr = 2000
|
|
||||||
^^bool bptr = 3000
|
|
||||||
|
|
||||||
|
|
||||||
; flptr[0] = 0.0
|
|
||||||
; flptr[1] = 1.1
|
|
||||||
cx16.r9L = 2
|
|
||||||
flptr[cx16.r9L] = 2.2
|
|
||||||
bptr[cx16.r9L] = true
|
|
||||||
|
|
||||||
; txt.print_f(flptr[0])
|
|
||||||
; txt.nl()
|
|
||||||
; txt.print_f(flptr[1])
|
|
||||||
; txt.nl()
|
|
||||||
txt.print_f(peekf(2000+8*2))
|
|
||||||
txt.nl()
|
|
||||||
txt.print_f(flptr[2])
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
pokef(2000+8*2, 9.9999)
|
|
||||||
txt.print_f(peekf(2000+8*2))
|
|
||||||
txt.nl()
|
|
||||||
txt.print_f(flptr[2])
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1019,8 +1019,15 @@ data class IRInstruction(
|
|||||||
|
|
||||||
private fun determineReg1Type(): IRDataType? {
|
private fun determineReg1Type(): IRDataType? {
|
||||||
if(type==IRDataType.FLOAT) {
|
if(type==IRDataType.FLOAT) {
|
||||||
// some float instructions have an integer register as well.
|
// some float instructions have an integer (byte or word) register as well in reg1
|
||||||
return if(opcode in arrayOf(Opcode.FFROMUB, Opcode.FFROMSB, Opcode.FTOUB, Opcode.FTOSB, Opcode.FCOMP, Opcode.LOADIX, Opcode.LOADX, Opcode.STOREIX, Opcode.STOREX, Opcode.STOREZX))
|
return if(opcode in arrayOf(Opcode.FFROMUB, Opcode.FFROMSB, Opcode.FTOUB, Opcode.FTOSB, Opcode.FCOMP, Opcode.LOADIX, Opcode.LOADX, Opcode.STOREX, Opcode.STOREIX, Opcode.STOREZX))
|
||||||
|
IRDataType.BYTE
|
||||||
|
else
|
||||||
|
IRDataType.WORD
|
||||||
|
}
|
||||||
|
if(type==IRDataType.WORD) {
|
||||||
|
// some word instructions have byte reg1
|
||||||
|
return if(opcode in arrayOf(Opcode.STOREZX))
|
||||||
IRDataType.BYTE
|
IRDataType.BYTE
|
||||||
else
|
else
|
||||||
IRDataType.WORD
|
IRDataType.WORD
|
||||||
|
Reference in New Issue
Block a user