remove self-modifying code from @(ptr)++ and @(ptr)--

romable errors for string and array variables turned into read-only warnings

remove self-modifying code from @(ptr)++ and @(ptr)--
This commit is contained in:
Irmen de Jong 2025-03-21 23:31:45 +01:00
parent 376f1cb139
commit a332e0e3d1
5 changed files with 47 additions and 24 deletions

View File

@ -1741,11 +1741,12 @@ $repeatLabel""")
return null
}
fun romableWarning(problem: String, pos: Position) {
fun romableWarning(problem: String, pos: Position, assemblerShouldFail: Boolean = true) {
if(options.romable) {
// until the code generation can provide an alternative, we have to report about code generated that is incompatible with ROMable code mode...
errors.warn("problem for ROMable code: $problem", pos)
out(" .error \"ROMable code selected but incompatible code was generated: $problem\"")
if(assemblerShouldFail)
out(" .error \"ROMable code selected but incompatible code was generated: $problem\"")
}
}
}

View File

@ -58,6 +58,10 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
if(bank==null) {
val varbank = if(sub.address?.varbank==null) null else asmgen.asmVariableName(sub.address!!.varbank!!)
if(varbank!=null) {
if(asmgen.options.romable)
TODO("no codegen yet for non-const bank in subroutine call that's usable in ROM ${call.position}")
// self-modifying code: set jsrfar bank argument
when(asmgen.options.compTarget.name) {
"cx16" -> {
// JSRFAR can jump to a banked RAM address as well!
@ -72,7 +76,6 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
.word $subAsmName ; ${sub.address!!.address.toHex()}
+ .byte 0 ; modified"""
)
asmgen.romableWarning("self-modifying code for cx16 banked jsr", call.position) // TODO
}
"c64" -> {
asmgen.out("""
@ -86,7 +89,6 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
.word $subAsmName ; ${sub.address!!.address.toHex()}
+ .byte 0 ; modified"""
)
asmgen.romableWarning("self-modifying code for c64 banked jsr", call.position) // TODO
}
"c128" -> {
asmgen.out("""
@ -100,7 +102,6 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
.word $subAsmName ; ${sub.address!!.address.toHex()}
+ .byte 0 ; modified"""
)
asmgen.romableWarning("self-modifying code for c128 banked jsr", call.position) // TODO
}
else -> throw AssemblyError("callfar is not supported on the selected compilation target")
}

View File

@ -652,7 +652,7 @@ internal class ProgramAndVarsGen(
it.initializationStringValue!!.second,
it.initializationStringValue!!.first
)
asmgen.romableWarning("inlined variable (${it.dt}, ${it.name})", Position.DUMMY) // TODO what to do with strings in romable? should they simply be treated as read-only?
asmgen.romableWarning("string (${it.dt} ${it.name}) can only be used as read-only in ROMable code", Position.DUMMY, false) // TODO print warning with position of the var
}
alignedStrings.sortedBy { it.align }.forEach {
outputStringvar(
@ -661,16 +661,22 @@ internal class ProgramAndVarsGen(
it.initializationStringValue!!.second,
it.initializationStringValue!!.first
)
asmgen.romableWarning("inlined variable (${it.dt}, ${it.name})", Position.DUMMY) // TODO what to do with strings in romable? should they simply be treated as read-only?
asmgen.romableWarning("string (${it.dt} ${it.name}) can only be used as read-only in ROMable code", Position.DUMMY, false) // TODO print warning with position of the var
}
notAlignedOther.sortedBy { it.type }.forEach {
staticVariable2asm(it)
asmgen.romableWarning("inlined variable (${it.dt}, ${it.name})", Position.DUMMY) // TODO
if(it.dt.isArray)
asmgen.romableWarning("array (${it.dt} ${it.name}) can only be used as read-only in ROMable code", Position.DUMMY, false) // TODO print warning with position of the var
else
asmgen.romableWarning("inlined variable (${it.dt} ${it.name})", Position.DUMMY) // TODO print warning with position of the var
}
alignedOther.sortedBy { it.align }.sortedBy { it.type }.forEach {
staticVariable2asm(it)
asmgen.romableWarning("inlined variable (${it.dt}, ${it.name})", Position.DUMMY) // TODO
if(it.dt.isArray)
asmgen.romableWarning("array (${it.dt} ${it.name}) can only be used as read-only in ROMable code", Position.DUMMY, false) // TODO print warning with position of the var
else
asmgen.romableWarning("inlined variable (${it.dt} ${it.name})", Position.DUMMY) // TODO print warning with position of the var
}
}
}

View File

@ -962,10 +962,18 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
when (operator) {
"+" -> {
if(value==1) {
asmgen.assignExpressionToRegister(pointervar, RegisterOrPair.AY)
asmgen.out(" sta (+) + 1 | sty (+) + 2")
asmgen.out("+\tinc ${'$'}ffff\t; modified")
asmgen.romableWarning("self-modifying code (access pointer)", pointervar.position) // TODO
if(asmgen.options.romable) {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
if(asmgen.isTargetCpu(CpuType.CPU65C02))
asmgen.out(" inc a")
else
asmgen.out(" clc | adc #1")
asmgen.storeAIntoZpPointerVar(sourceName, false)
} else {
asmgen.assignExpressionToRegister(pointervar, RegisterOrPair.AY)
asmgen.out(" sta (+) + 1 | sty (+) + 2")
asmgen.out("+\tinc ${'$'}ffff\t; modified")
}
} else {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" clc | adc #$value")
@ -974,10 +982,18 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
"-" -> {
if(value==1) {
asmgen.assignExpressionToRegister(pointervar, RegisterOrPair.AY)
asmgen.out(" sta (+) + 1 | sty (+) + 2")
asmgen.out("+\tdec ${'$'}ffff\t; modified")
asmgen.romableWarning("self-modifying code (access pointer)", pointervar.position) // TODO
if(asmgen.options.romable) {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
if(asmgen.isTargetCpu(CpuType.CPU65C02))
asmgen.out(" dec a")
else
asmgen.out(" sec | sbc #1")
asmgen.storeAIntoZpPointerVar(sourceName, false)
} else {
asmgen.assignExpressionToRegister(pointervar, RegisterOrPair.AY)
asmgen.out(" sta (+) + 1 | sty (+) + 2")
asmgen.out("+\tdec ${'$'}ffff\t; modified")
}
} else {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" sec | sbc #$value")

View File

@ -5,18 +5,17 @@
main {
sub start() {
ubyte[] @shared array = [1,2,3,4,5,6,7]
uword @shared @nozp ptr = $4000
@(ptr) = %11110001
txt.print_ubbin(@(ptr), true)
txt.print_ub(@(ptr))
txt.nl()
sys.set_carry()
rol(@(ptr))
txt.print_ubbin(@(ptr), true)
@(ptr)++
txt.print_ub(@(ptr))
txt.nl()
sys.clear_carry()
ror(@(ptr))
txt.print_ubbin(@(ptr), true)
@(ptr)--
txt.print_ub(@(ptr))
txt.nl()
; cx16.r0L = @(ptr)