mirror of
https://github.com/irmen/prog8.git
synced 2025-07-04 23:24:10 +00:00
fix alignment of uninitialized arrays in aligned blocks (make them initialized with zeros so they don't end up in the BSS section)
fix alignment of uninitialized arrays in aligned blocks (make them initialized with zeros so they don't end up in the BSS section)
This commit is contained in:
@ -196,13 +196,10 @@ class StStaticVariable(name: String,
|
|||||||
}
|
}
|
||||||
if(onetimeInitializationNumericValue!=null) {
|
if(onetimeInitializationNumericValue!=null) {
|
||||||
require(dt in NumericDatatypes)
|
require(dt in NumericDatatypes)
|
||||||
require(onetimeInitializationNumericValue!=0.0) { "zero as init value should just remain uninitialized"}
|
|
||||||
}
|
}
|
||||||
if(onetimeInitializationArrayValue!=null) {
|
if(onetimeInitializationArrayValue!=null) {
|
||||||
require(dt in ArrayDatatypes)
|
require(dt in ArrayDatatypes)
|
||||||
if(onetimeInitializationArrayValue.all { it.number!=null} ) {
|
require(length==onetimeInitializationArrayValue.size)
|
||||||
require(onetimeInitializationArrayValue.any { it.number != 0.0 }) { "array of all zerors as init value should just remain uninitialized" }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(onetimeInitializationStringValue!=null) {
|
if(onetimeInitializationStringValue!=null) {
|
||||||
require(dt == DataType.STR)
|
require(dt == DataType.STR)
|
||||||
|
@ -74,10 +74,9 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
|||||||
numElements = value.value.length + 1 // include the terminating 0-byte
|
numElements = value.value.length + 1 // include the terminating 0-byte
|
||||||
}
|
}
|
||||||
is PtArray -> {
|
is PtArray -> {
|
||||||
val array = makeInitialArray(value)
|
initialArray = makeInitialArray(value)
|
||||||
initialArray = if(array.all { it.number==0.0 }) null else array // all 0 as init value -> just uninitialized
|
|
||||||
initialString = null
|
initialString = null
|
||||||
numElements = array.size
|
numElements = initialArray.size
|
||||||
require(node.arraySize?.toInt()==numElements)
|
require(node.arraySize?.toInt()==numElements)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -276,10 +276,27 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
|||||||
return listOf(IAstModification.ReplaceNode(decl.value!!, newValue, decl))
|
return listOf(IAstModification.ReplaceNode(decl.value!!, newValue, decl))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
in ArrayDatatypes -> {
|
||||||
|
val replacedArrayInitializer = createConstArrayInitializerValue(decl)
|
||||||
|
if(replacedArrayInitializer!=null)
|
||||||
|
return listOf(IAstModification.ReplaceNode(decl.value!!, replacedArrayInitializer, decl))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// nothing to do for this type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return noModifications
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createConstArrayInitializerValue(decl: VarDecl): ArrayLiteral? {
|
||||||
|
// convert the initializer range expression from a range or int, to an actual array.
|
||||||
|
|
||||||
|
when(decl.datatype) {
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_W_SPLIT, DataType.ARRAY_UW_SPLIT -> {
|
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_W_SPLIT, DataType.ARRAY_UW_SPLIT -> {
|
||||||
val rangeExpr = decl.value as? RangeExpression
|
val rangeExpr = decl.value as? RangeExpression
|
||||||
if(rangeExpr!=null) {
|
if(rangeExpr!=null) {
|
||||||
// convert the initializer range expression to an actual array
|
|
||||||
val constRange = rangeExpr.toConstantIntegerRange()
|
val constRange = rangeExpr.toConstantIntegerRange()
|
||||||
if(constRange?.isEmpty()==true) {
|
if(constRange?.isEmpty()==true) {
|
||||||
if(constRange.first>constRange.last && constRange.step>=0)
|
if(constRange.first>constRange.last && constRange.step>=0)
|
||||||
@ -292,7 +309,7 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
|||||||
errors.err("range expression size (${rangeExpr.size()}) doesn't match declared array size ($declArraySize)", decl.value?.position!!)
|
errors.err("range expression size (${rangeExpr.size()}) doesn't match declared array size ($declArraySize)", decl.value?.position!!)
|
||||||
if(constRange!=null) {
|
if(constRange!=null) {
|
||||||
val eltType = rangeExpr.inferType(program).getOr(DataType.UBYTE)
|
val eltType = rangeExpr.inferType(program).getOr(DataType.UBYTE)
|
||||||
val newValue = if(eltType in ByteDatatypes) {
|
return if(eltType in ByteDatatypes) {
|
||||||
ArrayLiteral(InferredTypes.InferredType.known(decl.datatype),
|
ArrayLiteral(InferredTypes.InferredType.known(decl.datatype),
|
||||||
constRange.map { NumericLiteral(eltType, it.toDouble(), decl.value!!.position) }.toTypedArray(),
|
constRange.map { NumericLiteral(eltType, it.toDouble(), decl.value!!.position) }.toTypedArray(),
|
||||||
position = decl.value!!.position)
|
position = decl.value!!.position)
|
||||||
@ -301,13 +318,12 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
|||||||
constRange.map { NumericLiteral(eltType, it.toDouble(), decl.value!!.position) }.toTypedArray(),
|
constRange.map { NumericLiteral(eltType, it.toDouble(), decl.value!!.position) }.toTypedArray(),
|
||||||
position = decl.value!!.position)
|
position = decl.value!!.position)
|
||||||
}
|
}
|
||||||
return listOf(IAstModification.ReplaceNode(decl.value!!, newValue, decl))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val numericLv = decl.value as? NumericLiteral
|
val numericLv = decl.value as? NumericLiteral
|
||||||
if(numericLv!=null && numericLv.type== DataType.FLOAT)
|
if(numericLv!=null && numericLv.type== DataType.FLOAT)
|
||||||
errors.err("arraysize requires only integers here", numericLv.position)
|
errors.err("arraysize requires only integers here", numericLv.position)
|
||||||
val size = decl.arraysize?.constIndex() ?: return noModifications
|
val size = decl.arraysize?.constIndex() ?: return null
|
||||||
if (rangeExpr==null && numericLv!=null) {
|
if (rangeExpr==null && numericLv!=null) {
|
||||||
// arraysize initializer is empty or a single int, and we know the size; create the arraysize.
|
// arraysize initializer is empty or a single int, and we know the size; create the arraysize.
|
||||||
val fillvalue = numericLv.number.toInt()
|
val fillvalue = numericLv.number.toInt()
|
||||||
@ -332,8 +348,7 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
|||||||
}
|
}
|
||||||
// create the array itself, filled with the fillvalue.
|
// create the array itself, filled with the fillvalue.
|
||||||
val array = Array(size) {fillvalue}.map { NumericLiteral(ArrayToElementTypes.getValue(decl.datatype), it.toDouble(), numericLv.position) }.toTypedArray<Expression>()
|
val array = Array(size) {fillvalue}.map { NumericLiteral(ArrayToElementTypes.getValue(decl.datatype), it.toDouble(), numericLv.position) }.toTypedArray<Expression>()
|
||||||
val refValue = ArrayLiteral(InferredTypes.InferredType.known(decl.datatype), array, position = numericLv.position)
|
return ArrayLiteral(InferredTypes.InferredType.known(decl.datatype), array, position = numericLv.position)
|
||||||
return listOf(IAstModification.ReplaceNode(decl.value!!, refValue, decl))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.ARRAY_F -> {
|
DataType.ARRAY_F -> {
|
||||||
@ -345,15 +360,14 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
|||||||
errors.err("range expression size (${rangeExpr.size()}) doesn't match declared array size ($declArraySize)", decl.value?.position!!)
|
errors.err("range expression size (${rangeExpr.size()}) doesn't match declared array size ($declArraySize)", decl.value?.position!!)
|
||||||
val constRange = rangeExpr.toConstantIntegerRange()
|
val constRange = rangeExpr.toConstantIntegerRange()
|
||||||
if(constRange!=null) {
|
if(constRange!=null) {
|
||||||
val newValue = ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_F),
|
return ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_F),
|
||||||
constRange.map { NumericLiteral(DataType.FLOAT, it.toDouble(), decl.value!!.position) }.toTypedArray(),
|
constRange.map { NumericLiteral(DataType.FLOAT, it.toDouble(), decl.value!!.position) }.toTypedArray(),
|
||||||
position = decl.value!!.position)
|
position = decl.value!!.position)
|
||||||
return listOf(IAstModification.ReplaceNode(decl.value!!, newValue, decl))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val numericLv = decl.value as? NumericLiteral
|
val numericLv = decl.value as? NumericLiteral
|
||||||
val size = decl.arraysize?.constIndex() ?: return noModifications
|
val size = decl.arraysize?.constIndex() ?: return null
|
||||||
if(rangeExpr==null && numericLv!=null) {
|
if(rangeExpr==null && numericLv!=null) {
|
||||||
// arraysize initializer is a single int, and we know the size.
|
// arraysize initializer is a single int, and we know the size.
|
||||||
val fillvalue = numericLv.number
|
val fillvalue = numericLv.number
|
||||||
@ -362,28 +376,22 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
|||||||
else {
|
else {
|
||||||
// create the array itself, filled with the fillvalue.
|
// create the array itself, filled with the fillvalue.
|
||||||
val array = Array(size) {fillvalue}.map { NumericLiteral(DataType.FLOAT, it, numericLv.position) }.toTypedArray<Expression>()
|
val array = Array(size) {fillvalue}.map { NumericLiteral(DataType.FLOAT, it, numericLv.position) }.toTypedArray<Expression>()
|
||||||
val refValue = ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_F), array, position = numericLv.position)
|
return ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_F), array, position = numericLv.position)
|
||||||
return listOf(IAstModification.ReplaceNode(decl.value!!, refValue, decl))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.ARRAY_BOOL -> {
|
DataType.ARRAY_BOOL -> {
|
||||||
val numericLv = decl.value as? NumericLiteral
|
val numericLv = decl.value as? NumericLiteral
|
||||||
val size = decl.arraysize?.constIndex() ?: return noModifications
|
val size = decl.arraysize?.constIndex() ?: return null
|
||||||
if(numericLv!=null) {
|
if(numericLv!=null) {
|
||||||
// arraysize initializer is a single int, and we know the size.
|
// arraysize initializer is a single int, and we know the size.
|
||||||
val fillvalue = if(numericLv.number==0.0) 0.0 else 1.0
|
val fillvalue = if(numericLv.number==0.0) 0.0 else 1.0
|
||||||
val array = Array(size) {fillvalue}.map { NumericLiteral(DataType.UBYTE, fillvalue, numericLv.position) }.toTypedArray<Expression>()
|
val array = Array(size) {fillvalue}.map { NumericLiteral(DataType.UBYTE, fillvalue, numericLv.position) }.toTypedArray<Expression>()
|
||||||
val refValue = ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_BOOL), array, position = numericLv.position)
|
return ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_BOOL), array, position = numericLv.position)
|
||||||
return listOf(IAstModification.ReplaceNode(decl.value!!, refValue, decl))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> return null
|
||||||
// nothing to do for this type
|
|
||||||
}
|
}
|
||||||
}
|
return null
|
||||||
}
|
|
||||||
|
|
||||||
return noModifications
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
|||||||
program.processAstBeforeAsmGeneration(compilationOptions, args.errors)
|
program.processAstBeforeAsmGeneration(compilationOptions, args.errors)
|
||||||
args.errors.report()
|
args.errors.report()
|
||||||
|
|
||||||
val intermediateAst = IntermediateAstMaker(program).transform()
|
val intermediateAst = IntermediateAstMaker(program, args.errors).transform()
|
||||||
// println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
|
// println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
|
||||||
// printProgram(program)
|
// printProgram(program)
|
||||||
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
|
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
|
||||||
|
@ -824,6 +824,8 @@ internal class AstChecker(private val program: Program,
|
|||||||
err("missing option directive argument(s)")
|
err("missing option directive argument(s)")
|
||||||
else if(directive.args.map{it.name in arrayOf("enable_floats", "force_output", "no_sysinit", "align_word", "align_page", "merge", "splitarrays", "no_symbol_prefixing")}.any { !it })
|
else if(directive.args.map{it.name in arrayOf("enable_floats", "force_output", "no_sysinit", "align_word", "align_page", "merge", "splitarrays", "no_symbol_prefixing")}.any { !it })
|
||||||
err("invalid option directive argument(s)")
|
err("invalid option directive argument(s)")
|
||||||
|
if(directive.args.any {it.name=="align_word"} && directive.args.any { it.name=="align_page"})
|
||||||
|
err("conflicting alignment options")
|
||||||
}
|
}
|
||||||
else -> throw SyntaxError("invalid directive ${directive.directive}", directive.position)
|
else -> throw SyntaxError("invalid directive ${directive.directive}", directive.position)
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import kotlin.io.path.isRegularFile
|
|||||||
/**
|
/**
|
||||||
* Convert 'old' compiler-AST into the 'new' simplified AST with baked types.
|
* Convert 'old' compiler-AST into the 'new' simplified AST with baked types.
|
||||||
*/
|
*/
|
||||||
class IntermediateAstMaker(private val program: Program) {
|
class IntermediateAstMaker(private val program: Program, private val errors: IErrorReporter) {
|
||||||
fun transform(): PtProgram {
|
fun transform(): PtProgram {
|
||||||
val ptProgram = PtProgram(
|
val ptProgram = PtProgram(
|
||||||
program.name,
|
program.name,
|
||||||
@ -398,13 +398,26 @@ class IntermediateAstMaker(private val program: Program) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun transform(srcVar: VarDecl): PtNode {
|
private fun transform(srcVar: VarDecl): PtNode {
|
||||||
return when(srcVar.type) {
|
when(srcVar.type) {
|
||||||
VarDeclType.VAR -> {
|
VarDeclType.VAR -> {
|
||||||
val value = if(srcVar.value!=null) transformExpression(srcVar.value!!) else null
|
val value = if(srcVar.value!=null) transformExpression(srcVar.value!!) else null
|
||||||
PtVariable(srcVar.name, srcVar.datatype, srcVar.zeropage, value, srcVar.arraysize?.constIndex()?.toUInt(), srcVar.position)
|
if(srcVar.datatype in ArrayDatatypes) {
|
||||||
|
if(value==null) {
|
||||||
|
val blockOptions = srcVar.definingBlock.options()
|
||||||
|
if("align_page" in blockOptions || "align_word" in blockOptions) {
|
||||||
|
errors.warn("converting uninitialized array to explicit zeros because of block alignment option", srcVar.position)
|
||||||
|
val zeros = PtArray(srcVar.datatype, srcVar.position)
|
||||||
|
repeat(srcVar.arraysize!!.constIndex()!!) {
|
||||||
|
zeros.children.add(PtNumber(ArrayToElementTypes.getValue(srcVar.datatype), 0.0, srcVar.position))
|
||||||
}
|
}
|
||||||
VarDeclType.CONST -> PtConstant(srcVar.name, srcVar.datatype, (srcVar.value as NumericLiteral).number, srcVar.position)
|
return PtVariable(srcVar.name, srcVar.datatype, srcVar.zeropage, zeros, srcVar.arraysize?.constIndex()?.toUInt(), srcVar.position)
|
||||||
VarDeclType.MEMORY -> PtMemMapped(srcVar.name, srcVar.datatype, (srcVar.value as NumericLiteral).number.toUInt(), srcVar.arraysize?.constIndex()?.toUInt(), srcVar.position)
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PtVariable(srcVar.name, srcVar.datatype, srcVar.zeropage, value, srcVar.arraysize?.constIndex()?.toUInt(), srcVar.position)
|
||||||
|
}
|
||||||
|
VarDeclType.CONST -> return PtConstant(srcVar.name, srcVar.datatype, (srcVar.value as NumericLiteral).number, srcVar.position)
|
||||||
|
VarDeclType.MEMORY -> return PtMemMapped(srcVar.name, srcVar.datatype, (srcVar.value as NumericLiteral).number.toUInt(), srcVar.arraysize?.constIndex()?.toUInt(), srcVar.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +83,27 @@ class TestSymbolTable: FunSpec({
|
|||||||
st.allMemorySlabs.single().scopedName shouldBe "block1.sub1.slab1"
|
st.allMemorySlabs.single().scopedName shouldBe "block1.sub1.slab1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("static vars") {
|
||||||
|
val node = PtIdentifier("dummy", DataType.UBYTE, Position.DUMMY)
|
||||||
|
val stVar1 = StStaticVariable("initialized", DataType.UBYTE, 99.0, null, null, null, ZeropageWish.DONTCARE, node)
|
||||||
|
val stVar2 = StStaticVariable("uninitialized", DataType.UBYTE, null, null, null, null, ZeropageWish.DONTCARE, node)
|
||||||
|
val arrayInitNonzero = listOf(StArrayElement(1.1, null), StArrayElement(2.2, null), StArrayElement(3.3, null))
|
||||||
|
val arrayInitAllzero = listOf(StArrayElement(0.0, null), StArrayElement(0.0, null), StArrayElement(0.0, null))
|
||||||
|
val stVar3 = StStaticVariable("initialized", DataType.ARRAY_UW, null, null, arrayInitNonzero, 3, ZeropageWish.DONTCARE, node)
|
||||||
|
val stVar4 = StStaticVariable("initialized", DataType.ARRAY_UW, null, null, arrayInitAllzero, 3, ZeropageWish.DONTCARE, node)
|
||||||
|
val stVar5 = StStaticVariable("uninitialized", DataType.ARRAY_UW, null, null, null, 3, ZeropageWish.DONTCARE, node)
|
||||||
|
|
||||||
|
stVar1.uninitialized shouldBe false
|
||||||
|
stVar1.length shouldBe null
|
||||||
|
stVar2.uninitialized shouldBe true
|
||||||
|
stVar2.length shouldBe null
|
||||||
|
stVar3.uninitialized shouldBe false
|
||||||
|
stVar3.length shouldBe 3
|
||||||
|
stVar4.uninitialized shouldBe false
|
||||||
|
stVar4.length shouldBe 3
|
||||||
|
stVar5.uninitialized shouldBe true
|
||||||
|
stVar5.length shouldBe 3
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import prog8.code.ast.*
|
|||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
import prog8.code.target.C64Target
|
import prog8.code.target.C64Target
|
||||||
import prog8.compiler.astprocessing.IntermediateAstMaker
|
import prog8.compiler.astprocessing.IntermediateAstMaker
|
||||||
|
import prog8tests.helpers.ErrorReporterForTests
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
|
|
||||||
class TestIntermediateAst: FunSpec({
|
class TestIntermediateAst: FunSpec({
|
||||||
@ -26,8 +27,9 @@ class TestIntermediateAst: FunSpec({
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
val target = C64Target()
|
val target = C64Target()
|
||||||
|
val errors = ErrorReporterForTests()
|
||||||
val result = compileText(target, false, text, writeAssembly = false)!!
|
val result = compileText(target, false, text, writeAssembly = false)!!
|
||||||
val ast = IntermediateAstMaker(result.compilerAst).transform()
|
val ast = IntermediateAstMaker(result.compilerAst, errors).transform()
|
||||||
ast.name shouldBe result.compilerAst.name
|
ast.name shouldBe result.compilerAst.name
|
||||||
ast.allBlocks().any() shouldBe true
|
ast.allBlocks().any() shouldBe true
|
||||||
val entry = ast.entrypoint() ?: fail("no main.start() found")
|
val entry = ast.entrypoint() ?: fail("no main.start() found")
|
||||||
|
@ -75,7 +75,7 @@ class TestAsmGenSymbols: StringSpec({
|
|||||||
fun createTestAsmGen6502(program: Program): AsmGen6502Internal {
|
fun createTestAsmGen6502(program: Program): AsmGen6502Internal {
|
||||||
val errors = ErrorReporterForTests()
|
val errors = ErrorReporterForTests()
|
||||||
val options = CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target(), 999u)
|
val options = CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target(), 999u)
|
||||||
val ptProgram = IntermediateAstMaker(program).transform()
|
val ptProgram = IntermediateAstMaker(program, errors).transform()
|
||||||
val st = SymbolTableMaker(ptProgram, options).make()
|
val st = SymbolTableMaker(ptProgram, options).make()
|
||||||
return AsmGen6502Internal(ptProgram, st, options, errors)
|
return AsmGen6502Internal(ptProgram, st, options, errors)
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,8 @@ Compiler:
|
|||||||
- OR.... make all this more generic and use some %segment option to create real segments for 64tass?
|
- OR.... make all this more generic and use some %segment option to create real segments for 64tass?
|
||||||
- (need separate step in codegen and IR to write the "golden" variables)
|
- (need separate step in codegen and IR to write the "golden" variables)
|
||||||
|
|
||||||
|
- need variable alignment tag instead of block alignment tag, you want to align the data not the code in the block perse
|
||||||
|
- ir: block alignment doesn't translate well to variables in the block (the actual stuff that needs to be aligned in memory) but: need variable alignment tag instead of block alignment tag, really
|
||||||
- ir: idea: (but LLVM IR simply keeps the variables, so not a good idea then?...): replace all scalar variables by an allocated register. Keep a table of the variable to register mapping (including the datatype)
|
- ir: idea: (but LLVM IR simply keeps the variables, so not a good idea then?...): replace all scalar variables by an allocated register. Keep a table of the variable to register mapping (including the datatype)
|
||||||
global initialization values are simply a list of LOAD instructions.
|
global initialization values are simply a list of LOAD instructions.
|
||||||
Variables replaced include all subroutine parameters! So the only variables that remain as variables are arrays and strings.
|
Variables replaced include all subroutine parameters! So the only variables that remain as variables are arrays and strings.
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import gfx2
|
|
||||||
%import verafx
|
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
gfx2.screen_mode(4)
|
alignblock.flags[0] = 222
|
||||||
gfx2.disc(160, 120, 100, 2)
|
cx16.r0++
|
||||||
; verafx.transparency(true)
|
cx16.r1++
|
||||||
gfx2.position(0, 70)
|
txt.print_uwhex(alignblock.flags, true)
|
||||||
repeat 3000 {
|
txt.spc()
|
||||||
gfx2.next_pixel(7)
|
txt.print_ub(alignblock.flags[0])
|
||||||
repeat 10
|
txt.nl()
|
||||||
gfx2.next_pixel(0) ; transparent!
|
|
||||||
}
|
|
||||||
verafx.transparency(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alignblock {
|
||||||
|
%option align_page
|
||||||
|
ubyte[10] flags
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user