more asm symbol prefixing: variables with p8v_, subroutines with p8s_ etc

labels with p8l_ . All this to avoid symbol clashes in the generated assembly code.
Everything got its own distinguishing prefix so we're done with it once and for all and have only 1 breaking change moment.
This commit is contained in:
Irmen de Jong 2023-12-20 22:20:12 +01:00
parent 299419917e
commit 6bc079c7b7
16 changed files with 86 additions and 59 deletions

View File

@ -66,7 +66,7 @@ class PtProgram(
fun entrypoint(): PtSub? =
allBlocks().firstOrNull { it.name == "main" || it.name=="p8b_main" }
?.children
?.firstOrNull { it is PtSub && (it.name == "start" || it.name=="main.start" || it.name=="p8_start" || it.name=="p8b_main.p8_start") } as PtSub?
?.firstOrNull { it is PtSub && (it.name == "start" || it.name=="main.start" || it.name=="p8s_start" || it.name=="p8b_main.p8s_start") } as PtSub?
}

View File

@ -34,9 +34,10 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend {
fun prefixNamedNode(node: PtNamedNode) {
when(node) {
is PtAsmSub, is PtSub -> node.name = "p8s_${node.name}"
is PtBlock -> node.name = "p8b_${node.name}"
else -> node.name = "p8_${node.name}"
// TODO: more special prefixes for the other node types?
is PtLabel -> node.name = "p8l_${node.name}"
is PtVariable, is PtConstant, is PtMemMapped, is PtSubroutineParameter -> node.name = "p8v_${node.name}"
}
}
@ -120,16 +121,20 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend {
}
}
private fun prefixScopedName(name: String): String {
if('.' !in name) return "p8_$name"
// fully scoped, first part is block
private fun prefixScopedName(name: String, type: Char): String {
if('.' !in name)
return "p8${type}_$name"
val parts = name.split('.')
val prefixed = listOf("p8b_${parts[0]}") + parts.drop(1).map{"p8_$it"}
val firstPrefixed = "p8b_${parts[0]}"
val lastPrefixed = "p8${type}_${parts.last()}"
// the parts in between are assumed to be subroutine scopes.
val inbetweenPrefixed = parts.drop(1).dropLast(1).map{ "p8s_$it" }
val prefixed = listOf(firstPrefixed) + inbetweenPrefixed + listOf(lastPrefixed)
return prefixed.joinToString(".")
}
private fun PtVariable.prefix(st: SymbolTable): PtVariable {
name = prefixScopedName(name)
name = prefixScopedName(name, 'v')
if(value==null)
return this
@ -166,7 +171,7 @@ private fun PtJump.prefix(parent: PtNode, st: SymbolTable): PtJump {
}
private fun PtFunctionCall.prefix(parent: PtNode): PtFunctionCall {
val newName = prefixScopedName(name)
val newName = prefixScopedName(name, 's')
val call = PtFunctionCall(newName, void, type, position)
call.children.addAll(children)
call.children.forEach { it.parent = call }
@ -175,11 +180,28 @@ private fun PtFunctionCall.prefix(parent: PtNode): PtFunctionCall {
}
private fun PtIdentifier.prefix(parent: PtNode, st: SymbolTable): PtIdentifier {
val target = st.lookup(name)
var target = st.lookup(name)
if(target?.astNode?.definingBlock()?.noSymbolPrefixing==true)
return this
val newName = prefixScopedName(name)
if(target==null) {
if(name.endsWith("_lsb") || name.endsWith("_msb")) {
target = st.lookup(name.dropLast(4))
if(target?.astNode?.definingBlock()?.noSymbolPrefixing==true)
return this
}
}
val prefixType = when(target!!.type) {
StNodeType.BLOCK -> 'b'
StNodeType.SUBROUTINE, StNodeType.ROMSUB -> 's'
StNodeType.LABEL -> 'l'
StNodeType.STATICVAR, StNodeType.MEMVAR, StNodeType.CONSTANT -> 'v'
StNodeType.BUILTINFUNC -> 's'
StNodeType.MEMORYSLAB -> 'v'
else -> '?'
}
val newName = prefixScopedName(name, prefixType)
val node = PtIdentifier(newName, type, position)
node.parent = parent
return node
@ -3111,7 +3133,7 @@ $repeatLabel""")
internal fun makeLabel(postfix: String): String {
generatedLabelSequenceNumber++
return "prog8_label_asm_${generatedLabelSequenceNumber}_$postfix"
return "label_asm_${generatedLabelSequenceNumber}_$postfix"
}
fun assignConstFloatToPointerAY(number: PtNumber) {

View File

@ -138,24 +138,24 @@ internal class ProgramAndVarsGen(
"cx16" -> {
if(options.floats)
asmgen.out(" lda #4 | sta $01") // to use floats, make sure Basic rom is banked in
asmgen.out(" jsr p8b_main.p8_start")
asmgen.out(" jsr p8b_main.p8s_start")
asmgen.out(" jmp sys.cleanup_at_exit")
}
"c64" -> {
asmgen.out(" jsr p8b_main.p8_start | lda #31 | sta $01")
asmgen.out(" jsr p8b_main.p8s_start | lda #31 | sta $01")
if(!options.noSysInit)
asmgen.out(" jmp sys.cleanup_at_exit")
else
asmgen.out(" rts")
}
"c128" -> {
asmgen.out(" jsr p8b_main.p8_start | lda #0 | sta ${"$"}ff00")
asmgen.out(" jsr p8b_main.p8s_start | lda #0 | sta ${"$"}ff00")
if(!options.noSysInit)
asmgen.out(" jmp sys.cleanup_at_exit")
else
asmgen.out(" rts")
}
else -> asmgen.jmp("p8b_main.p8_start")
else -> asmgen.jmp("p8b_main.p8s_start")
}
}
@ -331,7 +331,7 @@ internal class ProgramAndVarsGen(
asmsubs2asm(sub.children)
// the main.start subroutine is the program's entrypoint and should perform some initialization logic
if((sub.name=="start" || sub.name=="p8_start") && (sub.definingBlock()!!.name=="main" || sub.definingBlock()!!.name=="p8b_main"))
if((sub.name=="start" || sub.name=="p8s_start") && (sub.definingBlock()!!.name=="main" || sub.definingBlock()!!.name=="p8b_main"))
entrypointInitialization()
if(functioncallAsmGen.optimizeIntArgsViaRegisters(sub)) {

View File

@ -1733,7 +1733,7 @@ class IRCodeGen(
private var labelSequenceNumber = 0
internal fun createLabelName(): String {
labelSequenceNumber++
return "prog8_label_gen_$labelSequenceNumber"
return "label_gen_$labelSequenceNumber"
}
internal fun translateBuiltinFunc(call: PtBuiltinFunctionCall): ExpressionCodeResult

View File

@ -843,7 +843,7 @@ main {
main {
sub start() {
%asm{{
jsr p8_test
jsr p8s_test
}}
}

View File

@ -122,11 +122,11 @@ main {
sub start() {
%asm {{
lda p8_normal
lda p8_uw_lsb
lda p8_uw_msb
lda p8_sw_lsb
lda p8_sw_msb
lda p8v_normal
lda p8v_uw_lsb
lda p8v_uw_msb
lda p8v_sw_lsb
lda p8v_sw_msb
}}
}
}"""

View File

@ -17,9 +17,9 @@ class TestVariables: FunSpec({
ubyte @shared bytevar = 0
%asm {{
lda p8_arrayvar
lda p8_stringvar
lda p8_bytevar
lda p8v_arrayvar
lda p8v_stringvar
lda p8v_bytevar
}}
}
}

View File

@ -85,10 +85,10 @@ main {
result.codegenAst!!.name shouldBe result.compilerAst.name
result.codegenAst!!.children.size shouldBeGreaterThan 2
val start = result.codegenAst!!.entrypoint()!!
start.name shouldBe "p8_start"
start.name shouldBe "p8s_start"
start.children.size shouldBeGreaterThan 2
val seed = start.children[0] as PtVariable
seed.name shouldBe "p8_seed"
seed.name shouldBe "p8v_seed"
seed.value shouldBe null
seed.type shouldBe DataType.ARRAY_UW
val assign = start.children[1] as PtAssignment

View File

@ -148,7 +148,7 @@ class Program(val name: String,
fun makeLabel(postfix: String): String {
generatedLabelSequenceNumber++
return "prog8_label_${generatedLabelSequenceNumber}_$postfix"
return "label_${generatedLabelSequenceNumber}_$postfix"
}
fun makeLabel(postfix: String, position: Position): Label {

View File

@ -163,7 +163,12 @@ class CallGraph(private val program: Program) : IAstVisitor {
return allIdentifiersAndTargets.filter { decl===it.value }.map{ it.key }
}
private fun nameInAssemblyCode(name: String) = allAssemblyNodes.any { "p8_$name" in it.names || "p8b_$name" in it.names || name in it.names }
private val prefixes = listOf("p8_", "p8b_", "p8v_", "p8s_", "p8l_", "")
private fun nameInAssemblyCode(name: String): Boolean {
return allAssemblyNodes.any {
prefixes.any { prefix -> prefix+name in it.names }
}
}
inline fun unused(label: Label) = false // just always output labels

View File

@ -94,11 +94,11 @@ main {
; @(screen+x) = xbuf[x] + yvalue
; max optimized asm is this: (achieving ~21 fps on the C64):
%asm {{
lda p8_yvalue
ldy p8_x
lda p8v_yvalue
ldy p8v_x
clc
adc p8_xbuf,y
sta (p8_screen),y
adc p8v_xbuf,y
sta (p8v_screen),y
}}
}
screen += 40

View File

@ -41,12 +41,12 @@ mcf {
%asm {{
lda cx16.r0
ldy cx16.r0+1
sta p8b_mcf.p8_stream.getbuffer_call+1
sty p8b_mcf.p8_stream.getbuffer_call+2
sta p8b_mcf.p8s_stream.getbuffer_call+1
sty p8b_mcf.p8s_stream.getbuffer_call+2
lda cx16.r1
ldy cx16.r1+1
sta p8b_mcf.p8_stream.processchunk_call+1
sty p8b_mcf.p8_stream.processchunk_call+2
sta p8b_mcf.p8s_stream.processchunk_call+1
sty p8b_mcf.p8s_stream.processchunk_call+2
rts
}}
}
@ -113,9 +113,9 @@ mcf {
; custom chunk
uword @shared chunksize = peekw(loadlist_ptr+1)
%asm {{
lda (p8b_mcf.p8_loadlist_ptr)
ldx p8_chunksize
ldy p8_chunksize+1
lda (p8b_mcf.p8v_loadlist_ptr)
ldx p8v_chunksize
ldy p8v_chunksize+1
getbuffer_call jsr $ffff ; modified
bcc +
rts ; fail - exit as if EOF

View File

@ -89,14 +89,14 @@ irq {
asmsub set_scanline_color(ubyte color_ix @Y) {
; uword color = mkword(reds[ix], (greens[ix] << 4) | blues[ix] )
%asm {{
lda p8_blinds_lines_reds,y
lda p8v_blinds_lines_reds,y
pha
lda p8_blinds_lines_greens,y
lda p8v_blinds_lines_greens,y
asl a
asl a
asl a
asl a
ora p8_blinds_lines_blues,y
ora p8v_blinds_lines_blues,y
tay
stz cx16.VERA_CTRL

View File

@ -268,13 +268,13 @@ stereo {
%asm {{
; copy to vera PSG fifo buffer
ldy #0
- lda p8_left,y
- lda p8v_left,y
sta cx16.VERA_AUDIO_DATA
lda p8_left+1,y
lda p8v_left+1,y
sta cx16.VERA_AUDIO_DATA
lda p8_right,y
lda p8v_right,y
sta cx16.VERA_AUDIO_DATA
lda p8_right+1,y
lda p8v_right+1,y
sta cx16.VERA_AUDIO_DATA
iny
iny

View File

@ -235,9 +235,9 @@ music {
; optimized loop to put 1024 bytes of data into the fifo as fast as possible
; converting unsigned wav 8 bit samples to signed 8 bit on the fly
%asm {{
lda p8_buffer
lda p8v_buffer
sta cx16.r0L
lda p8_buffer+1
lda p8v_buffer+1
sta cx16.r0H
ldx #4
- ldy #0
@ -265,9 +265,9 @@ music {
asmsub uncompressed_block_16() {
; optimized loop to put 1024 bytes of data into the fifo as fast as possible
%asm {{
lda p8_buffer
lda p8v_buffer
sta cx16.r0L
lda p8_buffer+1
lda p8v_buffer+1
sta cx16.r0H
ldx #4
- ldy #0
@ -373,13 +373,13 @@ music {
%asm {{
; copy to vera PSG fifo buffer
ldy #0
- lda p8_left,y
- lda p8v_left,y
sta cx16.VERA_AUDIO_DATA
lda p8_left+1,y
lda p8v_left+1,y
sta cx16.VERA_AUDIO_DATA
lda p8_right,y
lda p8v_right,y
sta cx16.VERA_AUDIO_DATA
lda p8_right+1,y
lda p8v_right+1,y
sta cx16.VERA_AUDIO_DATA
iny
iny

View File

@ -990,9 +990,9 @@ planet {
sbc #$81
asl a
tay
lda p8_wordlists,y
lda p8v_wordlists,y
sta P8ZP_SCRATCH_W1
lda p8_wordlists+1,y
lda p8v_wordlists+1,y
sta P8ZP_SCRATCH_W1+1
lda P8ZP_SCRATCH_REG
asl a