1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-01-16 16:31:04 +00:00

Fix evaluation of boolean expressions on all targets (#56)

This commit is contained in:
Karol Stasiak 2020-08-14 22:27:23 +02:00
parent fccbf7df7d
commit 70256e9d46
4 changed files with 55 additions and 4 deletions

View File

@ -1840,7 +1840,7 @@ object AlwaysGoodOptimizations {
val ifSet = Elidable & HasOpcode(LDA) & HasImmediate(if (zeroIfSet) 0 else nonZero)
val ifClear = Elidable & HasOpcode(LDA) & HasImmediate(if (zeroIfSet) nonZero else 0)
val jump = Elidable & HasOpcodeIn(Set(JMP, if (firstSet) BCS else BCC, if (zeroIfSet) BEQ else BNE)) & MatchParameter(1)
val elseLabel = (Elidable & HasOpcode(LABEL) & MatchParameter(0)).capture(10)
val elseLabel = (Elidable & HasOpcode(LABEL) & MatchParameter(0) & IsNotALabelUsedManyTimes).capture(10)
val afterLabel = Elidable & HasOpcode(LABEL) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.N, State.V, State.Z) & IsNotALabelUsedManyTimes
val store = Elidable & (Not(ReadsC) & Linear | HasOpcodeIn(RTS, JSR, RTI, RTL, BSR))
val secondReturn = (Elidable & (HasOpcodeIn(RTS, RTI) | NoopDiscardsFlags)).*.capture(6)

View File

@ -662,8 +662,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
MLine.shortBranch(BRA, label2),
MLine.label(label),
MLine.immediate(LDB, 0),
MLine.label(label2),
MLine.inherentB(ROL)
MLine.label(label2)
)
}

View File

@ -53,7 +53,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
// TODO: helper functions to convert flags to booleans, to make code smaller
}
}
if (ctx.options.flag(CompilationFlag.OptimizeForSpeed)) {
if (ctx.options.flag(CompilationFlag.OptimizeForSpeed) || !hasOnlyOneJump) {
val skip = ctx.env.nextLabel("bo")
condition ++ List(
ZLine.ldImm8(ZRegister.A, 1),

View File

@ -288,4 +288,56 @@ class BooleanSuite extends FunSuite with Matchers {
|}
|""".stripMargin)
}
test("Complex boolean expressions") {
for ((x,y,w,h) <- Seq(
(2,3,2,2),
(2,2,1,1),
(0,0,0,0),
(0,5,0,0),
(5,0,0,0),
(0,0,5,0),
(0,0,0,5),
)) {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(
s"""
|const byte MAX_SIZE = 4
|
|macro void is_room_within_bounds(byte x, byte y, byte width, byte height, bool output) {
| output = x < MAX_SIZE && y < MAX_SIZE && x + width < MAX_SIZE && y + height < MAX_SIZE
|}
|
|byte temp
|
|bool in_bounds
|bool output0 @0xc000
|
|void main() {
| byte x
| byte y
| byte width
| byte height
|
| temp=$x
| x = temp
| temp=$y
| y = temp
| temp=$w
| width = temp
| temp=$h
| height = temp
|
| is_room_within_bounds(x, y, width, height, in_bounds)
|
| output0 = in_bounds
|
|}
|""".stripMargin) { m =>
val MAX_SIZE = 4
val bool = x < MAX_SIZE && y < MAX_SIZE && x + w < MAX_SIZE && y + h < MAX_SIZE
m.readByte(0xc000) should equal(if (bool) 1 else 0)
}
}
}
}