fix struct size truncation to 256 bytes on targets that allow larger structs (m68k)

This commit is contained in:
Irmen de Jong committed 2026-09-24 00:22:23 +02:00
1 parent 2050fcb4ee
commit 976b64185d
11 files changed
+106 -54

No files matched your search

@@ -362,20 +362,20 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
private fun loadfield(
inplaceInstrs: MutableList<IRCodeChunkBase>,
addressReg: Int,
fieldOffset: UByte,
fieldOffset: Int,
targetDt: IRDataType,
oldvalueReg: Int
) {
if (targetDt == IRDataType.FLOAT) {
addInstr(
inplaceInstrs,
IRInstructions.loadMemory(Opcode.LOADI, targetDt, oldvalueReg, IRMemory.indirect(addressReg, fieldOffset.toInt())),
IRInstructions.loadMemory(Opcode.LOADI, targetDt, oldvalueReg, IRMemory.indirect(addressReg, fieldOffset)),
null
)
} else {
addInstr(
inplaceInstrs,
IRInstructions.loadMemory(Opcode.LOADI, targetDt, oldvalueReg, IRMemory.indirect(addressReg, fieldOffset.toInt())),
IRInstructions.loadMemory(Opcode.LOADI, targetDt, oldvalueReg, IRMemory.indirect(addressReg, fieldOffset)),
null
)
}
@@ -807,7 +807,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
result += codeGen.multiplyByConst(DataType.UWORD, indexReg, eltSize)
addInstr(result, IRInstructions.binary(Opcode.ADDR, IRDataType.POINTER, pointerReg, indexReg), null)
}
codeGen.storeValueAtPointersLocation(result, pointerReg, 0u, targetIdent.type.dereference(), true, -1)
codeGen.storeValueAtPointersLocation(result, pointerReg, 0, targetIdent.type.dereference(), true, -1)
} else {
if(constIndex!=null) {
val offset = eltSize * constIndex
@@ -820,7 +820,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
addInstr(result, IRInstructions.binary(Opcode.ADDR, IRDataType.POINTER, pointerReg, indexReg), null)
}
val realValueReg = if(targetDt == IRDataType.FLOAT) valueFpRegister else valueRegister
codeGen.storeValueAtPointersLocation(result, pointerReg, 0u, targetIdent.type.dereference(), false, realValueReg)
codeGen.storeValueAtPointersLocation(result, pointerReg, 0, targetIdent.type.dereference(), false, realValueReg)
}
}
@@ -186,7 +186,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
}
result += IRCodeChunk(null, null).also {
it += IRInstructions.binaryImmediate(Opcode.ADD, IRDataType.POINTER, pointerReg, firstField.second.toInt())
it += IRInstructions.binaryImmediate(Opcode.ADD, IRDataType.POINTER, pointerReg, firstField.second)
if (firstField.first.isPointer) {
// get the address stored in the pointer and use that for the rest of the chain
// LOADI has an exception to allo reg1 and reg2 to be the same, so we can avoid using extra temporary registers and LOADs
@@ -214,19 +214,19 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
// For inline array fields (not pointer fields), return the address (ptr+offset) instead of loading from it
if(deref.type.isArray && !deref.derefLast) {
if(offset > 0u)
addInstr(result, IRInstructions.binaryImmediate(Opcode.ADD, IRDataType.POINTER, pointerReg, offset.toInt()), null)
if(offset > 0)
addInstr(result, IRInstructions.binaryImmediate(Opcode.ADD, IRDataType.POINTER, pointerReg, offset), null)
return ExpressionCodeResult(result, IRDataType.POINTER, pointerReg, -1)
}
return if(deref.type.isFloat) {
val resultReg = codeGen.registers.next(IRDataType.FLOAT)
addInstr(result, IRInstructions.loadMemory(Opcode.LOADI, IRDataType.FLOAT, resultReg, IRMemory.indirect(pointerReg, offset.toInt())), null)
addInstr(result, IRInstructions.loadMemory(Opcode.LOADI, IRDataType.FLOAT, resultReg, IRMemory.indirect(pointerReg, offset)), null)
ExpressionCodeResult(result, IRDataType.FLOAT, -1, resultReg)
} else {
val irdt = codeGen.irType(deref.type)
val resultReg = codeGen.registers.next(irdt)
addInstr(result, IRInstructions.loadMemory(Opcode.LOADI, irdt, resultReg, IRMemory.indirect(pointerReg, offset.toInt())), null)
addInstr(result, IRInstructions.loadMemory(Opcode.LOADI, irdt, resultReg, IRMemory.indirect(pointerReg, offset)), null)
ExpressionCodeResult(result, irdt, resultReg, -1)
}
}
@@ -1876,7 +1876,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val right = binExpr.right as? PtIdentifier
require(binExpr.operator=="." && left!=null && right!=null) {"invalid dereference expression ${binExpr.position}"}
val result = mutableListOf<IRCodeChunkBase>()
val field: Pair<DataType, UByte>
val field: Pair<DataType, Int>
val pointerReg: Int
var extraFieldOffset = 0
@@ -1886,7 +1886,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val struct = left.type.subType!! as StStruct
field = struct.getField(right.name, codeGen.program.memsizer)
val fieldVmDt = codeGen.irType(field.first)
val fieldOffset = field.second.toInt()
val fieldOffset = field.second
if(left.variable!=null) {
val constindex = left.index as? PtNumber
if(constindex!=null) {
@@ -1940,7 +1940,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
// add field offset to pointer and load the value into the result register
val fieldVmDt = codeGen.irType(field.first)
val fieldOffset = field.second.toInt() + extraFieldOffset
val fieldOffset = field.second + extraFieldOffset
var resultFpReg = -1
var resultReg = -1
if (fieldVmDt == IRDataType.FLOAT)
@@ -1955,14 +1955,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return ExpressionCodeResult(result, fieldVmDt, resultReg, resultFpReg)
}
internal fun traverseRestOfDerefChainToCalculateFinalAddress(targetPointerDeref: PtPointerDeref, pointerReg: Int): Pair<IRCodeChunks, UByte> {
internal fun traverseRestOfDerefChainToCalculateFinalAddress(targetPointerDeref: PtPointerDeref, pointerReg: Int): Pair<IRCodeChunks, Int> {
// returns instructions to calculate the pointer address, and the offset into the struct it points to
// so that LOADI and STOREFIELD opcodes can be used instead of having an explicit extra ADD
val result = mutableListOf<IRCodeChunkBase>()
if(targetPointerDeref.chain.isEmpty())
return result to 0u // nothing to do; there's no deref chain
return result to 0 // nothing to do; there's no deref chain
var struct: StStruct? = null
if(targetPointerDeref.startpointer.type.subType!=null)
@@ -1978,11 +1978,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val field = targetPointerDeref.chain.last()
val fieldinfo = struct!!.getField(field, codeGen.program.memsizer)
if(fieldinfo.second>0u) {
if(fieldinfo.second>0) {
if(targetPointerDeref.derefLast) {
require(fieldinfo.first.isPointer)
result += updatePointerFromField(fieldinfo, pointerReg)
return result to 0u
return result to 0
} else {
return result to fieldinfo.second
}
@@ -1992,13 +1992,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
// LOADI has an exception to allow reg1 and reg2 to be the same, so we can avoid using extra temporary registers and LOADs
addInstr(result, IRInstructions.loadMemory(Opcode.LOADI, IRDataType.POINTER, pointerReg, IRMemory.indirect(pointerReg, 0)), null)
}
return result to 0u
return result to 0
}
private fun updatePointerFromField(fieldinfo: Pair<DataType, UByte>, pointerReg: Int): IRCodeChunk {
private fun updatePointerFromField(fieldinfo: Pair<DataType, Int>, pointerReg: Int): IRCodeChunk {
return IRCodeChunk(null, null).also {
// LOADI has an exception to allow reg1 and reg2 to be the same, so we can avoid using extra temporary registers and LOADs
it += IRInstructions.loadMemory(Opcode.LOADI, IRDataType.POINTER, pointerReg, IRMemory.indirect(pointerReg, fieldinfo.second.toInt()))
it += IRInstructions.loadMemory(Opcode.LOADI, IRDataType.POINTER, pointerReg, IRMemory.indirect(pointerReg, fieldinfo.second))
}
}
@@ -2181,7 +2181,7 @@ class IRCodeGen(
return chunk
}
internal fun evaluatePointerAddressIntoReg(result: MutableList<IRCodeChunkBase>, deref: PtPointerDeref): Pair<Int, UByte> {
internal fun evaluatePointerAddressIntoReg(result: MutableList<IRCodeChunkBase>, deref: PtPointerDeref): Pair<Int, Int> {
// calculates the pointer address and returns the register it's in + remaining offset into the struct (so that LOADI/STOREFIELD instructions can be used)
val pointerTr = expressionEval.translateExpression(deref.startpointer)
result += pointerTr.chunks
@@ -2190,8 +2190,8 @@ class IRCodeGen(
return pointerTr.resultReg to offset
}
internal fun storeValueAtPointersLocation(result: MutableList<IRCodeChunkBase>, addressReg: Int, offset: UByte, type: DataType, valueIsZero: Boolean, existingValueRegister: Int) {
if(offset<=0u) {
internal fun storeValueAtPointersLocation(result: MutableList<IRCodeChunkBase>, addressReg: Int, offset: Int, type: DataType, valueIsZero: Boolean, existingValueRegister: Int) {
if(offset<=0) {
val irdt = irType(type)
val instr = if(type.isFloat) {
if (valueIsZero) IRInstructions.storeZero(Opcode.STOREZI, IRDataType.FLOAT, IRMemory.indirect(addressReg, 0))
@@ -2208,12 +2208,12 @@ class IRCodeGen(
val valueRegister = existingValueRegister
val irdt = irType(type)
if(valueIsZero && valueRegister<0) {
addInstr(result, IRInstructions.storeZero(Opcode.STOREZI, irdt, IRMemory.indirect(addressReg, offset.toInt())), null)
addInstr(result, IRInstructions.storeZero(Opcode.STOREZI, irdt, IRMemory.indirect(addressReg, offset)), null)
} else {
val instr = if (type.isFloat)
IRInstructions.storeMemory(Opcode.STOREI, IRDataType.FLOAT, valueRegister, IRMemory.indirect(addressReg, offset.toInt()))
IRInstructions.storeMemory(Opcode.STOREI, IRDataType.FLOAT, valueRegister, IRMemory.indirect(addressReg, offset))
else
IRInstructions.storeMemory(Opcode.STOREI, irdt, valueRegister, IRMemory.indirect(addressReg, offset.toInt()))
IRInstructions.storeMemory(Opcode.STOREI, irdt, valueRegister, IRMemory.indirect(addressReg, offset))
addInstr(result, instr, null)
}
}