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:
parent
fccbf7df7d
commit
70256e9d46
@ -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)
|
||||
|
@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user