1
0
mirror of https://github.com/KarolS/millfork.git synced 2026-04-20 18:16:35 +00:00

Add memory barriers

This commit is contained in:
Karol Stasiak
2018-12-31 13:20:32 +01:00
parent fb42e77e6e
commit b400c884e0
10 changed files with 32 additions and 8 deletions
+2
View File
@@ -2,6 +2,8 @@
## Current version
* Added `memory_barrier` macro.
* Added `random` module.
* Added `ensure_mixedcase` function and `oldpet` and `origpet` text encodings.
+8
View File
@@ -61,3 +61,11 @@ Various colour constants.
Available for: VIC-20, C64, C264 series, ZX Spectrum.
#### `macro void memory_barrier()`
Informs the optimizer that at this point arbitrary memory has been accessed and either read or written by an external device.
The optimizer should not optimize any memory accesses across that macro.
Available for: all targets.
@@ -142,6 +142,7 @@ object OpcodeClasses {
SLO, RLA, SRE, RRA,
AHX, SHY, SHX, TAS, LAS,
COP,
CHANGED_MEM,
)
val ChangesMemoryIfNotImplied = Set(
DEC, INC, ASL, ROL, LSR, ROR,
@@ -158,6 +159,7 @@ object OpcodeClasses {
LAS,
TRB, TSB,
TRB_W, TSB_W,
CHANGED_MEM,
)
val AccessesWordInMemory = Set(
@@ -332,7 +334,7 @@ object OpcodeClasses {
CSH, CSL,
TXY, TYX, XBA,
PHD, PHB, PHK,
DISCARD_AF, DISCARD_XF, DISCARD_YF)
DISCARD_AF, DISCARD_XF, DISCARD_YF, CHANGED_MEM)
val NoopDiscardsFlags = Set(DISCARD_AF, DISCARD_XF, DISCARD_YF)
val DiscardsV = NoopDiscardsFlags | OverwritesV
@@ -120,7 +120,7 @@ object Opcode extends Enumeration {
PHA_W, PLA_W,
PHX_W, PHY_W, PLY_W, PLX_W,
DISCARD_AF, DISCARD_XF, DISCARD_YF,
DISCARD_AF, DISCARD_XF, DISCARD_YF, CHANGED_MEM,
BYTE, LABEL = Value
def widen(opcode: Opcode.Value): Option[Opcode.Value] = opcode match {
@@ -268,6 +268,7 @@ object HelperCheckers {
val a2 = l2.addrMode
if (goodAddrModes(a1) || goodAddrModes(a2)) return true
if (badAddrModes(a1) || badAddrModes(a2)) return false
if (l1.opcode == Opcode.CHANGED_MEM || l2.opcode == Opcode.CHANGED_MEM) return false
if ((a1 == IndexedSY) != (a2 == IndexedSY)) return true // bold assertion, but usually true
val p1 = l1.parameter
val p2 = l2.parameter
@@ -868,6 +868,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta
import ZOpcode._
import ZRegister._
opcode match {
case CHANGED_MEM => true
case POP => true
case LD | LD_16 | ADC_16 | ADD_16 | SBC_16 => registers match {
case TwoRegisters(MEM_IX_D | MEM_ABS_16 | MEM_ABS_8 | MEM_DE | MEM_BC | MEM_IY_D | MEM_HL, _) => true
@@ -25,7 +25,7 @@ object ZOpcode extends Enumeration {
DJNZ, JP, JR, CALL, RET, RETN, RETI, HALT,
//sharp:
LD_AHLI, LD_AHLD, LD_HLIA, LD_HLDA, SWAP, LDH_DA, LDH_AD, LDH_CA, LDH_AC, LD_HLSP, ADD_SP, STOP,
DISCARD_A, DISCARD_F, DISCARD_HL, DISCARD_BC, DISCARD_DE, DISCARD_IX, DISCARD_IY,
DISCARD_A, DISCARD_F, DISCARD_HL, DISCARD_BC, DISCARD_DE, DISCARD_IX, DISCARD_IY, CHANGED_MEM,
LABEL, BYTE = Value
}
@@ -196,6 +196,7 @@ object HelperCheckers {
case OneRegister(MEM_HL | MEM_IX_D | MEM_IY_D | MEM_BC | MEM_DE) => true
case OneRegister(_) => false
}
case CHANGED_MEM => true
case POP | PUSH => false
case _ => true // TODO
}
+12 -3
View File
@@ -1,9 +1,9 @@
package millfork.env
import millfork.assembly.BranchingOpcodeMapping
import millfork.assembly.{BranchingOpcodeMapping, Elidability}
import millfork.{env, _}
import millfork.assembly.mos.Opcode
import millfork.assembly.z80.{IfFlagClear, IfFlagSet, ZFlag}
import millfork.assembly.mos.{AddrMode, Opcode}
import millfork.assembly.z80._
import millfork.compiler.{AbstractExpressionCompiler, LabelGenerator}
import millfork.error.Logger
import millfork.node._
@@ -1300,6 +1300,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
def collectDeclarations(program: Program, options: CompilationOptions): Unit = {
val b = get[VariableType]("byte")
val v = get[Type]("void")
if (options.flag(CompilationFlag.OptimizeForSonicSpeed)) {
addThing(InitializedArray("identity$", None, List.tabulate(256)(n => LiteralExpression(n, 1)), declaredBank = None, b, b, defaultArrayAlignment(options, 256)), None)
}
@@ -1345,6 +1346,14 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
}
}
}
if (!things.contains("memory_barrier")) {
things("memory_barrier") = MacroFunction("memory_barrier", v, NormalParamSignature(Nil), this, CpuFamily.forType(options.platform.cpu) match {
case CpuFamily.M6502 => List(MosAssemblyStatement(Opcode.CHANGED_MEM, AddrMode.DoesNotExist, LiteralExpression(0, 1), Elidability.Fixed))
case CpuFamily.I80 => List(Z80AssemblyStatement(ZOpcode.CHANGED_MEM, NoRegisters, None, LiteralExpression(0, 1), Elidability.Fixed))
case _ => ???
})
}
}
def hintTypo(name: String): Unit = {
@@ -74,9 +74,9 @@ class Z80Assembler(program: Program,
case ZLine0(BYTE, NoRegisters, param) =>
writeByte(bank, index, param)
index + 1
case ZLine0(DISCARD_F | DISCARD_HL | DISCARD_BC | DISCARD_DE | DISCARD_IX | DISCARD_IY | DISCARD_A, NoRegisters, _) =>
case ZLine0(DISCARD_F | DISCARD_HL | DISCARD_BC | DISCARD_DE | DISCARD_IX | DISCARD_IY | DISCARD_A | CHANGED_MEM, NoRegisters, _) =>
index
case ZLine0(LABEL | BYTE | DISCARD_F | DISCARD_HL | DISCARD_BC | DISCARD_DE | DISCARD_IX | DISCARD_IY | DISCARD_A, _, _) =>
case ZLine0(LABEL | BYTE | DISCARD_F | DISCARD_HL | DISCARD_BC | DISCARD_DE | DISCARD_IX | DISCARD_IY | DISCARD_A | CHANGED_MEM, _, _) =>
???
case ZLine0(RST, NoRegisters, param) =>
val opcode = param.quickSimplify match {