From 1c97c22eff21f9b75d0b08fa485a384368403d53 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 29 Jun 2024 14:23:17 +0200 Subject: [PATCH] optimize simple word and byte addition/subtraction better --- .../cpu6502/assignment/AssignmentAsmGen.kt | 55 +++++- docs/source/todo.rst | 2 - examples/cx16/testmonogfx.p8 | 12 +- examples/test.p8 | 157 +++++++++++++----- 4 files changed, 172 insertions(+), 54 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index d375412cf..012aec2dc 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -1108,10 +1108,17 @@ internal class AssignmentAsmGen(private val program: PtProgram, } is PtNumber -> { assignExpressionToRegister(left, RegisterOrPair.A, dt==DataType.BYTE) - if(expr.operator=="+") - asmgen.out(" clc | adc #${right.number.toHex()}") - else - asmgen.out(" sec | sbc #${right.number.toHex()}") + if(right.number==1.0 && asmgen.isTargetCpu(CpuType.CPU65c02)) { + if (expr.operator == "+") + asmgen.out(" inc a") + else + asmgen.out(" dec a") + } else { + if (expr.operator == "+") + asmgen.out(" clc | adc #${right.number.toHex()}") + else + asmgen.out(" sec | sbc #${right.number.toHex()}") + } assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true) return true } @@ -1246,8 +1253,39 @@ internal class AssignmentAsmGen(private val program: PtProgram, } is PtNumber -> { assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD) - if(expr.operator=="+") { - asmgen.out(""" + if(right.number==1.0 && asmgen.isTargetCpu(CpuType.CPU65c02)) { + if(expr.operator=="+") { + asmgen.out(""" + inc a + bne + + iny ++""") + } else { + asmgen.out(""" + dec a + cmp #255 + bne + + dey ++""") + } + } else if(dt!=DataType.WORD && right.number.toInt() in 0..255) { + if(expr.operator=="+") { + asmgen.out(""" + clc + adc #${right.number.toHex()} + bcc + + iny ++""") } else if(expr.operator=="-") { + asmgen.out(""" + sec + sbc #${right.number.toHex()} + bcs + + dey ++""") + } + } else { + if(expr.operator=="+") { + asmgen.out(""" clc adc #<${right.number.toHex()} tax @@ -1255,8 +1293,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, adc #>${right.number.toHex()} tay txa""") - } else if(expr.operator=="-") { - asmgen.out(""" + } else if(expr.operator=="-") { + asmgen.out(""" sec sbc #<${right.number.toHex()} tax @@ -1264,6 +1302,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, sbc #>${right.number.toHex()} tay txa""") + } } assignRegisterpairWord(target, RegisterOrPair.AY) return true diff --git a/docs/source/todo.rst b/docs/source/todo.rst index ede881340..528257362 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -6,8 +6,6 @@ causes compiler error for virtual: just calling txt.cls() gives compile error un https://github.com/irmen/prog8/issues/136 (string.find register order issue) -optimization: for 65c02 sometimes clc adc #1 is generated (for instance for: cx16.r0L = math.sin8u(cx16.r0L+1)), this can be optimized into inc a (always? or not? mind the carry flag!) - optimization: for 65c02 sometimes tya pha is generated, could be just phy (mind if A gets used afterwards though!) (same for pla tay etcetera?) if-optimization: diff --git a/examples/cx16/testmonogfx.p8 b/examples/cx16/testmonogfx.p8 index 3af64e06d..b4dd75a2a 100644 --- a/examples/cx16/testmonogfx.p8 +++ b/examples/cx16/testmonogfx.p8 @@ -9,12 +9,12 @@ main { sub start() { -; monogfx.lores() -; demofill() -; sys.wait(2*60) -; monogfx.hires() -; demo1() -; sys.wait(2*60) + monogfx.lores() + demofill() + sys.wait(2*60) + monogfx.hires() + demo1() + sys.wait(2*60) demo2() monogfx.textmode() diff --git a/examples/test.p8 b/examples/test.p8 index af9b00870..39d622b6b 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,52 +1,133 @@ +%import math %import textio %zeropage basicsafe -%option no_sysinit main { sub start() { - signed() - unsigned() + cx16.r0sL = 127 + cx16.r0sL = bytefunc(cx16.r0sL+1) + cx16.r0sL = 0 + cx16.r0sL = bytefunc(cx16.r0sL-1) + cx16.r0sL = 55 + cx16.r0sL = bytefunc(cx16.r0sL+20) + cx16.r0sL = 55 + cx16.r0sL = bytefunc(cx16.r0sL-20) + + cx16.r0s = $99ff as word + cx16.r0s = wordfunc(cx16.r0s+1) + cx16.r0s = $9900 as word + cx16.r0s = wordfunc(cx16.r0s-1) + cx16.r0s = -12345 + cx16.r0s = wordfunc(cx16.r0s+100) + cx16.r0s = -12345 + cx16.r0s = wordfunc(cx16.r0s-100) } - sub signed() { - byte @shared bvalue = -100 - word @shared wvalue = -20000 - bvalue /= 2 ; TODO should be a simple bit shift? - wvalue /= 2 ; TODO should be a simple bit shift? - - txt.print_b(bvalue) - txt.nl() - txt.print_w(wvalue) - txt.nl() - - bvalue *= 2 - wvalue *= 2 - - txt.print_b(bvalue) - txt.nl() - txt.print_w(wvalue) + sub bytefunc(byte x) -> byte { + txt.print_ubhex(x as ubyte, true) + txt.spc() + txt.print_b(x) txt.nl() + return x } - sub unsigned() { - ubyte @shared ubvalue = 100 - uword @shared uwvalue = 20000 - - ubvalue /= 2 - uwvalue /= 2 - - txt.print_ub(ubvalue) - txt.nl() - txt.print_uw(uwvalue) - txt.nl() - - ubvalue *= 2 - uwvalue *= 2 - - txt.print_ub(ubvalue) - txt.nl() - txt.print_uw(uwvalue) + sub wordfunc(word x) -> word { + txt.print_uwhex(x as uword, true) + txt.spc() + txt.print_w(x) txt.nl() + return x } } + +;%import math +;%import sprites +; +;main { +; word[128] @split xpos_orig +; word[128] @split ypos_orig +; word[128] xpos +; word[128] ypos +; ubyte[128] tt +; +; sub start() { +; cx16.mouse_config2(1) +; sprites.set_mousepointer_hand() +; ubyte sprdat_bank +; uword sprdat_addr +; sprdat_bank, sprdat_addr = sprites.get_data_ptr(0) +; +; ubyte sprite +; for sprite in 0 to 127 { +; sprites.init(sprite, sprdat_bank, sprdat_addr, sprites.SIZE_16, sprites.SIZE_16, sprites.COLORS_256, 0) +; xpos_orig[sprite] = sprite*$0003 +100 as word +; ypos_orig[sprite] = sprite*$0002 +100 as word +; tt[sprite] = math.rnd() +; } +; +; repeat { +; sys.waitvsync() +; sprites.pos_batch(0, 128, &xpos, &ypos) +; for sprite in 0 to 127 { +; tt[sprite]++ +; xpos[sprite] = xpos_orig[sprite] + math.sin8(tt[sprite]) +; ypos[sprite] = ypos_orig[sprite] + math.cos8(tt[sprite]) +; } +; } +; } +;} +; +; +;;%import textio +;;%zeropage basicsafe +;;%option no_sysinit +;; +;;main { +;; sub start() { +;; signed() +;; unsigned() +;; } +;; +;; sub signed() { +;; byte @shared bvalue = -100 +;; word @shared wvalue = -20000 +;; +;; bvalue /= 2 ; TODO should be a simple bit shift? +;; wvalue /= 2 ; TODO should be a simple bit shift? +;; +;; txt.print_b(bvalue) +;; txt.nl() +;; txt.print_w(wvalue) +;; txt.nl() +;; +;; bvalue *= 2 +;; wvalue *= 2 +;; +;; txt.print_b(bvalue) +;; txt.nl() +;; txt.print_w(wvalue) +;; txt.nl() +;; } +;; +;; sub unsigned() { +;; ubyte @shared ubvalue = 100 +;; uword @shared uwvalue = 20000 +;; +;; ubvalue /= 2 +;; uwvalue /= 2 +;; +;; txt.print_ub(ubvalue) +;; txt.nl() +;; txt.print_uw(uwvalue) +;; txt.nl() +;; +;; ubvalue *= 2 +;; uwvalue *= 2 +;; +;; txt.print_ub(ubvalue) +;; txt.nl() +;; txt.print_uw(uwvalue) +;; txt.nl() +;; } +;;}