mirror of
https://github.com/KarolS/millfork.git
synced 2024-09-10 11:54:30 +00:00
Zeropage variable optimizations
This commit is contained in:
parent
50d4823e0a
commit
17920cee26
@ -184,6 +184,7 @@ object AddrMode extends Enumeration {
|
|||||||
case IndexedX | AbsoluteIndexedX => "(" + argument + ", X)"
|
case IndexedX | AbsoluteIndexedX => "(" + argument + ", X)"
|
||||||
case IndexedY => "(" + argument + "), Y"
|
case IndexedY => "(" + argument + "), Y"
|
||||||
case Indirect | ZeroPageIndirect => "(" + argument + ")"
|
case Indirect | ZeroPageIndirect => "(" + argument + ")"
|
||||||
|
case ZeroPage => argument // + "\t;zp"
|
||||||
case _ => argument;
|
case _ => argument;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,21 +282,15 @@ object MfCompiler {
|
|||||||
case 0 => ???
|
case 0 => ???
|
||||||
case 1 =>
|
case 1 =>
|
||||||
v match {
|
v match {
|
||||||
case mv: VariableInMemory => AssemblyLine.absolute(store, mv) :: Nil
|
case mv: VariableInMemory => AssemblyLine.variable(ctx, store, mv)
|
||||||
case sv@StackVariable(_, _, offset) => AssemblyLine.implied(transferToA) :: AssemblyLine.implied(TSX) :: AssemblyLine.absoluteX(STA, offset + ctx.extraStackOffset) :: Nil
|
case sv@StackVariable(_, _, offset) => AssemblyLine.implied(transferToA) :: AssemblyLine.implied(TSX) :: AssemblyLine.absoluteX(STA, offset + ctx.extraStackOffset) :: Nil
|
||||||
}
|
}
|
||||||
case s if s > 1 =>
|
case s if s > 1 =>
|
||||||
v match {
|
v match {
|
||||||
case mv: VariableInMemory =>
|
case mv: VariableInMemory =>
|
||||||
if (mv.zeropage) {
|
AssemblyLine.variable(ctx, store, mv) ++
|
||||||
AssemblyLine.zeropage(store, mv) ::
|
List(AssemblyLine.immediate(LDA, 0)) ++
|
||||||
AssemblyLine.immediate(LDA, 0) ::
|
List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, mv, i + 1)).flatten
|
||||||
List.tabulate(s - 1)(i => AssemblyLine.zeropage(STA, mv.toAddress + (i + 1)))
|
|
||||||
} else {
|
|
||||||
AssemblyLine.absolute(store, mv) ::
|
|
||||||
AssemblyLine.immediate(LDA, 0) ::
|
|
||||||
List.tabulate(s - 1)(i => AssemblyLine.absolute(STA, mv.toAddress + (i + 1)))
|
|
||||||
}
|
|
||||||
case sv@StackVariable(_, _, offset) =>
|
case sv@StackVariable(_, _, offset) =>
|
||||||
AssemblyLine.implied(transferToA) ::
|
AssemblyLine.implied(transferToA) ::
|
||||||
AssemblyLine.implied(TSX) ::
|
AssemblyLine.implied(TSX) ::
|
||||||
@ -465,15 +459,14 @@ object MfCompiler {
|
|||||||
env.get[TypedThing](name) match {
|
env.get[TypedThing](name) match {
|
||||||
case source: VariableInMemory =>
|
case source: VariableInMemory =>
|
||||||
target match {
|
target match {
|
||||||
case RegisterVariable(Register.A, _) => List(AssemblyLine.absolute(LDA, source))
|
case RegisterVariable(Register.A, _) => AssemblyLine.variable(ctx, LDA, source)
|
||||||
case RegisterVariable(Register.X, _) => List(AssemblyLine.absolute(LDX, source))
|
case RegisterVariable(Register.X, _) => AssemblyLine.variable(ctx, LDX, source)
|
||||||
case RegisterVariable(Register.Y, _) => List(AssemblyLine.absolute(LDY, source))
|
case RegisterVariable(Register.Y, _) => AssemblyLine.variable(ctx, LDY, source)
|
||||||
case RegisterVariable(Register.AX, _) =>
|
case RegisterVariable(Register.AX, _) =>
|
||||||
exprType.size match {
|
exprType.size match {
|
||||||
case 1 => if (exprType.isSigned) {
|
case 1 => if (exprType.isSigned) {
|
||||||
val label = nextLabel("sx")
|
val label = nextLabel("sx")
|
||||||
List(
|
AssemblyLine.variable(ctx, LDA, source) ++ List(
|
||||||
AssemblyLine.absolute(LDA, source),
|
|
||||||
AssemblyLine.implied(PHA),
|
AssemblyLine.implied(PHA),
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
AssemblyLine.immediate(ORA, 0x7F),
|
||||||
AssemblyLine.relative(BMI, label),
|
AssemblyLine.relative(BMI, label),
|
||||||
@ -481,19 +474,15 @@ object MfCompiler {
|
|||||||
AssemblyLine.label(label),
|
AssemblyLine.label(label),
|
||||||
AssemblyLine.implied(TAX),
|
AssemblyLine.implied(TAX),
|
||||||
AssemblyLine.implied(PLA))
|
AssemblyLine.implied(PLA))
|
||||||
} else List(
|
} else AssemblyLine.variable(ctx, LDA, source) :+ AssemblyLine.immediate(LDX, 0)
|
||||||
AssemblyLine.absolute(LDA, source),
|
case 2 =>
|
||||||
AssemblyLine.immediate(LDX, 0))
|
AssemblyLine.variable(ctx, LDA, source) ++ AssemblyLine.variable(ctx, LDX, source, 1)
|
||||||
case 2 => List(
|
|
||||||
AssemblyLine.absolute(LDA, source),
|
|
||||||
AssemblyLine.absolute(LDX, source, 1))
|
|
||||||
}
|
}
|
||||||
case RegisterVariable(Register.AY, _) =>
|
case RegisterVariable(Register.AY, _) =>
|
||||||
exprType.size match {
|
exprType.size match {
|
||||||
case 1 => if (exprType.isSigned) {
|
case 1 => if (exprType.isSigned) {
|
||||||
val label = nextLabel("sx")
|
val label = nextLabel("sx")
|
||||||
List(
|
AssemblyLine.variable(ctx, LDA, source) ++ List(
|
||||||
AssemblyLine.absolute(LDA, source),
|
|
||||||
AssemblyLine.implied(PHA),
|
AssemblyLine.implied(PHA),
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
AssemblyLine.immediate(ORA, 0x7F),
|
||||||
AssemblyLine.relative(BMI, label),
|
AssemblyLine.relative(BMI, label),
|
||||||
@ -502,56 +491,47 @@ object MfCompiler {
|
|||||||
AssemblyLine.implied(TAY),
|
AssemblyLine.implied(TAY),
|
||||||
AssemblyLine.implied(PLA))
|
AssemblyLine.implied(PLA))
|
||||||
} else {
|
} else {
|
||||||
List(
|
AssemblyLine.variable(ctx, LDA, source) :+ AssemblyLine.immediate(LDY, 0)
|
||||||
AssemblyLine.absolute(LDA, source),
|
|
||||||
AssemblyLine.immediate(LDY, 0))
|
|
||||||
}
|
}
|
||||||
case 2 => List(
|
case 2 =>
|
||||||
AssemblyLine.absolute(LDA, source),
|
AssemblyLine.variable(ctx, LDA, source) ++ AssemblyLine.variable(ctx, LDY, source, 1)
|
||||||
AssemblyLine.absolute(LDY, source, 1))
|
|
||||||
}
|
}
|
||||||
case RegisterVariable(Register.XA, _) =>
|
case RegisterVariable(Register.XA, _) =>
|
||||||
exprType.size match {
|
exprType.size match {
|
||||||
case 1 => if (exprType.isSigned) {
|
case 1 => if (exprType.isSigned) {
|
||||||
val label = nextLabel("sx")
|
val label = nextLabel("sx")
|
||||||
List(
|
AssemblyLine.variable(ctx, LDX, source) ++ List(
|
||||||
AssemblyLine.absolute(LDX, source),
|
|
||||||
AssemblyLine.implied(TXA),
|
AssemblyLine.implied(TXA),
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
AssemblyLine.immediate(ORA, 0x7F),
|
||||||
AssemblyLine.relative(BMI, label),
|
AssemblyLine.relative(BMI, label),
|
||||||
AssemblyLine.immediate(LDA, 0),
|
AssemblyLine.immediate(LDA, 0),
|
||||||
AssemblyLine.label(label))
|
AssemblyLine.label(label))
|
||||||
} else List(
|
} else
|
||||||
AssemblyLine.absolute(LDX, source),
|
AssemblyLine.variable(ctx, LDX, source) :+ AssemblyLine.immediate(LDA, 0)
|
||||||
AssemblyLine.immediate(LDA, 0))
|
case 2 =>
|
||||||
case 2 => List(
|
AssemblyLine.variable(ctx, LDX, source) ++ AssemblyLine.variable(ctx,LDA, source, 1)
|
||||||
AssemblyLine.absolute(LDX, source),
|
|
||||||
AssemblyLine.absolute(LDA, source, 1))
|
|
||||||
}
|
}
|
||||||
case RegisterVariable(Register.YA, _) =>
|
case RegisterVariable(Register.YA, _) =>
|
||||||
exprType.size match {
|
exprType.size match {
|
||||||
case 1 => if (exprType.isSigned) {
|
case 1 => if (exprType.isSigned) {
|
||||||
val label = nextLabel("sx")
|
val label = nextLabel("sx")
|
||||||
List(
|
AssemblyLine.variable(ctx, LDY, source) ++ List(
|
||||||
AssemblyLine.absolute(LDY, source),
|
|
||||||
AssemblyLine.implied(TYA),
|
AssemblyLine.implied(TYA),
|
||||||
AssemblyLine.immediate(ORA, 0x7F),
|
AssemblyLine.immediate(ORA, 0x7F),
|
||||||
AssemblyLine.relative(BMI, label),
|
AssemblyLine.relative(BMI, label),
|
||||||
AssemblyLine.immediate(LDA, 0),
|
AssemblyLine.immediate(LDA, 0),
|
||||||
AssemblyLine.label(label))
|
AssemblyLine.label(label))
|
||||||
} else List(
|
} else
|
||||||
AssemblyLine.absolute(LDY, source),
|
AssemblyLine.variable(ctx, LDY, source) :+ AssemblyLine.immediate(LDA, 0)
|
||||||
AssemblyLine.immediate(LDA, 0))
|
case 2 =>
|
||||||
case 2 => List(
|
AssemblyLine.variable(ctx, LDY, source) ++ AssemblyLine.variable(ctx, LDA, source, 1)
|
||||||
AssemblyLine.absolute(LDY, source),
|
|
||||||
AssemblyLine.absolute(LDA, source, 1))
|
|
||||||
}
|
}
|
||||||
case target: VariableInMemory =>
|
case target: VariableInMemory =>
|
||||||
if (exprType.size > target.typ.size) {
|
if (exprType.size > target.typ.size) {
|
||||||
ErrorReporting.error(s"Variable `$target.name` is too small", expr.position)
|
ErrorReporting.error(s"Variable `$target.name` is too small", expr.position)
|
||||||
Nil
|
Nil
|
||||||
} else {
|
} else {
|
||||||
val copy = List.tabulate(exprType.size)(i => List(AssemblyLine.absolute(LDA, source, i), AssemblyLine.absolute(STA, target, i)))
|
val copy = List.tabulate(exprType.size)(i => AssemblyLine.variable(ctx, LDA, source, i) ++ AssemblyLine.variable(ctx, STA, target, i))
|
||||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||||
val label = nextLabel("sx")
|
val label = nextLabel("sx")
|
||||||
List(
|
List(
|
||||||
@ -559,10 +539,10 @@ object MfCompiler {
|
|||||||
AssemblyLine.relative(BMI, label),
|
AssemblyLine.relative(BMI, label),
|
||||||
AssemblyLine.immediate(LDA, 0),
|
AssemblyLine.immediate(LDA, 0),
|
||||||
AssemblyLine.label(label)) ++
|
AssemblyLine.label(label)) ++
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absolute(STA, target, i + exprType.size))
|
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.immediate(LDA, 0) ::
|
AssemblyLine.immediate(LDA, 0) ::
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absolute(STA, target, i + exprType.size))
|
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||||
}
|
}
|
||||||
copy.flatten ++ extend
|
copy.flatten ++ extend
|
||||||
}
|
}
|
||||||
@ -571,7 +551,7 @@ object MfCompiler {
|
|||||||
ErrorReporting.error(s"Variable `$target.name` is too small", expr.position)
|
ErrorReporting.error(s"Variable `$target.name` is too small", expr.position)
|
||||||
Nil
|
Nil
|
||||||
} else {
|
} else {
|
||||||
val copy = List.tabulate(exprType.size)(i => List(AssemblyLine.absolute(LDA, source, i), AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i)))
|
val copy = List.tabulate(exprType.size)(i => AssemblyLine.variable(ctx, LDA, source, i) :+ AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i))
|
||||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||||
val label = nextLabel("sx")
|
val label = nextLabel("sx")
|
||||||
List(
|
List(
|
||||||
@ -657,7 +637,7 @@ object MfCompiler {
|
|||||||
ErrorReporting.error(s"Variable `$target.name` is too small", expr.position)
|
ErrorReporting.error(s"Variable `$target.name` is too small", expr.position)
|
||||||
Nil
|
Nil
|
||||||
} else {
|
} else {
|
||||||
val copy = List.tabulate(exprType.size)(i => List(AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset + i), AssemblyLine.absolute(STA, target, i)))
|
val copy = List.tabulate(exprType.size)(i => AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset + i) :: AssemblyLine.variable(ctx, STA, target, i))
|
||||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||||
val label = nextLabel("sx")
|
val label = nextLabel("sx")
|
||||||
List(
|
List(
|
||||||
@ -665,10 +645,10 @@ object MfCompiler {
|
|||||||
AssemblyLine.relative(BMI, label),
|
AssemblyLine.relative(BMI, label),
|
||||||
AssemblyLine.immediate(LDA, 0),
|
AssemblyLine.immediate(LDA, 0),
|
||||||
AssemblyLine.label(label)) ++
|
AssemblyLine.label(label)) ++
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absolute(STA, target, i + exprType.size))
|
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||||
} else {
|
} else {
|
||||||
AssemblyLine.immediate(LDA, 0) ::
|
AssemblyLine.immediate(LDA, 0) ::
|
||||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absolute(STA, target, i + exprType.size))
|
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||||
}
|
}
|
||||||
AssemblyLine.implied(TSX) :: (copy.flatten ++ extend)
|
AssemblyLine.implied(TSX) :: (copy.flatten ++ extend)
|
||||||
}
|
}
|
||||||
@ -1249,21 +1229,18 @@ object MfCompiler {
|
|||||||
case (t, v: VariableInMemory) => t.size match {
|
case (t, v: VariableInMemory) => t.size match {
|
||||||
case 1 => v.typ.size match {
|
case 1 => v.typ.size match {
|
||||||
case 1 =>
|
case 1 =>
|
||||||
List(AssemblyLine.absolute(STA, v))
|
AssemblyLine.variable(ctx, STA, v)
|
||||||
case s if s > 1 =>
|
case s if s > 1 =>
|
||||||
if (t.isSigned) {
|
if (t.isSigned) {
|
||||||
val label = nextLabel("sx")
|
val label = nextLabel("sx")
|
||||||
List(
|
AssemblyLine.variable(ctx, STA, v)++List(
|
||||||
AssemblyLine.absolute(STA, v),
|
|
||||||
AssemblyLine.immediate(ORA, 0x7f),
|
AssemblyLine.immediate(ORA, 0x7f),
|
||||||
AssemblyLine.relative(BMI, label),
|
AssemblyLine.relative(BMI, label),
|
||||||
AssemblyLine.immediate(LDA, 0),
|
AssemblyLine.immediate(LDA, 0),
|
||||||
AssemblyLine.label(label)) ++ List.tabulate(s - 1)(i => AssemblyLine.absolute(STA, v, i + 1))
|
AssemblyLine.label(label)) ++ List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, v, i + 1)).flatten
|
||||||
} else {
|
} else {
|
||||||
List(
|
AssemblyLine.variable(ctx, STA, v) ++ List(AssemblyLine.immediate(LDA, 0)) ++
|
||||||
AssemblyLine.absolute(STA, v),
|
List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, v, i + 1)).flatten
|
||||||
AssemblyLine.immediate(LDA, 0)) ++
|
|
||||||
List.tabulate(s - 1)(i => AssemblyLine.absolute(STA, v, i + 1))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 2 => v.typ.size match {
|
case 2 => v.typ.size match {
|
||||||
@ -1271,24 +1248,20 @@ object MfCompiler {
|
|||||||
ErrorReporting.error(s"Variable `${v.name}` cannot hold a word", position)
|
ErrorReporting.error(s"Variable `${v.name}` cannot hold a word", position)
|
||||||
Nil
|
Nil
|
||||||
case 2 =>
|
case 2 =>
|
||||||
List(AssemblyLine.absolute(STA, v), AssemblyLine.absolute(STX, v, 1))
|
AssemblyLine.variable(ctx, STA, v) ++ AssemblyLine.variable(ctx, STX, v, 1)
|
||||||
case s if s > 2 =>
|
case s if s > 2 =>
|
||||||
if (t.isSigned) {
|
if (t.isSigned) {
|
||||||
val label = nextLabel("sx")
|
val label = nextLabel("sx")
|
||||||
List(
|
AssemblyLine.variable(ctx, STA, v) ++ AssemblyLine.variable(ctx, STX, v, 1) ++ List(
|
||||||
AssemblyLine.absolute(STA, v),
|
|
||||||
AssemblyLine.absolute(STX, v, 1),
|
|
||||||
AssemblyLine.implied(TXA),
|
AssemblyLine.implied(TXA),
|
||||||
AssemblyLine.immediate(ORA, 0x7f),
|
AssemblyLine.immediate(ORA, 0x7f),
|
||||||
AssemblyLine.relative(BMI, label),
|
AssemblyLine.relative(BMI, label),
|
||||||
AssemblyLine.immediate(LDA, 0),
|
AssemblyLine.immediate(LDA, 0),
|
||||||
AssemblyLine.label(label)) ++ List.tabulate(s - 2)(i => AssemblyLine.absolute(STA, v, i + 2))
|
AssemblyLine.label(label)) ++ List.tabulate(s - 2)(i => AssemblyLine.variable(ctx, STA, v, i + 2)).flatten
|
||||||
} else {
|
} else {
|
||||||
List(
|
AssemblyLine.variable(ctx, STA, v) ++ AssemblyLine.variable(ctx, STX, v, 1) ++ List(
|
||||||
AssemblyLine.absolute(STA, v),
|
|
||||||
AssemblyLine.absolute(STX, v, 1),
|
|
||||||
AssemblyLine.immediate(LDA, 0)) ++
|
AssemblyLine.immediate(LDA, 0)) ++
|
||||||
List.tabulate(s - 2)(i => AssemblyLine.absolute(STA, v, i + 2))
|
List.tabulate(s - 2)(i => AssemblyLine.variable(ctx, STA, v, i + 2)).flatten
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user