diff --git a/src/main/scala/millfork/compiler/z80/ZBuiltIns.scala b/src/main/scala/millfork/compiler/z80/ZBuiltIns.scala index 6bf1d47a..62ef995e 100644 --- a/src/main/scala/millfork/compiler/z80/ZBuiltIns.scala +++ b/src/main/scala/millfork/compiler/z80/ZBuiltIns.scala @@ -217,19 +217,24 @@ object ZBuiltIns { } case (true, expr) => ctx.env.eval(expr) match { - case None => + case Some(c) if hasConst && const.isProvablyGreaterOrEqualThan(c)=> + const = CompoundConstant(MathOperator.DecimalMinus, const, c).quickSimplify + case _ => if (result.isEmpty) { - ??? - } else if (ctx.options.flag(CompilationFlag.EmitExtended80Opcodes)) { + result += ZLine.ldImm16(ZRegister.HL, const) + const = NumericConstant(0, 2) + hasConst = false + } + if (ctx.options.flag(CompilationFlag.EmitExtended80Opcodes)) { result += ZLine.ld8(ZRegister.E, ZRegister.L) result += ZLine.ld8(ZRegister.D, ZRegister.H) result ++= Z80ExpressionCompiler.stashDEIfChanged(ctx, Z80ExpressionCompiler.compileToHL(ctx, expr)) result += ZLine.ld8(ZRegister.A, ZRegister.E) - result += ZLine.registers(SUB, ZRegister.A, ZRegister.L) + result += ZLine.register(SUB, ZRegister.L) result += ZLine.implied(DAA) result += ZLine.ld8(ZRegister.L, ZRegister.A) result += ZLine.ld8(ZRegister.A, ZRegister.D) - result += ZLine.registers(SBC, ZRegister.A, ZRegister.H) + result += ZLine.register(SBC, ZRegister.H) result += ZLine.implied(DAA) result += ZLine.ld8(ZRegister.H, ZRegister.A) } else { @@ -248,9 +253,6 @@ object ZBuiltIns { result += ZLine.implied(DAA) result += ZLine.ld8(ZRegister.H, ZRegister.A) } - case Some(c) => - hasConst = true - const = CompoundConstant(MathOperator.DecimalMinus, const, c).quickSimplify } } } else { diff --git a/src/test/scala/millfork/test/WordMathSuite.scala b/src/test/scala/millfork/test/WordMathSuite.scala index 7b08adf0..f436b45b 100644 --- a/src/test/scala/millfork/test/WordMathSuite.scala +++ b/src/test/scala/millfork/test/WordMathSuite.scala @@ -44,6 +44,21 @@ class WordMathSuite extends FunSuite with Matchers { """.stripMargin)(_.readWord(0xc000) should equal(240)) } + test("Word subtraction 3") { + EmuCrossPlatformBenchmarkRun(Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(""" + | word output @$c000 + | word a + | void main () { + | a = 640 + | f() + | output = a - f() + | } + | word f() { + | return 400 + | } + """.stripMargin)(_.readWord(0xc000) should equal(240)) + } + test("Byte-to-word addition") { EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(""" | word output @$c000