c65gm/internal/optimizer/pass_imm.go

67 lines
1.2 KiB
Go

package optimizer
// passImmElimination removes redundant immediate loads.
// Pattern: lda #N; ... (no A modification) ...; lda #N → remove second
// Applies to A, X, Y.
func passImmElimination(lines []asmLine) []asmLine {
rs := newRegState()
var result []asmLine
for _, line := range lines {
if !line.isCode {
if line.optMarker {
continue
}
if line.isLabel {
rs.reset()
}
result = append(result, line)
continue
}
if isChainBreaker(line.opcode) {
rs.reset()
result = append(result, line)
continue
}
if isRedundantImm(line, rs) {
continue // remove line
}
updateRegState(line, rs)
result = append(result, line)
}
return result
}
func isRedundantImm(line asmLine, rs *regState) bool {
switch line.opcode {
case "lda":
if isImmediate(line.operand) {
val := parseHexOrDec(line.operand[1:])
if rs.a.val == val {
return true
}
rs.loadImm("a", val)
}
case "ldx":
if isImmediate(line.operand) {
val := parseHexOrDec(line.operand[1:])
if rs.x.val == val {
return true
}
rs.loadImm("x", val)
}
case "ldy":
if isImmediate(line.operand) {
val := parseHexOrDec(line.operand[1:])
if rs.y.val == val {
return true
}
rs.loadImm("y", val)
}
}
return false
}