mirror of
https://github.com/KarolS/millfork.git
synced 2024-12-22 01:29:30 +00:00
6502: optimize bitops on words
This commit is contained in:
parent
7ded8376d8
commit
51da5ab2c0
@ -288,6 +288,7 @@ object PseudoregisterBuiltIns {
|
||||
private def compileFastWordBitOpsToAX(reads: List[List[AssemblyLine]], op: Opcode.Value): Option[List[AssemblyLine]] = {
|
||||
val resultLo = mutable.ListBuffer[AssemblyLine]()
|
||||
val resultHi = mutable.ListBuffer[AssemblyLine]()
|
||||
var complex = Option.empty[List[AssemblyLine]]
|
||||
for(read <- reads) {
|
||||
read match {
|
||||
case List(l@AssemblyLine0(LDA, Immediate | Absolute | ZeroPage, _), h@AssemblyLine0(LDX, Immediate | Absolute | ZeroPage, _)) =>
|
||||
@ -298,12 +299,43 @@ object PseudoregisterBuiltIns {
|
||||
resultHi += h.copy(opcode = op)
|
||||
resultLo += l.copy(opcode = op)
|
||||
}
|
||||
case _ => return None
|
||||
case _ =>
|
||||
if (complex.isDefined) return None
|
||||
else complex = Some(read)
|
||||
}
|
||||
}
|
||||
resultHi += AssemblyLine.implied(TAX)
|
||||
resultHi ++= resultLo
|
||||
Some(resultHi.toList)
|
||||
complex match {
|
||||
case Some(x) =>
|
||||
if (resultHi.isEmpty) {
|
||||
if (resultLo.isEmpty) return Some(x)
|
||||
else return None
|
||||
} else {
|
||||
if (resultLo.isEmpty) return None
|
||||
if (resultHi.exists(_.concernsX)) return None
|
||||
if (resultLo.exists(_.concernsX)) return None
|
||||
if (resultHi.head.opcode != LDA) return None
|
||||
if (resultLo.head.opcode != LDA) return None
|
||||
resultHi(0) = resultHi.head.copy(opcode = op)
|
||||
resultLo(0) = resultLo.head.copy(opcode = op)
|
||||
}
|
||||
val index = x.lastIndexWhere(_.opcode.==(TAX))
|
||||
if (index < 0) return None
|
||||
val (handleHigh, taxAndHandleLo) = x.splitAt(index)
|
||||
if (taxAndHandleLo.tail.exists(l => l.concernsX || (l.opcode match {
|
||||
case TAX | CLC | SEC | CLD | SED => false
|
||||
case LDA | ADC | SBC | AND | ORA | EOR => false
|
||||
case ASL | LSR | ROL | ROR => false
|
||||
case ANC | ALR | ARR => false
|
||||
case NOP => false
|
||||
case INC | DEC => l.addrMode != Implied
|
||||
case _ => true
|
||||
}))) return None
|
||||
Some(handleHigh ++ resultHi ++ taxAndHandleLo ++ resultLo)
|
||||
case None =>
|
||||
resultHi += AssemblyLine.implied(TAX)
|
||||
resultHi ++= resultLo
|
||||
Some(resultHi.toList)
|
||||
}
|
||||
}
|
||||
|
||||
def compileWordBitOpsToAX(ctx: CompilationContext, params: List[Expression], op: Opcode.Value): List[AssemblyLine] = {
|
||||
|
@ -89,4 +89,17 @@ class BitOpSuite extends FunSuite with Matchers {
|
||||
""".stripMargin
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80)(code)(_.readByte(0xc000) should equal(2))
|
||||
}
|
||||
|
||||
test("Multiple words") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
|
||||
| word output @$c000
|
||||
| void main () {
|
||||
| word v, w
|
||||
| v = $ee0e
|
||||
| barrier()
|
||||
| output = (v & $F0F0) | $0303
|
||||
| }
|
||||
| noinline void barrier(){}
|
||||
""".stripMargin)(_.readWord(0xc000) should equal(0xE303))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user