mirror of
https://github.com/irmen/prog8.git
synced 2024-10-25 00:24:16 +00:00
fix optimized codegen for 2 arg functions, sometimes was passing wrong arg value due to register overwriting
This commit is contained in:
parent
46ca0ac10d
commit
f70b914779
@ -1384,7 +1384,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
|||||||
asmgen.out(" sta P8ESTACK_LO,x | tya | sta P8ESTACK_HI,x | dex")
|
asmgen.out(" sta P8ESTACK_LO,x | tya | sta P8ESTACK_HI,x | dex")
|
||||||
} else {
|
} else {
|
||||||
val reg = resultRegister ?: RegisterOrPair.AY
|
val reg = resultRegister ?: RegisterOrPair.AY
|
||||||
var needAsave = !(fcall.args[0] is DirectMemoryRead || fcall.args[0] is NumericLiteral || fcall.args[0] is IdentifierReference)
|
var needAsave = needAsaveForOtherArg(fcall.args[0])
|
||||||
if(!needAsave) {
|
if(!needAsave) {
|
||||||
val mr0 = fcall.args[0] as? DirectMemoryRead
|
val mr0 = fcall.args[0] as? DirectMemoryRead
|
||||||
val mr1 = fcall.args[1] as? DirectMemoryRead
|
val mr1 = fcall.args[1] as? DirectMemoryRead
|
||||||
@ -1633,4 +1633,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun needAsaveForOtherArg(arg: Expression): Boolean =
|
||||||
|
arg !is NumericLiteral && arg !is IdentifierReference && arg !is DirectMemoryRead
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,7 @@ package prog8.codegen.cpu6502
|
|||||||
import prog8.ast.IFunctionCall
|
import prog8.ast.IFunctionCall
|
||||||
import prog8.ast.Node
|
import prog8.ast.Node
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
import prog8.ast.expressions.AddressOf
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.expressions.Expression
|
|
||||||
import prog8.ast.expressions.IdentifierReference
|
|
||||||
import prog8.ast.expressions.NumericLiteral
|
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
import prog8.codegen.cpu6502.assignment.AsmAssignSource
|
import prog8.codegen.cpu6502.assignment.AsmAssignSource
|
||||||
@ -72,6 +69,10 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
(sub.parameters.size==1 && sub.parameters[0].type in IntegerDatatypes)
|
(sub.parameters.size==1 && sub.parameters[0].type in IntegerDatatypes)
|
||||||
|| (sub.parameters.size==2 && sub.parameters[0].type in ByteDatatypes && sub.parameters[1].type in ByteDatatypes)
|
|| (sub.parameters.size==2 && sub.parameters[0].type in ByteDatatypes && sub.parameters[1].type in ByteDatatypes)
|
||||||
|
|
||||||
|
private fun needAsaveForOtherArg(arg: Expression): Boolean =
|
||||||
|
arg !is NumericLiteral && arg !is IdentifierReference && arg !is DirectMemoryRead
|
||||||
|
|
||||||
|
|
||||||
internal fun translateFunctionCall(call: IFunctionCall, isExpression: Boolean) {
|
internal fun translateFunctionCall(call: IFunctionCall, isExpression: Boolean) {
|
||||||
// Output only the code to set up the parameters and perform the actual call
|
// Output only the code to set up the parameters and perform the actual call
|
||||||
// NOTE: does NOT output the code to deal with the result values!
|
// NOTE: does NOT output the code to deal with the result values!
|
||||||
@ -111,10 +112,10 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
} else {
|
} else {
|
||||||
// 2 byte params, second in Y, first in A
|
// 2 byte params, second in Y, first in A
|
||||||
argumentViaRegister(sub, IndexedValue(0, sub.parameters[0]), call.args[0], RegisterOrPair.A)
|
argumentViaRegister(sub, IndexedValue(0, sub.parameters[0]), call.args[0], RegisterOrPair.A)
|
||||||
if(!call.args[1].isSimple)
|
if(needAsaveForOtherArg(call.args[1]))
|
||||||
asmgen.out(" pha")
|
asmgen.out(" pha")
|
||||||
argumentViaRegister(sub, IndexedValue(1, sub.parameters[1]), call.args[1], RegisterOrPair.Y)
|
argumentViaRegister(sub, IndexedValue(1, sub.parameters[1]), call.args[1], RegisterOrPair.Y)
|
||||||
if(!call.args[1].isSimple)
|
if(needAsaveForOtherArg(call.args[1]))
|
||||||
asmgen.out(" pla")
|
asmgen.out(" pla")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -50,12 +50,8 @@ internal class AstOnetimeTransforms(private val program: Program, private val op
|
|||||||
} else {
|
} else {
|
||||||
val fcall = parent as? IFunctionCall
|
val fcall = parent as? IFunctionCall
|
||||||
if(fcall!=null) {
|
if(fcall!=null) {
|
||||||
if(options.compTarget.name != VMTarget.NAME) {
|
// TODO for now, codegen seems wrong when using pointer indexed args to an in-place modifying function.
|
||||||
// TODO for now, 6502 codegen seems wrong when using pointer indexed args to any function.
|
if(fcall.target.nameInSource.size==1 && fcall.target.nameInSource[0] in InplaceModifyingBuiltinFunctions) {
|
||||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
|
||||||
} else if(fcall.target.nameInSource.size==1 && fcall.target.nameInSource[0] in InplaceModifyingBuiltinFunctions) {
|
|
||||||
// TODO for now, vm codegen seems wrong when using pointer indexed args to an in-place modifying function.
|
|
||||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
||||||
return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,7 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- optimize pointervar indexing codegen: make them work as subroutine paramers
|
- optimize pointervar indexing codegen: make them work as params to in-place modifying functions (rol, swap, ...)
|
||||||
- optimize pointervar indexing codegen: writing (all sorts of things)
|
- optimize pointervar indexing codegen: writing (all sorts of things)
|
||||||
- pipe operator: (targets other than 'Virtual'): allow non-unary function calls in the pipe that specify the other argument(s) in the calls. Already working for VM target.
|
- pipe operator: (targets other than 'Virtual'): allow non-unary function calls in the pipe that specify the other argument(s) in the calls. Already working for VM target.
|
||||||
- add McCarthy evaluation to shortcircuit and/or expressions. First do ifs by splitting them up? Then do expressions that compute a value?
|
- add McCarthy evaluation to shortcircuit and/or expressions. First do ifs by splitting them up? Then do expressions that compute a value?
|
||||||
|
@ -29,27 +29,39 @@ main {
|
|||||||
; txt.spc()
|
; txt.spc()
|
||||||
; }
|
; }
|
||||||
|
|
||||||
|
; sub derp(ubyte u1, ubyte u2, ubyte u3) {
|
||||||
|
; txt.print_ub(u1)
|
||||||
|
; txt.spc()
|
||||||
|
; txt.print_ub(u2)
|
||||||
|
; txt.spc()
|
||||||
|
; txt.print_ub(u3)
|
||||||
|
; txt.nl()
|
||||||
|
; }
|
||||||
|
|
||||||
|
sub derp2(ubyte u1, ubyte u2) {
|
||||||
|
txt.print_ub(u1)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ub(u2)
|
||||||
|
txt.nl()
|
||||||
|
}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
; mcCarthy()
|
; mcCarthy()
|
||||||
uword uw1 = 9999
|
|
||||||
uword uw2 = uw1 - 2000 + 10000
|
|
||||||
ubyte ub1 = 99
|
|
||||||
ubyte ub2 = ub1 - 2 + 10
|
|
||||||
ubyte ubb = ub2 - -10
|
|
||||||
txt.print_uw(uw2)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_ub(ub2)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_ub(ubb)
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
;test_stack.test()
|
;test_stack.test()
|
||||||
|
|
||||||
; ubyte value = 0
|
ubyte value = 0
|
||||||
; ubyte one = 1
|
ubyte one = 1
|
||||||
; ubyte[10] data = [11,22,33,4,5,6,7,8,9,10]
|
ubyte two = 2
|
||||||
; uword bitmapbuf = &data
|
ubyte[10] data = [11,22,33,4,5,6,7,8,9,10]
|
||||||
;
|
uword bitmapbuf = &data
|
||||||
|
|
||||||
|
;derp(data[0],data[1],data[2])
|
||||||
|
;derp(bitmapbuf[0], bitmapbuf[1], bitmapbuf[2])
|
||||||
|
derp2(1,2)
|
||||||
|
derp2(one, two)
|
||||||
|
derp2(data[1], data[2])
|
||||||
|
derp2(bitmapbuf[1], bitmapbuf[2])
|
||||||
|
|
||||||
; value = bitmapbuf[2]
|
; value = bitmapbuf[2]
|
||||||
; txt.print_ub(value) ;; 33
|
; txt.print_ub(value) ;; 33
|
||||||
; txt.nl()
|
; txt.nl()
|
||||||
|
Loading…
Reference in New Issue
Block a user