mirror of
https://github.com/irmen/prog8.git
synced 2025-02-27 18:29:00 +00:00
slightly optimized code for assigning boolean expressions such as `b = xx>99
`
This commit is contained in:
parent
895534f32b
commit
124befe9d6
@ -285,16 +285,42 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
else throw AssemblyError("invalid dt")
|
||||
asmgen.assignRegister(register, assign.target)
|
||||
}
|
||||
is BinaryExpression -> {
|
||||
if(value.operator in ComparisonOperators) {
|
||||
// TODO real optimized code for comparison expressions
|
||||
// for now generate code for this: assign-false; if expr { assign-true }
|
||||
translateNormalAssignment(
|
||||
AsmAssignment(
|
||||
AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, asmgen, DataType.UBYTE, number=NumericLiteralValue.fromBoolean(false, assign.position)),
|
||||
assign.target, false, program.memsizer, assign.position
|
||||
)
|
||||
)
|
||||
val origTarget = assign.target.origAstTarget
|
||||
if(origTarget!=null) {
|
||||
val assignTrue = AnonymousScope(mutableListOf(
|
||||
Assignment(origTarget, NumericLiteralValue.fromBoolean(true, assign.position), assign.position)
|
||||
), assign.position)
|
||||
val assignFalse = AnonymousScope(mutableListOf(), assign.position)
|
||||
val ifelse = IfElse(value.copy(), assignTrue, assignFalse, assign.position)
|
||||
ifelse.linkParents(value)
|
||||
asmgen.translate(ifelse)
|
||||
}
|
||||
else {
|
||||
// no orig ast assign target, can't use the workaround, so fallback to stack eval
|
||||
fallbackToStackEval(value, assign)
|
||||
}
|
||||
} else {
|
||||
// Everything else just evaluate via the stack.
|
||||
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
|
||||
// because the code here is the implementation of exactly that...)
|
||||
fallbackToStackEval(value, assign)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
// Everything else just evaluate via the stack.
|
||||
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
|
||||
// because the code here is the implementation of exactly that...)
|
||||
// TODO DON'T STACK-EVAL THIS... by using a temp var? so that it becomes augmentable assignment expression?
|
||||
asmgen.translateExpression(value)
|
||||
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
|
||||
asmgen.signExtendStackLsb(assign.source.datatype)
|
||||
if(assign.target.kind!=TargetStorageKind.STACK || assign.target.datatype != assign.source.datatype)
|
||||
assignStackValue(assign.target)
|
||||
fallbackToStackEval(value, assign)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -308,6 +334,15 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
}
|
||||
|
||||
private fun fallbackToStackEval(value: Expression, assign: AsmAssignment) {
|
||||
// TODO DON'T STACK-EVAL THIS... by using a temp var? so that it becomes augmentable assignment expression?
|
||||
asmgen.translateExpression(value)
|
||||
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
|
||||
asmgen.signExtendStackLsb(assign.source.datatype)
|
||||
if (assign.target.kind != TargetStorageKind.STACK || assign.target.datatype != assign.source.datatype)
|
||||
assignStackValue(assign.target)
|
||||
}
|
||||
|
||||
private fun containmentCheckIntoA(containment: ContainmentCheck) {
|
||||
val elementDt = containment.element.inferType(program)
|
||||
val range = containment.iterable as? RangeExpression
|
||||
|
@ -4,7 +4,7 @@ TODO
|
||||
For next compiler release (7.7)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
- optimize codegen of pipe operator to avoid needless assigns to temp var
|
||||
- why is this using stack evaluation: bb = ww>0 (if ww>0 is not using stack!)
|
||||
|
||||
|
||||
Need help with
|
||||
^^^^^^^^^^^^^^
|
||||
@ -53,6 +53,7 @@ Future Things and Ideas
|
||||
|
||||
More optimization ideas
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
- translateNormalAssignment() -> better code gen for assigning boolean comparison expressions
|
||||
- if a for loop's loopvariable isn't referenced in the body, replace by a repeatloop
|
||||
- automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements, instead of just a warning
|
||||
- byte typed expressions should be evaluated in the accumulator where possible, without (temp)var
|
||||
|
@ -5,15 +5,14 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
ubyte dead
|
||||
dead = 1
|
||||
dead = func()
|
||||
dead = 2
|
||||
dead = func()
|
||||
dead = 3
|
||||
dead = func()
|
||||
dead = 4
|
||||
dead = func()
|
||||
uword ww
|
||||
ubyte bb
|
||||
|
||||
bb = ww==0
|
||||
bb++
|
||||
if ww==0 {
|
||||
bb++
|
||||
}
|
||||
|
||||
; fl = 1.234 |> addfloat1 |> addfloat2 |> addfloat3
|
||||
; floats.print_f(fl)
|
||||
|
Loading…
x
Reference in New Issue
Block a user