mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
fix faulty binexpr splitting
This commit is contained in:
parent
e0c5ccc16b
commit
526e4b8bdc
@ -1053,26 +1053,29 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
when {
|
||||
conv.variable -> {
|
||||
val varname = "prog8_lib.func_${signature.name}_cc._arg_${paramName}" // TODO after all builtin funcs have been changed into _cc, remove that suffix again
|
||||
val src = AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||
val src = if(conv.dt==DataType.FLOAT || conv.dt in PassByReferenceDatatypes) {
|
||||
// put the address of the argument in AY
|
||||
val addr = AddressOf(value as IdentifierReference, value.position)
|
||||
AsmAssignSource.fromAstSource(addr, program, asmgen)
|
||||
} else {
|
||||
AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||
}
|
||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, conv.dt, null, variableAsmName = varname)
|
||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
||||
asmgen.translateNormalAssignment(assign)
|
||||
}
|
||||
conv.reg != null -> {
|
||||
if(conv.dt==DataType.FLOAT || conv.dt in PassByReferenceDatatypes) {
|
||||
val src = if(conv.dt==DataType.FLOAT || conv.dt in PassByReferenceDatatypes) {
|
||||
// put the address of the argument in AY
|
||||
val addr = AddressOf(value as IdentifierReference, value.position)
|
||||
val src = AsmAssignSource.fromAstSource(addr, program, asmgen)
|
||||
val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen)
|
||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
||||
asmgen.translateNormalAssignment(assign)
|
||||
AsmAssignSource.fromAstSource(addr, program, asmgen)
|
||||
} else {
|
||||
val src = AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||
AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||
}
|
||||
val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen)
|
||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
||||
asmgen.translateNormalAssignment(assign)
|
||||
}
|
||||
}
|
||||
else -> throw AssemblyError("callconv")
|
||||
}
|
||||
}
|
||||
|
@ -38,22 +38,26 @@ internal class BinExprSplitter(private val program: Program) : AstWalker() {
|
||||
if (binExpr != null) {
|
||||
/*
|
||||
|
||||
reduce the complexity of a (binary) expression that has to be evaluated on the eval stack,
|
||||
by attempting to splitting it up into individual simple steps:
|
||||
Reduce the complexity of a (binary) expression that has to be evaluated on the eval stack,
|
||||
by attempting to splitting it up into individual simple steps.
|
||||
We only consider a binary expression *one* level deep (so the operands must not be a combined expression)
|
||||
|
||||
|
||||
X = BinExpr X = LeftExpr
|
||||
<operator> followed by
|
||||
/ \ IF 'X' not used X = BinExpr
|
||||
/ \ IN LEFTEXPR ==> <operator>
|
||||
/ \ IN expression ==> <operator>
|
||||
/ \ / \
|
||||
LeftExpr. RightExpr. / \
|
||||
/ \ / \ X RightExpr.
|
||||
.. .. .. ..
|
||||
X RightExpr.
|
||||
|
||||
|
||||
*/
|
||||
if(binExpr.operator in augmentAssignmentOperators && isSimpleTarget(assignment.target, program.namespace)) {
|
||||
if (!assignment.isAugmentable) {
|
||||
if(assignment.target isSameAs binExpr.left || assignment.target isSameAs binExpr.right)
|
||||
return noModifications
|
||||
|
||||
if(isSimpleExpression(binExpr.left) && isSimpleExpression(binExpr.right) && !assignment.isAugmentable) {
|
||||
val firstAssign = Assignment(assignment.target, binExpr.left, binExpr.left.position)
|
||||
val targetExpr = assignment.target.toExpression()
|
||||
val augExpr = BinaryExpression(targetExpr, binExpr.operator, binExpr.right, binExpr.right.position)
|
||||
@ -71,6 +75,9 @@ X = BinExpr X = LeftExpr
|
||||
return noModifications
|
||||
}
|
||||
|
||||
private fun isSimpleExpression(expr: Expression) =
|
||||
expr is IdentifierReference || expr is NumericLiteralValue || expr is AddressOf || expr is DirectMemoryRead || expr is StringLiteralValue || expr is ArrayLiteralValue || expr is RangeExpr
|
||||
|
||||
private fun isSimpleTarget(target: AssignTarget, namespace: INameScope) =
|
||||
if (target.identifier!=null || target.memoryAddress!=null || target.arrayindexed!=null)
|
||||
target.isInRegularRAM(namespace)
|
||||
|
@ -8,9 +8,10 @@
|
||||
; Cleanup and porting to C by Ullrich von Bassewitz.
|
||||
; Converted to prog8 by Irmen de Jong.
|
||||
|
||||
|
||||
; TODO the random charset is all wrong
|
||||
; TODO why has the prg become bigger since register args?
|
||||
|
||||
|
||||
main {
|
||||
const uword SCREEN1 = $E000
|
||||
const uword SCREEN2 = $E400
|
||||
|
@ -12,28 +12,28 @@ main {
|
||||
const uword ADDR = $0400
|
||||
|
||||
byte zerob=0
|
||||
word zerow=0
|
||||
float zerof=0
|
||||
; word zerow=0
|
||||
; float zerof=0
|
||||
byte bb
|
||||
word ww
|
||||
float fl
|
||||
; word ww
|
||||
; float fl
|
||||
|
||||
testX()
|
||||
|
||||
bb = -100
|
||||
bb = zerob+abs(bb)
|
||||
bb = zerob+abs(bb) ; TODO optimizer generates wrong code for this (wrong order of splitted expression?)
|
||||
txt.print_b(bb)
|
||||
txt.chrout('\n')
|
||||
|
||||
ww = -12345
|
||||
ww = zerow+abs(ww)
|
||||
txt.print_w(ww)
|
||||
txt.chrout('\n')
|
||||
|
||||
fl = -9.876
|
||||
fl = zerof+abs(fl)
|
||||
floats.print_f(fl)
|
||||
txt.chrout('\n')
|
||||
; ww = -12345
|
||||
; ww = zerow+abs(ww) ; TODO optimizer generates wrong code for this (wrong order of splitted expression?)
|
||||
; txt.print_w(ww)
|
||||
; txt.chrout('\n')
|
||||
;
|
||||
; fl = -9.876
|
||||
; fl = zerof+abs(fl) ; TODO optimizer generates wrong code for this (wrong order of splitted expression?)
|
||||
; floats.print_f(fl)
|
||||
; txt.chrout('\n')
|
||||
|
||||
; memset(ADDR, 40*25, 100)
|
||||
; memsetw(ADDR, 20*10, $3031)
|
||||
|
Loading…
Reference in New Issue
Block a user