introduce bss segments

This commit is contained in:
Irmen de Jong 2023-02-19 18:12:37 +01:00
parent dddf9a9396
commit adc15c24ef
3 changed files with 60 additions and 28 deletions

View File

@ -162,18 +162,18 @@ internal class ProgramAndVarsGen(
} }
private fun memorySlabs() { private fun memorySlabs() {
asmgen.out("; memory slabs") asmgen.out("; memory slabs\n .section slabs_BSS")
asmgen.out("prog8_slabs\t.block") asmgen.out("prog8_slabs\t.block")
for(slab in symboltable.allMemorySlabs) { for(slab in symboltable.allMemorySlabs) {
if(slab.align>1u) if(slab.align>1u)
asmgen.out("\t.align ${slab.align.toHex()}") asmgen.out("\t.align ${slab.align.toHex()}")
asmgen.out("${slab.name}\t.fill ${slab.size}") asmgen.out("${slab.name}\t.fill ${slab.size}")
} }
asmgen.out("\t.bend") asmgen.out("\t.bend\n .send slabs_BSS")
} }
private fun footer() { private fun footer() {
// program end asmgen.out("; bss sections\n .dsection BSS\n .dsection slabs_BSS")
asmgen.out("prog8_program_end\t; end of program label for progend()") asmgen.out("prog8_program_end\t; end of program label for progend()")
} }
@ -468,20 +468,52 @@ internal class ProgramAndVarsGen(
} }
} }
private fun nonZpVariables2asm(variables: List<StStaticVariable>) { private fun nonZpVariables2asm(variables2: List<StStaticVariable>) {
asmgen.out("") asmgen.out("")
val (varsNoInit, varsWithInit) = variables2.partition { it.uninitialized }
if(varsNoInit.isNotEmpty()) {
asmgen.out("; non-zeropage variables without initialization value")
asmgen.out(" .section BSS")
varsNoInit.sortedWith(compareBy<StStaticVariable> { it.name }.thenBy { it.dt }).forEach {
uninitializedVariable2asm(it)
}
asmgen.out(" .send BSS")
}
if(varsWithInit.isNotEmpty()) {
asmgen.out("; non-zeropage variables") asmgen.out("; non-zeropage variables")
val (stringvars, othervars) = variables.sortedBy { it.name }.partition { it.dt==DataType.STR } val (stringvars, othervars) = varsWithInit.sortedBy { it.name }.partition { it.dt == DataType.STR }
stringvars.forEach { stringvars.forEach {
outputStringvar(it.name, it.onetimeInitializationStringValue!!.second, it.onetimeInitializationStringValue!!.first) outputStringvar(
it.name,
it.onetimeInitializationStringValue!!.second,
it.onetimeInitializationStringValue!!.first
)
} }
othervars.sortedBy { it.type }.forEach { othervars.sortedBy { it.type }.forEach {
staticVariable2asm(it) staticVariable2asm(it)
} }
} }
}
private fun uninitializedVariable2asm(variable: StStaticVariable) {
when (variable.dt) {
DataType.UBYTE -> asmgen.out("${variable.name}\t.byte ?")
DataType.BYTE -> asmgen.out("${variable.name}\t.char ?")
DataType.UWORD -> asmgen.out("${variable.name}\t.word ?")
DataType.WORD -> asmgen.out("${variable.name}\t.sint ?")
DataType.FLOAT -> asmgen.out("${variable.name}\t.fill ${compTarget.machine.FLOAT_MEM_SIZE}")
in ArrayDatatypes -> {
val numbytes = compTarget.memorySize(variable.dt, variable.length!!)
asmgen.out("${variable.name}\t.fill $numbytes")
}
else -> {
throw AssemblyError("weird dt")
}
}
}
private fun staticVariable2asm(variable: StStaticVariable) { private fun staticVariable2asm(variable: StStaticVariable) {
val name = variable.name
val initialValue: Number = val initialValue: Number =
if(variable.onetimeInitializationNumericValue!=null) { if(variable.onetimeInitializationNumericValue!=null) {
if(variable.dt== DataType.FLOAT) if(variable.dt== DataType.FLOAT)
@ -491,22 +523,22 @@ internal class ProgramAndVarsGen(
} else 0 } else 0
when (variable.dt) { when (variable.dt) {
DataType.UBYTE -> asmgen.out("$name\t.byte ${initialValue.toHex()}") DataType.UBYTE -> asmgen.out("${variable.name}\t.byte ${initialValue.toHex()}")
DataType.BYTE -> asmgen.out("$name\t.char $initialValue") DataType.BYTE -> asmgen.out("${variable.name}\t.char $initialValue")
DataType.UWORD -> asmgen.out("$name\t.word ${initialValue.toHex()}") DataType.UWORD -> asmgen.out("${variable.name}\t.word ${initialValue.toHex()}")
DataType.WORD -> asmgen.out("$name\t.sint $initialValue") DataType.WORD -> asmgen.out("${variable.name}\t.sint $initialValue")
DataType.FLOAT -> { DataType.FLOAT -> {
if(initialValue==0) { if(initialValue==0) {
asmgen.out("$name\t.byte 0,0,0,0,0 ; float") asmgen.out("${variable.name}\t.byte 0,0,0,0,0 ; float")
} else { } else {
val floatFill = compTarget.machine.getFloatAsmBytes(initialValue) val floatFill = compTarget.machine.getFloatAsmBytes(initialValue)
asmgen.out("$name\t.byte $floatFill ; float $initialValue") asmgen.out("${variable.name}\t.byte $floatFill ; float $initialValue")
} }
} }
DataType.STR -> { DataType.STR -> {
throw AssemblyError("all string vars should have been interned into prog") throw AssemblyError("all string vars should have been interned into prog")
} }
in ArrayDatatypes -> arrayVariable2asm(name, variable.dt, variable.onetimeInitializationArrayValue, variable.length) in ArrayDatatypes -> arrayVariable2asm(variable.name, variable.dt, variable.onetimeInitializationArrayValue, variable.length)
else -> { else -> {
throw AssemblyError("weird dt") throw AssemblyError("weird dt")
} }

View File

@ -3,16 +3,10 @@ TODO
For next minor release For next minor release
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
- BSS. - cleanup handling of noreinit
64tass can put variables into a section with .section BSS <variable> .send BSS - BSS: initialize BSS block (without slabs!) to zeros on start, using 1 loop instead of all those initialization assignments
and then putting .dsection BSS where it should output the BSS - BSS subroutine parameters don't have to be set to 0. But meh, the loop should be super fast anyway.
Define vars in BSS with .fill rather than .byte otherwise they STILL take up space! - allow putting BSS in specific upper memory block ($a000-$bfff, $c000-$cfff on C64) add a .cerror check for overflow!
- BSS in 6502 codegen: create BSS section in output assembly code and put StStaticVariables in there with uninitialized=true.
Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE if possible.
Note that 'uninitialized' can still be true for variables that were moved into zeropage, so have to check that!
- BSS subroutine parameters don't have to be set to 0.
- when putting BSS in specific memory block ($a000-$bfff, $c000-$cfff) add a .cerror check for overflow!
... ...

View File

@ -21,6 +21,8 @@ main {
ubyte[10] filledarray = [1,2,3,4,5,6,7,8,9,10] ubyte[10] filledarray = [1,2,3,4,5,6,7,8,9,10]
float[3] floatarray float[3] floatarray
uword[3] wordarray uword[3] wordarray
uword slab1 = memory("slab1",400, 0)
uword slab2 = memory("slab2",200, $1000)
txt.print("**subroutine scope**\n") txt.print("**subroutine scope**\n")
txt.print("uninit wordvar=") txt.print("uninit wordvar=")
@ -103,5 +105,9 @@ main {
txt.print_ub(b_filledarray[2]) txt.print_ub(b_filledarray[2])
txt.print("\n\nrun again to see effect of re-init.\n") txt.print("\n\nrun again to see effect of re-init.\n")
txt.print_uwhex(slab1, true)
txt.nl()
txt.print_uwhex(slab2, true)
txt.nl()
} }
} }