IR: fix & of array-element

This commit is contained in:
Irmen de Jong 2024-02-08 02:22:37 +01:00
parent 9d6d98930b
commit 6a48de9a9f
4 changed files with 52 additions and 37 deletions

View File

@ -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)
} }

View File

@ -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()

View File

@ -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.

View File

@ -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()
} }
} }