mirror of
https://github.com/irmen/prog8.git
synced 2026-10-22 05:02:58 +00:00
m68k: pin @shared variables to static storage
This commit is contained in:
1 parent
9c9552174e
commit
0189903a63
20 files changed
+143
-37
No files matched your search
@@ -818,7 +818,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
|
||||
val offset = eltSize * constIndex
|
||||
addInstr(result, IRInstructions.binaryImmediate(Opcode.ADD, IRDataType.POINTER, pointerReg, offset), null)
|
||||
} else {
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, eltSize, true, targetArray.splitWords)
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, true)
|
||||
result += code
|
||||
if(eltSize!=1)
|
||||
result += codeGen.multiplyByConst(DataType.UWORD, indexReg, eltSize)
|
||||
@@ -830,7 +830,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
|
||||
val offset = eltSize * constIndex
|
||||
addInstr(result, IRInstructions.binaryImmediate(Opcode.ADD, IRDataType.POINTER, pointerReg, offset), null)
|
||||
} else {
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, eltSize, true, targetArray.splitWords)
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, true)
|
||||
result += code
|
||||
if(eltSize!=1)
|
||||
result += codeGen.multiplyByConst(DataType.UWORD, indexReg, eltSize)
|
||||
@@ -864,7 +864,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
|
||||
}
|
||||
result += chunk
|
||||
} else {
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, eltSize, codeGen.wordArrayIndex, targetArray.splitWords)
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, codeGen.wordArrayIndex)
|
||||
result += code
|
||||
val scaleZX = if(targetArray.splitWords) 1 else eltSize
|
||||
result += IRCodeChunk(null, null).also {
|
||||
@@ -885,7 +885,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
|
||||
}
|
||||
result += chunk
|
||||
} else {
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, eltSize, codeGen.wordArrayIndex, targetArray.splitWords)
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, codeGen.wordArrayIndex)
|
||||
result += code
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstructions.storeMemory(Opcode.STOREX, targetDt, valueFpRegister, IRMemory.indexed(variable, indexReg, codeGen.options.compTarget.indexRegType, scale=eltSize))
|
||||
@@ -906,7 +906,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
|
||||
}
|
||||
result += chunk
|
||||
} else {
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, eltSize, codeGen.wordArrayIndex, targetArray.splitWords)
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, codeGen.wordArrayIndex)
|
||||
result += code
|
||||
result += IRCodeChunk(null, null).also {
|
||||
if(targetArray.splitWords) {
|
||||
@@ -954,7 +954,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
|
||||
}
|
||||
} else {
|
||||
// index is an expression
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, eltSize, true, targetArray.splitWords)
|
||||
val (code, indexReg) = codeGen.loadIndexReg(targetArray.index, true)
|
||||
result += code
|
||||
if(eltSize!=1)
|
||||
result += codeGen.multiplyByConst(DataType.UWORD, indexReg, eltSize)
|
||||
@@ -3062,7 +3062,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
|
||||
|
||||
private fun tryFoldStructArrayDirectWrite(addressExpr: PtExpression, zero: Boolean, valueReg: Int, targetDt: IRDataType, result: MutableList<IRCodeChunkBase>): Boolean {
|
||||
val info = extractStructArrayIndexInfo(addressExpr, codeGen) ?: return false
|
||||
val (idxCode, indexReg) = codeGen.loadIndexReg(info.idxExpr, info.structSize, codeGen.wordArrayIndex, false)
|
||||
val (idxCode, indexReg) = codeGen.loadIndexReg(info.idxExpr, codeGen.wordArrayIndex)
|
||||
result += idxCode
|
||||
if(zero) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
|
||||
@@ -876,7 +876,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
if(offset > 0)
|
||||
addInstr(result, IRInstructions.binaryImmediate(Opcode.ADD, IRDataType.POINTER, pointerTr.resultReg, offset), null)
|
||||
} else {
|
||||
val (code, indexWordReg) = codeGen.loadIndexReg(target.index, eltSize, true, false)
|
||||
val (code, indexWordReg) = codeGen.loadIndexReg(target.index, true)
|
||||
result += code
|
||||
if(eltSize!=1)
|
||||
result += codeGen.multiplyByConst(DataType.UWORD, indexWordReg, eltSize)
|
||||
@@ -946,7 +946,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
it += IRInstructions.storeZero(Opcode.STOREZX, IRDataType.BYTE, IRMemory.indexed(targetVariable.name, offsetReg, codeGen.options.compTarget.indexRegType))
|
||||
}
|
||||
} else {
|
||||
val (code, indexReg) = codeGen.loadIndexReg(target.index, eltSize, codeGen.wordArrayIndex, false)
|
||||
val (code, indexReg) = codeGen.loadIndexReg(target.index, codeGen.wordArrayIndex)
|
||||
result += code
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val offset = byteOffset(eltSize)
|
||||
@@ -964,7 +964,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
it += IRInstructions.storeMemory(Opcode.STOREX, IRDataType.BYTE, valueTr.resultReg, IRMemory.indexed(targetVariable.name, offsetReg, codeGen.options.compTarget.indexRegType))
|
||||
}
|
||||
} else {
|
||||
val (code, indexReg) = codeGen.loadIndexReg(target.index, eltSize, codeGen.wordArrayIndex, false)
|
||||
val (code, indexReg) = codeGen.loadIndexReg(target.index, codeGen.wordArrayIndex)
|
||||
result += code
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val offset = byteOffset(eltSize)
|
||||
@@ -985,7 +985,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val info = extractStructArrayIndexInfo(call.args[0], codeGen) ?: return null
|
||||
val isZero = codeGen.isZero(call.args[1])
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val (idxCode, indexReg) = codeGen.loadIndexReg(info.idxExpr, info.structSize, codeGen.wordArrayIndex, false)
|
||||
val (idxCode, indexReg) = codeGen.loadIndexReg(info.idxExpr, codeGen.wordArrayIndex)
|
||||
result += idxCode
|
||||
return if(isZero) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
|
||||
@@ -645,7 +645,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
|
||||
fun indexByExpression() {
|
||||
val (code, indexReg) = codeGen.loadIndexReg(arrayIx.index, eltSize, codeGen.wordArrayIndex, arrayIx.splitWords)
|
||||
val (code, indexReg) = codeGen.loadIndexReg(arrayIx.index, codeGen.wordArrayIndex)
|
||||
result += code
|
||||
val scale = if(arrayIx.splitWords) 1 else eltSize
|
||||
if(vmDt==IRDataType.FLOAT) {
|
||||
@@ -681,7 +681,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addInstr(result, IRInstructions.binaryImmediate(Opcode.ADD, IRDataType.POINTER, pointerReg, memOffset), null)
|
||||
}
|
||||
else {
|
||||
val (code, indexWordReg) = codeGen.loadIndexReg(index, eltSize, true, false)
|
||||
val (code, indexWordReg) = codeGen.loadIndexReg(index, true)
|
||||
result += code
|
||||
if(eltSize!=1)
|
||||
result += codeGen.multiplyByConst(DataType.UWORD, indexWordReg, eltSize)
|
||||
@@ -1895,7 +1895,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
} else if(left.variable!!.type.isArray) {
|
||||
// variable index: fold to single LOADX with scale=structSize, disp=fieldOffset
|
||||
// only for known array symbols (not generic pointer derefs)
|
||||
val (chunks, indexReg) = codeGen.loadIndexReg(left.index, struct.size.toInt(), codeGen.wordArrayIndex, false)
|
||||
val (chunks, indexReg) = codeGen.loadIndexReg(left.index, codeGen.wordArrayIndex)
|
||||
result += chunks
|
||||
if (fieldVmDt == IRDataType.FLOAT) {
|
||||
val fpReg = codeGen.registers.next(IRDataType.FLOAT)
|
||||
@@ -1911,7 +1911,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val pointerTr = translateExpression(left.variable!!)
|
||||
result += pointerTr.chunks
|
||||
pointerReg = pointerTr.resultReg
|
||||
val (chunks, indexReg) = codeGen.loadIndexReg(left.index, struct.size.toInt(), true, false)
|
||||
val (chunks, indexReg) = codeGen.loadIndexReg(left.index, true)
|
||||
result += chunks
|
||||
if(struct.size.toInt()!=1)
|
||||
result += codeGen.multiplyByConst(DataType.UWORD, indexReg, struct.size.toInt())
|
||||
|
||||
@@ -168,7 +168,7 @@ class IRCodeGen(
|
||||
replacements += IRStStaticVariable(
|
||||
variable.name, variable.dt, null, variable.length,
|
||||
variable.zpwish, variable.align, variable.dirty,
|
||||
variable.inBss, variable.readonly
|
||||
variable.inBss, variable.readonly, variable.shared
|
||||
)
|
||||
}
|
||||
is IRVariableInitializer.Str, is IRVariableInitializer.Array -> {
|
||||
@@ -274,7 +274,8 @@ class IRCodeGen(
|
||||
variable.align,
|
||||
variable.dirty,
|
||||
variable.inBss,
|
||||
variable.readonly
|
||||
variable.readonly,
|
||||
variable.shared
|
||||
)
|
||||
irProg.st.add(clearedVar)
|
||||
|
||||
@@ -2218,7 +2219,7 @@ class IRCodeGen(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun loadIndexReg(index: PtExpression, itemsize: Int, wordIndex: Boolean, arrayIsSplitWords: Boolean): Pair<IRCodeChunks, Int> {
|
||||
internal fun loadIndexReg(index: PtExpression, wordIndex: Boolean): Pair<IRCodeChunks, Int> {
|
||||
// returns the code to load the Index into the register, which is also returned.
|
||||
// The returned register is always canonicalized to the expected index width
|
||||
// (WORD on 32-bit targets, BYTE on 8-bit) so that LOADX/STOREX/STOREZX never
|
||||
|
||||
@@ -78,7 +78,7 @@ private class StToIrConverter(val romable: Boolean) {
|
||||
val hasInit = initValue != null
|
||||
val inBss = !hasInit || romable
|
||||
val readonly = romable && hasInit
|
||||
return IRStStaticVariable(name, variable.dt, initValue, variable.length, variable.zpwish, variable.align, variable.dirty, inBss, readonly)
|
||||
return IRStStaticVariable(name, variable.dt, initValue, variable.length, variable.zpwish, variable.align, variable.dirty, inBss, readonly, variable.shared)
|
||||
}
|
||||
|
||||
fun convert(variable: StMemVar): IRStMemVar {
|
||||
|
||||
@@ -389,7 +389,7 @@ class StackFrameLayout(private val program: IRProgram, private val errors: IErro
|
||||
/** outcome of the frameability decision for one subroutine */
|
||||
private sealed interface Frameability {
|
||||
class Frameable(val layout: FrameLayoutResult) : Frameability
|
||||
class NotFrameable(val reason: String) : Frameability
|
||||
class NotFrameable() : Frameability
|
||||
}
|
||||
|
||||
private fun frameableSubroutine(
|
||||
@@ -403,7 +403,7 @@ class StackFrameLayout(private val program: IRProgram, private val errors: IErro
|
||||
reentrant: Set<String>,
|
||||
reachesFramePointerClobber: Map<String, ClobberReach>
|
||||
): Frameability {
|
||||
val static = { reason: String -> Frameability.NotFrameable(reason) }
|
||||
val static = { reason: String -> Frameability.NotFrameable() }
|
||||
// a %option noframe subroutine requires the legacy static convention (it manipulates
|
||||
// the machine stack itself), so it never gets a frame
|
||||
if (sub.noframe) return static("it is marked %option noframe")
|
||||
@@ -1090,6 +1090,7 @@ class StackFrameLayout(private val program: IRProgram, private val errors: IErro
|
||||
|
||||
/** returns why the variable cannot be moved into a frame, or null when it can */
|
||||
private fun frameableVariableProblem(v: IRStStaticVariable, name: String, addressTaken: Set<String>, asmTexts: List<String>, asmAllowed: Boolean = false): String? {
|
||||
if (v.shared) return "it is marked @shared" // @shared guarantees a stable, externally visible address
|
||||
if (name in addressTaken) return "its address is taken"
|
||||
if (!asmAllowed && isLabelReferencedInAsm(name, asmTexts)) return "inline assembly refers to it"
|
||||
if (v.initializationValue != null && v.initializationValue !is IRVariableInitializer.Numeric) return "it has a static initializer"
|
||||
|
||||
@@ -278,7 +278,7 @@ private fun PtVariable.prefixVariableOrThis(parent: PtNode, st: SymbolTable): Pt
|
||||
else -> throw AssemblyError("weird array value element $elt")
|
||||
}
|
||||
}
|
||||
val result = PtVariable(name, type, isSplitWordArray, zeropage, align, dirty, newValue, arraySize, position)
|
||||
val result = PtVariable(name, type, isSplitWordArray, zeropage, align, dirty, newValue, arraySize, position, shared)
|
||||
result.parent = parent
|
||||
result
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user