no longer clear msb on asmsub argument byte @R0

avoid unneeded push/pop for 2 byte arguments to a functioncall
This commit is contained in:
Irmen de Jong 2025-01-05 12:15:13 +01:00
parent d187cef6b7
commit cf1dbaf0d8
5 changed files with 49 additions and 47 deletions

View File

@ -1033,38 +1033,38 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
private fun funcMkword(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
val reg = resultRegister ?: RegisterOrPair.AY
var needAsave = asmgen.needAsaveForExpr(fcall.args[0])
if(!needAsave) {
var needAsaveForArg0 = asmgen.needAsaveForExpr(fcall.args[0])
if(!needAsaveForArg0) {
val mr0 = fcall.args[0] as? PtMemoryByte
val mr1 = fcall.args[1] as? PtMemoryByte
if (mr0 != null)
needAsave = mr0.address !is PtNumber
needAsaveForArg0 = mr0.address !is PtNumber
if (mr1 != null)
needAsave = needAsave or (mr1.address !is PtNumber)
needAsaveForArg0 = needAsaveForArg0 or (mr1.address !is PtNumber)
}
when(reg) {
RegisterOrPair.AX -> {
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.A) // lsb
if(needAsave)
if(needAsaveForArg0)
asmgen.out(" pha")
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.X) // msb
if(needAsave)
if(needAsaveForArg0)
asmgen.out(" pla")
}
RegisterOrPair.AY -> {
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.A) // lsb
if(needAsave)
if(needAsaveForArg0)
asmgen.out(" pha")
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.Y) // msb
if(needAsave)
if(needAsaveForArg0)
asmgen.out(" pla")
}
RegisterOrPair.XY -> {
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.A) // lsb
if(needAsave)
if(needAsaveForArg0)
asmgen.out(" pha")
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.Y) // msb
if(needAsave)
if(needAsaveForArg0)
asmgen.out(" pla")
asmgen.out(" tax")
}

View File

@ -159,12 +159,22 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
2 -> {
if(params[0].type.isByteOrBool && params[1].type.isByteOrBool) {
// 2 byte params, second in Y, first in A
argumentViaRegister(sub, IndexedValue(0, params[0]), args[0], RegisterOrPair.A)
if(asmgen.needAsaveForExpr(args[1]))
asmgen.out(" pha")
argumentViaRegister(sub, IndexedValue(1, params[1]), args[1], RegisterOrPair.Y)
if(asmgen.needAsaveForExpr(args[1]))
asmgen.out(" pla")
if(asmgen.needAsaveForExpr(args[0]) && !asmgen.needAsaveForExpr(args[1])) {
// first 0 then 1
argumentViaRegister(sub, IndexedValue(0, params[0]), args[0], RegisterOrPair.A)
argumentViaRegister(sub, IndexedValue(1, params[1]), args[1], RegisterOrPair.Y)
} else if(!asmgen.needAsaveForExpr(args[0]) && asmgen.needAsaveForExpr(args[1])) {
// first 1 then 0
argumentViaRegister(sub, IndexedValue(1, params[1]), args[1], RegisterOrPair.Y)
argumentViaRegister(sub, IndexedValue(0, params[0]), args[0], RegisterOrPair.A)
} else {
argumentViaRegister(sub, IndexedValue(0, params[0]), args[0], RegisterOrPair.A)
if (asmgen.needAsaveForExpr(args[1]))
asmgen.out(" pha")
argumentViaRegister(sub, IndexedValue(1, params[1]), args[1], RegisterOrPair.Y)
if (asmgen.needAsaveForExpr(args[1]))
asmgen.out(" pla")
}
} else {
throw AssemblyError("cannot use registers for word+byte")
}

View File

@ -3695,7 +3695,9 @@ $endLabel""")
RegisterOrPair.XY -> asmgen.out(" ldx #0 | ldy #0")
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float")
in Cx16VirtualRegisters -> {
asmgen.out(" stz cx16.${target.register.toString().lowercase()} | stz cx16.${target.register.toString().lowercase()}+1")
asmgen.out(" stz cx16.${target.register.toString().lowercase()}")
if(target.datatype.isWord)
asmgen.out(" stz cx16.${target.register.toString().lowercase()}+1")
}
else -> throw AssemblyError("weird register")
}
@ -3734,10 +3736,12 @@ $endLabel""")
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float")
in Cx16VirtualRegisters -> {
asmgen.out(" lda #${byte.toHex()} | sta cx16.${target.register.toString().lowercase()}")
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz cx16.${target.register.toString().lowercase()}+1\n")
else
asmgen.out(" lda #0 | sta cx16.${target.register.toString().lowercase()}+1\n")
if(target.datatype.isWord) {
if (asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz cx16.${target.register.toString().lowercase()}+1\n")
else
asmgen.out(" lda #0 | sta cx16.${target.register.toString().lowercase()}+1\n")
}
}
else -> throw AssemblyError("weird register")
}

View File

@ -1,6 +1,9 @@
TODO
====
return mkword(attrs[cx16.r2L], object[cx16.r2L]) same as the explode() above; push pops unneeded?
- add paypal donation button as well?
- announce prog8 on the 6502.org site?
@ -83,8 +86,6 @@ Optimizations
- word offset = (row as uword) * 128 + col*2 inefficient code for col*2 (rockrunner)
- if magicwall_enabled and (jiffy_counter & 3 == 1) sounds.magicwall() -> generates shortcut jump to another jump, why not immediately after the if
- explode(x, y+1) pushes x on the stack and pops it, could simply load it in reverse order and not use the stack.normal
- return mkword(attrs[cx16.r2L], object[cx16.r2L]) same as the explode() above
- if cx16.r0L>=97 and cx16.r0L<=122 {...} -> treats the boolean condition as a byte 0/1 result , can't it somehow just act on the carry bit alone?
same with if x1!=x2 or y1!=y2..... but it's because of the way boolean expressions are handled... can this be optimized?

View File

@ -3,31 +3,18 @@
%zeropage basicsafe
main {
ubyte[4] attrs
ubyte[4] object
sub start() {
ubyte @shared bb0, bb1, bb2, bb3, bb4
uword @shared ww0, ww1, ww2, ww3, ww4
cx16.r0 = mkword(attrs[cx16.r2L], object[cx16.r2L])
cx16.r1 = mkword(attrs[cx16.r2L], 22)
cx16.r2 = mkword(22,attrs[cx16.r2L])
explode(1, attrs[2]+2)
explode(attrs[2]+2, 1)
}
bb4 = 100
ww4 = 100
bb0 = min(bb1+10, 100)
bb0 = min(100, bb1+10)
; bb0 = min(bb1, bb4)
; bb2 = min(bb1+bb2, bb3+bb4)
;
; bb0 = max(bb1, 100)
; bb0 = max(100, bb1)
; bb0 = max(bb1, bb4)
; bb2 = max(bb1+bb2, bb3+bb4)
;
; ww0 = min(ww1, 100)
; ww0 = min(100, ww1)
; ww0 = min(ww1, ww4)
; ww2 = min(ww1+ww2, ww3+ww4)
;
; ww0 = max(ww1, 100)
; ww0 = max(100, ww1)
; ww0 = max(ww1, ww4)
; ww2 = max(ww1+ww2, ww3+ww4)
sub explode(ubyte a1, ubyte a2) -> uword {
return mkword(attrs[cx16.r2L], object[cx16.r2L])
}
}