mirror of
https://github.com/irmen/prog8.git
synced 2025-01-12 19:29:50 +00:00
nontrivial return value evaluation now via intermediary variable to try to avoid slow stack based evaluation
This commit is contained in:
parent
8e3e996f4a
commit
8e927e0b73
@ -8,6 +8,8 @@ prog8_lib {
|
|||||||
%asminclude "library:prog8_lib.asm", ""
|
%asminclude "library:prog8_lib.asm", ""
|
||||||
%asminclude "library:prog8_funcs.asm", ""
|
%asminclude "library:prog8_funcs.asm", ""
|
||||||
|
|
||||||
|
uword @zp retval_interm_w ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
|
||||||
|
ubyte @zp retval_interm_b ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
|
||||||
|
|
||||||
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
|
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
|
||||||
%asm {{
|
%asm {{
|
||||||
|
@ -215,12 +215,12 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
// Everything else just evaluate via the stack.
|
// Everything else just evaluate via the stack.
|
||||||
// (we can't use the assignment helper functions to do it via registers here,
|
// (we can't use the assignment helper functions to do it via registers here,
|
||||||
// because the code here is the implementation of exactly that...)
|
// because the code here is the implementation of exactly that...)
|
||||||
if(value.parent is Return) {
|
if (value.parent is Return) {
|
||||||
if (this.asmgen.options.slowCodegenWarnings)
|
if (this.asmgen.options.slowCodegenWarnings)
|
||||||
println("warning: slow stack evaluation used for return: $value target=${assign.target.kind} at ${value.position}")
|
println("warning: slow stack evaluation used for return: $value target=${assign.target.kind} at ${value.position}")
|
||||||
}
|
}
|
||||||
asmgen.translateExpression(value)
|
exprAsmgen.translateExpression(value)
|
||||||
if(assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
|
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
|
||||||
asmgen.signExtendStackLsb(assign.source.datatype)
|
asmgen.signExtendStackLsb(assign.source.datatype)
|
||||||
assignStackValue(assign.target)
|
assignStackValue(assign.target)
|
||||||
}
|
}
|
||||||
|
@ -441,6 +441,44 @@ internal class StatementOptimizer(private val program: Program,
|
|||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun after(returnStmt: Return, parent: Node): Iterable<IAstModification> {
|
||||||
|
fun returnViaIntermediary(value: Expression): Iterable<IAstModification>? {
|
||||||
|
val returnDt = returnStmt.definingSubroutine()!!.returntypes.single()
|
||||||
|
if (returnDt in IntegerDatatypes) {
|
||||||
|
// first assign to intermediary, then return that register
|
||||||
|
val returnValueIntermediary =
|
||||||
|
if (returnDt in ByteDatatypes)
|
||||||
|
IdentifierReference(listOf("prog8_lib", "retval_interm_b"), returnStmt.position)
|
||||||
|
else
|
||||||
|
IdentifierReference(listOf("prog8_lib", "retval_interm_w"), returnStmt.position)
|
||||||
|
val tgt = AssignTarget(returnValueIntermediary, null, null, returnStmt.position)
|
||||||
|
val assign = Assignment(tgt, value, returnStmt.position)
|
||||||
|
val returnReplacement = Return(returnValueIntermediary, returnStmt.position)
|
||||||
|
return listOf(
|
||||||
|
IAstModification.InsertBefore(returnStmt, assign, parent as INameScope),
|
||||||
|
IAstModification.ReplaceNode(returnStmt, returnReplacement, parent)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
when(returnStmt.value) {
|
||||||
|
is PrefixExpression -> {
|
||||||
|
val mod = returnViaIntermediary(returnStmt.value!!)
|
||||||
|
if(mod!=null)
|
||||||
|
return mod
|
||||||
|
}
|
||||||
|
is BinaryExpression -> {
|
||||||
|
val mod = returnViaIntermediary(returnStmt.value!!)
|
||||||
|
if(mod!=null)
|
||||||
|
return mod
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.after(returnStmt, parent)
|
||||||
|
}
|
||||||
|
|
||||||
private fun hasBreak(scope: INameScope): Boolean {
|
private fun hasBreak(scope: INameScope): Boolean {
|
||||||
|
|
||||||
class Searcher: IAstVisitor
|
class Searcher: IAstVisitor
|
||||||
|
@ -125,14 +125,17 @@ main {
|
|||||||
xx+=4
|
xx+=4
|
||||||
}
|
}
|
||||||
|
|
||||||
cx16.wait(3*60)
|
cx16.wait(3*60)
|
||||||
|
|
||||||
|
demo2()
|
||||||
|
|
||||||
gfx2.screen_mode(255)
|
gfx2.screen_mode(255)
|
||||||
txt.print("done!\n")
|
txt.print("done!\n")
|
||||||
|
|
||||||
test_stack.test()
|
test_stack.test()
|
||||||
}
|
}
|
||||||
|
|
||||||
sub start2 () {
|
sub demo2 () {
|
||||||
gfx2.text_charset(3)
|
gfx2.text_charset(3)
|
||||||
|
|
||||||
ubyte[] modes = [1, 0, 128]
|
ubyte[] modes = [1, 0, 128]
|
||||||
@ -143,9 +146,6 @@ main {
|
|||||||
cx16.wait(200)
|
cx16.wait(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx2.screen_mode(255)
|
|
||||||
txt.print("done!\n")
|
|
||||||
test_stack.test()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub draw() {
|
sub draw() {
|
||||||
|
@ -1,91 +1,36 @@
|
|||||||
%import test_stack
|
%import test_stack
|
||||||
%import textio
|
%import textio
|
||||||
%import diskio
|
%import floats
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
sub start () {
|
sub start () {
|
||||||
|
uword uw
|
||||||
|
ubyte ub
|
||||||
|
float ff
|
||||||
|
|
||||||
uword large_buffer_ptr = progend()
|
uw = funcuw()
|
||||||
ubyte[256] buffer
|
ub = funcub()
|
||||||
uword size
|
ff = funcff()
|
||||||
|
|
||||||
if diskio.f_open(8, "rom.asm") {
|
|
||||||
txt.print("read-exact\n")
|
|
||||||
c64.SETTIM(0,0,0)
|
|
||||||
size = 0
|
|
||||||
while not c64.READST() {
|
|
||||||
diskio.f_read_exact(&buffer, len(buffer))
|
|
||||||
size += 256
|
|
||||||
}
|
|
||||||
|
|
||||||
diskio.f_close()
|
|
||||||
txt.print_uw(size)
|
|
||||||
txt.chrout('\n')
|
|
||||||
print_time()
|
|
||||||
txt.chrout('\n')
|
|
||||||
} else
|
|
||||||
txt.print("can't open file!\n")
|
|
||||||
txt.print(diskio.status(8))
|
|
||||||
txt.chrout('\n')
|
|
||||||
|
|
||||||
|
|
||||||
if diskio.f_open(8, "rom.asm") {
|
|
||||||
txt.print("read-all\n")
|
|
||||||
c64.SETTIM(0,0,0)
|
|
||||||
size = 0
|
|
||||||
size = diskio.f_read_all(large_buffer_ptr)
|
|
||||||
diskio.f_close()
|
|
||||||
txt.print_uw(size)
|
|
||||||
txt.chrout('\n')
|
|
||||||
print_time()
|
|
||||||
txt.chrout('\n')
|
|
||||||
} else
|
|
||||||
txt.print("can't open file!\n")
|
|
||||||
txt.print(diskio.status(8))
|
|
||||||
txt.chrout('\n')
|
|
||||||
|
|
||||||
; if diskio.f_open(8, "rom.asm") {
|
|
||||||
; txt.print("read\n")
|
|
||||||
; c64.SETTIM(0,0,0)
|
|
||||||
; size = 0
|
|
||||||
; while not c64.READST() {
|
|
||||||
; size += diskio.f_read(&buffer, len(buffer))
|
|
||||||
; }
|
|
||||||
;
|
|
||||||
; diskio.f_close()
|
|
||||||
; txt.print_uw(size)
|
|
||||||
; txt.chrout('\n')
|
|
||||||
; print_time()
|
|
||||||
; txt.chrout('\n')
|
|
||||||
; }
|
|
||||||
|
|
||||||
test_stack.test()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub funcuw() -> uword {
|
||||||
|
uword a=1111
|
||||||
|
uword b=2222
|
||||||
|
return a+b
|
||||||
|
}
|
||||||
|
|
||||||
sub print_time() {
|
sub funcub() -> ubyte {
|
||||||
ubyte time_lo
|
ubyte a=11
|
||||||
ubyte time_mid
|
ubyte b=22
|
||||||
ubyte time_hi
|
return a+b
|
||||||
|
}
|
||||||
|
|
||||||
%asm {{
|
sub funcff() -> float {
|
||||||
stx P8ZP_SCRATCH_REG
|
float a=1111.1
|
||||||
jsr c64.RDTIM ; A/X/Y
|
float b=2222.2
|
||||||
sta time_lo
|
return a+b
|
||||||
stx time_mid
|
|
||||||
sty time_hi
|
|
||||||
ldx P8ZP_SCRATCH_REG
|
|
||||||
}}
|
|
||||||
|
|
||||||
txt.print_ub(time_hi)
|
|
||||||
txt.chrout(':')
|
|
||||||
txt.print_ub(time_mid)
|
|
||||||
txt.chrout(':')
|
|
||||||
txt.print_ub(time_lo)
|
|
||||||
txt.chrout('\n')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user