mirror of
https://github.com/irmen/prog8.git
synced 2026-10-22 05:02:58 +00:00
fix struct size truncation to 256 bytes on targets that allow larger structs (m68k)
This commit is contained in:
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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user