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:
parent
fb42e77e6e
commit
b400c884e0
@ -2,6 +2,8 @@
|
||||
|
||||
## Current version
|
||||
|
||||
* Added `memory_barrier` macro.
|
||||
|
||||
* Added `random` module.
|
||||
|
||||
* Added `ensure_mixedcase` function and `oldpet` and `origpet` text encodings.
|
||||
|
@ -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
|
||||
}
|
||||
|
15
src/main/scala/millfork/env/Environment.scala
vendored
15
src/main/scala/millfork/env/Environment.scala
vendored
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user