6502: optimize bitops on words

This commit is contained in:
Karol Stasiak 2019-08-01 13:27:03 +02:00
parent 7ded8376d8
commit 51da5ab2c0
2 changed files with 49 additions and 4 deletions

View File

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

View File

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