make address-of dereference work

This commit is contained in:
Irmen de Jong
2025-04-26 17:35:04 +02:00
parent 5e2d0d0dfc
commit b920d553a0
28 changed files with 188 additions and 122 deletions

View File

@@ -511,7 +511,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
else if(targetPointerDeref!=null) {
val pointerTr = expressionEval.translateExpression(targetPointerDeref.start)
result += pointerTr.chunks
result += expressionEval.traverseDerefChain(targetPointerDeref, pointerTr.resultReg)
result += expressionEval.traverseDerefChainToCalculateFinalAddress(targetPointerDeref, pointerTr.resultReg)
val instr = when {
targetPointerDeref.type.isByteOrBool -> {
@@ -977,37 +977,33 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
val result = mutableListOf<IRCodeChunkBase>()
if(vmDt==IRDataType.FLOAT) {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(constAddress!=null)
IRInstruction(Opcode.INCM, vmDt, address = constAddress)
else
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
, null)
addInstr(result, if (constAddress != null)
IRInstruction(Opcode.INCM, vmDt, address = constAddress)
else
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol) , null)
}
else {
val tr = expressionEval.translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, if(constAddress!=null)
IRInstruction(Opcode.ADDM, vmDt, fpReg1=tr.resultFpReg, address = constAddress)
else
IRInstruction(Opcode.ADDM, vmDt, fpReg1=tr.resultFpReg, labelSymbol = symbol)
, null)
addInstr(result, if (constAddress != null)
IRInstruction(Opcode.ADDM, vmDt, fpReg1 = tr.resultFpReg, address = constAddress)
else
IRInstruction(Opcode.ADDM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol) , null)
}
} else {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(constAddress!=null)
IRInstruction(Opcode.INCM, vmDt, address = constAddress)
else
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
, null)
addInstr(result, if (constAddress != null)
IRInstruction(Opcode.INCM, vmDt, address = constAddress)
else
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol) , null)
}
else {
val tr = expressionEval.translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(constAddress!=null)
IRInstruction(Opcode.ADDM, vmDt, reg1=tr.resultReg, address = constAddress)
else
IRInstruction(Opcode.ADDM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
addInstr(result, if (constAddress != null)
IRInstruction(Opcode.ADDM, vmDt, reg1 = tr.resultReg, address = constAddress)
else
IRInstruction(Opcode.ADDM, vmDt, reg1 = tr.resultReg, labelSymbol = symbol) , null)
}
}
return result

View File

@@ -101,7 +101,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val result = mutableListOf<IRCodeChunkBase>()
val tr = translateExpression(deref.start)
result += tr.chunks
result += traverseDerefChain(deref, tr.resultReg)
result += traverseDerefChainToCalculateFinalAddress(deref, tr.resultReg)
when {
deref.type.isByteOrBool -> {
val resultReg = codeGen.registers.next(IRDataType.BYTE)
@@ -199,8 +199,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
fun loadAddressOfArrayLabel(reg: Int) {
if (expr.isMsbForSplitArray) {
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = reg, labelSymbol = identifier.name + "_msb"), null)
} else if (identifier.type.isSplitWordArray) {
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = reg, labelSymbol = identifier!!.name + "_msb"), null)
} else if (identifier!!.type.isSplitWordArray) {
// the _lsb split array comes first in memory
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = reg, labelSymbol = identifier.name + "_lsb"), null)
} else
@@ -213,25 +213,35 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val indexTr = translateExpression(expr.arrayIndexExpr!!)
addToResult(result, indexTr, indexTr.resultReg, -1)
val indexWordReg = codeGen.registers.next(IRDataType.WORD)
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=indexWordReg, reg2=indexTr.resultReg), null)
if(identifier.type.isUnsignedWord) {
addInstr(
result,
IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1 = indexWordReg, reg2 = indexTr.resultReg),
null
)
if (identifier!!.type.isUnsignedWord) {
require(!expr.isMsbForSplitArray)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, labelSymbol = identifier.name)
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=resultRegister, reg2=indexWordReg)
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1 = resultRegister, reg2 = indexWordReg)
}
} else {
val eltSize = codeGen.program.memsizer.memorySize(identifier.type, 1)
result += IRCodeChunk(null, null).also {
loadAddressOfArrayLabel(resultRegister)
if(eltSize>1 && !identifier.type.isSplitWordArray) {
it += IRInstruction(Opcode.MUL, IRDataType.WORD, reg1=indexWordReg, immediate = eltSize)
if (eltSize > 1 && !identifier.type.isSplitWordArray) {
it += IRInstruction(Opcode.MUL, IRDataType.WORD, reg1 = indexWordReg, immediate = eltSize)
}
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=resultRegister, reg2=indexWordReg)
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1 = resultRegister, reg2 = indexWordReg)
}
}
} else {
} else if(expr.identifier!=null ) {
loadAddressOfArrayLabel(resultRegister)
} else {
require(vmDt==IRDataType.WORD)
val pointerTr = translateExpression(expr.dereference!!.start)
result += pointerTr.chunks
result += traverseDerefChainToCalculateFinalAddress(expr.dereference!!, pointerTr.resultReg)
addInstr(result, IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1 = resultRegister, reg2 = pointerTr.resultReg), null)
}
return ExpressionCodeResult(result, vmDt, resultRegister, -1)
}
@@ -1473,7 +1483,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
}
}
internal fun traverseDerefChain(targetPointerDeref: PtPointerDeref, pointerReg: Int): IRCodeChunks {
internal fun traverseDerefChainToCalculateFinalAddress(targetPointerDeref: PtPointerDeref, pointerReg: Int): IRCodeChunks {
val result = mutableListOf<IRCodeChunkBase>()
var struct: StStruct? = null
if(targetPointerDeref.start.type.subIdentifier!=null)