mirror of
https://github.com/irmen/prog8.git
synced 2024-12-22 18:30:01 +00:00
better codegen for call() function
This commit is contained in:
parent
df35aa7942
commit
a064ade1e0
@ -266,23 +266,40 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun funcCall(fcall: PtBuiltinFunctionCall) {
|
||||
// note: the routine can return a word value (in AY)
|
||||
val constAddr = fcall.args[0].asConstInteger()
|
||||
if(constAddr!=null) {
|
||||
asmgen.out(" jsr ${constAddr.toHex()}")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) // jump address
|
||||
asmgen.out("""
|
||||
sta (+)+1
|
||||
sty (+)+2
|
||||
+ jsr 0 ; modified""")
|
||||
// TODO: avoid using modifying code here by pushing return address on the stack manually and use JMP (INDIRECT) ? And if it's just a variable, simply JMP (variable) !
|
||||
// TODO: also do this for CallFar below!
|
||||
return
|
||||
}
|
||||
|
||||
// note: the routine can return a word value (in AY)
|
||||
val identifier = fcall.args[0] as? PtIdentifier
|
||||
if(identifier!=null) {
|
||||
asmgen.out("""
|
||||
; push a return address so the jmp becomes indirect jsr
|
||||
lda #>((+)-1)
|
||||
pha
|
||||
lda #<((+)-1)
|
||||
pha
|
||||
jmp (${asmgen.asmSymbolName(identifier)})
|
||||
+""")
|
||||
return
|
||||
}
|
||||
|
||||
asmgen.assignExpressionToVariable(fcall.args[0], asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD) // jump address
|
||||
asmgen.out("""
|
||||
; push a return address so the jmp becomes indirect jsr
|
||||
lda #>((+)-1)
|
||||
pha
|
||||
lda #<((+)-1)
|
||||
pha
|
||||
jmp (P8ZP_SCRATCH_W2)
|
||||
+""")
|
||||
}
|
||||
|
||||
private fun funcCallFar(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
||||
// TODO apply same optimizations here as used on call() codegen above
|
||||
|
||||
if(asmgen.options.compTarget.name != "cx16")
|
||||
throw AssemblyError("callfar only works on cx16 target at this time")
|
||||
|
||||
|
@ -1346,7 +1346,7 @@ internal class AstChecker(private val program: Program,
|
||||
if(target.name=="call") {
|
||||
if(args[0] is AddressOf)
|
||||
errors.err("can't call this indirectly, just use normal function call syntax", args[0].position)
|
||||
if(args[0] is IdentifierReference) {
|
||||
else if(args[0] is IdentifierReference) {
|
||||
val callTarget = (args[0] as IdentifierReference).targetStatement(program)
|
||||
if(callTarget !is VarDecl)
|
||||
errors.err("can't call this indirectly, just use normal function call syntax", args[0].position)
|
||||
|
@ -92,8 +92,11 @@ main {
|
||||
main {
|
||||
sub start() {
|
||||
uword func = 12345
|
||||
uword[] pointers = [1234,6789]
|
||||
void call(func) ; ok
|
||||
void call(12345) ; ok
|
||||
void call(pointers[1]) ; ok
|
||||
void call(cx16.r0+10) ; ok
|
||||
cx16.r0 = call(func) ; ok
|
||||
void call(&start) ; error
|
||||
void call(start) ; error
|
||||
|
@ -5,9 +5,8 @@ Regenerate skeleton doc files.
|
||||
|
||||
"invalid number of arguments" -> print the list of missing arguments
|
||||
|
||||
call() asm gen in funcCall() could be improved by not using modifying code , see the TODO.
|
||||
callfar() should allow setting an argument in the X register as well? + similar optimizations that call() got.
|
||||
|
||||
callfar() should allow setting an argument in the X register as well?
|
||||
|
||||
Add a new SublimeText syntax file for prog8, and also install this for bat: https://github.com/sharkdp/bat?tab=readme-ov-file#adding-new-syntaxes--language-definitions
|
||||
|
||||
@ -21,6 +20,7 @@ Future Things and Ideas
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Compiler:
|
||||
|
||||
- AST weirdness: why is call(...) a normal FunctionCallStatement and not a BuiltinFunctionCall? What does ror() produce for instance?
|
||||
- Can we support signed % (remainder) somehow?
|
||||
- Don't add "random" rts to %asm blocks but instead give a warning about it? (but this breaks existing behavior that others already depend on... command line switch? block directive?)
|
||||
- IR: implement missing operators in AssignmentGen (array shifts etc)
|
||||
|
124
examples/test.p8
124
examples/test.p8
@ -1,116 +1,42 @@
|
||||
%import textio
|
||||
%import string
|
||||
%import compression
|
||||
%import test_stack
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
ubyte[] rle = [
|
||||
5, '1', '2', '3', '4', '5', '6',
|
||||
3, 'a', 'b', 'c', 'd',
|
||||
0, 'z',
|
||||
3, '1', '2', '3','4',
|
||||
-5, '=',
|
||||
-127, '+',
|
||||
4, '!', '@', '#', '$', '%',
|
||||
128]
|
||||
test_stack.test()
|
||||
example(function1, 42)
|
||||
example(function1, 99)
|
||||
example(function2, 42)
|
||||
example(function2, 99)
|
||||
test_stack.test()
|
||||
cx16.r0++
|
||||
|
||||
str @shared result = "\x00"*200
|
||||
|
||||
uword ptr = &rle
|
||||
|
||||
txt.print_uw(compression.decode_rle_srcfunc(callback, result, len(result)))
|
||||
txt.nl()
|
||||
txt.print_uw(compression.decode_rle(rle, result, len(result)))
|
||||
txt.nl()
|
||||
txt.print_uw(string.length(result))
|
||||
txt.nl()
|
||||
txt.print(result)
|
||||
txt.nl()
|
||||
txt.print_uwhex(&result, true)
|
||||
txt.nl()
|
||||
|
||||
sub callback() -> ubyte {
|
||||
ubyte x = @(ptr)
|
||||
ptr++
|
||||
return x
|
||||
}
|
||||
|
||||
|
||||
ubyte[256] buffer
|
||||
ubyte[256] buffer2
|
||||
uword bufptr = &buffer
|
||||
uword outputsize=0
|
||||
|
||||
sub outputter(ubyte value) {
|
||||
@(bufptr) = value
|
||||
bufptr++
|
||||
outputsize++
|
||||
}
|
||||
|
||||
str input = iso:"123456aaaaabcdzzz1234======++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++!@#$%"
|
||||
ubyte[31] expected_rle = [$5, $31, $32, $33, $34, $35, $36, $fc, $61, $2, $62, $63, $64, $fe, $7a, $3, $31, $32, $33, $34, $fb, $3d, $81, $2b, $4, $21, $40, $23, $24, $25, $80]
|
||||
txt.print(input)
|
||||
txt.nl()
|
||||
|
||||
compression.encode_rle_outfunc(input, len(input), outputter, true)
|
||||
txt.print_uw(outputsize)
|
||||
txt.nl()
|
||||
if outputsize!=len(expected_rle)
|
||||
txt.print("wrong rle size!\n")
|
||||
|
||||
txt.print("\ncompare rle (encode using callback):\n")
|
||||
for cx16.r9L in 0 to len(expected_rle)-1 {
|
||||
; txt.print_ub0(cx16.r9L)
|
||||
; txt.spc()
|
||||
; txt.print_ubhex(expected_rle[cx16.r9L], false)
|
||||
; txt.spc()
|
||||
; txt.print_ubhex(buffer[cx16.r9L], false)
|
||||
if buffer[cx16.r9L] != expected_rle[cx16.r9L]
|
||||
txt.print(" wrong rle data!")
|
||||
; txt.nl()
|
||||
}
|
||||
txt.nl()
|
||||
|
||||
cx16.r0 = compression.decode_rle(buffer, buffer2, len(buffer2))
|
||||
if cx16.r0 != len(input)
|
||||
txt.print("wrong decompress result!\n")
|
||||
else {
|
||||
txt.print("good result: ")
|
||||
txt.print(buffer2)
|
||||
sub function1(ubyte arg) {
|
||||
txt.print("function 1 arg=")
|
||||
txt.print_ub(arg)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
|
||||
buffer[0] = buffer[1] = buffer[2] = 128
|
||||
outputsize = compression.encode_rle(input, len(input), buffer, true)
|
||||
txt.print_uw(outputsize)
|
||||
txt.nl()
|
||||
if outputsize!=len(expected_rle)
|
||||
txt.print("wrong rle size!\n")
|
||||
|
||||
txt.print("\ncompare rle (encode into buffer):\n")
|
||||
for cx16.r9L in 0 to len(expected_rle)-1 {
|
||||
; txt.print_ub0(cx16.r9L)
|
||||
; txt.spc()
|
||||
; txt.print_ubhex(expected_rle[cx16.r9L], false)
|
||||
; txt.spc()
|
||||
; txt.print_ubhex(buffer[cx16.r9L], false)
|
||||
if buffer[cx16.r9L] != expected_rle[cx16.r9L]
|
||||
txt.print(" wrong rle data!")
|
||||
; txt.nl()
|
||||
}
|
||||
txt.nl()
|
||||
|
||||
cx16.r0 = compression.decode_rle(buffer, buffer2, len(buffer2))
|
||||
if cx16.r0 != len(input)
|
||||
txt.print("wrong decompress result!\n")
|
||||
else {
|
||||
txt.print("good result: ")
|
||||
txt.print(buffer2)
|
||||
sub function2(ubyte arg) {
|
||||
txt.print("function 2 arg=")
|
||||
txt.print_ub(arg)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub example(uword function, ubyte value) {
|
||||
|
||||
%asm {{
|
||||
lda p8v_value
|
||||
}}
|
||||
|
||||
call(function)
|
||||
cx16.r1 = function+10
|
||||
call(cx16.r1-10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user