1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-12-22 16:31:02 +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
* Added `memory_barrier` macro.
* Added `random` module.
* 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.
#### `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,
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

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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
}

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(_) => false
}
case CHANGED_MEM => true
case POP | PUSH => false
case _ => true // TODO
}

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 = {

View File

@ -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 {