optimize simple word and byte addition/subtraction better

This commit is contained in:
Irmen de Jong 2024-06-29 14:23:17 +02:00
parent bbf621a8c4
commit 1c97c22eff
4 changed files with 172 additions and 54 deletions

View File

@ -1108,10 +1108,17 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
is PtNumber -> {
assignExpressionToRegister(left, RegisterOrPair.A, dt==DataType.BYTE)
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,6 +1253,37 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
is PtNumber -> {
assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD)
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
@ -1265,6 +1303,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
tay
txa""")
}
}
assignRegisterpairWord(target, RegisterOrPair.AY)
return true
}

View File

@ -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:

View File

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

View File

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