mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
fix missing symboltable entries for asmgen
This commit is contained in:
parent
94c9b0d23b
commit
e67464325f
@ -48,7 +48,7 @@ class AsmGen(
|
||||
if(options.optimize) {
|
||||
val separateLines = assemblyLines.flatMapTo(mutableListOf()) { it.split('\n') }
|
||||
assemblyLines.clear()
|
||||
while(optimizeAssembly(separateLines, options.compTarget.machine, program)>0) {
|
||||
while(optimizeAssembly(separateLines, options.compTarget.machine, symbolTable)>0) {
|
||||
// optimize the assembly source code
|
||||
}
|
||||
output.writeLines(separateLines)
|
||||
|
@ -1,13 +1,16 @@
|
||||
package prog8.codegen.cpu6502
|
||||
|
||||
import prog8.code.ast.PtProgram
|
||||
import prog8.code.StConstant
|
||||
import prog8.code.StMemVar
|
||||
import prog8.code.SymbolTable
|
||||
import prog8.code.core.AssemblyError
|
||||
import prog8.code.core.IMachineDefinition
|
||||
|
||||
|
||||
// note: see https://wiki.nesdev.org/w/index.php/6502_assembly_optimisations
|
||||
|
||||
|
||||
internal fun optimizeAssembly(lines: MutableList<String>, machine: IMachineDefinition, program: PtProgram): Int {
|
||||
internal fun optimizeAssembly(lines: MutableList<String>, machine: IMachineDefinition, symbolTable: SymbolTable): Int {
|
||||
|
||||
var numberOfOptimizations = 0
|
||||
|
||||
@ -34,7 +37,7 @@ internal fun optimizeAssembly(lines: MutableList<String>, machine: IMachineDefin
|
||||
numberOfOptimizations++
|
||||
}
|
||||
|
||||
mods = optimizeStoreLoadSame(linesByFour, machine, program)
|
||||
mods = optimizeStoreLoadSame(linesByFour, machine, symbolTable)
|
||||
if(mods.isNotEmpty()) {
|
||||
apply(mods, lines)
|
||||
linesByFour = getLinesBy(lines, 4)
|
||||
@ -49,14 +52,14 @@ internal fun optimizeAssembly(lines: MutableList<String>, machine: IMachineDefin
|
||||
}
|
||||
|
||||
var linesByFourteen = getLinesBy(lines, 14)
|
||||
mods = optimizeSameAssignments(linesByFourteen, machine, program)
|
||||
mods = optimizeSameAssignments(linesByFourteen, machine, symbolTable)
|
||||
if(mods.isNotEmpty()) {
|
||||
apply(mods, lines)
|
||||
linesByFourteen = getLinesBy(lines, 14)
|
||||
numberOfOptimizations++
|
||||
}
|
||||
|
||||
mods = optimizeSamePointerIndexing(linesByFourteen, machine, program)
|
||||
mods = optimizeSamePointerIndexing(linesByFourteen)
|
||||
if(mods.isNotEmpty()) {
|
||||
apply(mods, lines)
|
||||
linesByFourteen = getLinesBy(lines, 14)
|
||||
@ -126,7 +129,11 @@ private fun optimizeUselessStackByteWrites(linesByFour: List<List<IndexedValue<S
|
||||
return mods
|
||||
}
|
||||
|
||||
private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<String>>>, machine: IMachineDefinition, program: PtProgram): List<Modification> {
|
||||
private fun optimizeSameAssignments(
|
||||
linesByFourteen: List<List<IndexedValue<String>>>,
|
||||
machine: IMachineDefinition,
|
||||
symbolTable: SymbolTable
|
||||
): List<Modification> {
|
||||
|
||||
// Optimize sequential assignments of the same value to various targets (bytes, words, floats)
|
||||
// the float one is the one that requires 2*7=14 lines of code to check...
|
||||
@ -151,8 +158,8 @@ private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<Stri
|
||||
val fourthvalue = sixth.substring(4)
|
||||
if(firstvalue==thirdvalue && secondvalue==fourthvalue) {
|
||||
// lda/ldy sta/sty twice the same word --> remove second lda/ldy pair (fifth and sixth lines)
|
||||
val address1 = getAddressArg(first, program)
|
||||
val address2 = getAddressArg(second, program)
|
||||
val address1 = getAddressArg(first, symbolTable)
|
||||
val address2 = getAddressArg(second, symbolTable)
|
||||
if(address1==null || address2==null || (!machine.isIOAddress(address1) && !machine.isIOAddress(address2))) {
|
||||
mods.add(Modification(lines[4].index, true, null))
|
||||
mods.add(Modification(lines[5].index, true, null))
|
||||
@ -165,7 +172,7 @@ private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<Stri
|
||||
val secondvalue = third.substring(4)
|
||||
if(firstvalue==secondvalue) {
|
||||
// lda value / sta ? / lda same-value / sta ? -> remove second lda (third line)
|
||||
val address = getAddressArg(first, program)
|
||||
val address = getAddressArg(first, symbolTable)
|
||||
if(address==null || !machine.isIOAddress(address))
|
||||
mods.add(Modification(lines[2].index, true, null))
|
||||
}
|
||||
@ -248,7 +255,7 @@ private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<Stri
|
||||
val thirdvalue = third.substring(4)
|
||||
val fourthvalue = fourth.substring(4)
|
||||
if(firstvalue==thirdvalue && secondvalue == fourthvalue) {
|
||||
val address = getAddressArg(first, program)
|
||||
val address = getAddressArg(first, symbolTable)
|
||||
if(address==null || !machine.isIOAddress(address)) {
|
||||
overlappingMods = true
|
||||
mods.add(Modification(lines[2].index, true, null))
|
||||
@ -272,7 +279,7 @@ private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<Stri
|
||||
val firstvalue = first.substring(4)
|
||||
val thirdvalue = third.substring(4)
|
||||
if(firstvalue==thirdvalue) {
|
||||
val address = getAddressArg(first, program)
|
||||
val address = getAddressArg(first, symbolTable)
|
||||
if(address==null || !machine.isIOAddress(address)) {
|
||||
overlappingMods = true
|
||||
mods.add(Modification(lines[2].index, true, null))
|
||||
@ -292,7 +299,7 @@ private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<Stri
|
||||
val secondvalue = second.substring(4)
|
||||
val thirdvalue = third.substring(4)
|
||||
if(firstvalue==secondvalue && firstvalue==thirdvalue) {
|
||||
val address = getAddressArg(first, program)
|
||||
val address = getAddressArg(first, symbolTable)
|
||||
if(address==null || !machine.isIOAddress(address)) {
|
||||
overlappingMods = true
|
||||
val reg2 = second[2]
|
||||
@ -311,7 +318,7 @@ private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<Stri
|
||||
val firstvalue = first.substring(4)
|
||||
val secondvalue = second.substring(4)
|
||||
if(firstvalue==secondvalue) {
|
||||
val address = getAddressArg(first, program)
|
||||
val address = getAddressArg(first, symbolTable)
|
||||
if(address==null || !machine.isIOAddress(address)) {
|
||||
overlappingMods = true
|
||||
mods.add(Modification(lines[0].index, true, null))
|
||||
@ -324,7 +331,7 @@ private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<Stri
|
||||
return mods
|
||||
}
|
||||
|
||||
private fun optimizeSamePointerIndexing(linesByFourteen: List<List<IndexedValue<String>>>, machine: IMachineDefinition, program: PtProgram): List<Modification> {
|
||||
private fun optimizeSamePointerIndexing(linesByFourteen: List<List<IndexedValue<String>>>): List<Modification> {
|
||||
|
||||
// Optimize same pointer indexing where for instance we load and store to the same ptr index in Y
|
||||
// if Y isn't modified in between we can omit the second LDY:
|
||||
@ -366,7 +373,11 @@ private fun optimizeSamePointerIndexing(linesByFourteen: List<List<IndexedValue<
|
||||
return mods
|
||||
}
|
||||
|
||||
private fun optimizeStoreLoadSame(linesByFour: List<List<IndexedValue<String>>>, machine: IMachineDefinition, program: PtProgram): List<Modification> {
|
||||
private fun optimizeStoreLoadSame(
|
||||
linesByFour: List<List<IndexedValue<String>>>,
|
||||
machine: IMachineDefinition,
|
||||
symbolTable: SymbolTable
|
||||
): List<Modification> {
|
||||
// sta X + lda X, sty X + ldy X, stx X + ldx X -> the second instruction can OFTEN be eliminated
|
||||
val mods = mutableListOf<Modification>()
|
||||
for (lines in linesByFour) {
|
||||
@ -394,7 +405,7 @@ private fun optimizeStoreLoadSame(linesByFour: List<List<IndexedValue<String>>>,
|
||||
}
|
||||
else {
|
||||
// no branch instruction follows, we can remove the load instruction
|
||||
val address = getAddressArg(lines[2].value, program)
|
||||
val address = getAddressArg(lines[2].value, symbolTable)
|
||||
address==null || !machine.isIOAddress(address)
|
||||
}
|
||||
|
||||
@ -436,7 +447,7 @@ private fun optimizeStoreLoadSame(linesByFour: List<List<IndexedValue<String>>>,
|
||||
|
||||
private val identifierRegex = Regex("""^([a-zA-Z_$][a-zA-Z\d_\.$]*)""")
|
||||
|
||||
private fun getAddressArg(line: String, program: PtProgram): UInt? {
|
||||
private fun getAddressArg(line: String, symbolTable: SymbolTable): UInt? {
|
||||
val loadArg = line.trimStart().substring(3).trim()
|
||||
return when {
|
||||
loadArg.startsWith('$') -> loadArg.substring(1).toUIntOrNull(16)
|
||||
@ -447,7 +458,12 @@ private fun getAddressArg(line: String, program: PtProgram): UInt? {
|
||||
val identMatch = identifierRegex.find(loadArg)
|
||||
if(identMatch!=null) {
|
||||
val identifier = identMatch.value
|
||||
TODO("lookup symbol's value $identifier")
|
||||
when (val symbol = symbolTable.flat[identifier]) {
|
||||
is StConstant -> symbol.value.toUInt()
|
||||
is StMemVar -> symbol.address
|
||||
null -> null
|
||||
else -> throw AssemblyError("expected constant or memvar for address $line")
|
||||
}
|
||||
} else null
|
||||
}
|
||||
else -> loadArg.substring(1).toUIntOrNull()
|
||||
|
@ -28,6 +28,15 @@ internal class SymbolTableMaker(private val program: Program, private val option
|
||||
st.add(node)
|
||||
}
|
||||
require(scopestack.isEmpty())
|
||||
|
||||
// add the hardcoded temporary zeropage variables
|
||||
st.add(StMemVar("P8ZP_SCRATCH_B1", DataType.UBYTE, options.compTarget.machine.zeropage.SCRATCH_B1, null, Position.DUMMY))
|
||||
st.add(StMemVar("P8ZP_SCRATCH_REG", DataType.UBYTE, options.compTarget.machine.zeropage.SCRATCH_REG, null, Position.DUMMY))
|
||||
st.add(StMemVar("P8ZP_SCRATCH_W1", DataType.UWORD, options.compTarget.machine.zeropage.SCRATCH_W1, null, Position.DUMMY))
|
||||
st.add(StMemVar("P8ZP_SCRATCH_W2", DataType.UWORD, options.compTarget.machine.zeropage.SCRATCH_W2, null, Position.DUMMY))
|
||||
st.add(StMemVar("P8ESTACK_LO", DataType.UBYTE, options.compTarget.machine.ESTACK_LO, null, Position.DUMMY))
|
||||
st.add(StMemVar("P8ESTACK_HI", DataType.UBYTE, options.compTarget.machine.ESTACK_HI, null, Position.DUMMY))
|
||||
|
||||
return st
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user