mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
optimize trivial 65c02 stack instructions
This commit is contained in:
parent
1c97c22eff
commit
7a9dd1ac9b
@ -384,6 +384,7 @@ private fun optimizeStoreLoadSame(
|
|||||||
for (lines in linesByFour) {
|
for (lines in linesByFour) {
|
||||||
val first = lines[1].value.trimStart()
|
val first = lines[1].value.trimStart()
|
||||||
val second = lines[2].value.trimStart()
|
val second = lines[2].value.trimStart()
|
||||||
|
val third = lines[3].value.trimStart()
|
||||||
|
|
||||||
// sta X + lda X, sty X + ldy X, stx X + ldx X -> the second instruction can OFTEN be eliminated
|
// sta X + lda X, sty X + ldy X, stx X + ldx X -> the second instruction can OFTEN be eliminated
|
||||||
if ((first.startsWith("sta ") && second.startsWith("lda ")) ||
|
if ((first.startsWith("sta ") && second.startsWith("lda ")) ||
|
||||||
@ -393,7 +394,6 @@ private fun optimizeStoreLoadSame(
|
|||||||
(first.startsWith("ldy ") && second.startsWith("ldy ")) ||
|
(first.startsWith("ldy ") && second.startsWith("ldy ")) ||
|
||||||
(first.startsWith("ldx ") && second.startsWith("ldx "))
|
(first.startsWith("ldx ") && second.startsWith("ldx "))
|
||||||
) {
|
) {
|
||||||
val third = lines[3].value.trimStart()
|
|
||||||
val attemptRemove =
|
val attemptRemove =
|
||||||
if(third.isBranch()) {
|
if(third.isBranch()) {
|
||||||
// a branch instruction follows, we can only remove the load instruction if
|
// a branch instruction follows, we can only remove the load instruction if
|
||||||
@ -446,6 +446,23 @@ private fun optimizeStoreLoadSame(
|
|||||||
if (firstLoc == secondLoc)
|
if (firstLoc == secondLoc)
|
||||||
mods.add(Modification(lines[2].index, true, null))
|
mods.add(Modification(lines[2].index, true, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// phy + ldy + pla -> tya + ldy
|
||||||
|
// phx + ldx + pla -> txa + ldx
|
||||||
|
// pha + lda + pla -> nop
|
||||||
|
if(first=="phy" && second.startsWith("ldy ") && third=="pla") {
|
||||||
|
mods.add(Modification(lines[3].index, true, null))
|
||||||
|
mods.add(Modification(lines[1].index, false, " tya"))
|
||||||
|
}
|
||||||
|
else if(first=="phx" && second.startsWith("ldx ") && third=="pla") {
|
||||||
|
mods.add(Modification(lines[3].index, true, null))
|
||||||
|
mods.add(Modification(lines[1].index, false, " txa"))
|
||||||
|
}
|
||||||
|
else if(first=="pha" && second.startsWith("lda ") && third=="pla") {
|
||||||
|
mods.add(Modification(lines[1].index, true, null))
|
||||||
|
mods.add(Modification(lines[2].index, true, null))
|
||||||
|
mods.add(Modification(lines[3].index, true, null))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return mods
|
return mods
|
||||||
}
|
}
|
||||||
|
@ -3182,11 +3182,20 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (regs !in Cx16VirtualRegisters) {
|
if (regs !in Cx16VirtualRegisters) {
|
||||||
when (regs) {
|
if (asmgen.isTargetCpu(CpuType.CPU65c02)) {
|
||||||
RegisterOrPair.AX -> asmgen.out(" pha | txa | pha")
|
when (regs) {
|
||||||
RegisterOrPair.AY -> asmgen.out(" pha | tya | pha")
|
RegisterOrPair.AX -> asmgen.out(" pha | phx")
|
||||||
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
|
RegisterOrPair.AY -> asmgen.out(" pha | phy")
|
||||||
else -> throw AssemblyError("expected reg pair")
|
RegisterOrPair.XY -> asmgen.out(" phx | phy")
|
||||||
|
else -> throw AssemblyError("expected reg pair")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
when (regs) {
|
||||||
|
RegisterOrPair.AX -> asmgen.out(" pha | txa | pha")
|
||||||
|
RegisterOrPair.AY -> asmgen.out(" pha | tya | pha")
|
||||||
|
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
|
||||||
|
else -> throw AssemblyError("expected reg pair")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -3225,11 +3234,20 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (regs !in Cx16VirtualRegisters) {
|
if (regs !in Cx16VirtualRegisters) {
|
||||||
when (regs) {
|
if (asmgen.isTargetCpu(CpuType.CPU65c02)) {
|
||||||
RegisterOrPair.AX -> asmgen.out(" pha | txa | pha")
|
when (regs) {
|
||||||
RegisterOrPair.AY -> asmgen.out(" pha | tya | pha")
|
RegisterOrPair.AX -> asmgen.out(" pha | phx")
|
||||||
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
|
RegisterOrPair.AY -> asmgen.out(" pha | phy")
|
||||||
else -> throw AssemblyError("expected reg pair")
|
RegisterOrPair.XY -> asmgen.out(" phx | phy")
|
||||||
|
else -> throw AssemblyError("expected reg pair")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
when (regs) {
|
||||||
|
RegisterOrPair.AX -> asmgen.out(" pha | txa | pha")
|
||||||
|
RegisterOrPair.AY -> asmgen.out(" pha | tya | pha")
|
||||||
|
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
|
||||||
|
else -> throw AssemblyError("expected reg pair")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
|
@ -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)
|
https://github.com/irmen/prog8/issues/136 (string.find register order issue)
|
||||||
|
|
||||||
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:
|
if-optimization:
|
||||||
if row == NUMQUEENS {
|
if row == NUMQUEENS {
|
||||||
print_solution()
|
print_solution()
|
||||||
|
157
examples/test.p8
157
examples/test.p8
@ -1,133 +1,52 @@
|
|||||||
%import math
|
|
||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
cx16.r0sL = 127
|
signed()
|
||||||
cx16.r0sL = bytefunc(cx16.r0sL+1)
|
unsigned()
|
||||||
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
|
||||||
|
|
||||||
sub bytefunc(byte x) -> byte {
|
bvalue /= 2 ; TODO should be a simple bit shift?
|
||||||
txt.print_ubhex(x as ubyte, true)
|
wvalue /= 2 ; TODO should be a simple bit shift?
|
||||||
txt.spc()
|
|
||||||
txt.print_b(x)
|
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()
|
txt.nl()
|
||||||
return x
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub wordfunc(word x) -> word {
|
sub unsigned() {
|
||||||
txt.print_uwhex(x as uword, true)
|
ubyte @shared ubvalue = 100
|
||||||
txt.spc()
|
uword @shared uwvalue = 20000
|
||||||
txt.print_w(x)
|
|
||||||
|
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()
|
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()
|
|
||||||
;; }
|
|
||||||
;;}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user