mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 22:16:16 +00:00
avoid fallback JSR peek for common case pointer+offset
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 82 KiB |
@@ -1067,6 +1067,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
val varname = asmgen.asmVariableName(pointer)
|
||||
asmgen.assignExpressionToRegister(result.second, RegisterOrPair.Y)
|
||||
asmgen.out(" lda ($varname),y")
|
||||
} else if(addrExpr.operator in arrayOf("+", "-") && addrExpr.left is PtIdentifier) {
|
||||
readValueFromPointerPlusOrMinOffset(addrExpr.left as PtIdentifier, addrExpr.operator, addrExpr.right, BaseDataType.BOOL)
|
||||
} else fallback()
|
||||
}
|
||||
else -> fallback()
|
||||
@@ -1112,6 +1114,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
lda ($varname),y
|
||||
tay
|
||||
txa""")
|
||||
} else if(addrExpr.operator in arrayOf("+", "-") && addrExpr.left is PtIdentifier) {
|
||||
readValueFromPointerPlusOrMinOffset(addrExpr.left as PtIdentifier, addrExpr.operator, addrExpr.right, BaseDataType.UWORD)
|
||||
} else fallback()
|
||||
}
|
||||
else -> fallback()
|
||||
@@ -1129,6 +1133,37 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun readValueFromPointerPlusOrMinOffset(ptr: PtIdentifier, operator: String, offset: PtExpression, dt: BaseDataType) {
|
||||
val varname = asmgen.asmVariableName(ptr)
|
||||
asmgen.assignExpressionToRegister(offset, RegisterOrPair.AY)
|
||||
if(operator=="+")
|
||||
asmgen.out("""
|
||||
clc
|
||||
adc $varname
|
||||
sta P8ZP_SCRATCH_W1
|
||||
tya
|
||||
adc $varname+1
|
||||
sta P8ZP_SCRATCH_W1+1""")
|
||||
else
|
||||
asmgen.out("""
|
||||
sec
|
||||
sbc $varname
|
||||
sta P8ZP_SCRATCH_W1
|
||||
tya
|
||||
sbc $varname+1
|
||||
sta P8ZP_SCRATCH_W1+1""")
|
||||
|
||||
if (dt.isByteOrBool) {
|
||||
if(asmgen.isTargetCpu(CpuType.CPU65C02)) {
|
||||
asmgen.out(" lda (P8ZP_SCRATCH_W1)")
|
||||
} else {
|
||||
asmgen.out(" ldy #0 | lda (P8ZP_SCRATCH_W1),y")
|
||||
}
|
||||
} else if(dt.isWord) {
|
||||
asmgen.out(" jsr prog8_lib.func_peekw.from_scratchW1")
|
||||
} else throw AssemblyError("unsupported type for peek $dt")
|
||||
}
|
||||
|
||||
private fun funcPeekL(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
||||
// TODO optimize for the simple cases
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
|
||||
|
||||
@@ -435,6 +435,7 @@ func_peek .proc
|
||||
; -- read the byte value on the address in AY, into A
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
from_scratchW1
|
||||
ldy #0
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
rts
|
||||
@@ -444,6 +445,7 @@ func_peekw .proc
|
||||
; -- read the word value on the address in AY, into AY
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
from_scratchW1
|
||||
ldy #0
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
pha
|
||||
@@ -458,6 +460,7 @@ func_peekl .proc
|
||||
; -- read the ;pmg value on the address in AY, into R0:R1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
from_scratchW1
|
||||
ldy #0
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
sta cx16.r0
|
||||
|
||||
@@ -297,6 +297,17 @@ _after:
|
||||
val peek = FunctionCallExpression(IdentifierReference(listOf("peekbool"), arrayIndexedExpression.position), mutableListOf(address), arrayIndexedExpression.position)
|
||||
return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, peek, parent))
|
||||
}
|
||||
} else if(arrayVar.datatype.sub==BaseDataType.LONG) {
|
||||
// use peekl/pokel
|
||||
if(parent is AssignTarget) {
|
||||
val assignment = parent.parent as Assignment
|
||||
val args = mutableListOf(address, assignment.value)
|
||||
val poke = FunctionCallStatement(IdentifierReference(listOf("pokel"), arrayIndexedExpression.position), args, false, arrayIndexedExpression.position)
|
||||
return listOf(IAstModification.ReplaceNode(assignment, poke, assignment.parent))
|
||||
} else {
|
||||
val peek = FunctionCallExpression(IdentifierReference(listOf("peekl"), arrayIndexedExpression.position), mutableListOf(address), arrayIndexedExpression.position)
|
||||
return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, peek, parent))
|
||||
}
|
||||
} else if(arrayVar.datatype.sub==BaseDataType.FLOAT) {
|
||||
// use peekf/pokef
|
||||
if(parent is AssignTarget) {
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- optimized translation for pokeX and peekX if address = pointer + uwordoffset.
|
||||
|
||||
|
||||
STRUCTS and TYPED POINTERS
|
||||
--------------------------
|
||||
|
||||
- implement the remaining TODO's in PointerAssignmentsGen.
|
||||
- optimize deref in PointerAssignmentsGen: optimize 'forceTemporary' to only use a temporary when the offset is >0
|
||||
- optimize the float copying in assignIndexedPointer() (also word?)
|
||||
- optimize the float copying in assignIndexedPointer() (also word and long?)
|
||||
- optimize augmented assignments to indexed pointer targets like sprptr[2]^^.y++ (these are now not performend in-place but as a regular assignment)
|
||||
- implement even more struct instance assignments (via memcopy) in CodeDesugarer (see the TODO) (add to documentation as well, paragraph 'Structs')
|
||||
- support @nosplit pointer arrays?
|
||||
@@ -24,6 +27,8 @@ Future Things and Ideas
|
||||
This will break some existing programs that depend on value wrap arounds, but gives more intuitive constant number handling.
|
||||
Can give descriptive error message for old syntax that still includes the type name?
|
||||
- improve ANTLR grammar with better error handling (as suggested by Qwen AI)
|
||||
- add documentation for more library modules instead of just linking to the source code
|
||||
- add an Index to the documentation
|
||||
- allow memory() to occur in array initializer
|
||||
- when a complete block is removed because unused, suppress all info messages about everything in the block being removed
|
||||
- fix the line, cols in Position, sometimes they count from 0 sometimes from 1
|
||||
|
||||
@@ -36,7 +36,7 @@ irq {
|
||||
; Here is the actual multiplexing routine.
|
||||
; it's a raster irq just after the start of the sprite,
|
||||
; that updates the Y position of all the sprits,
|
||||
; and registers a new rater irq for that next row of sprites.
|
||||
; and registers a new raster irq for that next row of sprites.
|
||||
; If the bottom of the screen is reached, it resets the X position of the sprites as well,
|
||||
; and moves the sprites back to the top of the screen.
|
||||
sub multiplexer() -> bool {
|
||||
@@ -51,12 +51,15 @@ irq {
|
||||
first_sprite_X = 0
|
||||
sprites.set_sprites_Y(sprites_Y)
|
||||
while c64.RASTER != cx16.r2 {
|
||||
; wait until raster line after sprite has been fully drawn (at least 24 lines down)
|
||||
; wait until raster line after sprites have been fully drawn (at least 24 lines down)
|
||||
}
|
||||
sprites.set_sprites_X(first_sprite_X) ; we can now update the X positions without risk of sprite tearing
|
||||
system_irq = true
|
||||
} else {
|
||||
; only set the new Y positions. But it's possible to change other attributes as well ofcourse (colors, x-position, data)
|
||||
; but raster timing is critical for that if you want to avoid tearing and glitches. Can probably not be done here at this raster position...
|
||||
sprites.set_sprites_Y(sprites_Y)
|
||||
c64.SPXY[0]++
|
||||
}
|
||||
|
||||
sys.set_rasterline(sprites_Y+1)
|
||||
|
||||
@@ -3,45 +3,17 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
long @shared lv1 = -9999
|
||||
; txt.print_uw(lsw(lv1))
|
||||
; txt.spc()
|
||||
; txt.print_w(lv1 as word)
|
||||
; txt.spc()
|
||||
; txt.print_uw(lv1 as uword)
|
||||
; txt.spc()
|
||||
; txt.print_b(lv1 as byte)
|
||||
; txt.spc()
|
||||
; txt.print_ub(lv1 as ubyte)
|
||||
; txt.spc()
|
||||
; txt.print_w(msw(lv1 << 8) as word)
|
||||
; txt.spc()
|
||||
; txt.print_w(lsw(lv1 >> 8) as word)
|
||||
^^bool flags
|
||||
^^word words
|
||||
^^long longs
|
||||
|
||||
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
lv1 = -9876543
|
||||
conv.str_ub0(123)
|
||||
txt.print(conv.str_l(lv1))
|
||||
txt.spc()
|
||||
txt.print(conv.string_out)
|
||||
txt.nl()
|
||||
lv1 = 123456
|
||||
txt.print(conv.str_l(lv1))
|
||||
txt.spc()
|
||||
txt.print(conv.string_out)
|
||||
txt.nl()
|
||||
lv1 = -2147483647
|
||||
txt.print(conv.str_l(lv1))
|
||||
txt.spc()
|
||||
txt.print(conv.string_out)
|
||||
txt.nl()
|
||||
lv1 = 2147483647
|
||||
txt.print(conv.str_l(lv1))
|
||||
txt.spc()
|
||||
txt.print(conv.string_out)
|
||||
txt.nl()
|
||||
|
||||
; TODO optimized translation of the peekX and pokeX calls:
|
||||
if flags[cx16.r0]
|
||||
flags[cx16.r0] = true
|
||||
if words[cx16.r0]!=0
|
||||
words[cx16.r0] = 9990
|
||||
if longs[cx16.r0]!=0
|
||||
longs[cx16.r0] = 999999
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user