mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
IR: fix & of array-element
This commit is contained in:
parent
9d6d98930b
commit
6a48de9a9f
@ -154,6 +154,8 @@ private fun PtVariable.prefix(st: SymbolTable): PtVariable {
|
|||||||
else {
|
else {
|
||||||
val newAddr = PtAddressOf(elt.position)
|
val newAddr = PtAddressOf(elt.position)
|
||||||
newAddr.children.add(elt.identifier.prefix(newAddr, st))
|
newAddr.children.add(elt.identifier.prefix(newAddr, st))
|
||||||
|
if(elt.arrayIndexExpr!=null)
|
||||||
|
newAddr.children.add(elt.arrayIndexExpr!!)
|
||||||
newAddr.parent = arrayValue
|
newAddr.parent = arrayValue
|
||||||
newValue.add(newAddr)
|
newValue.add(newAddr)
|
||||||
}
|
}
|
||||||
|
@ -66,33 +66,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
ExpressionCodeResult(code, vmDt, resultRegister, -1)
|
ExpressionCodeResult(code, vmDt, resultRegister, -1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is PtAddressOf -> {
|
is PtAddressOf -> translate(expr)
|
||||||
val vmDt = irType(expr.type)
|
|
||||||
val symbol = expr.identifier.name
|
|
||||||
// note: LOAD <symbol> gets you the address of the symbol, whereas LOADM <symbol> would get you the value stored at that location
|
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
|
||||||
val resultRegister = codeGen.registers.nextFree()
|
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol), null)
|
|
||||||
if(expr.isFromArrayElement) {
|
|
||||||
val indexTr = translateExpression(expr.arrayIndexExpr!!)
|
|
||||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
|
||||||
if(expr.identifier.type in SplitWordArrayTypes) {
|
|
||||||
result += IRCodeChunk(null, null).also {
|
|
||||||
// multiply indexTr resultreg by the eltSize and add this to the resultRegister.
|
|
||||||
it += IRInstruction(Opcode.ADDR, IRDataType.BYTE, reg1=resultRegister, reg2=indexTr.resultReg)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val eltSize = codeGen.program.memsizer.memorySize(expr.identifier.type, 1)
|
|
||||||
result += IRCodeChunk(null, null).also {
|
|
||||||
// multiply indexTr resultreg by the eltSize and add this to the resultRegister.
|
|
||||||
if(eltSize>1)
|
|
||||||
it += IRInstruction(Opcode.MUL, IRDataType.BYTE, reg1=indexTr.resultReg, immediate = eltSize)
|
|
||||||
it += IRInstruction(Opcode.ADDR, IRDataType.BYTE, reg1=resultRegister, reg2=indexTr.resultReg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ExpressionCodeResult(result, vmDt, resultRegister, -1)
|
|
||||||
}
|
|
||||||
is PtMemoryByte -> translate(expr)
|
is PtMemoryByte -> translate(expr)
|
||||||
is PtTypeCast -> translate(expr)
|
is PtTypeCast -> translate(expr)
|
||||||
is PtPrefix -> translate(expr)
|
is PtPrefix -> translate(expr)
|
||||||
@ -108,6 +82,44 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun translate(expr: PtAddressOf): ExpressionCodeResult {
|
||||||
|
val vmDt = irType(expr.type)
|
||||||
|
val symbol = expr.identifier.name
|
||||||
|
// note: LOAD <symbol> gets you the address of the symbol, whereas LOADM <symbol> would get you the value stored at that location
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val resultRegister = codeGen.registers.nextFree()
|
||||||
|
if(expr.isFromArrayElement) {
|
||||||
|
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol), null)
|
||||||
|
val indexTr2 = translateExpression(expr.arrayIndexExpr!!)
|
||||||
|
addToResult(result, indexTr2, indexTr2.resultReg, -1)
|
||||||
|
val indexWordReg = codeGen.registers.nextFree()
|
||||||
|
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=indexWordReg, reg2=indexTr2.resultReg), null)
|
||||||
|
if(expr.identifier.type in SplitWordArrayTypes) {
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=resultRegister, reg2=indexWordReg)
|
||||||
|
}
|
||||||
|
} else if(expr.identifier.type == DataType.UWORD) {
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, labelSymbol = symbol)
|
||||||
|
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=resultRegister, reg2=indexWordReg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val eltSize = codeGen.program.memsizer.memorySize(expr.identifier.type, 1)
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
// multiply indexTr resultreg by the eltSize and add this to the resultRegister.
|
||||||
|
it += IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol)
|
||||||
|
if(eltSize>1) {
|
||||||
|
it += IRInstruction(Opcode.MUL, IRDataType.WORD, reg1=indexWordReg, immediate = eltSize)
|
||||||
|
}
|
||||||
|
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=resultRegister, reg2=indexWordReg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol), null)
|
||||||
|
}
|
||||||
|
return ExpressionCodeResult(result, vmDt, resultRegister, -1)
|
||||||
|
}
|
||||||
|
|
||||||
private fun translate(mem: PtMemoryByte): ExpressionCodeResult {
|
private fun translate(mem: PtMemoryByte): ExpressionCodeResult {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val resultRegister = codeGen.registers.nextFree()
|
val resultRegister = codeGen.registers.nextFree()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
&pointervar[x] isn't the correct value
|
&pointervar[x] isn't the correct value (6502, IR is fixed)
|
||||||
@(s) where s is a str parameter, doesn't work
|
@(s) where s is a str parameter, doesn't work
|
||||||
|
|
||||||
(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.
|
||||||
|
@ -9,22 +9,23 @@ main {
|
|||||||
foo("zzz")
|
foo("zzz")
|
||||||
}
|
}
|
||||||
|
|
||||||
sub foo (str s2) {
|
sub foo (str sarg) {
|
||||||
str s = "irmen"
|
str svar = "irmen"
|
||||||
txt.print_uwhex(s, true)
|
txt.print_uwhex(svar, true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.print_uwhex(&s, true)
|
txt.print_uwhex(&svar, true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.print_uwhex(&s[2], true)
|
txt.print_uwhex(&svar[2], true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.print_uwhex(s2, true)
|
txt.print_uwhex(sarg, true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.print_uwhex(&s2, true)
|
txt.print_uwhex(&sarg, true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.print_uwhex(s2+2, true)
|
txt.print_uwhex(sarg+2, true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.print_uwhex(&s2[2], true) ; TODO should be the same as the previous one!
|
cx16.r0 = &sarg[2]
|
||||||
|
txt.print_uwhex(cx16.r0, true) ; TODO should be the same as the previous one sarg+2 (13)!
|
||||||
txt.nl()
|
txt.nl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user