diff --git a/compiler/res/prog8lib/prog8lib.asm b/compiler/res/prog8lib/prog8lib.asm index bc5dc48ee..dbd2d98aa 100644 --- a/compiler/res/prog8lib/prog8lib.asm +++ b/compiler/res/prog8lib/prog8lib.asm @@ -686,7 +686,7 @@ func_sqrt16 .proc sta P8ZP_SCRATCH_W2 lda P8ESTACK_HI+1,x sta P8ZP_SCRATCH_W2+1 - stx P8ZP_SCRATCH_REG_X + stx P8ZP_SCRATCH_REG ldy #$00 ; r = 0 ldx #$07 clc ; clear bit 16 of m @@ -721,7 +721,7 @@ _skip1 _skip2 iny ; r = r or d (d is 1 here) _skip3 - ldx P8ZP_SCRATCH_REG_X + ldx P8ZP_SCRATCH_REG tya sta P8ESTACK_LO+1,x lda #0 @@ -1216,7 +1216,7 @@ func_rndw .proc func_memcopy .proc ; note: clobbers A,Y inx - stx P8ZP_SCRATCH_REG_X + stx P8ZP_SCRATCH_REG lda P8ESTACK_LO+2,x sta P8ZP_SCRATCH_W1 lda P8ESTACK_HI+2,x @@ -1233,7 +1233,7 @@ func_memcopy .proc iny dex bne - - ldx P8ZP_SCRATCH_REG_X + ldx P8ZP_SCRATCH_REG inx inx rts @@ -1242,7 +1242,7 @@ func_memcopy .proc func_memset .proc ; note: clobbers A,Y inx - stx P8ZP_SCRATCH_REG_X + stx P8ZP_SCRATCH_REG lda P8ESTACK_LO+2,x sta P8ZP_SCRATCH_W1 lda P8ESTACK_HI+2,x @@ -1253,7 +1253,7 @@ func_memset .proc lda P8ESTACK_LO,x ldx P8ZP_SCRATCH_B1 jsr memset - ldx P8ZP_SCRATCH_REG_X + ldx P8ZP_SCRATCH_REG inx inx rts @@ -1264,7 +1264,7 @@ func_memsetw .proc ; -- fill memory from (SCRATCH_ZPWORD1) number of words in SCRATCH_ZPWORD2, with word value in AY. inx - stx P8ZP_SCRATCH_REG_X + stx P8ZP_SCRATCH_REG lda P8ESTACK_LO+2,x sta P8ZP_SCRATCH_W1 lda P8ESTACK_HI+2,x @@ -1276,7 +1276,7 @@ func_memsetw .proc lda P8ESTACK_LO,x ldy P8ESTACK_HI,x jsr memsetw - ldx P8ZP_SCRATCH_REG_X + ldx P8ZP_SCRATCH_REG inx inx rts @@ -1328,9 +1328,9 @@ memset .proc ; -- fill memory from (SCRATCH_ZPWORD1), length XY, with value in A. ; clobbers X, Y stx P8ZP_SCRATCH_B1 - sty P8ZP_SCRATCH_REG + sty _save_reg ldy #0 - ldx P8ZP_SCRATCH_REG + ldx _save_reg beq _lastpage _fullpage sta (P8ZP_SCRATCH_W1),y @@ -1347,6 +1347,7 @@ _lastpage ldy P8ZP_SCRATCH_B1 bne - + rts +_save_reg .byte 0 .pend diff --git a/compiler/src/prog8/compiler/Zeropage.kt b/compiler/src/prog8/compiler/Zeropage.kt index 6638d8099..7ea901129 100644 --- a/compiler/src/prog8/compiler/Zeropage.kt +++ b/compiler/src/prog8/compiler/Zeropage.kt @@ -10,7 +10,6 @@ abstract class Zeropage(protected val options: CompilationOptions) { abstract val SCRATCH_B1 : Int // temp storage for a single byte abstract val SCRATCH_REG : Int // temp storage for a register - abstract val SCRATCH_REG_X : Int // temp storage for register X (the evaluation stack pointer) abstract val SCRATCH_W1 : Int // temp storage 1 for a word $fb+$fc abstract val SCRATCH_W2 : Int // temp storage 2 for a word $fb+$fc diff --git a/compiler/src/prog8/compiler/target/c64/C64MachineDefinition.kt b/compiler/src/prog8/compiler/target/c64/C64MachineDefinition.kt index 3b9c357be..fa914442f 100644 --- a/compiler/src/prog8/compiler/target/c64/C64MachineDefinition.kt +++ b/compiler/src/prog8/compiler/target/c64/C64MachineDefinition.kt @@ -108,7 +108,6 @@ internal object C64MachineDefinition: IMachineDefinition { override val SCRATCH_B1 = 0x02 // temp storage for a single byte override val SCRATCH_REG = 0x03 // temp storage for a register - override val SCRATCH_REG_X = 0xfa // temp storage for register X (the evaluation stack pointer) override val SCRATCH_W1 = 0xfb // temp storage 1 for a word $fb+$fc override val SCRATCH_W2 = 0xfd // temp storage 2 for a word $fb+$fc @@ -126,7 +125,7 @@ internal object C64MachineDefinition: IMachineDefinition { if (options.zeropage == ZeropageType.FULL) { free.addAll(0x04..0xf9) free.add(0xff) - free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_REG_X, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) + free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) free.removeAll(listOf(0xa0, 0xa1, 0xa2, 0x91, 0xc0, 0xc5, 0xcb, 0xf5, 0xf6)) // these are updated by IRQ } else { if (options.zeropage == ZeropageType.KERNALSAFE || options.zeropage == ZeropageType.FLOATSAFE) { @@ -169,7 +168,6 @@ internal object C64MachineDefinition: IMachineDefinition { } require(SCRATCH_B1 !in free) require(SCRATCH_REG !in free) - require(SCRATCH_REG_X !in free) require(SCRATCH_W1 !in free) require(SCRATCH_W2 !in free) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index 8d91cd64b..44aabb35c 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -105,7 +105,7 @@ internal class AsmGen(private val program: Program, val zp = CompilationTarget.instance.machine.zeropage out("P8ZP_SCRATCH_B1 = ${zp.SCRATCH_B1}") out("P8ZP_SCRATCH_REG = ${zp.SCRATCH_REG}") - out("P8ZP_SCRATCH_REG_X = ${zp.SCRATCH_REG_X}") + out("P8ZP_SCRATCH_REG_X = ${'$'}9fff") // TODO remove this REG_X altogether!!! out("P8ZP_SCRATCH_W1 = ${zp.SCRATCH_W1} ; word") out("P8ZP_SCRATCH_W2 = ${zp.SCRATCH_W2} ; word") out("P8ESTACK_LO = ${CompilationTarget.instance.machine.ESTACK_LO.toHex()}") @@ -555,23 +555,20 @@ internal class AsmGen(private val program: Program, private val saveRegisterLabels = Stack(); - internal fun saveRegister(register: CpuRegister, forFuncCall: Boolean = false) { + internal fun saveRegister(register: CpuRegister) { when(register) { CpuRegister.A -> out(" pha") CpuRegister.X -> { // TODO get rid of REG_X altogether! - when { - CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" phx") - forFuncCall -> { - val save = makeLabel("saveX") - saveRegisterLabels.push(save) - out(""" - stx $save - jmp + -$save .byte 0 + if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" phx") + else { + val save = makeLabel("saveX") + saveRegisterLabels.push(save) + out(""" + stx $save + jmp + +$save .byte 0 +""") - } - else -> out(" stx P8ZP_SCRATCH_REG_X") } } CpuRegister.Y -> { @@ -579,26 +576,23 @@ $save .byte 0 else { val save = makeLabel("saveY") out(""" - sty $save - jmp + -$save .byte 0 + sty $save + jmp + +$save .byte 0 +""") } } } } - internal fun restoreRegister(register: CpuRegister, forFuncCall: Boolean = false) { + internal fun restoreRegister(register: CpuRegister) { when(register) { CpuRegister.A -> out(" pla") CpuRegister.X -> { - when { - CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" plx") - forFuncCall -> { - val save = saveRegisterLabels.pop() - out(" ldx $save") - } - else -> out(" ldx P8ZP_SCRATCH_REG_X") + if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" plx") + else { + val save = saveRegisterLabels.pop() + out(" ldx $save") } } CpuRegister.Y -> { diff --git a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt index 84afb5af7..05ecf251a 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt @@ -19,7 +19,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}") val saveX = CpuRegister.X in sub.asmClobbers || sub.regXasResult() || sub.regXasParam() if(saveX) - asmgen.saveRegister(CpuRegister.X, forFuncCall = true) + asmgen.saveRegister(CpuRegister.X) val subName = asmgen.asmSymbolName(stmt.target) if(stmt.args.isNotEmpty()) { @@ -58,7 +58,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg asmgen.out(" jsr $subName") if(saveX) - asmgen.restoreRegister(CpuRegister.X, forFuncCall = true) + asmgen.restoreRegister(CpuRegister.X) } private fun registerArgsViaStackEvaluation(stmt: IFunctionCall, sub: Subroutine) { diff --git a/compiler/src/prog8/compiler/target/cx16/CX16MachineDefinition.kt b/compiler/src/prog8/compiler/target/cx16/CX16MachineDefinition.kt index a6993464d..b76ac6009 100644 --- a/compiler/src/prog8/compiler/target/cx16/CX16MachineDefinition.kt +++ b/compiler/src/prog8/compiler/target/cx16/CX16MachineDefinition.kt @@ -74,7 +74,6 @@ internal object CX16MachineDefinition: IMachineDefinition { override val SCRATCH_B1 = 0x79 // temp storage for a single byte override val SCRATCH_REG = 0x7a // temp storage for a register - override val SCRATCH_REG_X = 0x7b // temp storage for register X (the evaluation stack pointer) override val SCRATCH_W1 = 0x7c // temp storage 1 for a word $7c+$7d override val SCRATCH_W2 = 0x7e // temp storage 2 for a word $7e+$7f @@ -95,16 +94,16 @@ internal object CX16MachineDefinition: IMachineDefinition { when (options.zeropage) { ZeropageType.FULL -> { free.addAll(0x22..0xff) - free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_REG_X, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) + free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) } ZeropageType.KERNALSAFE -> { free.addAll(0x22..0x7f) free.addAll(0xa9..0xff) - free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_REG_X, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) + free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) } ZeropageType.BASICSAFE -> { free.addAll(0x22..0x7f) - free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_REG_X, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) + free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) } ZeropageType.DONTUSE -> { free.clear() // don't use zeropage at all @@ -114,7 +113,6 @@ internal object CX16MachineDefinition: IMachineDefinition { require(SCRATCH_B1 !in free) require(SCRATCH_REG !in free) - require(SCRATCH_REG_X !in free) require(SCRATCH_W1 !in free) require(SCRATCH_W2 !in free)