mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +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_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 {
|
||||
%asm {{
|
||||
|
@ -215,12 +215,12 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
// Everything else just evaluate via the stack.
|
||||
// (we can't use the assignment helper functions to do it via registers here,
|
||||
// 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)
|
||||
println("warning: slow stack evaluation used for return: $value target=${assign.target.kind} at ${value.position}")
|
||||
}
|
||||
asmgen.translateExpression(value)
|
||||
if(assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
|
||||
exprAsmgen.translateExpression(value)
|
||||
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
|
||||
asmgen.signExtendStackLsb(assign.source.datatype)
|
||||
assignStackValue(assign.target)
|
||||
}
|
||||
|
@ -441,6 +441,44 @@ internal class StatementOptimizer(private val program: Program,
|
||||
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 {
|
||||
|
||||
class Searcher: IAstVisitor
|
||||
|
@ -125,14 +125,17 @@ main {
|
||||
xx+=4
|
||||
}
|
||||
|
||||
cx16.wait(3*60)
|
||||
cx16.wait(3*60)
|
||||
|
||||
demo2()
|
||||
|
||||
gfx2.screen_mode(255)
|
||||
txt.print("done!\n")
|
||||
|
||||
test_stack.test()
|
||||
}
|
||||
|
||||
sub start2 () {
|
||||
sub demo2 () {
|
||||
gfx2.text_charset(3)
|
||||
|
||||
ubyte[] modes = [1, 0, 128]
|
||||
@ -143,9 +146,6 @@ main {
|
||||
cx16.wait(200)
|
||||
}
|
||||
|
||||
gfx2.screen_mode(255)
|
||||
txt.print("done!\n")
|
||||
test_stack.test()
|
||||
}
|
||||
|
||||
sub draw() {
|
||||
|
@ -1,91 +1,36 @@
|
||||
%import test_stack
|
||||
%import textio
|
||||
%import diskio
|
||||
%import floats
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
|
||||
sub start () {
|
||||
uword uw
|
||||
ubyte ub
|
||||
float ff
|
||||
|
||||
uword large_buffer_ptr = progend()
|
||||
ubyte[256] buffer
|
||||
uword size
|
||||
|
||||
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()
|
||||
|
||||
uw = funcuw()
|
||||
ub = funcub()
|
||||
ff = funcff()
|
||||
}
|
||||
|
||||
sub funcuw() -> uword {
|
||||
uword a=1111
|
||||
uword b=2222
|
||||
return a+b
|
||||
}
|
||||
|
||||
sub print_time() {
|
||||
ubyte time_lo
|
||||
ubyte time_mid
|
||||
ubyte time_hi
|
||||
sub funcub() -> ubyte {
|
||||
ubyte a=11
|
||||
ubyte b=22
|
||||
return a+b
|
||||
}
|
||||
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG
|
||||
jsr c64.RDTIM ; A/X/Y
|
||||
sta time_lo
|
||||
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')
|
||||
sub funcff() -> float {
|
||||
float a=1111.1
|
||||
float b=2222.2
|
||||
return a+b
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user