mirror of
https://github.com/KarolS/millfork.git
synced 2024-12-24 15:29:23 +00:00
6502: Shifting improvements and fixes
This commit is contained in:
parent
74dbca1f53
commit
b41f9bebc1
@ -205,6 +205,33 @@ object BuiltIns {
|
||||
firstParamCompiled ++ remainingParamsCompiled
|
||||
}
|
||||
|
||||
def maybeCompileShiftFromByteToWord(ctx: CompilationContext, l: Expression, r: Expression, left: Boolean): Option[List[AssemblyLine]] = {
|
||||
val env = ctx.env
|
||||
env.eval(r) match {
|
||||
case Some(NumericConstant(n, _)) =>
|
||||
l match {
|
||||
case FunctionCallExpression(wordTypeName, List(param)) =>
|
||||
if (AbstractExpressionCompiler.getExpressionType(ctx, param).size == 1 && env.maybeGet[Type](wordTypeName).exists(_.size == 2)) {
|
||||
Some(MosExpressionCompiler.compileToA(ctx, param) ++ BuiltIns.compileShiftFromByteToWord(ctx, n.toInt, left))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
def compileShiftFromByteToWord(ctx: CompilationContext, count: Int, left: Boolean): List[AssemblyLine] = {
|
||||
if (count == 8) {
|
||||
List(AssemblyLine.implied(TAX), AssemblyLine.immediate(LDA, 0))
|
||||
} else {
|
||||
List(AssemblyLine.implied(PHA)) ++
|
||||
List.fill(8 - count)(AssemblyLine.implied(if (left) LSR else ASL)) ++
|
||||
List(AssemblyLine.implied(TAX), AssemblyLine.implied(PLA)) ++
|
||||
List.fill(count)(AssemblyLine.implied(if (left) ASL else LSR))
|
||||
}
|
||||
}
|
||||
|
||||
def compileShiftOps(opcode: Opcode.Value, ctx: CompilationContext, l: Expression, r: Expression): List[AssemblyLine] = {
|
||||
val b = ctx.env.get[Type]("byte")
|
||||
val firstParamCompiled = MosExpressionCompiler.compile(ctx, l, Some(b -> RegisterVariable(MosRegister.A, b)), NoBranching)
|
||||
|
@ -831,7 +831,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
zeroExtend = true
|
||||
BuiltIns.compileShiftOps(ASL, ctx, l, r)
|
||||
case 2 =>
|
||||
PseudoregisterBuiltIns.compileWordShiftOps(left = true, ctx, l, r)
|
||||
BuiltIns.maybeCompileShiftFromByteToWord(ctx, l, r, left = true).getOrElse(PseudoregisterBuiltIns.compileWordShiftOps(left = true, ctx, l, r))
|
||||
case _ =>
|
||||
ctx.log.error("Long shift ops not supported", l.position)
|
||||
Nil
|
||||
@ -843,7 +843,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
zeroExtend = true
|
||||
BuiltIns.compileShiftOps(LSR, ctx, l, r)
|
||||
case 2 =>
|
||||
PseudoregisterBuiltIns.compileWordShiftOps(left = false, ctx, l, r)
|
||||
BuiltIns.maybeCompileShiftFromByteToWord(ctx, l, r, left = false).getOrElse(PseudoregisterBuiltIns.compileWordShiftOps(left = false, ctx, l, r))
|
||||
case _ =>
|
||||
ctx.log.error("Long shift ops not supported", l.position)
|
||||
Nil
|
||||
|
@ -229,7 +229,7 @@ object PseudoregisterBuiltIns {
|
||||
val firstParamCompiled = MosExpressionCompiler.compile(ctx, l, Some(MosExpressionCompiler.getExpressionType(ctx, l) -> reg), NoBranching)
|
||||
ctx.env.eval(r) match {
|
||||
case Some(NumericConstant(0, _)) =>
|
||||
Nil
|
||||
List(AssemblyLine.zeropage(LDA, reg), AssemblyLine.zeropage(LDX, reg, 1))
|
||||
case Some(NumericConstant(v, _)) if v > 0 =>
|
||||
if (ctx.options.flag(CompilationFlag.EmitNative65816Opcodes)) {
|
||||
firstParamCompiled ++
|
||||
|
Loading…
Reference in New Issue
Block a user