From 10760a53a800e0d5da863119ab003bf57dfdf947 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 29 Nov 2022 20:09:10 +0100 Subject: [PATCH] optimize cmp word equal/notequal --- .../src/prog8/codegen/cpu6502/AsmGen.kt | 16 +-- docs/source/todo.rst | 2 - examples/test.p8 | 133 +++++++----------- 3 files changed, 54 insertions(+), 97 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 720a3b8e2..30a3aeaee 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -2456,11 +2456,9 @@ $repeatLabel lda $counterVar assignExpressionToRegister(right, RegisterOrPair.AY) } else { pushCpuStack(DataType.UWORD, left) - assignExpressionToRegister(right, RegisterOrPair.AY) - out(" sta P8ZP_SCRATCH_REG") - popCpuStack(DataType.UWORD, "P8ZP_SCRATCH_W2") - out(" lda P8ZP_SCRATCH_REG") - // TODO optimize this path..... CMP_OPT + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) } out(""" cmp P8ZP_SCRATCH_W2 @@ -2544,11 +2542,9 @@ $repeatLabel lda $counterVar assignExpressionToRegister(right, RegisterOrPair.AY) } else { pushCpuStack(DataType.UWORD, left) - assignExpressionToRegister(right, RegisterOrPair.AY) - out(" sta P8ZP_SCRATCH_REG") - popCpuStack(DataType.UWORD, "P8ZP_SCRATCH_W2") - out(" lda P8ZP_SCRATCH_REG") - // TODO optimize this path..... CMP_OPT + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) } out(""" cmp P8ZP_SCRATCH_W2 diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 8735f62bf..5262a1b79 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- optimize cmp's that can use the variable directly out(" cmp $..... -- optimize cmp word equal/notequal search for CMP_OPT - 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway) then we can get rid of the instruction lists in the machinedefinitions as well. This is already no problem at all in the IR codegen. - create BSS section in output program and put StStaticVariables in there with bss=true. Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE! So requires self-modifying code diff --git a/examples/test.p8 b/examples/test.p8 index 53672cb17..6d34e6faa 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,11 +1,17 @@ %import textio %zeropage dontuse + +; base level code size: $279 + + main { bool[1] expected = [ true ] uword[1] expectedw = [4242 ] sub get() -> bool { + ubyte xx + xx = 1 %asm {{ stz P8ZP_SCRATCH_W1 stz P8ZP_SCRATCH_W1+1 @@ -14,9 +20,11 @@ main { stz P8ZP_SCRATCH_REG stz P8ZP_SCRATCH_B1 }} - return true + return xx } sub same() -> bool { + ubyte xx + xx = 1 %asm {{ stz P8ZP_SCRATCH_W1 stz P8ZP_SCRATCH_W1+1 @@ -25,10 +33,11 @@ main { stz P8ZP_SCRATCH_REG stz P8ZP_SCRATCH_B1 }} - return true + return xx } sub getw() -> uword { + uword xx=4242 %asm {{ stz P8ZP_SCRATCH_W1 stz P8ZP_SCRATCH_W1+1 @@ -37,9 +46,10 @@ main { stz P8ZP_SCRATCH_REG stz P8ZP_SCRATCH_B1 }} - return 4242 + return xx } sub samew() -> uword { + uword xx=4242 %asm {{ stz P8ZP_SCRATCH_W1 stz P8ZP_SCRATCH_W1+1 @@ -48,9 +58,22 @@ main { stz P8ZP_SCRATCH_REG stz P8ZP_SCRATCH_B1 }} - return 4242 + return xx + } + sub differentw() -> uword { + uword xx=9999 + %asm {{ + stz P8ZP_SCRATCH_W1 + stz P8ZP_SCRATCH_W1+1 + stz P8ZP_SCRATCH_W2 + stz P8ZP_SCRATCH_W2+1 + stz P8ZP_SCRATCH_REG + stz P8ZP_SCRATCH_B1 + }} + return xx } sub one() -> ubyte { + ubyte xx=1 %asm {{ stz P8ZP_SCRATCH_W1 stz P8ZP_SCRATCH_W1+1 @@ -59,110 +82,50 @@ main { stz P8ZP_SCRATCH_REG stz P8ZP_SCRATCH_B1 }} - return 1 + return xx } sub start() { - if get() == expected[0] - txt.print("ok\n") - else - txt.print("fail\n") - - ; this is working fine: - if expected[0] == get() - txt.print("ok\n") - else - txt.print("fail\n") - - if getw() == expectedw[0] - txt.print("ok\n") - else - txt.print("fail\n") - - ; this is working fine: - if expectedw[0] == getw() - txt.print("ok\n") - else - txt.print("fail\n") - - ; unquals - - if get() != expected[0] - txt.print("fail\n") - else - txt.print("ok\n") - - ; this is working fine: - if expected[0] != get() - txt.print("fail\n") - else - txt.print("ok\n") - - if getw() != expectedw[0] - txt.print("fail\n") - else - txt.print("ok\n") - - ; this is working fine: - if expectedw[0] != getw() - txt.print("fail\n") - else - txt.print("ok\n") - - ; now with 2 non-simple operands: - if get() == same() - txt.print("ok\n") - else - txt.print("fail\n") - - ; this is working fine: - if same() == get() - txt.print("ok\n") - else - txt.print("fail\n") - if getw() == samew() txt.print("ok\n") else txt.print("fail\n") - ; this is working fine: if samew() == getw() txt.print("ok\n") else txt.print("fail\n") - ; unquals - - if get() != same() - txt.print("fail\n") - else - txt.print("ok\n") - - ; this is working fine: - if same() != get() - txt.print("fail\n") - else - txt.print("ok\n") - if getw() != samew() txt.print("fail\n") else txt.print("ok\n") - ; this is working fine: if samew() != getw() txt.print("fail\n") else txt.print("ok\n") - ; pointer stuff - uword ptr = $4000 - @(ptr+one()) = 42 - if @(ptr+one()) == 42 - txt.print("ok\n") - else - txt.print("fail\n") + if getw() == differentw() + txt.print("fail\n") + else + txt.print("ok\n") + + if differentw() == getw() + txt.print("fail\n") + else + txt.print("ok\n") + + if getw() != differentw() + txt.print("ok\n") + else + txt.print("fail\n") + + if differentw() != getw() + txt.print("ok\n") + else + txt.print("fail\n") + } }