mirror of
https://github.com/irmen/prog8.git
synced 2025-01-12 19:29:50 +00:00
more optimal if expression code
This commit is contained in:
parent
326eab3dd1
commit
c14f6cfc2b
@ -66,6 +66,7 @@ What does Prog8 provide?
|
||||
- conditional branches that map 1:1 to cpu status flags
|
||||
- ``when`` statement to provide a concise jump table alternative to if/elseif chains
|
||||
- ``in`` expression for concise and efficient multi-value/containment check
|
||||
- ``defer`` statement to help write concise and robust subroutine cleanup logic
|
||||
- several specialized built-in functions such as ``lsb``, ``msb``, ``min``, ``max``, ``rol``, ``ror``
|
||||
- various powerful built-in libraries to do I/O, number conversions, graphics and more
|
||||
- inline assembly allows you to have full control when every cycle or byte matters
|
||||
|
@ -645,7 +645,7 @@ internal class AssignmentAsmGen(
|
||||
}
|
||||
|
||||
private fun assignIfExpression(target: AsmAssignTarget, expr: PtIfExpression) {
|
||||
// TODO dont store condition as expression result but just use the flags, like a normal PtIfElse translation does
|
||||
// TODO don't store condition as expression result but just use the flags, like a normal PtIfElse translation does
|
||||
require(target.datatype==expr.type)
|
||||
val falseLabel = asmgen.makeLabel("ifexpr_false")
|
||||
val endLabel = asmgen.makeLabel("ifexpr_end")
|
||||
@ -654,32 +654,27 @@ internal class AssignmentAsmGen(
|
||||
when(expr.type) {
|
||||
in ByteDatatypesWithBoolean -> {
|
||||
assignExpressionToRegister(expr.truevalue, RegisterOrPair.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, false)
|
||||
asmgen.jmp(endLabel)
|
||||
asmgen.out(falseLabel)
|
||||
assignExpressionToRegister(expr.falsevalue, RegisterOrPair.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, false)
|
||||
asmgen.out(endLabel)
|
||||
assignRegisterByte(target, CpuRegister.A, false, false)
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
assignExpressionToRegister(expr.truevalue, RegisterOrPair.AY, false)
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
asmgen.jmp(endLabel)
|
||||
asmgen.out(falseLabel)
|
||||
assignExpressionToRegister(expr.falsevalue, RegisterOrPair.AY, false)
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
asmgen.out(endLabel)
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
val trueSrc = AsmAssignSource.fromAstSource(expr.truevalue, program, asmgen)
|
||||
val assignTrue = AsmAssignment(trueSrc, target, program.memsizer, expr.position)
|
||||
translateNormalAssignment(assignTrue, expr.definingISub())
|
||||
assignExpressionToRegister(expr.truevalue, RegisterOrPair.FAC1, true)
|
||||
asmgen.jmp(endLabel)
|
||||
asmgen.out(falseLabel)
|
||||
val falseSrc = AsmAssignSource.fromAstSource(expr.falsevalue, program, asmgen)
|
||||
val assignFalse = AsmAssignment(falseSrc, target, program.memsizer, expr.position)
|
||||
translateNormalAssignment(assignFalse, expr.definingISub())
|
||||
assignExpressionToRegister(expr.falsevalue, RegisterOrPair.FAC1, true)
|
||||
asmgen.out(endLabel)
|
||||
asmgen.assignRegister(RegisterOrPair.FAC1, target)
|
||||
}
|
||||
else -> throw AssemblyError("weird dt")
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
|
||||
private fun translate(ifExpr: PtIfExpression): ExpressionCodeResult {
|
||||
// TODO dont store condition as expression result but just use the flags, like a normal PtIfElse translation does
|
||||
// TODO don't store condition as expression result but just use the flags, like a normal PtIfElse translation does
|
||||
val condTr = translateExpression(ifExpr.condition)
|
||||
val trueTr = translateExpression(ifExpr.truevalue)
|
||||
val falseTr = translateExpression(ifExpr.falsevalue)
|
||||
|
@ -93,11 +93,12 @@ Features
|
||||
still able to directly use memory addresses and ROM subroutines,
|
||||
and inline assembly to have full control when every register, cycle or byte matters
|
||||
- Variables are all allocated statically, no memory allocation overhead
|
||||
- Variable data types include signed and unsigned bytes and words, arrays, strings.
|
||||
- Conditional branches for status flags that map 1:1 to processor branch instructions for optimal efficiency
|
||||
- ``when`` statement to avoid if-else chains
|
||||
- ``in`` expression for concise and efficient multi-value/containment test
|
||||
- ``defer`` statement to help write concise and robust subroutine cleanup logic
|
||||
- Several specialized built-in functions, such as ``lsb``, ``msb``, ``min``, ``max``, ``rol``, ``ror``
|
||||
- Variable data types include signed and unsigned bytes and words, arrays, strings.
|
||||
- Various powerful built-in libraries to do I/O, number conversions, graphics and more
|
||||
- Floating point math is supported on certain compiler targets.
|
||||
- Easy and highly efficient integration with external subroutines and ROM routines on the target systems.
|
||||
|
@ -1,7 +1,7 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- Optimize the IfExpression code generation to be more like regular if-else code. (both 6502 and IR)
|
||||
- Optimize the IfExpression code generation to be more like regular if-else code. (both 6502 and IR) (assignIfExpression / translate(ifExpr: PtIfExpression))
|
||||
|
||||
|
||||
Improve register load order in subroutine call args assignments:
|
||||
|
@ -1,54 +1,24 @@
|
||||
%import textio
|
||||
%import floats
|
||||
%import textio
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
uword res1 = allocate(111)
|
||||
defer deallocate(res1)
|
||||
uword res2 = allocate(222)
|
||||
if res2==0
|
||||
return
|
||||
defer deallocate(res2)
|
||||
ubyte[4] values
|
||||
uword[4] wvalues
|
||||
float[4] fvalues
|
||||
cx16.r0L = 0
|
||||
cx16.r1L = 3
|
||||
values[cx16.r0L+2] = if cx16.r1L>2 99 else 111
|
||||
wvalues[cx16.r0L+2] = if cx16.r1L>2 9999 else 1111
|
||||
fvalues[cx16.r0L+2] = if cx16.r1L>2 9.99 else 1.111
|
||||
|
||||
if not process1(res1, res2)
|
||||
return
|
||||
if not process2(res1, res2)
|
||||
return
|
||||
}
|
||||
|
||||
sub allocate(uword arg) -> uword {
|
||||
; if arg==222
|
||||
; return 0
|
||||
txt.print("allocate ")
|
||||
txt.print_uw(4000+arg)
|
||||
txt.print_ub(values[2])
|
||||
txt.nl()
|
||||
return 4000+arg
|
||||
}
|
||||
|
||||
sub deallocate(uword arg) {
|
||||
txt.print("dealloc ")
|
||||
txt.print_uw(arg)
|
||||
txt.print_uw(wvalues[2])
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub process1(uword arg1, uword arg2) -> bool {
|
||||
txt.print("process1 ")
|
||||
txt.print_uw(arg1)
|
||||
txt.spc()
|
||||
txt.print_uw(arg2)
|
||||
txt.nl()
|
||||
return true
|
||||
}
|
||||
|
||||
sub process2(uword arg1, uword arg2) -> bool {
|
||||
txt.print("process2 ")
|
||||
txt.print_uw(arg1)
|
||||
txt.spc()
|
||||
txt.print_uw(arg2)
|
||||
txt.nl()
|
||||
return true
|
||||
floats.print(fvalues[2])
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user