mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
improved var -> const replacement, now done in constfolding already (fixes some obscure problems later on)
Also fixed some directive parenting errors
This commit is contained in:
parent
932bbd0381
commit
d03ff1e4d0
@ -1,5 +1,7 @@
|
||||
package prog8.optimizer
|
||||
|
||||
import prog8.ast.IFunctionCall
|
||||
import prog8.ast.IStatementContainer
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.FatalAstException
|
||||
@ -9,10 +11,17 @@ import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
import prog8.code.core.*
|
||||
import prog8.compiler.CallGraph
|
||||
|
||||
// Fix up the literal value's type to match that of the vardecl
|
||||
// (also check range literal operands types before they get expanded into arrays for instance)
|
||||
class VarConstantValueTypeAdjuster(private val program: Program, private val errors: IErrorReporter) : AstWalker() {
|
||||
class VarConstantValueTypeAdjuster(
|
||||
private val program: Program,
|
||||
private val options: CompilationOptions,
|
||||
private val errors: IErrorReporter
|
||||
) : AstWalker() {
|
||||
|
||||
private val callGraph by lazy { CallGraph(program) }
|
||||
|
||||
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||
|
||||
@ -38,6 +47,73 @@ class VarConstantValueTypeAdjuster(private val program: Program, private val err
|
||||
errors.err(x.message, x.position)
|
||||
}
|
||||
|
||||
// replace variables by constants, if possible
|
||||
if(options.optimize) {
|
||||
if (decl.sharedWithAsm || decl.type != VarDeclType.VAR || decl.origin != VarDeclOrigin.USERCODE || decl.datatype !in NumericDatatypes)
|
||||
return noModifications
|
||||
if (decl.value != null && decl.value!!.constValue(program) == null)
|
||||
return noModifications
|
||||
val usages = callGraph.usages(decl)
|
||||
val (writes, reads) = usages
|
||||
.partition {
|
||||
it is InlineAssembly // can't really tell if it's written to or only read, assume the worst
|
||||
|| it.parent is AssignTarget
|
||||
|| it.parent is ForLoop
|
||||
|| it.parent is AddressOf
|
||||
|| (it.parent as? IFunctionCall)?.target?.nameInSource?.singleOrNull() in InplaceModifyingBuiltinFunctions
|
||||
}
|
||||
val singleAssignment =
|
||||
writes.singleOrNull()?.parent?.parent as? Assignment ?: writes.singleOrNull()?.parent as? Assignment
|
||||
if (singleAssignment == null) {
|
||||
if (writes.isEmpty()) {
|
||||
if(reads.isEmpty()) {
|
||||
// variable is never used AT ALL so we just remove it altogether
|
||||
if("ignore_unused" !in decl.definingBlock.options())
|
||||
errors.info("removing unused variable '${decl.name}'", decl.position)
|
||||
return listOf(IAstModification.Remove(decl, parent as IStatementContainer))
|
||||
}
|
||||
val declValue = decl.value?.constValue(program)
|
||||
if (declValue != null) {
|
||||
// variable is never written to, so it can be replaced with a constant, IF the value is a constant
|
||||
errors.info("variable is never written to and was replaced by a constant", decl.position)
|
||||
val const = VarDecl(VarDeclType.CONST, decl.origin, decl.datatype, decl.zeropage, decl.arraysize, decl.name, decl.names, declValue, decl.sharedWithAsm, decl.splitArray, decl.position)
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(decl, const, parent),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (singleAssignment.origin == AssignmentOrigin.VARINIT && singleAssignment.value.constValue(program) != null) {
|
||||
if(reads.isEmpty()) {
|
||||
// variable is never used AT ALL so we just remove it altogether, including the single assignment
|
||||
if("ignore_unused" !in decl.definingBlock.options())
|
||||
errors.info("removing unused variable '${decl.name}'", decl.position)
|
||||
return listOf(
|
||||
IAstModification.Remove(decl, parent as IStatementContainer),
|
||||
IAstModification.Remove(singleAssignment, singleAssignment.parent as IStatementContainer)
|
||||
)
|
||||
}
|
||||
// variable only has a single write and it is the initialization value, so it can be replaced with a constant, IF the value is a constant
|
||||
errors.info("variable is never written to and was replaced by a constant", decl.position)
|
||||
val const = VarDecl(VarDeclType.CONST, decl.origin, decl.datatype, decl.zeropage, decl.arraysize, decl.name, decl.names, singleAssignment.value, decl.sharedWithAsm, decl.splitArray, decl.position)
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(decl, const, parent),
|
||||
IAstModification.Remove(singleAssignment, singleAssignment.parent as IStatementContainer)
|
||||
)
|
||||
}
|
||||
}
|
||||
/*
|
||||
TODO: need to check if there are no variable usages between the declaration and the assignment (because these rely on the original initialization value)
|
||||
if(writes.size==2) {
|
||||
val firstAssignment = writes[0].parent as? Assignment
|
||||
val secondAssignment = writes[1].parent as? Assignment
|
||||
if(firstAssignment?.origin==AssignmentOrigin.VARINIT && secondAssignment?.value?.constValue(program)!=null) {
|
||||
errors.warn("variable is only assigned once here, consider using this as the initialization value in the declaration instead", secondAssignment.position)
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return noModifications
|
||||
}
|
||||
|
||||
|
@ -7,13 +7,13 @@ import prog8.code.core.ICompilationTarget
|
||||
import prog8.code.core.IErrorReporter
|
||||
|
||||
|
||||
fun Program.constantFold(errors: IErrorReporter, compTarget: ICompilationTarget) {
|
||||
val valuetypefixer = VarConstantValueTypeAdjuster(this, errors)
|
||||
fun Program.constantFold(errors: IErrorReporter, options: CompilationOptions) {
|
||||
val valuetypefixer = VarConstantValueTypeAdjuster(this, options, errors)
|
||||
valuetypefixer.visit(this)
|
||||
if(errors.noErrors()) {
|
||||
valuetypefixer.applyModifications()
|
||||
|
||||
val replacer = ConstantIdentifierReplacer(this, errors, compTarget)
|
||||
val replacer = ConstantIdentifierReplacer(this, errors, options.compTarget)
|
||||
replacer.visit(this)
|
||||
if (errors.noErrors()) {
|
||||
replacer.applyModifications()
|
||||
|
@ -1,11 +1,17 @@
|
||||
package prog8.optimizer
|
||||
|
||||
import prog8.ast.*
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.expressions.BinaryExpression
|
||||
import prog8.ast.expressions.NumericLiteral
|
||||
import prog8.ast.expressions.PrefixExpression
|
||||
import prog8.ast.expressions.TypecastExpression
|
||||
import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
import prog8.code.core.*
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.ICompilationTarget
|
||||
import prog8.code.core.IErrorReporter
|
||||
import prog8.code.core.internedStringsModuleName
|
||||
import prog8.compiler.CallGraph
|
||||
|
||||
|
||||
@ -118,36 +124,6 @@ class UnusedCodeRemover(private val program: Program,
|
||||
return listOf(IAstModification.Remove(decl, parent as IStatementContainer))
|
||||
}
|
||||
else {
|
||||
val (writes, reads) = usages
|
||||
.partition{
|
||||
it is InlineAssembly // can't really tell if it's written to or only read, assume the worst
|
||||
|| it.parent is AssignTarget
|
||||
|| it.parent is ForLoop
|
||||
|| it.parent is AddressOf
|
||||
|| (it.parent as? IFunctionCall)?.target?.nameInSource?.singleOrNull() in InplaceModifyingBuiltinFunctions
|
||||
}
|
||||
val singleAssignment = writes.singleOrNull()?.parent?.parent as? Assignment ?: writes.singleOrNull()?.parent as? Assignment
|
||||
if (singleAssignment!=null && reads.isNotEmpty()) {
|
||||
if (singleAssignment.origin == AssignmentOrigin.VARINIT && singleAssignment.value.constValue(program) != null) {
|
||||
// variable only has a single write and it is the initialization value, so it can be replaced with a constant, IF the value is a constant
|
||||
errors.info("variable is never written to and was replaced by a constant", decl.position)
|
||||
val const = VarDecl(VarDeclType.CONST, decl.origin, decl.datatype, decl.zeropage, decl.arraysize, decl.name, decl.names, singleAssignment.value, decl.sharedWithAsm, decl.splitArray, decl.position)
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(decl, const, parent),
|
||||
IAstModification.Remove(singleAssignment, singleAssignment.parent as IStatementContainer)
|
||||
)
|
||||
}
|
||||
}
|
||||
/*
|
||||
TODO: need to check if there are no variable usages between the declaration and the assignment (because these rely on the original initialization value)
|
||||
if(writes.size==2) {
|
||||
val firstAssignment = writes[0].parent as? Assignment
|
||||
val secondAssignment = writes[1].parent as? Assignment
|
||||
if(firstAssignment?.origin==AssignmentOrigin.VARINIT && secondAssignment?.value?.constValue(program)!=null) {
|
||||
errors.warn("variable is only assigned once here, consider using this as the initialization value in the declaration instead", secondAssignment.position)
|
||||
}
|
||||
}
|
||||
*/
|
||||
if(usages.size==1) {
|
||||
val singleUse = usages[0].parent
|
||||
if(singleUse is AssignTarget) {
|
||||
|
@ -358,7 +358,7 @@ private fun processAst(program: Program, errors: IErrorReporter, compilerOptions
|
||||
errors.report()
|
||||
program.charLiteralsToUByteLiterals(compilerOptions.compTarget, errors)
|
||||
errors.report()
|
||||
program.constantFold(errors, compilerOptions.compTarget)
|
||||
program.constantFold(errors, compilerOptions)
|
||||
errors.report()
|
||||
program.desugaring(errors)
|
||||
errors.report()
|
||||
@ -385,7 +385,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
|
||||
val optsDone1 = program.simplifyExpressions(errors, compTarget)
|
||||
val optsDone2 = program.optimizeStatements(errors, functions, compilerOptions)
|
||||
val optsDone3 = program.inlineSubroutines(compilerOptions)
|
||||
program.constantFold(errors, compTarget) // because simplified statements and expressions can result in more constants that can be folded away
|
||||
program.constantFold(errors, compilerOptions) // because simplified statements and expressions can result in more constants that can be folded away
|
||||
if(!errors.noErrors()) {
|
||||
errors.report()
|
||||
break
|
||||
@ -397,7 +397,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
|
||||
remover2.visit(program)
|
||||
remover2.applyModifications()
|
||||
if(errors.noErrors())
|
||||
program.constantFold(errors, compTarget) // because simplified statements and expressions can result in more constants that can be folded away
|
||||
program.constantFold(errors, compilerOptions) // because simplified statements and expressions can result in more constants that can be folded away
|
||||
errors.report()
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,9 @@ class ModuleImporter(private val program: Program,
|
||||
importedModule.statements.remove(block)
|
||||
|
||||
if(blockHasMergeOption && !existingBlockHasMergeOption) {
|
||||
existingBlock.statements.add(0, Directive("%option", listOf(DirectiveArg(null, "merge", null, block.position)), block.position))
|
||||
val directive = Directive("%option", listOf(DirectiveArg(null, "merge", null, block.position)), block.position)
|
||||
existingBlock.statements.add(0, directive)
|
||||
directive.linkParents(existingBlock)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -465,8 +465,8 @@ class TestOptimization: FunSpec({
|
||||
%option force_output
|
||||
|
||||
sub start() {
|
||||
uword aa
|
||||
ubyte zz
|
||||
uword @shared aa
|
||||
ubyte @shared zz
|
||||
@(aa) = zz + 32
|
||||
}
|
||||
}
|
||||
|
@ -386,182 +386,182 @@ main {
|
||||
}
|
||||
|
||||
sub shiftruw0() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q >> 0
|
||||
}
|
||||
|
||||
sub shiftruw1() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q >> 1
|
||||
}
|
||||
|
||||
sub shiftruw2() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q >> 2
|
||||
}
|
||||
|
||||
sub shiftruw3() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q >> 3
|
||||
}
|
||||
|
||||
sub shiftruw4() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q >> 4
|
||||
}
|
||||
|
||||
sub shiftruw5() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q >> 5
|
||||
}
|
||||
|
||||
sub shiftruw6() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q >> 6
|
||||
}
|
||||
|
||||
sub shiftruw7() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q >> 7
|
||||
}
|
||||
|
||||
sub shiftruw8() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 8)
|
||||
}
|
||||
|
||||
sub shiftruw9() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 9)
|
||||
}
|
||||
|
||||
sub shiftruw10() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 10)
|
||||
}
|
||||
|
||||
sub shiftruw11() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 11)
|
||||
}
|
||||
|
||||
sub shiftruw12() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 12)
|
||||
}
|
||||
|
||||
sub shiftruw13() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 13)
|
||||
}
|
||||
|
||||
sub shiftruw14() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 14)
|
||||
}
|
||||
|
||||
sub shiftruw15() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 15)
|
||||
}
|
||||
|
||||
sub shiftruw16() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 16)
|
||||
}
|
||||
|
||||
sub shiftruw17() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return (q >> 17)
|
||||
}
|
||||
|
||||
sub shiftrsw0() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q >> 0
|
||||
}
|
||||
|
||||
sub shiftrsw1() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q >> 1
|
||||
}
|
||||
|
||||
sub shiftrsw2() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q >> 2
|
||||
}
|
||||
|
||||
sub shiftrsw3() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q >> 3
|
||||
}
|
||||
|
||||
sub shiftrsw4() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q >> 4
|
||||
}
|
||||
|
||||
sub shiftrsw5() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q >> 5
|
||||
}
|
||||
|
||||
sub shiftrsw6() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q >> 6
|
||||
}
|
||||
|
||||
sub shiftrsw7() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q >> 7
|
||||
}
|
||||
|
||||
sub shiftrsw8() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 8)
|
||||
}
|
||||
|
||||
sub shiftrsw9() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 9)
|
||||
}
|
||||
|
||||
sub shiftrsw10() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 10)
|
||||
}
|
||||
|
||||
sub shiftrsw11() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 11)
|
||||
}
|
||||
|
||||
sub shiftrsw12() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 12)
|
||||
}
|
||||
|
||||
sub shiftrsw13() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 13)
|
||||
}
|
||||
|
||||
sub shiftrsw14() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 14)
|
||||
}
|
||||
|
||||
sub shiftrsw15() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 15)
|
||||
}
|
||||
|
||||
sub shiftrsw16() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 16)
|
||||
}
|
||||
|
||||
sub shiftrsw17() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return (q >> 17)
|
||||
}
|
||||
|
||||
@ -569,352 +569,352 @@ main {
|
||||
|
||||
|
||||
sub shiftluw0() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 0
|
||||
}
|
||||
|
||||
sub shiftluw1() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 1
|
||||
}
|
||||
|
||||
sub shiftluw2() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 2
|
||||
}
|
||||
|
||||
sub shiftluw3() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 3
|
||||
}
|
||||
|
||||
sub shiftluw4() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 4
|
||||
}
|
||||
|
||||
sub shiftluw5() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 5
|
||||
}
|
||||
|
||||
sub shiftluw6() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 6
|
||||
}
|
||||
|
||||
sub shiftluw7() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 7
|
||||
}
|
||||
|
||||
sub shiftluw8() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 8
|
||||
}
|
||||
|
||||
sub shiftluw9() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 9
|
||||
}
|
||||
|
||||
sub shiftluw10() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 10
|
||||
}
|
||||
|
||||
sub shiftluw11() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 11
|
||||
}
|
||||
|
||||
sub shiftluw12() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 12
|
||||
}
|
||||
|
||||
sub shiftluw13() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 13
|
||||
}
|
||||
|
||||
sub shiftluw14() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 14
|
||||
}
|
||||
|
||||
sub shiftluw15() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 15
|
||||
}
|
||||
|
||||
sub shiftluw16() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 16
|
||||
}
|
||||
|
||||
sub shiftluw17() -> uword {
|
||||
uword q = $a49f
|
||||
uword @shared q = $a49f
|
||||
return q << 17
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub shiftlsw0() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 0
|
||||
}
|
||||
|
||||
sub shiftlsw1() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 1
|
||||
}
|
||||
|
||||
sub shiftlsw2() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 2
|
||||
}
|
||||
|
||||
sub shiftlsw3() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 3
|
||||
}
|
||||
|
||||
sub shiftlsw4() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 4
|
||||
}
|
||||
|
||||
sub shiftlsw5() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 5
|
||||
}
|
||||
|
||||
sub shiftlsw6() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 6
|
||||
}
|
||||
|
||||
sub shiftlsw7() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 7
|
||||
}
|
||||
|
||||
sub shiftlsw8() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 8
|
||||
}
|
||||
|
||||
sub shiftlsw9() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 9
|
||||
}
|
||||
|
||||
sub shiftlsw10() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 10
|
||||
}
|
||||
|
||||
sub shiftlsw11() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 11
|
||||
}
|
||||
|
||||
sub shiftlsw12() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 12
|
||||
}
|
||||
|
||||
sub shiftlsw13() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 13
|
||||
}
|
||||
|
||||
sub shiftlsw14() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 14
|
||||
}
|
||||
|
||||
sub shiftlsw15() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 15
|
||||
}
|
||||
|
||||
sub shiftlsw16() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 16
|
||||
}
|
||||
|
||||
sub shiftlsw17() -> word {
|
||||
word q = -12345
|
||||
word @shared q = -12345
|
||||
return q << 17
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub shiftlb0() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 0
|
||||
}
|
||||
sub shiftlb1() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 1
|
||||
}
|
||||
sub shiftlb2() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 2
|
||||
}
|
||||
sub shiftlb3() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 3
|
||||
}
|
||||
sub shiftlb4() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 4
|
||||
}
|
||||
sub shiftlb5() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 5
|
||||
}
|
||||
sub shiftlb6() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 6
|
||||
}
|
||||
sub shiftlb7() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 7
|
||||
}
|
||||
sub shiftlb8() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 8
|
||||
}
|
||||
sub shiftlb9() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy << 9
|
||||
}
|
||||
|
||||
sub shiftrb0() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 0
|
||||
}
|
||||
sub shiftrb1() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 1
|
||||
}
|
||||
sub shiftrb2() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 2
|
||||
}
|
||||
sub shiftrb3() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 3
|
||||
}
|
||||
sub shiftrb4() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 4
|
||||
}
|
||||
sub shiftrb5() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 5
|
||||
}
|
||||
sub shiftrb6() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 6
|
||||
}
|
||||
sub shiftrb7() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 7
|
||||
}
|
||||
sub shiftrb8() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 8
|
||||
}
|
||||
sub shiftrb9() -> ubyte {
|
||||
ubyte yy=$ed
|
||||
ubyte @shared yy=$ed
|
||||
return yy >> 9
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub shiftlsb0() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 0
|
||||
}
|
||||
sub shiftlsb1() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 1
|
||||
}
|
||||
sub shiftlsb2() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 2
|
||||
}
|
||||
sub shiftlsb3() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 3
|
||||
}
|
||||
sub shiftlsb4() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 4
|
||||
}
|
||||
sub shiftlsb5() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 5
|
||||
}
|
||||
sub shiftlsb6() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 6
|
||||
}
|
||||
sub shiftlsb7() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 7
|
||||
}
|
||||
sub shiftlsb8() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 8
|
||||
}
|
||||
sub shiftlsb9() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy << 9
|
||||
}
|
||||
|
||||
sub shiftrsb0() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 0
|
||||
}
|
||||
sub shiftrsb1() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 1
|
||||
}
|
||||
sub shiftrsb2() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 2
|
||||
}
|
||||
sub shiftrsb3() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 3
|
||||
}
|
||||
sub shiftrsb4() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 4
|
||||
}
|
||||
sub shiftrsb5() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 5
|
||||
}
|
||||
sub shiftrsb6() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 6
|
||||
}
|
||||
sub shiftrsb7() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 7
|
||||
}
|
||||
sub shiftrsb8() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 8
|
||||
}
|
||||
sub shiftrsb9() -> byte {
|
||||
byte yy=-123
|
||||
byte @shared yy=-123
|
||||
return yy >> 9
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ class Program(val name: String,
|
||||
val block = Block(internedStringsModuleName, null, mutableListOf(), true, Position.DUMMY)
|
||||
val directive = Directive("%option", listOf(DirectiveArg(null,"no_symbol_prefixing", null, Position.DUMMY)), Position.DUMMY)
|
||||
block.statements.add(directive)
|
||||
directive.linkParents(block)
|
||||
internedStringsModule.statements.add(block)
|
||||
|
||||
_modules.add(0, internedStringsModule)
|
||||
|
@ -2,8 +2,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- fix bitshift.p8
|
||||
|
||||
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||
|
||||
...
|
||||
|
Loading…
x
Reference in New Issue
Block a user