1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-01-10 20:29: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

View File

@ -2,6 +2,8 @@
## Current version ## Current version
* Added `memory_barrier` macro.
* Added `random` module. * Added `random` module.
* Added `ensure_mixedcase` function and `oldpet` and `origpet` text encodings. * Added `ensure_mixedcase` function and `oldpet` and `origpet` text encodings.

View File

@ -61,3 +61,11 @@ Various colour constants.
Available for: VIC-20, C64, C264 series, ZX Spectrum. 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.

View File

@ -142,6 +142,7 @@ object OpcodeClasses {
SLO, RLA, SRE, RRA, SLO, RLA, SRE, RRA,
AHX, SHY, SHX, TAS, LAS, AHX, SHY, SHX, TAS, LAS,
COP, COP,
CHANGED_MEM,
) )
val ChangesMemoryIfNotImplied = Set( val ChangesMemoryIfNotImplied = Set(
DEC, INC, ASL, ROL, LSR, ROR, DEC, INC, ASL, ROL, LSR, ROR,
@ -158,6 +159,7 @@ object OpcodeClasses {
LAS, LAS,
TRB, TSB, TRB, TSB,
TRB_W, TSB_W, TRB_W, TSB_W,
CHANGED_MEM,
) )
val AccessesWordInMemory = Set( val AccessesWordInMemory = Set(
@ -332,7 +334,7 @@ object OpcodeClasses {
CSH, CSL, CSH, CSL,
TXY, TYX, XBA, TXY, TYX, XBA,
PHD, PHB, PHK, 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 NoopDiscardsFlags = Set(DISCARD_AF, DISCARD_XF, DISCARD_YF)
val DiscardsV = NoopDiscardsFlags | OverwritesV val DiscardsV = NoopDiscardsFlags | OverwritesV

View File

@ -120,7 +120,7 @@ object Opcode extends Enumeration {
PHA_W, PLA_W, PHA_W, PLA_W,
PHX_W, PHY_W, PLY_W, PLX_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 BYTE, LABEL = Value
def widen(opcode: Opcode.Value): Option[Opcode.Value] = opcode match { def widen(opcode: Opcode.Value): Option[Opcode.Value] = opcode match {

View File

@ -268,6 +268,7 @@ object HelperCheckers {
val a2 = l2.addrMode val a2 = l2.addrMode
if (goodAddrModes(a1) || goodAddrModes(a2)) return true if (goodAddrModes(a1) || goodAddrModes(a2)) return true
if (badAddrModes(a1) || badAddrModes(a2)) return false 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 if ((a1 == IndexedSY) != (a2 == IndexedSY)) return true // bold assertion, but usually true
val p1 = l1.parameter val p1 = l1.parameter
val p2 = l2.parameter val p2 = l2.parameter

View File

@ -868,6 +868,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta
import ZOpcode._ import ZOpcode._
import ZRegister._ import ZRegister._
opcode match { opcode match {
case CHANGED_MEM => true
case POP => true case POP => true
case LD | LD_16 | ADC_16 | ADD_16 | SBC_16 => registers match { 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 case TwoRegisters(MEM_IX_D | MEM_ABS_16 | MEM_ABS_8 | MEM_DE | MEM_BC | MEM_IY_D | MEM_HL, _) => true

View File

@ -25,7 +25,7 @@ object ZOpcode extends Enumeration {
DJNZ, JP, JR, CALL, RET, RETN, RETI, HALT, DJNZ, JP, JR, CALL, RET, RETN, RETI, HALT,
//sharp: //sharp:
LD_AHLI, LD_AHLD, LD_HLIA, LD_HLDA, SWAP, LDH_DA, LDH_AD, LDH_CA, LDH_AC, LD_HLSP, ADD_SP, STOP, 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 LABEL, BYTE = Value
} }

View File

@ -196,6 +196,7 @@ object HelperCheckers {
case OneRegister(MEM_HL | MEM_IX_D | MEM_IY_D | MEM_BC | MEM_DE) => true case OneRegister(MEM_HL | MEM_IX_D | MEM_IY_D | MEM_BC | MEM_DE) => true
case OneRegister(_) => false case OneRegister(_) => false
} }
case CHANGED_MEM => true
case POP | PUSH => false case POP | PUSH => false
case _ => true // TODO case _ => true // TODO
} }

View File

@ -1,9 +1,9 @@
package millfork.env package millfork.env
import millfork.assembly.BranchingOpcodeMapping import millfork.assembly.{BranchingOpcodeMapping, Elidability}
import millfork.{env, _} import millfork.{env, _}
import millfork.assembly.mos.Opcode import millfork.assembly.mos.{AddrMode, Opcode}
import millfork.assembly.z80.{IfFlagClear, IfFlagSet, ZFlag} import millfork.assembly.z80._
import millfork.compiler.{AbstractExpressionCompiler, LabelGenerator} import millfork.compiler.{AbstractExpressionCompiler, LabelGenerator}
import millfork.error.Logger import millfork.error.Logger
import millfork.node._ 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 = { def collectDeclarations(program: Program, options: CompilationOptions): Unit = {
val b = get[VariableType]("byte") val b = get[VariableType]("byte")
val v = get[Type]("void")
if (options.flag(CompilationFlag.OptimizeForSonicSpeed)) { if (options.flag(CompilationFlag.OptimizeForSonicSpeed)) {
addThing(InitializedArray("identity$", None, List.tabulate(256)(n => LiteralExpression(n, 1)), declaredBank = None, b, b, defaultArrayAlignment(options, 256)), None) 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 = { def hintTypo(name: String): Unit = {

View File

@ -74,9 +74,9 @@ class Z80Assembler(program: Program,
case ZLine0(BYTE, NoRegisters, param) => case ZLine0(BYTE, NoRegisters, param) =>
writeByte(bank, index, param) writeByte(bank, index, param)
index + 1 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 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) => case ZLine0(RST, NoRegisters, param) =>
val opcode = param.quickSimplify match { val opcode = param.quickSimplify match {