1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-05 09:28:54 +00:00

Track equality of S and X. Add relevant optimizations.

This commit is contained in:
Karol Stasiak 2018-06-23 23:24:32 +02:00
parent bc21e5befc
commit 456c674a0c
6 changed files with 81 additions and 22 deletions

View File

@ -217,6 +217,20 @@ object AlwaysGoodOptimizations {
pointlessImmediateStoreToTheSameVariable(MatchX(0), STX, MatchY(0), STY),
pointlessImmediateStoreToTheSameVariable(MatchY(0), STY, MatchY(0), STY),
(HasOpcode(PHA)) ~
(Linear & Not(ChangesA) & Not(ChangesStack) & Not(ChangesMemory)).* ~
(Elidable & XContainsStackPointer & HasOpcode(STA) & HasAddrMode(AbsoluteX) & HasParameterWhere(p => p.quickSimplify match {
case NumericConstant(n, _) => n == 0x101
case _ => false
})) ~~> (_.init),
(HasOpcode(PHA)) ~
(Linear & Not(ChangesA) & Not(ChangesStack) & Not(ChangesMemory)).* ~
(Elidable & HasOpcode(STA) & HasAddrMode(Stack) & HasParameterWhere(p => p.quickSimplify match {
case NumericConstant(n, _) => n == 1
case _ => false
})) ~~> (_.init)
)
val PointlessStashingForLaterStore = new RuleBasedAssemblyOptimization("Pointless stashing for later store",
@ -1093,6 +1107,18 @@ object AlwaysGoodOptimizations {
HasOpcodeIn(Set(TYA, TAY)) ~
(Not(Set(TYA, TAY)) & Linear & Not(ChangesA) & Not(ChangesY)).* ~
(Elidable & HasOpcodeIn(Set(TYA, TAY)) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_.init),
(HasOpcodeIn(Set(STA, LDA)) & HasAddrModeIn(Set(ZeroPage, Absolute)) & MatchAddrMode(0) & MatchParameter(1)) ~
(Linear & Not(HasOpcode(TAX)) & Not(ChangesA) & DoesntChangeMemoryAt(0, 1)).* ~
HasOpcode(TAX) ~
(LinearOrBranch & Not(ChangesX) & DoesntChangeMemoryAt(0, 1)).* ~
(Elidable & HasOpcode(LDX) & HasAddrModeIn(Set(ZeroPage, Absolute)) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_.init),
(HasOpcodeIn(Set(STA, LDA)) & HasAddrModeIn(Set(ZeroPage, Absolute)) & MatchAddrMode(0) & MatchParameter(1)) ~
(Linear & Not(HasOpcode(TAY)) & Not(ChangesA) & DoesntChangeMemoryAt(0, 1)).* ~
HasOpcode(TAY) ~
(LinearOrBranch & Not(ChangesY) & DoesntChangeMemoryAt(0, 1)).* ~
(Elidable & HasOpcode(LDY) & HasAddrModeIn(Set(ZeroPage, Absolute)) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_.init),
)
val RearrangableLoadFromTheSameLocation = new RuleBasedAssemblyOptimization("Rearrangable load from the same location",

View File

@ -62,7 +62,7 @@ object CoarseFlowAnalyzer {
case AssemblyLine(opcode, addrMode, _, _) =>
currentStatus = currentStatus.copy(src = AnyStatus)
if (OpcodeClasses.ChangesX(opcode)) currentStatus = currentStatus.copy(x = AnyStatus)
if (OpcodeClasses.ChangesX(opcode)) currentStatus = currentStatus.copy(x = AnyStatus, eqSX = false)
if (OpcodeClasses.ChangesY(opcode)) currentStatus = currentStatus.copy(y = AnyStatus)
if (OpcodeClasses.ChangesAAlways(opcode)) currentStatus = currentStatus.copy(a = AnyStatus, a0 = AnyStatus, a7 = AnyStatus)
if (addrMode == Implied && OpcodeClasses.ChangesAIfImplied(opcode)) currentStatus = currentStatus.copy(a = AnyStatus, a0 = AnyStatus, a7 = AnyStatus)
@ -71,6 +71,7 @@ object CoarseFlowAnalyzer {
if (OpcodeClasses.ChangesNAndZ(opcode)) currentStatus = currentStatus.nz
if (OpcodeClasses.ChangesC(opcode)) currentStatus = currentStatus.copy(c = AnyStatus)
if (OpcodeClasses.ChangesV(opcode)) currentStatus = currentStatus.copy(v = AnyStatus)
if (OpcodeClasses.ChangesStack(opcode) || OpcodeClasses.ChangesS(opcode)) currentStatus = currentStatus.copy(eqSX = false)
}
}
// flagArray.zip(codeArray).foreach{

View File

@ -48,6 +48,7 @@ case class CpuStatus(a: Status[Int] = UnknownStatus,
y: Status[Int] = UnknownStatus,
iz: Status[Int] = UnknownStatus,
src: Status[SourceOfNZ] = UnknownStatus,
eqSX: Boolean = false,
z: Status[Boolean] = UnknownStatus,
n: Status[Boolean] = UnknownStatus,
c: Status[Boolean] = UnknownStatus,
@ -115,6 +116,7 @@ case class CpuStatus(a: Status[Int] = UnknownStatus,
y = this.y ~ that.y,
iz = this.iz ~ that.iz,
src = this.src ~ that.src,
eqSX = this.eqSX && that.eqSX,
z = this.z ~ that.z,
n = this.n ~ that.n,
c = this.c ~ that.c,

View File

@ -15,7 +15,7 @@ object FlowAnalyzerForImmediate {
if ((nn & 1) != 0) currentStatus = currentStatus.copy(c = Status.SingleFalse)
if ((nn & 2) != 0) currentStatus = currentStatus.copy(z = Status.SingleFalse)
if ((nn & 8) != 0) currentStatus = currentStatus.copy(d = Status.SingleFalse)
if ((nn & 0x10) != 0) currentStatus = currentStatus.copy(w = Status.SingleFalse)
if ((nn & 0x10) != 0) currentStatus = currentStatus.copy(w = Status.SingleFalse, eqSX = false)
if ((nn & 0x20) != 0) currentStatus = currentStatus.copy(m = Status.SingleFalse)
if ((nn & 0x40) != 0) currentStatus = currentStatus.copy(v = Status.SingleFalse)
if ((nn & 0x80) != 0) currentStatus = currentStatus.copy(n = Status.SingleFalse)
@ -26,7 +26,7 @@ object FlowAnalyzerForImmediate {
if ((nn & 1) != 0) currentStatus = currentStatus.copy(c = Status.SingleTrue)
if ((nn & 2) != 0) currentStatus = currentStatus.copy(z = Status.SingleTrue)
if ((nn & 8) != 0) currentStatus = currentStatus.copy(d = Status.SingleTrue)
if ((nn & 0x10) != 0) currentStatus = currentStatus.copy(w = Status.SingleTrue)
if ((nn & 0x10) != 0) currentStatus = currentStatus.copy(w = Status.SingleTrue, eqSX = false)
if ((nn & 0x20) != 0) currentStatus = currentStatus.copy(m = Status.SingleTrue)
if ((nn & 0x40) != 0) currentStatus = currentStatus.copy(v = Status.SingleTrue)
if ((nn & 0x80) != 0) currentStatus = currentStatus.copy(n = Status.SingleTrue)
@ -34,7 +34,7 @@ object FlowAnalyzerForImmediate {
},
LDX -> {(nn, currentStatus) =>
val n = nn & 0xff
currentStatus.nz(n).copy(x = SingleStatus(n), src = SourceOfNZ.X)
currentStatus.nz(n).copy(x = SingleStatus(n), src = SourceOfNZ.X, eqSX = false)
},
LDY -> {(nn, currentStatus) =>
val n = nn & 0xff
@ -54,7 +54,7 @@ object FlowAnalyzerForImmediate {
},
LDX_W -> {(nn, currentStatus) =>
val n = nn & 0xff
currentStatus.nzw(nn).copy(x = SingleStatus(n), src = AnyStatus)
currentStatus.nzw(nn).copy(x = SingleStatus(n), src = AnyStatus, eqSX = false)
},
LDY_W -> {(nn, currentStatus) =>
val n = nn & 0xff
@ -251,6 +251,17 @@ object FlowAnalyzerForImmediate {
z = currentStatus.iz.map(v => (v & 0xff) == (nn & 0xff)),
src = if (nn == 0) SourceOfNZ.Z else AnyStatus)
},
SBX -> { (nn, currentStatus) =>
val newX = (currentStatus.x <*> currentStatus.a) { (x, a) => (x - (x & a)) & 0xff }
currentStatus.copy(
x = newX,
n = newX.n(),
z = newX.z(),
c = AnyStatus,
eqSX = false,
src = SourceOfNZ.X)
}
)
def hasDefinition(opcode: Opcode.Value): Boolean = map.contains(opcode)

View File

@ -15,28 +15,30 @@ object FlowAnalyzerForImplied {
RTI -> identity,
SEI -> identity,
CLI -> identity,
TXS -> identity,
PHP -> identity,
PHA -> identity,
PHA_W -> identity,
PHX -> identity,
PHX_W -> identity,
PHY -> identity,
PHY_W -> identity,
PHZ -> identity,
PHD -> identity,
PHK -> identity,
PHB -> identity,
TXS -> (_.copy(eqSX = true)),
PHP -> (_.copy(eqSX = false)),
PHA -> (_.copy(eqSX = false)),
PHA_W -> (_.copy(eqSX = false)),
PHX -> (_.copy(eqSX = false)),
PHX_W -> (_.copy(eqSX = false)),
PHY -> (_.copy(eqSX = false)),
PHY_W -> (_.copy(eqSX = false)),
PHZ -> (_.copy(eqSX = false)),
PHD -> (_.copy(eqSX = false)),
PHK -> (_.copy(eqSX = false)),
PHB -> (_.copy(eqSX = false)),
SED -> (_.copy(d = Status.SingleTrue)),
CLD -> (_.copy(d = Status.SingleFalse)),
CLC -> (_.copy(c = Status.SingleFalse)),
SEC -> (_.copy(c = Status.SingleTrue)),
CLV -> (_.copy(v = Status.SingleFalse)),
XCE -> (_.copy(c = AnyStatus, m = AnyStatus, x = AnyStatus)),
PLA -> (_.copy(src = SourceOfNZ.A, a = AnyStatus, n = AnyStatus, z = AnyStatus)),
PLX -> (_.copy(src = SourceOfNZ.X, x = AnyStatus, n = AnyStatus, z = AnyStatus)),
PLY -> (_.copy(src = SourceOfNZ.Y, y = AnyStatus, n = AnyStatus, z = AnyStatus)),
PLZ -> (_.copy(src = SourceOfNZ.Z, iz = AnyStatus, n = AnyStatus, z = AnyStatus)),
XCE -> (_.copy(c = AnyStatus, m = AnyStatus, w = AnyStatus, x = AnyStatus, y = AnyStatus, eqSX = false)),
PLA -> (_.copy(src = SourceOfNZ.A, a = AnyStatus, n = AnyStatus, z = AnyStatus, eqSX = false)),
PLX -> (_.copy(src = SourceOfNZ.X, x = AnyStatus, n = AnyStatus, z = AnyStatus, eqSX = false)),
PLX_W -> (_.copy(src = SourceOfNZ.X, x = AnyStatus, n = AnyStatus, z = AnyStatus, eqSX = false)),
PLY -> (_.copy(src = SourceOfNZ.Y, y = AnyStatus, n = AnyStatus, z = AnyStatus, eqSX = false)),
PLY_W -> (_.copy(src = SourceOfNZ.Y, y = AnyStatus, n = AnyStatus, z = AnyStatus, eqSX = false)),
PLZ -> (_.copy(src = SourceOfNZ.Z, iz = AnyStatus, n = AnyStatus, z = AnyStatus, eqSX = false)),
XBA -> (currentStatus => currentStatus.copy(
a = currentStatus.ah,
a0 = currentStatus.ah.bit0,
@ -51,6 +53,7 @@ object FlowAnalyzerForImplied {
n = newX.n(),
z = newX.z(),
x = newX,
eqSX = false,
src = SourceOfNZ.X)
}),
DEX -> (currentStatus => {
@ -59,6 +62,7 @@ object FlowAnalyzerForImplied {
n = newX.n(),
z = newX.z(),
x = newX,
eqSX = false,
src = SourceOfNZ.X)
}),
INY -> (currentStatus => {
@ -129,6 +133,7 @@ object FlowAnalyzerForImplied {
n = AnyStatus,
z = newX.z().withHiddenHi,
x = newX,
eqSX = false,
src = AnyStatus)
}),
DEX_W -> (currentStatus => {
@ -137,6 +142,7 @@ object FlowAnalyzerForImplied {
n = AnyStatus,
z = newX.z().withHiddenHi,
x = newX,
eqSX = false,
src = AnyStatus)
}),
INY_W -> (currentStatus => {
@ -182,6 +188,7 @@ object FlowAnalyzerForImplied {
TAX -> (currentStatus => {
currentStatus.copy(
x = currentStatus.a,
eqSX = false,
n = currentStatus.a.n(),
z = currentStatus.a.z(),
src = SourceOfNZ.AX)
@ -221,6 +228,7 @@ object FlowAnalyzerForImplied {
TYX -> (currentStatus => {
currentStatus.copy(
x = currentStatus.y,
eqSX = false,
n = currentStatus.y.n(),
z = currentStatus.y.z(),
src = SourceOfNZ.XY)
@ -246,6 +254,7 @@ object FlowAnalyzerForImplied {
a = currentStatus.x,
a0 = currentStatus.x.bit0,
a7 = currentStatus.x.bit7,
eqSX = false,
x = currentStatus.a)
}),
SAY -> (currentStatus => {
@ -258,6 +267,7 @@ object FlowAnalyzerForImplied {
SXY -> (currentStatus => {
currentStatus.copy(
y = currentStatus.x,
eqSX = false,
x = currentStatus.y)
}),
ASL -> (currentStatus => {
@ -362,6 +372,7 @@ object FlowAnalyzerForImplied {
TSX -> (currentStatus => {
currentStatus.copy(
x = AnyStatus,
eqSX = true,
src = SourceOfNZ.X)
}),
)

View File

@ -558,6 +558,14 @@ case class HasSet(state: State.Value) extends AssemblyLinePattern {
flowInfo.hasSet(state)
}
case object XContainsStackPointer extends AssemblyLinePattern {
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit =
FlowInfoRequirement.assertForward(needsFlowInfo)
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: AssemblyLine): Boolean =
flowInfo.statusBefore.eqSX
}
case class HasSourceOfNZ(state: State.Value) extends AssemblyLinePattern {
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit =
FlowInfoRequirement.assertForward(needsFlowInfo)