mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
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:
parent
d187cef6b7
commit
cf1dbaf0d8
@ -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")
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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?
|
||||
|
||||
|
@ -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])
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user