From c1343a78f1a462628e39fa29f12d88d4954bd228 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 9 Jul 2019 21:29:20 +0200 Subject: [PATCH] when working correctly in asm (corrected dup & cmp) --- .../prog8/compiler/target/c64/AsmOptimizer.kt | 4 ++++ .../prog8/compiler/target/c64/AsmPatterns.kt | 21 ++++++++++++++++ .../prog8/compiler/target/c64/SimpleAsm.kt | 22 +++++++++-------- examples/test.p8 | 24 +++++++++++++++---- 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/compiler/src/prog8/compiler/target/c64/AsmOptimizer.kt b/compiler/src/prog8/compiler/target/c64/AsmOptimizer.kt index 2e9e199b2..3fd563aa9 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmOptimizer.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmOptimizer.kt @@ -2,6 +2,10 @@ package prog8.compiler.target.c64 import prog8.compiler.toHex + +// note: see https://wiki.nesdev.com/w/index.php/6502_assembly_optimisations + + fun optimizeAssembly(lines: MutableList): Int { var numberOfOptimizations = 0 diff --git a/compiler/src/prog8/compiler/target/c64/AsmPatterns.kt b/compiler/src/prog8/compiler/target/c64/AsmPatterns.kt index 852dc99cf..2c1634138 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmPatterns.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmPatterns.kt @@ -5,6 +5,9 @@ import prog8.compiler.intermediate.Instruction import prog8.compiler.intermediate.Opcode import prog8.compiler.toHex +// note: see https://wiki.nesdev.com/w/index.php/6502_assembly_optimisations + + internal class AsmPattern(val sequence: List, val altSequence: List?=null, val asm: (List)->String?) internal fun loadAFromIndexedByVar(idxVarInstr: Instruction, readArrayInstr: Instruction): String { @@ -2289,6 +2292,24 @@ internal val patterns = listOf( ldx ${C64Zeropage.SCRATCH_REG_X} """ } else null + }, + + AsmPattern(listOf(Opcode.DUP_W, Opcode.CMP_UW), + listOf(Opcode.DUP_W, Opcode.CMP_W)) { segment -> + """ + lda ${(ESTACK_HI+1).toHex()},x + cmp #>${segment[1].arg!!.integerValue().toHex()} + bne + + lda ${(ESTACK_LO+1).toHex()},x + cmp #<${segment[1].arg!!.integerValue().toHex()} + ; bne + not necessary? + ; lda #0 not necessary? ++ + """ + }, + AsmPattern(listOf(Opcode.DUP_B, Opcode.CMP_UB), + listOf(Opcode.DUP_B, Opcode.CMP_B)) { segment -> + """ lda ${(ESTACK_LO+1).toHex()},x | cmp #${segment[1].arg!!.integerValue().toHex()} """ } ) diff --git a/compiler/src/prog8/compiler/target/c64/SimpleAsm.kt b/compiler/src/prog8/compiler/target/c64/SimpleAsm.kt index d1e9b3f1e..9a06bc2fb 100644 --- a/compiler/src/prog8/compiler/target/c64/SimpleAsm.kt +++ b/compiler/src/prog8/compiler/target/c64/SimpleAsm.kt @@ -10,6 +10,9 @@ import prog8.vm.stackvm.Syscall import prog8.vm.stackvm.syscallsForStackVm +// note: see https://wiki.nesdev.com/w/index.php/6502_assembly_optimisations + + private var breakpointCounter = 0 internal fun simpleInstr2Asm(ins: Instruction, block: IntermediateProgram.ProgramBlock): String? { @@ -63,27 +66,26 @@ internal fun simpleInstr2Asm(ins: Instruction, block: IntermediateProgram.Progra Opcode.DISCARD_WORD -> " inx" Opcode.DISCARD_FLOAT -> " inx | inx | inx" Opcode.DUP_B -> { - " dex | lda ${(ESTACK_LO+1).toHex()},x | sta ${ESTACK_LO.toHex()},x" + " lda ${(ESTACK_LO+1).toHex()},x | sta ${ESTACK_LO.toHex()},x | dex | ;DUP_B " } Opcode.DUP_W -> { - " dex | lda ${(ESTACK_LO+1).toHex()},x | sta ${ESTACK_LO.toHex()},x | lda ${(ESTACK_HI+1).toHex()},x | sta ${ESTACK_HI.toHex()},x " + " lda ${(ESTACK_LO+1).toHex()},x | sta ${ESTACK_LO.toHex()},x | lda ${(ESTACK_HI+1).toHex()},x | sta ${ESTACK_HI.toHex()},x | dex " } Opcode.CMP_B, Opcode.CMP_UB -> { - " inx | lda ${ESTACK_LO.toHex()},x | inx | cmp ${ESTACK_LO.toHex()},x " + " inx | lda ${ESTACK_LO.toHex()},x | cmp #${ins.arg!!.integerValue().toHex()} | ;CMP_B " } Opcode.CMP_W, Opcode.CMP_UW -> { """ inx - inx - lda ${(ESTACK_HI-1).toHex()},x - cmp ${(ESTACK_HI).toHex()},x + lda ${ESTACK_HI.toHex()},x + cmp #>${ins.arg!!.integerValue().toHex()} bne + - lda ${(ESTACK_LO-1).toHex()},x - cmp ${(ESTACK_LO).toHex()},x - bne + - lda #0 + lda ${ESTACK_LO.toHex()},x + cmp #<${ins.arg!!.integerValue().toHex()} + ; bne + not necessary? + ; lda #0 not necessary? + """ } diff --git a/examples/test.p8 b/examples/test.p8 index c781fe555..f26fa13c0 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -18,13 +18,32 @@ c64scr.print_ub(aa+yy) c64scr.print("?: ") check(aa, yy) - aa+=9 + aa++ + c64scr.print_ub(aa+yy) + c64scr.print("?: ") + check(aa, yy) + aa++ c64scr.print_ub(aa+yy) c64scr.print("?: ") check(aa, yy) c64scr.print_uw(uw) c64scr.print("?: ") + checkuw(uw) + uw++ + c64scr.print_uw(uw) + c64scr.print("?: ") + checkuw(uw) + uw++ + c64scr.print_uw(uw) + c64scr.print("?: ") + checkuw(uw) + + c64scr.print("stack (255?): ") + c64scr.print_ub(X) + } + + sub checkuw(uword uw) { when uw { 12345 -> c64scr.print("12345") 12346 -> c64scr.print("12346") @@ -34,9 +53,6 @@ else -> c64scr.print("not in table") } c64.CHROUT('\n') - - c64scr.print("stack (255?): ") - c64scr.print_ub(X) } sub check(ubyte a, ubyte y) {