diff --git a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt index cd548561f..2de042862 100644 --- a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt +++ b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt @@ -22,6 +22,9 @@ class BinExprSplitter(private val program: Program, private val options: Compila override fun after(assignment: Assignment, parent: Node): Iterable { + if(options.compTarget.name == VMTarget.NAME) + return noModifications // don't split expressions when targeting the vm codegen, it handles nested expressions well + if(assignment.value.inferType(program) istype DataType.FLOAT && !options.optimizeFloatExpressions) return noModifications diff --git a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt index 3b3d9c561..3097ca17a 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -1,18 +1,15 @@ package prog8.optimizer -import prog8.ast.Node -import prog8.ast.Program +import prog8.ast.* import prog8.ast.base.FatalAstException import prog8.ast.base.UndefinedSymbolError import prog8.ast.expressions.* -import prog8.ast.maySwapOperandOrder -import prog8.ast.statements.ForLoop -import prog8.ast.statements.VarDecl -import prog8.ast.statements.VarDeclType +import prog8.ast.statements.* import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification import prog8.code.core.AssociativeOperators import prog8.code.core.DataType +import prog8.compiler.BuiltinFunctions class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { @@ -265,7 +262,6 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { } override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable { - // the args of a fuction are constfolded via recursion already. val constvalue = functionCallExpr.constValue(program) return if(constvalue!=null) listOf(IAstModification.ReplaceNode(functionCallExpr, constvalue, parent)) @@ -273,6 +269,14 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { noModifications } + override fun after(bfc: BuiltinFunctionCall, parent: Node): Iterable { + val constvalue = bfc.constValue(program) + return if(constvalue!=null) + listOf(IAstModification.ReplaceNode(bfc, constvalue, parent)) + else + noModifications + } + override fun after(forLoop: ForLoop, parent: Node): Iterable { fun adjustRangeDt(rangeFrom: NumericLiteral, targetDt: DataType, rangeTo: NumericLiteral, stepLiteral: NumericLiteral?, range: RangeExpression): RangeExpression? { val fromCast = rangeFrom.cast(targetDt) diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index a7ef7a44d..ba5543605 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -10,6 +10,7 @@ import prog8.ast.statements.* import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstVisitor import prog8.code.core.* +import prog8.compiler.BuiltinFunctions import java.util.* import kotlin.math.abs import kotlin.math.floor @@ -1142,7 +1143,13 @@ class BuiltinFunctionCall(override var target: IdentifierReference, replacement.parent = this } - override fun constValue(program: Program): NumericLiteral? = null + override fun constValue(program: Program): NumericLiteral? { + val function = BuiltinFunctions.getValue(name) + if(function.pure) { + return program.builtinFunctions.constValue(name, args, position) + } + return null + } override fun toString() = "BuiltinFunctionCall(name=$name, pos=$position)" override fun accept(visitor: IAstVisitor) = visitor.visit(this) override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 3ccf06b85..e174b356a 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,17 +3,7 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- logical.p8 is huge compared to 8.2 - -- compiling logical.p8 to virtual with optimization generates code that is smaller, - but takes many more vm instructions to execute than not-optimized code!? - -- petaxian.prg became quite a bit (150 bytes) larger since 8.2, what causes that - -- add some more optimizations in vmPeepholeOptimizer -- vm Instruction needs to know what the read-registers/memory are, and what the write-register/memory is. - this info is needed for more advanced optimizations and later code generation steps. - +... Need help with ^^^^^^^^^^^^^^ @@ -25,7 +15,10 @@ Need help with Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ Compiler: - +- add true 'bool' type that can only be 0 or 1, so that logical expressons don't have to use boolean() all the time on their operands +- add some more optimizations in vmPeepholeOptimizer +- vm Instruction needs to know what the read-registers/memory are, and what the write-register/memory is. + this info is needed for more advanced optimizations and later code generation steps. - vm: implement remaining sin/cos functions in math.p8 - vm: somehow deal with asmsubs otherwise the vm IR can't fully encode all of prog8 - vm: don't store symbol names in instructions to make optimizing the IR easier? but what about jumps to labels. And it's no longer readable by humans. diff --git a/examples/cx16/zsound/play-zsound.p8 b/examples/cx16/zsound/play-zsound.p8 index 548439233..3dca74728 100644 --- a/examples/cx16/zsound/play-zsound.p8 +++ b/examples/cx16/zsound/play-zsound.p8 @@ -45,7 +45,7 @@ zsound_lib: const ubyte song_bank = 1 const uword song_address = $a000 - const ubyte digi_bank = 5 + const ubyte digi_bank = 6 const uword digi_address = $a000 const ubyte zcm_DIGITAB_size = 8 ; header size @@ -82,8 +82,6 @@ zsound_lib: txt.print_uw(zsm_get_music_speed()) txt.print(" hz\nplaying song! hit enter to also play a digi sample!\n") - ; for IRQ based playback instead: cx16.set_irq(&zsm_playIRQ, true) - repeat { if cx16.joystick_get2(0)!=$ffff pcm_trigger_digi(digi_bank, digi_address) diff --git a/examples/cx16/zsound/stream-test-zcm.p8 b/examples/cx16/zsound/stream-test-zcm.p8 index 49c330953..94c3ebc43 100644 --- a/examples/cx16/zsound/stream-test-zcm.p8 +++ b/examples/cx16/zsound/stream-test-zcm.p8 @@ -3,6 +3,12 @@ %import cx16diskio %zpreserved $22,$2d ; zsound lib uses this region +; NOTE: this is a proof of concept to stream ZCM digi from disk while playing. +; currently there's no real streaming API / circular buffer in zsound, +; so it simply loads the whole ZCM file in chunks in memory sequentially. +; But it does so while the playback is going on in the background. +; It seems fast enough to stream + play 16khz 16bit stereo samples. (around 64 Kb/sec) +; Maybe we can go faster but 22 Khz seemed too much to keep up with. main $0830 { @@ -54,7 +60,7 @@ zsound_lib: pcm_init() pcm_trigger_digi(digi_bank, digi_address) - cx16.set_irq(&zsm_playroutine, true) + cx16.set_irq(&zsm_playroutine_irq, true) txt.print("\nstreaming from file, playback in irq!\n") uword size = 1 @@ -73,7 +79,7 @@ zsound_lib: pcm_stop() ;unreached } - sub zsm_playroutine() { + sub zsm_playroutine_irq() { pcm_play() } }