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() {
asmgen.out("; memory slabs")
asmgen.out("; memory slabs\n .section slabs_BSS")
asmgen.out("prog8_slabs\t.block")
for(slab in symboltable.allMemorySlabs) {
if(slab.align>1u)
asmgen.out("\t.align ${slab.align.toHex()}")
asmgen.out("${slab.name}\t.fill ${slab.size}")
}
asmgen.out("\t.bend")
asmgen.out("\t.bend\n .send slabs_BSS")
}
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()")
}
@ -468,20 +468,52 @@ internal class ProgramAndVarsGen(
}
}
private fun nonZpVariables2asm(variables: List<StStaticVariable>) {
private fun nonZpVariables2asm(variables2: List<StStaticVariable>) {
asmgen.out("")
asmgen.out("; non-zeropage variables")
val (stringvars, othervars) = variables.sortedBy { it.name }.partition { it.dt==DataType.STR }
stringvars.forEach {
outputStringvar(it.name, it.onetimeInitializationStringValue!!.second, it.onetimeInitializationStringValue!!.first)
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")
}
othervars.sortedBy { it.type }.forEach {
staticVariable2asm(it)
if(varsWithInit.isNotEmpty()) {
asmgen.out("; non-zeropage variables")
val (stringvars, othervars) = varsWithInit.sortedBy { it.name }.partition { it.dt == DataType.STR }
stringvars.forEach {
outputStringvar(
it.name,
it.onetimeInitializationStringValue!!.second,
it.onetimeInitializationStringValue!!.first
)
}
othervars.sortedBy { it.type }.forEach {
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) {
val name = variable.name
val initialValue: Number =
if(variable.onetimeInitializationNumericValue!=null) {
if(variable.dt== DataType.FLOAT)
@ -491,22 +523,22 @@ internal class ProgramAndVarsGen(
} else 0
when (variable.dt) {
DataType.UBYTE -> asmgen.out("$name\t.byte ${initialValue.toHex()}")
DataType.BYTE -> asmgen.out("$name\t.char $initialValue")
DataType.UWORD -> asmgen.out("$name\t.word ${initialValue.toHex()}")
DataType.WORD -> asmgen.out("$name\t.sint $initialValue")
DataType.UBYTE -> asmgen.out("${variable.name}\t.byte ${initialValue.toHex()}")
DataType.BYTE -> asmgen.out("${variable.name}\t.char $initialValue")
DataType.UWORD -> asmgen.out("${variable.name}\t.word ${initialValue.toHex()}")
DataType.WORD -> asmgen.out("${variable.name}\t.sint $initialValue")
DataType.FLOAT -> {
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 {
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 -> {
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 -> {
throw AssemblyError("weird dt")
}

View File

@ -3,16 +3,10 @@ TODO
For next minor release
^^^^^^^^^^^^^^^^^^^^^^
- BSS.
64tass can put variables into a section with .section BSS <variable> .send BSS
and then putting .dsection BSS where it should output the BSS
Define vars in BSS with .fill rather than .byte otherwise they STILL take up space!
- 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!
- cleanup handling of noreinit
- BSS: initialize BSS block (without slabs!) to zeros on start, using 1 loop instead of all those initialization assignments
- BSS subroutine parameters don't have to be set to 0. But meh, the loop should be super fast anyway.
- allow putting BSS in specific upper memory block ($a000-$bfff, $c000-$cfff on C64) 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]
float[3] floatarray
uword[3] wordarray
uword slab1 = memory("slab1",400, 0)
uword slab2 = memory("slab2",200, $1000)
txt.print("**subroutine scope**\n")
txt.print("uninit wordvar=")
@ -103,5 +105,9 @@ main {
txt.print_ub(b_filledarray[2])
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()
}
}