mirror of
https://github.com/KarolS/millfork.git
synced 2024-07-05 09:28:54 +00:00
hi()/lo() builtins; identity table for using index registers as operands
This commit is contained in:
parent
f31086e686
commit
3dc526bcb7
@ -54,6 +54,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
TRB, TSB)
|
TRB, TSB)
|
||||||
|
|
||||||
private val opcodesCommutative = Set(AND, ORA, EOR, ADC)
|
private val opcodesCommutative = Set(AND, ORA, EOR, ADC)
|
||||||
|
private val opcodesIdentityTable = Set(AND, ORA, EOR, CMP, ADC, SBC)
|
||||||
|
|
||||||
private val LdxAddrModes = Set(ZeroPage, Absolute, Immediate, AbsoluteY, ZeroPageY)
|
private val LdxAddrModes = Set(ZeroPage, Absolute, Immediate, AbsoluteY, ZeroPageY)
|
||||||
private val LdyAddrModes = Set(ZeroPage, Absolute, Immediate, AbsoluteX, ZeroPageX)
|
private val LdyAddrModes = Set(ZeroPage, Absolute, Immediate, AbsoluteX, ZeroPageX)
|
||||||
@ -94,13 +95,15 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val importances = ReverseFlowAnalyzer.analyze(f, code)
|
val importances = ReverseFlowAnalyzer.analyze(f, code)
|
||||||
|
val blastProcessing = options.flag(CompilationFlag.OptimizeForSonicSpeed)
|
||||||
|
val identityArray = f.environment.maybeGet[ThingInMemory]("identity$").map(MemoryAddressConstant).getOrElse(Constant.Zero)
|
||||||
|
|
||||||
val xCandidates = variablesWithLifetimes.filter {
|
val xCandidates = variablesWithLifetimes.filter {
|
||||||
case (vName, range) =>
|
case (vName, range) =>
|
||||||
importances(range.start).x != Important
|
importances(range.start).x != Important
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
case (vName, range) =>
|
case (vName, range) =>
|
||||||
canBeInlined(Some(vName), None, code.zip(importances).slice(range.start, range.end)).map { score =>
|
canBeInlined(Some(vName), None, blastProcessing, code.zip(importances).slice(range.start, range.end)).map { score =>
|
||||||
(vName, range, if (variablesWithRegisterHint(vName)) score + 16 else score)
|
(vName, range, if (variablesWithRegisterHint(vName)) score + 16 else score)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +113,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
importances(range.start).y != Important
|
importances(range.start).y != Important
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
case (vName, range) =>
|
case (vName, range) =>
|
||||||
canBeInlined(None, Some(vName), code.zip(importances).slice(range.start, range.end)).map { score =>
|
canBeInlined(None, Some(vName), blastProcessing, code.zip(importances).slice(range.start, range.end)).map { score =>
|
||||||
(vName, range, if (variablesWithRegisterHint(vName)) score + 16 else score)
|
(vName, range, if (variablesWithRegisterHint(vName)) score + 16 else score)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,7 +174,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
case (v, range, _) =>
|
case (v, range, _) =>
|
||||||
ErrorReporting.debug(s"Inlining $v to register X")
|
ErrorReporting.debug(s"Inlining $v to register X")
|
||||||
val oldCode = code.zip(importances).slice(range.start, range.end)
|
val oldCode = code.zip(importances).slice(range.start, range.end)
|
||||||
val newCode = inlineVars(Some(v), None, None, oldCode)
|
val newCode = inlineVars(Some(v), None, None, identityArray, oldCode)
|
||||||
reportOptimizedBlock(oldCode, newCode)
|
reportOptimizedBlock(oldCode, newCode)
|
||||||
output ++= newCode
|
output ++= newCode
|
||||||
i = range.end
|
i = range.end
|
||||||
@ -182,7 +185,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
case (v, range, _) =>
|
case (v, range, _) =>
|
||||||
ErrorReporting.debug(s"Inlining $v to register Y")
|
ErrorReporting.debug(s"Inlining $v to register Y")
|
||||||
val oldCode = code.zip(importances).slice(range.start, range.end)
|
val oldCode = code.zip(importances).slice(range.start, range.end)
|
||||||
val newCode = inlineVars(None, Some(v), None, oldCode)
|
val newCode = inlineVars(None, Some(v), None, identityArray, oldCode)
|
||||||
reportOptimizedBlock(oldCode, newCode)
|
reportOptimizedBlock(oldCode, newCode)
|
||||||
output ++= newCode
|
output ++= newCode
|
||||||
i = range.end
|
i = range.end
|
||||||
@ -194,7 +197,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
case (v, range, _) =>
|
case (v, range, _) =>
|
||||||
ErrorReporting.debug(s"Inlining $v to register A")
|
ErrorReporting.debug(s"Inlining $v to register A")
|
||||||
val oldCode = code.zip(importances).slice(range.start, range.end)
|
val oldCode = code.zip(importances).slice(range.start, range.end)
|
||||||
val newCode = inlineVars(None, None, Some(v), oldCode)
|
val newCode = inlineVars(None, None, Some(v), identityArray, oldCode)
|
||||||
reportOptimizedBlock(oldCode, newCode)
|
reportOptimizedBlock(oldCode, newCode)
|
||||||
output ++= newCode
|
output ++= newCode
|
||||||
i = range.end
|
i = range.end
|
||||||
@ -213,7 +216,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def canBeInlined(xCandidate: Option[String], yCandidate: Option[String], lines: List[(AssemblyLine, CpuImportance)]): Option[Int] = {
|
def canBeInlined(xCandidate: Option[String], yCandidate: Option[String], blastProcessing: Boolean, lines: List[(AssemblyLine, CpuImportance)]): Option[Int] = {
|
||||||
val vx = xCandidate.getOrElse("-")
|
val vx = xCandidate.getOrElse("-")
|
||||||
val vy = yCandidate.getOrElse("-")
|
val vy = yCandidate.getOrElse("-")
|
||||||
lines match {
|
lines match {
|
||||||
@ -231,7 +234,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
if (th.name == vx || th.name == vy) {
|
if (th.name == vx || th.name == vy) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
canBeInlined(xCandidate, yCandidate, xs)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs)
|
||||||
}
|
}
|
||||||
|
|
||||||
case (AssemblyLine(opcode, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(opcode, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
@ -250,9 +253,9 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
// removing LDX saves 3 cycles
|
// removing LDX saves 3 cycles
|
||||||
if (elidable && th.name == vx) {
|
if (elidable && th.name == vx) {
|
||||||
if (imp.z == Unimportant && imp.n == Unimportant) {
|
if (imp.z == Unimportant && imp.n == Unimportant) {
|
||||||
canBeInlined(xCandidate, yCandidate, xs).map(_ + 3)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 3)
|
||||||
} else {
|
} else {
|
||||||
canBeInlined(xCandidate, yCandidate, xs).map(_ + 1)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -263,7 +266,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
// LAX = LDX-LDA, and since LDX simplifies to nothing and LDA simplifies to TXA,
|
// LAX = LDX-LDA, and since LDX simplifies to nothing and LDA simplifies to TXA,
|
||||||
// LAX simplifies to TXA, saving two bytes
|
// LAX simplifies to TXA, saving two bytes
|
||||||
if (elidable && th.name == vx) {
|
if (elidable && th.name == vx) {
|
||||||
canBeInlined(xCandidate, yCandidate, xs).map(_ + 2)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 2)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -274,9 +277,9 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
// sometimes that LDX has to be converted into CPX#0
|
// sometimes that LDX has to be converted into CPX#0
|
||||||
if (elidable && th.name == vy) {
|
if (elidable && th.name == vy) {
|
||||||
if (imp.z == Unimportant && imp.n == Unimportant) {
|
if (imp.z == Unimportant && imp.n == Unimportant) {
|
||||||
canBeInlined(xCandidate, yCandidate, xs).map(_ + 3)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 3)
|
||||||
} else {
|
} else {
|
||||||
canBeInlined(xCandidate, yCandidate, xs).map(_ + 1)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -290,26 +293,33 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
// if a register is populated with something else than a variable, then no variable cannot be assigned to that register
|
// if a register is populated with something else than a variable, then no variable cannot be assigned to that register
|
||||||
None
|
None
|
||||||
|
|
||||||
|
case (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), elidable),_) :: xs
|
||||||
|
if opcodesIdentityTable(op) =>
|
||||||
|
if (th.name == vx || th.name == vy) {
|
||||||
|
if (elidable) canBeInlined(xCandidate, yCandidate, blastProcessing, xs)
|
||||||
|
else None
|
||||||
|
} else canBeInlined(xCandidate, yCandidate, blastProcessing, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, _, _, elidable),_) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), elidable2),_) :: xs
|
case (AssemblyLine(LDA, _, _, elidable),_) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), elidable2),_) :: xs
|
||||||
if opcodesCommutative(op) =>
|
if opcodesCommutative(op) =>
|
||||||
if (th.name == vx || th.name == vy) {
|
if (th.name == vx || th.name == vy) {
|
||||||
if (elidable && elidable2) canBeInlined(xCandidate, yCandidate, xs).map(_ + 2)
|
if (elidable && elidable2) canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 2)
|
||||||
else None
|
else None
|
||||||
} else canBeInlined(xCandidate, yCandidate, xs)
|
} else canBeInlined(xCandidate, yCandidate, blastProcessing, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, _, _, elidable),_) :: (AssemblyLine(CLC, _, _, _),_) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), elidable2),_) :: xs
|
case (AssemblyLine(LDA, _, _, elidable),_) :: (AssemblyLine(CLC, _, _, _),_) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), elidable2),_) :: xs
|
||||||
if opcodesCommutative(op) =>
|
if opcodesCommutative(op) =>
|
||||||
if (th.name == vx || th.name == vy) {
|
if (th.name == vx || th.name == vy) {
|
||||||
if (elidable && elidable2) canBeInlined(xCandidate, yCandidate, xs).map(_ + 2)
|
if (elidable && elidable2) canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 2)
|
||||||
else None
|
else None
|
||||||
} else canBeInlined(xCandidate, yCandidate, xs)
|
} else canBeInlined(xCandidate, yCandidate, blastProcessing, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), elidable), _) :: (AssemblyLine(TAX, _, _, elidable2), _) :: xs
|
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), elidable), _) :: (AssemblyLine(TAX, _, _, elidable2), _) :: xs
|
||||||
if xCandidate.isDefined =>
|
if xCandidate.isDefined =>
|
||||||
// a variable cannot be inlined if there is TAX not after LDA of that variable
|
// a variable cannot be inlined if there is TAX not after LDA of that variable
|
||||||
// but LDA-TAX can be simplified to TXA
|
// but LDA-TAX can be simplified to TXA
|
||||||
if (elidable && elidable2 && th.name == vx) {
|
if (elidable && elidable2 && th.name == vx) {
|
||||||
canBeInlined(xCandidate, yCandidate, xs).map(_ + 3)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 3)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -319,7 +329,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
// a variable cannot be inlined if there is TAY not after LDA of that variable
|
// a variable cannot be inlined if there is TAY not after LDA of that variable
|
||||||
// but LDA-TAY can be simplified to TYA
|
// but LDA-TAY can be simplified to TYA
|
||||||
if (elidable && elidable2 && th.name == vy) {
|
if (elidable && elidable2 && th.name == vy) {
|
||||||
canBeInlined(xCandidate, yCandidate, xs).map(_ + 3)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 3)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -328,12 +338,12 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
// changing LDA->TXA, STA->TAX, INC->INX, DEC->DEX, STZ->LDA saves 2 bytes
|
// changing LDA->TXA, STA->TAX, INC->INX, DEC->DEX, STZ->LDA saves 2 bytes
|
||||||
if (th.name == vy || th.name == vx) {
|
if (th.name == vy || th.name == vx) {
|
||||||
if (elidable) {
|
if (elidable) {
|
||||||
canBeInlined(xCandidate, yCandidate, xs).map(_ + 2)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs).map(_ + 2)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
canBeInlined(xCandidate, yCandidate, xs)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs)
|
||||||
}
|
}
|
||||||
|
|
||||||
case (AssemblyLine(TAX, _, _, _), _) :: xs if xCandidate.isDefined =>
|
case (AssemblyLine(TAX, _, _, _), _) :: xs if xCandidate.isDefined =>
|
||||||
@ -346,7 +356,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
|
|
||||||
case (AssemblyLine(LABEL, _, _, _), _) :: xs =>
|
case (AssemblyLine(LABEL, _, _, _), _) :: xs =>
|
||||||
// labels always end the initial section
|
// labels always end the initial section
|
||||||
canBeInlined(xCandidate, yCandidate, xs)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs)
|
||||||
|
|
||||||
case (x, _) :: xs =>
|
case (x, _) :: xs =>
|
||||||
if (xCandidate.isDefined && opcodesThatAlwaysPrecludeXAllocation(x.opcode)) {
|
if (xCandidate.isDefined && opcodesThatAlwaysPrecludeXAllocation(x.opcode)) {
|
||||||
@ -354,7 +364,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
} else if (yCandidate.isDefined && opcodesThatAlwaysPrecludeYAllocation(x.opcode)) {
|
} else if (yCandidate.isDefined && opcodesThatAlwaysPrecludeYAllocation(x.opcode)) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
canBeInlined(xCandidate, yCandidate, xs)
|
canBeInlined(xCandidate, yCandidate, blastProcessing, xs)
|
||||||
}
|
}
|
||||||
|
|
||||||
case Nil => Some(0)
|
case Nil => Some(0)
|
||||||
@ -498,170 +508,178 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def inlineVars(xCandidate: Option[String], yCandidate: Option[String], aCandidate: Option[String], lines: List[(AssemblyLine, CpuImportance)]): List[AssemblyLine] = {
|
def inlineVars(xCandidate: Option[String], yCandidate: Option[String], aCandidate: Option[String], identityArray: Constant, lines: List[(AssemblyLine, CpuImportance)]): List[AssemblyLine] = {
|
||||||
val vx = xCandidate.getOrElse("-")
|
val vx = xCandidate.getOrElse("-")
|
||||||
val vy = yCandidate.getOrElse("-")
|
val vy = yCandidate.getOrElse("-")
|
||||||
val va = aCandidate.getOrElse("-")
|
val va = aCandidate.getOrElse("-")
|
||||||
lines match {
|
lines match {
|
||||||
case (AssemblyLine(INC, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(INC, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vx =>
|
if th.name == vx =>
|
||||||
AssemblyLine.implied(INX) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(INX) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(INC, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(INC, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vy =>
|
if th.name == vy =>
|
||||||
AssemblyLine.implied(INY) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(INY) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(DEC, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(DEC, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vx =>
|
if th.name == vx =>
|
||||||
AssemblyLine.implied(DEX) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(DEX) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(DEC, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(DEC, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vy =>
|
if th.name == vy =>
|
||||||
AssemblyLine.implied(DEY) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(DEY) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(opcode@(DEC | INC | ROL | ROR | ASL | LSR), Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(opcode@(DEC | INC | ROL | ROR | ASL | LSR), Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
AssemblyLine.implied(opcode) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(opcode) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDX, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs
|
case (AssemblyLine(LDX, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs
|
||||||
if th.name == vx =>
|
if th.name == vx =>
|
||||||
if (imp.z == Unimportant && imp.n == Unimportant) {
|
if (imp.z == Unimportant && imp.n == Unimportant) {
|
||||||
inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.immediate(CPX, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.immediate(CPX, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
}
|
}
|
||||||
|
|
||||||
case (AssemblyLine(LAX, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(LAX, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vx =>
|
if th.name == vx =>
|
||||||
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
|
case (l@AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
|
if opcodesIdentityTable(op) && th.name == vx =>
|
||||||
|
l.copy(addrMode = AbsoluteX, parameter = identityArray) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
|
case (l@AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
|
if opcodesIdentityTable(op) && th.name == vy =>
|
||||||
|
l.copy(addrMode = AbsoluteY, parameter = identityArray) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == va =>
|
if opcodesCommutative(op) && th.name == va =>
|
||||||
l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == va =>
|
if opcodesCommutative(op) && th.name == va =>
|
||||||
l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == vx =>
|
if opcodesCommutative(op) && th.name == vx =>
|
||||||
AssemblyLine.implied(TXA) :: l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TXA) :: l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == vx =>
|
if opcodesCommutative(op) && th.name == vx =>
|
||||||
AssemblyLine.implied(TXA) :: l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TXA) :: l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == vy =>
|
if opcodesCommutative(op) && th.name == vy =>
|
||||||
AssemblyLine.implied(TYA) :: l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TYA) :: l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == vy =>
|
if opcodesCommutative(op) && th.name == vy =>
|
||||||
AssemblyLine.implied(TYA) :: l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TYA) :: l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA | STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs
|
case (AssemblyLine(LDA | STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
if (imp.z == Unimportant && imp.n == Unimportant) {
|
if (imp.z == Unimportant && imp.n == Unimportant) {
|
||||||
inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.immediate(CMP, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.immediate(CMP, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
}
|
}
|
||||||
|
|
||||||
case (AssemblyLine(LAX, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(LAX, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
AssemblyLine.implied(TAX) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TAX) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDY, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs
|
case (AssemblyLine(LDY, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs
|
||||||
if th.name == vy =>
|
if th.name == vy =>
|
||||||
if (imp.z == Unimportant && imp.n == Unimportant) {
|
if (imp.z == Unimportant && imp.n == Unimportant) {
|
||||||
inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.immediate(CPY, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.immediate(CPY, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
}
|
}
|
||||||
|
|
||||||
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: (AssemblyLine(TAX, _, _, true), _) :: xs
|
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: (AssemblyLine(TAX, _, _, true), _) :: xs
|
||||||
if th.name == vx =>
|
if th.name == vx =>
|
||||||
// these TXA's may get optimized away by a different optimization
|
// these TXA's may get optimized away by a different optimization
|
||||||
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: (AssemblyLine(TAY, _, _, true), _) :: xs
|
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: (AssemblyLine(TAY, _, _, true), _) :: xs
|
||||||
if th.name == vy =>
|
if th.name == vy =>
|
||||||
// these TYA's may get optimized away by a different optimization
|
// these TYA's may get optimized away by a different optimization
|
||||||
AssemblyLine.implied(TYA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TYA) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDX, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: (AssemblyLine(TXA, _, _, true), _) :: xs
|
case (AssemblyLine(LDX, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: (AssemblyLine(TXA, _, _, true), _) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
// these TAX's may get optimized away by a different optimization
|
// these TAX's may get optimized away by a different optimization
|
||||||
AssemblyLine.implied(TAX) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TAX) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDY, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: (AssemblyLine(TYA, _, _, true), _) :: xs
|
case (AssemblyLine(LDY, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: (AssemblyLine(TYA, _, _, true), _) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
// these TAY's may get optimized away by a different optimization
|
// these TAY's may get optimized away by a different optimization
|
||||||
AssemblyLine.implied(TAY) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TAY) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, am, param, true), _) :: (AssemblyLine(STA, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: xs
|
case (AssemblyLine(LDA, am, param, true), _) :: (AssemblyLine(STA, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: xs
|
||||||
if th.name == vx && LdxAddrModes(am) =>
|
if th.name == vx && LdxAddrModes(am) =>
|
||||||
// these TXA's may get optimized away by a different optimization
|
// these TXA's may get optimized away by a different optimization
|
||||||
AssemblyLine(LDX, am, param) :: AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine(LDX, am, param) :: AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, am, param, true), _) :: (AssemblyLine(STA, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: xs
|
case (AssemblyLine(LDA, am, param, true), _) :: (AssemblyLine(STA, Absolute | ZeroPage, MemoryAddressConstant(th), true), _) :: xs
|
||||||
if th.name == vy && LdyAddrModes(am) =>
|
if th.name == vy && LdyAddrModes(am) =>
|
||||||
// these TYA's may get optimized away by a different optimization
|
// these TYA's may get optimized away by a different optimization
|
||||||
AssemblyLine(LDY, am, param) :: AssemblyLine.implied(TYA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine(LDY, am, param) :: AssemblyLine.implied(TYA) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: (AssemblyLine(CMP, am, param, true), _) :: xs
|
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: (AssemblyLine(CMP, am, param, true), _) :: xs
|
||||||
if th.name == vx && doesntUseXOrY(am) =>
|
if th.name == vx && doesntUseXOrY(am) =>
|
||||||
// ditto
|
// ditto
|
||||||
AssemblyLine.implied(TXA) :: AssemblyLine(CPX, am, param) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TXA) :: AssemblyLine(CPX, am, param) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: (AssemblyLine(CMP, am, param, true), _) :: xs
|
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: (AssemblyLine(CMP, am, param, true), _) :: xs
|
||||||
if th.name == vy && doesntUseXOrY(am) =>
|
if th.name == vy && doesntUseXOrY(am) =>
|
||||||
// ditto
|
// ditto
|
||||||
AssemblyLine.implied(TYA) :: AssemblyLine(CPY, am, param) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TYA) :: AssemblyLine(CPY, am, param) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vx =>
|
if th.name == vx =>
|
||||||
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vy =>
|
if th.name == vy =>
|
||||||
AssemblyLine.implied(TYA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TYA) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDX, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(LDX, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
AssemblyLine.implied(TAX) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TAX) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDY, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(LDY, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
AssemblyLine.implied(TAY) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TAY) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vx =>
|
if th.name == vx =>
|
||||||
AssemblyLine.implied(TAX) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TAX) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vy =>
|
if th.name == vy =>
|
||||||
AssemblyLine.implied(TAY) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TAY) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(STX, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(STX, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(STY, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(STY, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
AssemblyLine.implied(TYA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TYA) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(STZ, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(STZ, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vx =>
|
if th.name == vx =>
|
||||||
AssemblyLine.immediate(LDX, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.immediate(LDX, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(STZ, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(STZ, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == vy =>
|
if th.name == vy =>
|
||||||
AssemblyLine.immediate(LDY, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.immediate(LDY, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(STZ, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
case (AssemblyLine(STZ, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
AssemblyLine.immediate(LDA, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.immediate(LDA, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(TAX, _, _, _), _) :: xs if xCandidate.isDefined =>
|
case (AssemblyLine(TAX, _, _, _), _) :: xs if xCandidate.isDefined =>
|
||||||
ErrorReporting.fatal("Unexpected TAX")
|
ErrorReporting.fatal("Unexpected TAX")
|
||||||
@ -670,12 +688,12 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
ErrorReporting.fatal("Unexpected TAY")
|
ErrorReporting.fatal("Unexpected TAY")
|
||||||
|
|
||||||
case (AssemblyLine(TXA, _, _, _), _) :: xs if aCandidate.isDefined =>
|
case (AssemblyLine(TXA, _, _, _), _) :: xs if aCandidate.isDefined =>
|
||||||
AssemblyLine.immediate(CPX, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.immediate(CPX, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (AssemblyLine(TYA, _, _, _), _) :: xs if aCandidate.isDefined =>
|
case (AssemblyLine(TYA, _, _, _), _) :: xs if aCandidate.isDefined =>
|
||||||
AssemblyLine.immediate(CPY, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.immediate(CPY, 0) :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case (x, _) :: xs => x :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
case (x, _) :: xs => x :: inlineVars(xCandidate, yCandidate, aCandidate, identityArray, xs)
|
||||||
|
|
||||||
case Nil => Nil
|
case Nil => Nil
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,8 @@ object ExpressionCompiler {
|
|||||||
w
|
w
|
||||||
case SumExpression(params, _) => b
|
case SumExpression(params, _) => b
|
||||||
case FunctionCallExpression("not", params) => bool
|
case FunctionCallExpression("not", params) => bool
|
||||||
|
case FunctionCallExpression("hi", params) => bool
|
||||||
|
case FunctionCallExpression("lo", params) => bool
|
||||||
case FunctionCallExpression("*", params) => b
|
case FunctionCallExpression("*", params) => b
|
||||||
case FunctionCallExpression("|", params) => b
|
case FunctionCallExpression("|", params) => b
|
||||||
case FunctionCallExpression("&", params) => b
|
case FunctionCallExpression("&", params) => b
|
||||||
@ -376,13 +378,8 @@ object ExpressionCompiler {
|
|||||||
case RegisterVariable(Register.AX, _) =>
|
case RegisterVariable(Register.AX, _) =>
|
||||||
exprType.size match {
|
exprType.size match {
|
||||||
case 1 => if (exprType.isSigned) {
|
case 1 => if (exprType.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
|
||||||
AssemblyLine.variable(ctx, LDA, source) ++ List(
|
AssemblyLine.variable(ctx, LDA, source) ++ List(
|
||||||
AssemblyLine.implied(PHA),
|
AssemblyLine.implied(PHA)) ++ signExtendA() ++ List(
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label),
|
|
||||||
AssemblyLine.implied(TAX),
|
AssemblyLine.implied(TAX),
|
||||||
AssemblyLine.implied(PLA))
|
AssemblyLine.implied(PLA))
|
||||||
} else AssemblyLine.variable(ctx, LDA, source) :+ AssemblyLine.immediate(LDX, 0)
|
} else AssemblyLine.variable(ctx, LDA, source) :+ AssemblyLine.immediate(LDX, 0)
|
||||||
@ -392,13 +389,8 @@ object ExpressionCompiler {
|
|||||||
case RegisterVariable(Register.AY, _) =>
|
case RegisterVariable(Register.AY, _) =>
|
||||||
exprType.size match {
|
exprType.size match {
|
||||||
case 1 => if (exprType.isSigned) {
|
case 1 => if (exprType.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
|
||||||
AssemblyLine.variable(ctx, LDA, source) ++ List(
|
AssemblyLine.variable(ctx, LDA, source) ++ List(
|
||||||
AssemblyLine.implied(PHA),
|
AssemblyLine.implied(PHA)) ++ signExtendA() ++ List(
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label),
|
|
||||||
AssemblyLine.implied(TAY),
|
AssemblyLine.implied(TAY),
|
||||||
AssemblyLine.implied(PLA))
|
AssemblyLine.implied(PLA))
|
||||||
} else {
|
} else {
|
||||||
@ -410,13 +402,7 @@ object ExpressionCompiler {
|
|||||||
case RegisterVariable(Register.XA, _) =>
|
case RegisterVariable(Register.XA, _) =>
|
||||||
exprType.size match {
|
exprType.size match {
|
||||||
case 1 => if (exprType.isSigned) {
|
case 1 => if (exprType.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
AssemblyLine.variable(ctx, LDX, source) ++ List(AssemblyLine.implied(TXA)) ++ signExtendA()
|
||||||
AssemblyLine.variable(ctx, LDX, source) ++ List(
|
|
||||||
AssemblyLine.implied(TXA),
|
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label))
|
|
||||||
} else
|
} else
|
||||||
AssemblyLine.variable(ctx, LDX, source) :+ AssemblyLine.immediate(LDA, 0)
|
AssemblyLine.variable(ctx, LDX, source) :+ AssemblyLine.immediate(LDA, 0)
|
||||||
case 2 =>
|
case 2 =>
|
||||||
@ -425,13 +411,7 @@ object ExpressionCompiler {
|
|||||||
case RegisterVariable(Register.YA, _) =>
|
case RegisterVariable(Register.YA, _) =>
|
||||||
exprType.size match {
|
exprType.size match {
|
||||||
case 1 => if (exprType.isSigned) {
|
case 1 => if (exprType.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
AssemblyLine.variable(ctx, LDY, source) ++ List(AssemblyLine.implied(TYA)) ++ signExtendA()
|
||||||
AssemblyLine.variable(ctx, LDY, source) ++ List(
|
|
||||||
AssemblyLine.implied(TYA),
|
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label))
|
|
||||||
} else
|
} else
|
||||||
AssemblyLine.variable(ctx, LDY, source) :+ AssemblyLine.immediate(LDA, 0)
|
AssemblyLine.variable(ctx, LDY, source) :+ AssemblyLine.immediate(LDA, 0)
|
||||||
case 2 =>
|
case 2 =>
|
||||||
@ -444,13 +424,7 @@ object ExpressionCompiler {
|
|||||||
} else {
|
} else {
|
||||||
val copy = List.tabulate(exprType.size)(i => AssemblyLine.variable(ctx, LDA, source, i) ++ AssemblyLine.variable(ctx, STA, target, i))
|
val copy = List.tabulate(exprType.size)(i => AssemblyLine.variable(ctx, LDA, source, i) ++ AssemblyLine.variable(ctx, STA, target, i))
|
||||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
signExtendA() ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||||
List(
|
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label)) ++
|
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.immediate(LDA, 0) ::
|
AssemblyLine.immediate(LDA, 0) ::
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||||
@ -464,13 +438,7 @@ object ExpressionCompiler {
|
|||||||
} else {
|
} else {
|
||||||
val copy = List.tabulate(exprType.size)(i => AssemblyLine.variable(ctx, LDA, source, i) :+ AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i))
|
val copy = List.tabulate(exprType.size)(i => AssemblyLine.variable(ctx, LDA, source, i) :+ AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i))
|
||||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
signExtendA() ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||||
List(
|
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label)) ++
|
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.immediate(LDA, 0) ::
|
AssemblyLine.immediate(LDA, 0) ::
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||||
@ -486,15 +454,10 @@ object ExpressionCompiler {
|
|||||||
case RegisterVariable(Register.AX, _) =>
|
case RegisterVariable(Register.AX, _) =>
|
||||||
exprType.size match {
|
exprType.size match {
|
||||||
case 1 => if (exprType.isSigned) {
|
case 1 => if (exprType.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
|
||||||
List(
|
List(
|
||||||
AssemblyLine.implied(TSX),
|
AssemblyLine.implied(TSX),
|
||||||
AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset),
|
AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset),
|
||||||
AssemblyLine.implied(PHA),
|
AssemblyLine.implied(PHA)) ++ signExtendA() ++ List(
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label),
|
|
||||||
AssemblyLine.implied(TAX),
|
AssemblyLine.implied(TAX),
|
||||||
AssemblyLine.implied(PLA))
|
AssemblyLine.implied(PLA))
|
||||||
} else List(
|
} else List(
|
||||||
@ -550,13 +513,7 @@ object ExpressionCompiler {
|
|||||||
} else {
|
} else {
|
||||||
val copy = List.tabulate(exprType.size)(i => AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset + i) :: AssemblyLine.variable(ctx, STA, target, i))
|
val copy = List.tabulate(exprType.size)(i => AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset + i) :: AssemblyLine.variable(ctx, STA, target, i))
|
||||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
signExtendA() ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||||
List(
|
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label)) ++
|
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.immediate(LDA, 0) ::
|
AssemblyLine.immediate(LDA, 0) ::
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||||
@ -570,13 +527,7 @@ object ExpressionCompiler {
|
|||||||
} else {
|
} else {
|
||||||
val copy = List.tabulate(exprType.size)(i => List(AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset + i), AssemblyLine.absoluteX(STA, target.baseOffset + i)))
|
val copy = List.tabulate(exprType.size)(i => List(AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset + i), AssemblyLine.absoluteX(STA, target.baseOffset + i)))
|
||||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
signExtendA() ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||||
List(
|
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label)) ++
|
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.immediate(LDA, 0) ::
|
AssemblyLine.immediate(LDA, 0) ::
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||||
@ -606,13 +557,7 @@ object ExpressionCompiler {
|
|||||||
AssemblyLine.variable(ctx, STA, target)
|
AssemblyLine.variable(ctx, STA, target)
|
||||||
}
|
}
|
||||||
else if (target.typ.isSigned) {
|
else if (target.typ.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
AssemblyLine.variable(ctx, STA, target) ++ signExtendA() ++
|
||||||
AssemblyLine.variable(ctx, STA, target) ++
|
|
||||||
List(
|
|
||||||
AssemblyLine.immediate(ORA, 0x7f),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label)) ++
|
|
||||||
List.tabulate(target.typ.size - 1)(i => AssemblyLine.variable(ctx, STA, target, i + 1)).flatten
|
List.tabulate(target.typ.size - 1)(i => AssemblyLine.variable(ctx, STA, target, i + 1)).flatten
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.variable(ctx, STA, target) ++
|
AssemblyLine.variable(ctx, STA, target) ++
|
||||||
@ -734,6 +679,26 @@ object ExpressionCompiler {
|
|||||||
case "not" =>
|
case "not" =>
|
||||||
assertBool(ctx, params, 1)
|
assertBool(ctx, params, 1)
|
||||||
compile(ctx, params.head, exprTypeAndVariable, branches.flip)
|
compile(ctx, params.head, exprTypeAndVariable, branches.flip)
|
||||||
|
case "hi" | "lo" =>
|
||||||
|
val hi = name == "hi"
|
||||||
|
if (params.length != 1) {
|
||||||
|
ErrorReporting.error("Too many parameters for hi/lo", f.position)
|
||||||
|
Nil
|
||||||
|
} else {
|
||||||
|
val param = params.head
|
||||||
|
val typ = getExpressionType(ctx, param)
|
||||||
|
if (typ.size < 1 || typ.size > 2) {
|
||||||
|
ErrorReporting.error("Invalid parameter type for hi/lo", param.position)
|
||||||
|
compile(ctx, param, None, BranchSpec.None)
|
||||||
|
} else {
|
||||||
|
val compilation = compile(ctx, param, Some(w -> RegisterVariable(Register.AX, w)), BranchSpec.None)
|
||||||
|
if (hi) {
|
||||||
|
if (typ.size == 2) compilation :+ AssemblyLine.implied(TXA)
|
||||||
|
else if (typ.isSigned) compilation ++ signExtendA()
|
||||||
|
else List(AssemblyLine.immediate(LDA, 0))
|
||||||
|
} else compilation
|
||||||
|
}
|
||||||
|
}
|
||||||
case "&&" =>
|
case "&&" =>
|
||||||
assertBool(ctx, params, 2)
|
assertBool(ctx, params, 2)
|
||||||
val a = params.head
|
val a = params.head
|
||||||
@ -1151,12 +1116,7 @@ object ExpressionCompiler {
|
|||||||
AssemblyLine.variable(ctx, STA, v)
|
AssemblyLine.variable(ctx, STA, v)
|
||||||
case s if s > 1 =>
|
case s if s > 1 =>
|
||||||
if (t.isSigned) {
|
if (t.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
AssemblyLine.variable(ctx, STA, v) ++ signExtendA() ++ List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, v, i + 1)).flatten
|
||||||
AssemblyLine.variable(ctx, STA, v)++List(
|
|
||||||
AssemblyLine.immediate(ORA, 0x7f),
|
|
||||||
AssemblyLine.relative(BMI, label),
|
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label)) ++ List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, v, i + 1)).flatten
|
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.variable(ctx, STA, v) ++ List(AssemblyLine.immediate(LDA, 0)) ++
|
AssemblyLine.variable(ctx, STA, v) ++ List(AssemblyLine.immediate(LDA, 0)) ++
|
||||||
List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, v, i + 1)).flatten
|
List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, v, i + 1)).flatten
|
||||||
@ -1170,13 +1130,11 @@ object ExpressionCompiler {
|
|||||||
AssemblyLine.variable(ctx, STA, v) ++ AssemblyLine.variable(ctx, STX, v, 1)
|
AssemblyLine.variable(ctx, STA, v) ++ AssemblyLine.variable(ctx, STX, v, 1)
|
||||||
case s if s > 2 =>
|
case s if s > 2 =>
|
||||||
if (t.isSigned) {
|
if (t.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
AssemblyLine.variable(ctx, STA, v) ++
|
||||||
AssemblyLine.variable(ctx, STA, v) ++ AssemblyLine.variable(ctx, STX, v, 1) ++ List(
|
AssemblyLine.variable(ctx, STX, v, 1) ++
|
||||||
AssemblyLine.implied(TXA),
|
List(AssemblyLine.implied(TXA)) ++
|
||||||
AssemblyLine.immediate(ORA, 0x7f),
|
signExtendA() ++
|
||||||
AssemblyLine.relative(BMI, label),
|
List.tabulate(s - 2)(i => AssemblyLine.variable(ctx, STA, v, i + 2)).flatten
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label)) ++ List.tabulate(s - 2)(i => AssemblyLine.variable(ctx, STA, v, i + 2)).flatten
|
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.variable(ctx, STA, v) ++ AssemblyLine.variable(ctx, STX, v, 1) ++ List(
|
AssemblyLine.variable(ctx, STA, v) ++ AssemblyLine.variable(ctx, STX, v, 1) ++ List(
|
||||||
AssemblyLine.immediate(LDA, 0)) ++
|
AssemblyLine.immediate(LDA, 0)) ++
|
||||||
@ -1190,14 +1148,11 @@ object ExpressionCompiler {
|
|||||||
List(AssemblyLine.implied(TSX), AssemblyLine.absoluteX(STA, v.baseOffset + ctx.extraStackOffset))
|
List(AssemblyLine.implied(TSX), AssemblyLine.absoluteX(STA, v.baseOffset + ctx.extraStackOffset))
|
||||||
case s if s > 1 =>
|
case s if s > 1 =>
|
||||||
if (t.isSigned) {
|
if (t.isSigned) {
|
||||||
val label = MfCompiler.nextLabel("sx")
|
|
||||||
List(
|
List(
|
||||||
AssemblyLine.implied(TSX),
|
AssemblyLine.implied(TSX),
|
||||||
AssemblyLine.absoluteX(STA, v.baseOffset + ctx.extraStackOffset),
|
AssemblyLine.absoluteX(STA, v.baseOffset + ctx.extraStackOffset)) ++
|
||||||
AssemblyLine.immediate(ORA, 0x7f),
|
signExtendA() ++
|
||||||
AssemblyLine.relative(BMI, label),
|
List.tabulate(s - 1)(i => AssemblyLine.absoluteX(STA, v.baseOffset + ctx.extraStackOffset + i + 1))
|
||||||
AssemblyLine.immediate(LDA, 0),
|
|
||||||
AssemblyLine.label(label)) ++ List.tabulate(s - 1)(i => AssemblyLine.absoluteX(STA, v.baseOffset + ctx.extraStackOffset + i + 1))
|
|
||||||
} else {
|
} else {
|
||||||
List(
|
List(
|
||||||
AssemblyLine.implied(TSX),
|
AssemblyLine.implied(TSX),
|
||||||
@ -1297,4 +1252,13 @@ object ExpressionCompiler {
|
|||||||
Nil
|
Nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def signExtendA(): List[AssemblyLine] = {
|
||||||
|
val label = MfCompiler.nextLabel("sx")
|
||||||
|
List(
|
||||||
|
AssemblyLine.immediate(ORA, 0x7F),
|
||||||
|
AssemblyLine.relative(BMI, label),
|
||||||
|
AssemblyLine.immediate(LDA, 0),
|
||||||
|
AssemblyLine.label(label))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -723,6 +723,9 @@ class Environment(val parent: Option[Environment], val prefix: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def collectDeclarations(program: Program, options: CompilationOptions): Unit = {
|
def collectDeclarations(program: Program, options: CompilationOptions): Unit = {
|
||||||
|
if (options.flag(CompilationFlag.OptimizeForSonicSpeed)) {
|
||||||
|
addThing(InitializedArray("identity$", None, List.tabulate(256)(n => NumericConstant(n, 1))), None)
|
||||||
|
}
|
||||||
program.declarations.foreach {
|
program.declarations.foreach {
|
||||||
case f: FunctionDeclarationStatement => registerFunction(f, options)
|
case f: FunctionDeclarationStatement => registerFunction(f, options)
|
||||||
case v: VariableDeclarationStatement => registerVariable(v, options)
|
case v: VariableDeclarationStatement => registerVariable(v, options)
|
||||||
@ -774,9 +777,13 @@ class Environment(val parent: Option[Environment], val prefix: String) {
|
|||||||
case SumExpression(params, _) =>
|
case SumExpression(params, _) =>
|
||||||
nameCheck(params.map(_._2))
|
nameCheck(params.map(_._2))
|
||||||
case FunctionCallExpression(name, params) =>
|
case FunctionCallExpression(name, params) =>
|
||||||
if (name.exists(_.isLetter) && name != "not") {
|
if (name.exists(_.isLetter) && !Environment.predefinedFunctions(name)) {
|
||||||
checkName[CallableThing]("Function or type", name, node.position)
|
checkName[CallableThing]("Function or type", name, node.position)
|
||||||
}
|
}
|
||||||
nameCheck(params)
|
nameCheck(params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Environment {
|
||||||
|
val predefinedFunctions = Set("not", "hi", "lo")
|
||||||
|
}
|
||||||
|
@ -100,4 +100,36 @@ class WordMathSuite extends FunSuite with Matchers {
|
|||||||
| }
|
| }
|
||||||
""".stripMargin)(m => ())
|
""".stripMargin)(m => ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("hi()/lo()") {
|
||||||
|
EmuBenchmarkRun("""
|
||||||
|
| array output [7] @$c000
|
||||||
|
| void main () {
|
||||||
|
| output[0] = lo(33)
|
||||||
|
| output[1] = hi(33)
|
||||||
|
| output[2] = hi(w($504))
|
||||||
|
| output[3] = lo(w($209))
|
||||||
|
| output[4] = hi(s(-2))
|
||||||
|
| output[5] = lo(s(-2))
|
||||||
|
| output[6] = hi(b(200) + b(200))
|
||||||
|
| }
|
||||||
|
| word w(word w) {
|
||||||
|
| return w
|
||||||
|
| }
|
||||||
|
| byte b(byte b) {
|
||||||
|
| return b
|
||||||
|
| }
|
||||||
|
| sbyte s(sbyte s) {
|
||||||
|
| return s
|
||||||
|
| }
|
||||||
|
""".stripMargin){ m =>
|
||||||
|
m.readByte(0xc000) should equal(33)
|
||||||
|
m.readByte(0xc001) should equal(0)
|
||||||
|
m.readByte(0xc002) should equal(5)
|
||||||
|
m.readByte(0xc003) should equal(9)
|
||||||
|
m.readByte(0xc004) should equal(255)
|
||||||
|
m.readByte(0xc005) should equal(254)
|
||||||
|
m.readByte(0xc006) should equal(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,10 @@ object EmuOptimizedInlinedRun extends EmuRun(
|
|||||||
OptimizationPresets.Good ++ LaterOptimizations.Nmos ++
|
OptimizationPresets.Good ++ LaterOptimizations.Nmos ++
|
||||||
OptimizationPresets.Good ++ LaterOptimizations.Nmos ++
|
OptimizationPresets.Good ++ LaterOptimizations.Nmos ++
|
||||||
OptimizationPresets.Good,
|
OptimizationPresets.Good,
|
||||||
false)
|
false) {
|
||||||
|
override def inline: Boolean = true
|
||||||
|
override def blastProcessing: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ class EmuRun(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimization],
|
|||||||
|
|
||||||
def inline = false
|
def inline = false
|
||||||
|
|
||||||
|
def blastProcessing = false
|
||||||
|
|
||||||
private val timingNmos = Array[Int](
|
private val timingNmos = Array[Int](
|
||||||
7, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6,
|
7, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6,
|
||||||
2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
|
2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
|
||||||
@ -96,6 +98,7 @@ class EmuRun(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimization],
|
|||||||
CompilationFlag.InlineFunctions -> this.inline,
|
CompilationFlag.InlineFunctions -> this.inline,
|
||||||
CompilationFlag.CompactReturnDispatchParams -> true,
|
CompilationFlag.CompactReturnDispatchParams -> true,
|
||||||
CompilationFlag.EmitCmosOpcodes -> (platform.cpu == millfork.Cpu.Cmos),
|
CompilationFlag.EmitCmosOpcodes -> (platform.cpu == millfork.Cpu.Cmos),
|
||||||
|
CompilationFlag.OptimizeForSonicSpeed -> blastProcessing
|
||||||
// CompilationFlag.CheckIndexOutOfBounds -> true,
|
// CompilationFlag.CheckIndexOutOfBounds -> true,
|
||||||
))
|
))
|
||||||
ErrorReporting.hasErrors = false
|
ErrorReporting.hasErrors = false
|
||||||
|
Loading…
Reference in New Issue
Block a user