summaryrefslogtreecommitdiff
path: root/src/stm8/peeph.def
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/stm8/peeph.def
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'src/stm8/peeph.def')
-rw-r--r--src/stm8/peeph.def1592
1 files changed, 1592 insertions, 0 deletions
diff --git a/src/stm8/peeph.def b/src/stm8/peeph.def
new file mode 100644
index 0000000..f204389
--- /dev/null
+++ b/src/stm8/peeph.def
@@ -0,0 +1,1592 @@
+// peeph.def - STM8 peephole rules
+
+replace restart {
+ ld %1, %2
+} by {
+ ; peephole 0 removed dead load into %1 from %2.
+} if notVolatile(%1), notVolatile(%2), notUsed(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ldw a, (%2, sp)
+} by {
+ ; peephole 0a removed dead load into a from %2.
+} if notUsed('n'), notUsed('z')
+
+replace restart {
+ ldw %1, %2
+} by {
+ ; peephole 0w removed dead load into %1 from %2.
+} if notVolatile(%1), notVolatile(%2), notUsed(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ldw %1, (%2, sp)
+} by {
+ ; peephole 0wa removed dead load into %1 from %2.
+} if notUsed(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ clr %1
+} by {
+ ; peephole 1 removed dead clear of %1.
+} if notVolatile(%1), notUsed(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ or a, %1
+} by {
+ ; peephole 2 removed dead or.
+} if notVolatile(%1), notUsed('a'), notUsed('n'), notUsed('z')
+
+replace restart {
+ clrw %1
+} by {
+ ; peephole 3 removed dead clrw of %1.
+} if notVolatile(%1), notUsed(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ld %1, %2
+ ld %2, %1
+} by {
+ ld %1, %2
+ ; peephole 4 removed redundant load from %1 into %2.
+} if notVolatile(%1), notVolatile(%2)
+
+replace restart {
+ ldw %1, %2
+ ldw %2, %1
+} by {
+ ldw %1, %2
+ ; peephole 4w removed redundant load from %1 into %2.
+} if notVolatile(%1), notVolatile(%2)
+
+replace restart {
+ ld (%1, sp), %2
+ ld %2, (%1, sp)
+} by {
+ ld (%1, sp), %2
+ ; peephole 4a removed redundant load from (%1, sp) into %2.
+}
+
+replace restart {
+ ld %1, %2
+ ld %3, %1
+ ld %1, %2
+} by {
+ ld %1, %2
+ ld %3, %1
+ ; peephole 4b removed redundant load from %2 into %1.
+} if notVolatile(%1), notVolatile(%2)
+
+replace restart {
+ ldw (%1, sp), %2
+ ld a, (%2)
+ %3 a
+ ldw %2, (%1, sp)
+} by {
+ ldw (%1, sp), %2
+ ld a, (%2)
+ %3 a
+ ; peephole 4c removed redundant load from (%1, sp) into %2.
+}
+
+replace restart {
+ ld %1, a
+ exg a, %1
+} by {
+ ld %1, a
+ ; peephole 5 removed redundant exg.
+} if notVolatile(%1)
+
+replace restart {
+ ld xl, a
+ srl a
+ srlw x
+} by {
+ srl a
+ ; peephole 5a removed redundant srlw x.
+} if notUsed('x')
+
+replace restart {
+ ld %1, %2
+ ld %3, %1
+ ld %1, %2
+} by {
+ ld %1, %2
+ ld %3, %1
+ ; peephole 5a removed redundant rght shift of .
+} if notVolatile(%1), notVolatile(%2)
+
+replace restart {
+ pop %1
+ push %1
+} by {
+ ; peephole 6 removed dead pop / push pair.
+} if notUsed(%1)
+
+replace restart {
+ popw %1
+ pushw %1
+} by {
+ ; peephole 7 removed dead popw / pushw pair.
+} if notUsed(%1)
+
+replace restart {
+ addw %1, #%2
+ ldw (%1), %3
+} by {
+ ; peephole 8 moved addition of offset into storage instruction
+ ldw (%2, %1), %3
+} if notUsed(%1)
+
+replace restart {
+ addw %1, #%2
+ ld a, %4
+ ld (%1), a
+} by {
+ ; peephole 9 moved addition of offset into storage instruction
+ ld a, %4
+ ld (%2, %1), a
+} if notUsed(%1)
+
+replace restart {
+ addw %1, #%2
+ clr (%1)
+} by {
+ ; peephole 9a moved addition of offset into clear instruction
+ clr (%2, %1)
+} if notUsed(%1)
+
+replace restart {
+ addw %1, #%2
+ ldw %3, %4
+ ldw (%1), %3
+} by {
+ ; peephole 10 moved addition of offset into storage instruction
+ ldw %3, %4
+ ldw (%2, %1), %3
+} if notUsed(%1)
+
+replace restart {
+ incw %1
+ incw %1
+ ldw %3, %4
+ ldw (%1), %3
+} by {
+ ; peephole 10a moved addition of offset into storage instruction
+ ldw %3, %4
+ ldw (0x02, %1), %3
+} if notUsed(%1)
+
+replace restart {
+ ldw (%1, sp), x
+ ldw x, (%2, sp)
+ addw x, (%1, sp)
+} by {
+ ldw (%1, sp), x
+ ; peephole 11 eliminated load using commutativity of addition
+ addw x, (%2, sp)
+}
+
+replace restart {
+ ldw %1, (%2, sp)
+ ld a, (%1)
+ %3 a
+ ldw %1, (%2, sp)
+} by {
+ ldw %1, (%2, sp)
+ ld a, (%1)
+ %3 a
+ ; peephole 12 removed redundant load from (%2, sp) into %1.
+} if notSame(%3 'push' 'pop')
+
+replace restart {
+ ldw (%1, sp), %2
+ ldw %2, (%1, sp)
+} by {
+ ldw (%1, sp), %2
+ ; peephole 13 removed redundant load from (%1, sp) into %2.
+}
+
+replace restart {
+ ldw (%1, sp), x
+ ldw y, (%1, sp)
+} by {
+ ldw (%1, sp), x
+ ldw y, x
+ ; peephole 14 replaced load from (%1, sp) into y by load from x into y.
+}
+
+replace restart {
+ ldw y, x
+ ldw (%1, sp), y
+} by {
+ ldw (%1, sp), x
+ ; peephole 14a loaded (%1, sp) directly from x instead of going through y.
+} if notUsed('y')
+
+replace restart {
+ ldw y, x
+ ld a, %1
+ ld (%2, y), a
+} by {
+ ; peephole 14b used y directly instead of going through x.
+ ld a, %1
+ ld (%2, x), a
+} if notUsed('y')
+
+replace restart {
+ ldw x, y
+ ld a, %1
+ ld (%2, x), a
+} by {
+ ; peephole 14c used y directly instead of going through x.
+ ld a, %1
+ ld (%2, y), a
+} if notUsed('x')
+
+replace restart {
+ ldw (%1, sp), y
+ ldw x, (%1, sp)
+} by {
+ ldw (%1, sp), y
+ ldw x, y
+ ; peephole 15 replaced load from (%1, sp) into x by load from y into x.
+}
+
+replace restart {
+ ld a, %1
+ %2 a
+ ld %1, a
+} by {
+ %2 %1
+ ; peephole 16 applied %2 on %1 instead of a.
+} if notUsed('a'), notSame(%2 'push' 'pop'), notSame(%1 'xl' 'xh' 'yl' 'yh')
+
+replace restart {
+ ld a, %1
+ or a, #0x80
+ ld %1, a
+} by {
+ rlc %1
+ scf
+ rrc %1
+ ; peephole 17 set msb in carry instead of a.
+} if notUsed('a'), notSame(%1 'xl' 'xh' 'yl' 'yh'), notUsed('c'), notVolatile(%1)
+
+replace restart {
+ ld a, %1
+ or a, #0x01
+ ld %1, a
+} by {
+ bset %2, #0
+ ; peephole 18-0 replaced or by bset.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ or a, #0x02
+ ld %1, a
+} by {
+ bset %2, #1
+ ; peephole 18-1 replaced or by bset.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ or a, #0x04
+ ld %1, a
+} by {
+ bset %2, #2
+ ; peephole 18-2 replaced or by bset.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ or a, #0x08
+ ld %1, a
+} by {
+ bset %2, #3
+ ; peephole 18-3 replaced or by bset.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ or a, #0x10
+ ld %1, a
+} by {
+ bset %2, #4
+ ; peephole 18-4 replaced or by bset.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1, %2)
+
+replace restart {
+ ld a, %1
+ or a, #0x20
+ ld %1, a
+} by {
+ bset %2, #5
+ ; peephole 18-5 replaced or by bset.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ or a, #0x40
+ ld %1, a
+} by {
+ bset %2, #6
+ ; peephole 18-6 replaced or by bset.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ or a, #0x80
+ ld %1, a
+} by {
+ bset %2, #7
+ ; peephole 18-7 replaced or by bset.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ and a, #0xfe
+ ld %1, a
+} by {
+ bres %2, #0
+ ; peephole 19-0 replaced and by bres.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ and a, #0xfd
+ ld %1, a
+} by {
+ bres %2, #1
+ ; peephole 19-1 replaced and by bres.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ and a, #0xfb
+ ld %1, a
+} by {
+ bres %2, #2
+ ; peephole 19-2 replaced and by bres.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ and a, #0xf7
+ ld %1, a
+} by {
+ bres %2, #3
+ ; peephole 19-3 replaced and by bres.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ and a, #0xef
+ ld %1, a
+} by {
+ bres %2, #4
+ ; peephole 19-4 replaced and by bres.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ and a, #0xdf
+ ld %1, a
+} by {
+ bres %2, #5
+ ; peephole 19-5 replaced and by bres.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ and a, #0xbf
+ ld %1, a
+} by {
+ bres %2, #6
+ ; peephole 19-6 replaced and by bres.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ and a, #0x7f
+ ld %1, a
+} by {
+ bres %2, #7
+ ; peephole 19-7 replaced and by bres.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ldw %1, #%2
+ ld a, (%1)
+ xor a, #0x01
+ ld (%1), a
+} by {
+ bcpl %2, #0
+ ; peephole 20-0 replaced or by bcpl.
+} if notUsed(%1), notUsed('a')
+
+replace restart {
+ ldw %1, #%2
+ ld a, (%1)
+ xor a, #0x02
+ ld (%1), a
+} by {
+ bcpl %2, #1
+ ; peephole 20-1 replaced or by bcpl.
+} if notUsed(%1), notUsed('a')
+
+replace restart {
+ ldw %1, #%2
+ ld a, (%1)
+ xor a, #0x04
+ ld (%1), a
+} by {
+ bcpl %2, #2
+ ; peephole 20-2 replaced or by bcpl.
+} if notUsed(%1), notUsed('a')
+
+replace restart {
+ ldw %1, #%2
+ ld a, (%1)
+ xor a, #0x08
+ ld (%1), a
+} by {
+ bcpl %2, #3
+ ; peephole 20-3 replaced or by bcpl.
+} if notUsed(%1), notUsed('a')
+
+replace restart {
+ ldw %1, #%2
+ ld a, (%1)
+ xor a, #0x10
+ ld (%1), a
+} by {
+ bcpl %2, #4
+ ; peephole 20-4 replaced or by bcpl.
+} if notUsed(%1), notUsed('a')
+
+replace restart {
+ ldw %1, #%2
+ ld a, (%1)
+ xor a, #0x20
+ ld (%1), a
+} by {
+ bcpl %2, #5
+ ; peephole 20-5 replaced or by bcpl.
+} if notUsed(%1), notUsed('a')
+
+replace restart {
+ ldw %1, #%2
+ ld a, (%1)
+ xor a, #0x40
+ ld (%1), a
+} by {
+ bcpl %2, #6
+ ; peephole 20-6 replaced or by bcpl.
+} if notUsed(%1), notUsed('a')
+
+replace restart {
+ ldw %1, #%2
+ ld a, (%1)
+ xor a, #0x80
+ ld (%1), a
+} by {
+ bcpl %2, #7
+ ; peephole 20-7 replaced or by bcpl.
+} if notUsed(%1), notUsed('a')
+
+replace restart {
+ ld a, %1
+ xor a, #0x01
+ ld %1, a
+} by {
+ bcpl %2, #0
+ ; peephole 21-0 replaced or by bcpl.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ xor a, #0x02
+ ld %1, a
+} by {
+ bcpl %2, #1
+ ; peephole 21-1 replaced or by bcpl.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ xor a, #0x04
+ ld %1, a
+} by {
+ bcpl %2, #2
+ ; peephole 21-2 replaced or by bcpl.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ xor a, #0x08
+ ld %1, a
+} by {
+ bcpl %2, #3
+ ; peephole 21-3 replaced or by bcpl.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ xor a, #0x10
+ ld %1, a
+} by {
+ bcpl %2, #4
+ ; peephole 21-4 replaced or by bcpl.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1, %2)
+
+replace restart {
+ ld a, %1
+ xor a, #0x20
+ ld %1, a
+} by {
+ bcpl %2, #5
+ ; peephole 21-5 replaced or by bcpl.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ xor a, #0x40
+ ld %1, a
+} by {
+ bcpl %2, #6
+ ; peephole 21-6 replaced or by bcpl.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ ld a, %1
+ xor a, #0x80
+ ld %1, a
+} by {
+ bcpl %2, #7
+ ; peephole 21-7 replaced or by bcpl.
+} if notUsed('a'), operandsLiteral(%1), immdInRange(0 65535 '+' 0 %1 %2)
+
+replace restart {
+ clr a
+ and a, %1
+} by {
+ clr a
+ ; peephole 22 removed redundant and.
+} if notVolatile(%1)
+
+replace restart {
+ clr a
+ ; peephole 22a removed redundant clr a.
+ or a, %1
+} by {
+ ld a, %1
+}
+
+replace restart {
+ clr a
+ or a, (%1, %2)
+} by {
+ ; peephole 22b removed redundant clr a.
+ ld a, (%1, %2)
+}
+
+replace restart {
+ tnzw %1
+ jrne %2
+ clrw %1
+} by {
+ tnzw %1
+ jrne %2
+ ; peephole 22c removed redundant clrw %1.
+}
+
+replace restart {
+ ldw %1, (%3, %4)
+ jrne %2
+ clrw %1
+} by {
+ ldw %1, (%3, %4)
+ jrne %2
+ ; peephole 22d removed redundant clrw %1.
+}
+
+replace restart {
+ and a, %1
+ tnz a
+} by {
+ and a, %1
+ ; peephole 23 removed redundant tnz.
+}
+
+replace restart {
+ or a, %1
+ tnz a
+} by {
+ or a, %1
+ ; peephole 24 removed redundant tnz.
+}
+
+replace restart {
+ xor a, %1
+ tnz a
+} by {
+ xor a, %1
+ ; peephole 25 removed redundant tnz.
+}
+
+replace restart {
+ add a, %1
+ tnz a
+} by {
+ add a, %1
+ ; peephole 26 removed redundant tnz.
+}
+
+replace restart {
+ adc a, %1
+ tnz a
+} by {
+ adc a, %1
+ ; peephole 27 removed redundant tnz.
+}
+
+replace restart {
+ sub a, %1
+ tnz a
+} by {
+ sub a, %1
+ ; peephole 28 removed redundant tnz.
+}
+
+replace restart {
+ sbc a, %1
+ tnz a
+} by {
+ sbc a, %1
+ ; peephole 29 removed redundant tnz.
+}
+
+replace restart {
+ ld a, %1
+ tnz a
+} by {
+ ld a, %1
+ ; peephole 30 removed redundant tnz.
+} if notSame(%1 'xl' 'xh' 'yl' 'yh')
+
+replace restart {
+ ldw %1, (%1)
+ tnzw %1
+} by {
+ ldw %1, (%1)
+ ; peephole 30bw removed redundant tnzw.
+}
+
+replace restart {
+ ld a, (%1, %2)
+ tnz a
+} by {
+ ld a, (%1, %2)
+ ; peephole 31 removed redundant tnz.
+}
+
+replace restart {
+ ldw %1, (%2, %3)
+ tnzw %1
+} by {
+ ldw %1, (%2, %3)
+ ; peephole 31w removed redundant tnzw.
+}
+
+replace restart {
+ ld (%1, %2), a
+ tnz (%1, %2)
+} by {
+ ld (%1, %2), a
+ ; peephole 31a removed redundant tnz.
+}
+
+replace restart {
+ ld (%1, %2), a
+ tnz a
+} by {
+ ld (%1, %2), a
+ ; peephole 31b removed redundant tnz.
+}
+
+replace restart {
+ rlc a
+ tnz a
+} by {
+ rlc a
+ ; peephole 32 removed redundant tnz.
+}
+
+replace restart {
+ addw sp, #%1
+ addw sp, #%2
+} by {
+ addw sp, #%9
+ ; peephole 33 combined additions to sp.
+} if immdInRange(0 255 '+' %1 %2 %9)
+
+replace restart {
+ pop a
+ addw sp, #%2
+} by {
+ addw sp, #%9
+ ; peephole 34 merged pop a into addw.
+} if notUsed('a'), immdInRange(0 255 '+' 1 %2 %9)
+
+replace restart {
+ addw sp, #%2
+ pop a
+} by {
+ addw sp, #%9
+ ; peephole 35 merged pop a into addw.
+} if notUsed('a'), immdInRange(0 255 '+' 1 %2 %9)
+
+replace restart {
+ popw x
+ addw sp, #%2
+} by {
+ addw sp, #%9
+ ; peephole 36 merged popw x into addw.
+} if notUsed('x'), immdInRange(0 255 '+' 2 %2 %9)
+
+replace restart {
+ addw sp, #%2
+ popw x
+} by {
+ addw sp, #%9
+ ; peephole 37 merged popw x into addw.
+} if notUsed('x'), immdInRange(0 255 '+' 2 %2 %9)
+
+replace restart {
+ pop a
+ pop a
+} by {
+ popw x
+ ; peephole 38 merged pop a into popw x
+} if notUsed('a'), notUsed('x')
+
+replace restart {
+ pop a
+ popw x
+} by {
+ addw sp, #3
+ ; peephole 39 merged popw x into addw.
+} if notUsed('a'), notUsed('x')
+
+replace restart {
+ popw x
+ pop a
+} by {
+ addw sp, #3
+ ; peephole 40 merged popw x into addw.
+} if notUsed('a'), notUsed('x')
+
+replace restart {
+ popw x
+ popw x
+} by {
+ addw sp, #4
+ ; peephole 41 merged popw x into addw.
+} if notUsed('x')
+
+replace restart {
+ ld a, %1
+ cp a, %2
+ jrc %3
+ ld a, %1
+} by {
+ ld a, %1
+ cp a, %2
+ jrc %3
+ ; peephole 42 removed redundant load of a from %1.
+} if notVolatile(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ld a, %1
+ cp a, %2
+ jrslt %3
+ ld a, %1
+} by {
+ ld a, %1
+ cp a, %2
+ jrslt %3
+ ; peephole 43 removed redundant load of a from %1.
+} if notVolatile(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ld a, %1
+ cp a, %2
+ jrsle %3
+ ld a, %1
+} by {
+ ld a, %1
+ cp a, %2
+ jrsle %3
+ ; peephole 44 removed redundant load of a from %1.
+} if notVolatile(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ld a, %1
+ cp a, %2
+ jrule %3
+ ld a, %1
+} by {
+ ld a, %1
+ cp a, %2
+ jrule %3
+ ; peephole 45 removed redundant load of a from %1.
+} if notVolatile(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ldw x, %1
+ cpw x, %2
+ jrc %3
+ ldw x, %1
+} by {
+ ldw x, %1
+ cpw x, %2
+ jrc %3
+ ; peephole 46 removed redundant load of a from %1.
+} if notVolatile(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ldw x, %1
+ cpw x, %2
+ jrslt %3
+ ldw x, %1
+} by {
+ ldw x, %1
+ cpw x, %2
+ jrslt %3
+ ; peephole 47 removed redundant load of a from %1.
+} if notVolatile(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ldw x, %1
+ cpw x, %2
+ jrsle %3
+ ldw x, %1
+} by {
+ ldw x, %1
+ cpw x, %2
+ jrsle %3
+ ; peephole 48 removed redundant load of a from %1.
+} if notVolatile(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ldw x, %1
+ cpw x, %2
+ jrule %3
+ ldw x, %1
+} by {
+ ldw x, %1
+ cpw x, %2
+ jrule %3
+ ; peephole 49 removed redundant load of a from %1.
+} if notVolatile(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ldw x, %1
+ cpw x, %2
+ jrnc %3
+ ldw x, %1
+} by {
+ ldw x, %1
+ cpw x, %2
+ jrnc %3
+ ; peephole 50 removed redundant load of a from %1.
+} if notVolatile(%1), notUsed('n'), notUsed('z')
+
+replace restart {
+ ldw x, %1
+ jreq %3
+ ldw x, %1
+} by {
+ ldw x, %1
+ jreq %3
+ ; peephole 50eq removed redundant load of x from %1.
+} if notVolatile(%1)
+
+replace restart {
+ ldw x, %1
+ jrne %3
+ ldw x, %1
+} by {
+ ldw x, %1
+ jrne %3
+ ; peephole 50ne removed redundant load of x from %1.
+} if notVolatile(%1)
+
+replace restart {
+ cp a, %1
+ jrne %2
+ ld a, #0x01
+} by {
+ sub a, %1
+ jrne %2
+ inc a
+ ; peephole 51 used inc to get #1 into a.
+} if notUsedFrom(%2 'a')
+
+replace {
+ jp %5
+ ret
+} by {
+ jp %5
+ ; peephole 52 removed unused ret.
+}
+
+replace {
+ jp %5
+ addw sp, %1
+ ret
+} by {
+ jp %5
+ ; peephole 53 removed unused ret.
+}
+
+replace restart {
+ jp %5
+} by {
+ jp %6
+ ; peephole j1 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jpf %5
+} by {
+ jpf %6
+ ; peephole j1a jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jp %1
+%1:
+} by {
+%1:
+ ; peephole j1b removed redundant jump.
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jpf %1
+%1:
+} by {
+%1:
+ ; peephole j1c removed redundant jump.
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jp %1
+%2:
+%1:
+} by {
+%2:
+%1:
+ ; peephole j1d removed redundant jump.
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jpf %1
+%2:
+%1:
+} by {
+%2:
+%1:
+ ; peephole j1e removed redundant jump.
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jra %1
+%1:
+} by {
+%1:
+ ; peephole j1f removed redundant jump.
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jp %1
+ jp %2
+} by {
+ jp %1
+ ; peephole j2a removed unreachable jump to %2.
+} if labelRefCountChange(%2 -1)
+
+replace restart {
+ jra %1
+ jp %2
+} by {
+ jra %1
+ ; peephole j2b removed unreachable jump to %2.
+} if labelRefCountChange(%2 -1)
+
+replace restart {
+ jp %1
+ jra %2
+} by {
+ jp %1
+ ; peephole jc2 removed unreachable jump to %2.
+} if labelRefCountChange(%2 -1)
+
+replace restart {
+ jra %1
+ jra %2
+} by {
+ jra %1
+ ; peephole j2d removed unreachable jump to %2.
+} if labelRefCountChange(%2 -1)
+
+replace restart {
+ jreq %1
+ jreq %2
+} by {
+ jreq %1
+ ; peephole j2d-eq removed unreachable jump to %2.
+} if labelRefCountChange(%2 -1)
+
+replace restart {
+ jrne %1
+ jrne %2
+} by {
+ jrne %1
+ ; peephole j2d-ne removed unreachable jump to %2.
+} if labelRefCountChange(%2 -1)
+
+// Ensure jump-to-jump optimiation of absolute jumps above is done before other jump-related optimizations.
+barrier
+
+replace restart {
+ jp %5
+} by {
+ ret
+ ; peephole j2e replaced jump by return.
+} if labelIsReturnOnly(%5), labelRefCountChange(%5 -1)
+
+replace restart {
+ jpf %5
+} by {
+ retf
+ ; peephole j2f replaced jump by return.
+} if labelIsReturnOnly(%5), labelRefCountChange(%5 -1)
+
+replace restart {
+ ld a, %1
+ srl a
+ btjt %1, #0, %2
+} by {
+ ld a, %1
+ srl a
+ ; peephole j3 jumped by carry bit instead of testing bit explicitly.
+ jrc %2
+}
+
+replace restart {
+ ld a, %1
+ srl a
+ btjf %1, #0, %2
+} by {
+ ld a, %1
+ srl a
+ ; peephole j4 jumped by carry bit instead of testing bit explicitly.
+ jrnc %2
+}
+
+replace restart {
+ jp %5
+} by {
+ jra %5
+ ; peephole j5 changed absolute to relative unconditional jump.
+} if labelInRange(%5)
+
+replace restart {
+ jpf %5
+} by {
+ jra %5
+ ; peephole j5a changed absolute to relative unconditional jump.
+} if labelInRange(%5)
+
+replace restart {
+ jrc %1
+ jra %5
+%1:
+} by {
+ jrnc %5
+ ; peephole j6 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jreq %1
+ jra %5
+%1:
+} by {
+ jrne %5
+ ; peephole j7 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jreq %1
+ jrne %2
+%1:
+} by {
+ jrne %2
+ ; peephole j7-eq-ne replaced jreq-jrne by jrne
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrne %1
+ jreq %2
+%1:
+} by {
+ jreq %2
+ ; peephole j7-ne-eq replaced jrne-jreq by jreq
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrmi %1
+ jra %5
+%1:
+} by {
+ jrpl %5
+ ; peephole j8 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrnc %1
+ jra %5
+%1:
+} by {
+ jrc %5
+ ; peephole j9 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrne %1
+ jra %5
+%1:
+} by {
+ jreq %5
+ ; peephole j10 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrpl %1
+ jra %5
+%1:
+} by {
+ jrmi %5
+ ; peephole j11 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrsge %1
+ jra %5
+%1:
+} by {
+ jrslt %5
+ ; peephole j12 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrsgt %1
+ jra %5
+%1:
+} by {
+ jrsle %5
+ ; peephole j13 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrsle %1
+ jra %5
+%1:
+} by {
+ jrsgt %5
+ ; peephole j14 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrslt %1
+ jra %5
+%1:
+} by {
+ jrsge %5
+ ; peephole j15 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrugt %1
+ jra %5
+%1:
+} by {
+ jrule %5
+ ; peephole j16 removed jra by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrule %1
+ jra %5
+%1:
+} by {
+ jrugt %5
+ ; peephole j17 removed jp by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+ jrc %5
+} by {
+ jrc %6
+ ; peephole j18 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jreq %5
+} by {
+ jreq %6
+ ; peephole j19 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrmi %5
+} by {
+ jrmi %6
+ ; peephole j20 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrnc %5
+} by {
+ jrnc %6
+ ; peephole j21 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrne %5
+} by {
+ jrne %6
+ ; peephole j22 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrpl %5
+} by {
+ jrpl %6
+ ; peephole j23 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrge %5
+} by {
+ jrge %6
+ ; peephole j24 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrgt %5
+} by {
+ jrgt %6
+ ; peephole j25 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrle %5
+} by {
+ jrle %6
+ ; peephole j26 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrlt %5
+} by {
+ jrlt %6
+ ; peephole j27 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrugt %5
+} by {
+ jrugt %6
+ ; peephole j28 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ jrule %5
+} by {
+ jrule %6
+ ; peephole j29 jumped to %6 directly instead of via %5.
+} if labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
+
+replace restart {
+ call %5
+} by {
+ callr %5
+ ; peephole j30 changed absolute to relative call.
+} if labelInRange(%5)
+
+// Should be one of the last ones. Opens the code to further peephole optimization.
+replace restart {
+%1:
+} by {
+ ; peephole j30 removed unused label %1.
+} if labelRefCount(%1 0)
+
+
+replace restart {
+ ldw x, (%1, sp)
+ cpw x, #%2
+ jrsge %3
+ ldw x, #%2
+} by {
+ ldw x, #%2
+ cpw x, (%1, sp)
+ jrslt %3
+ ; peephole j31 removed load by inverting jump condition.
+} if notUsedFrom(%3 'x')
+
+replace restart {
+ ldw x, (%1, sp)
+ cpw x, #%2
+ jrsle %3
+ ldw x, #%2
+} by {
+ ldw x, #%2
+ cpw x, (%1, sp)
+ jrsgt %3
+ ; peephole j32 removed load by inverting jump condition.
+} if notUsedFrom(%3 'x')
+
+// Barrier, since notUsed() is better at dealing with ret than with jp to unknown location.
+barrier
+
+replace restart {
+ call %1
+ ret
+} by {
+ jp %1
+ ; peephole j31 replaced call at end of function by jump (tail call optimization).
+}
+
+replace restart {
+ callf %1
+ retf
+} by {
+ jpf %1
+ ; peephole j31a replaced call at end of function by jump (tail call optimization).
+}
+
+replace restart {
+ ld xl, a
+ ld a, xh
+} by {
+ rlwa x
+ ; peephole r1 used rlwa.
+} if notUsed('xh')
+
+replace restart {
+ ld yl, a
+ ld a, yh
+} by {
+ rlwa y
+ ; peephole r2 used rlwa.
+} if notUsed('yh')
+
+replace restart {
+ ld xh, a
+ ld a, xl
+} by {
+ rrwa x
+ ; peephole r3 used rrwa.
+} if notUsed('xl')
+
+replace restart {
+ ld yh, a
+ ld a, yl
+} by {
+ rrwa y
+ ; peephole r4 used rrwa.
+} if notUsed('yl')
+
+// Barrier, so nothing else ever sees the jump-on-false optimization.
+barrier
+
+// The STM8 has a relative jump-on-false instruction, which never jumps to its target. This can be used to optimize jumps over 1-byte instructions as we can use the instruction we jump over as the offset for the jump.
+replace {
+ jra %5
+%2:
+ clr a
+%5:
+} by {
+ .byte 0x21
+ ; peephole jrf1 used jump-on-false opcode to shorten jump over 1-byte instruction.
+ %2:
+ clr a
+ %5:
+} if labelRefCountChange(%5 -1)
+
+replace {
+ jra %5
+%2:
+ clrw x
+%5:
+} by {
+ .byte 0x21
+ ; peephole jrf2 used jump-on-false opcode to shorten jump over 1-byte instruction.
+ %2:
+ clrw x
+ %5:
+} if labelRefCountChange(%5 -1)
+
+replace {
+ jra %5
+%2:
+ ld a, xl
+%5:
+} by {
+ .byte 0x21
+ ; peephole jrf3 used jump-on-false opcode to shorten jump over 1-byte instruction.
+ %2:
+ ld a, xl
+ %5:
+} if labelRefCountChange(%5 -1)
+
+replace {
+ jrugt %1
+ clr a
+ jra %2
+%1:
+ ld a, #0x01
+%2:
+} by {
+ jrule %1
+ ld a, #0x01
+ .byte 0x21
+ ; peephole jrf4 used jump-on-false opcode to shorten jump over 1-byte instruction.
+%1:
+ clr a
+%2:
+} if labelRefCount(%1 1), labelRefCountChange(%2 -1)
+
+replace {
+ jra %5
+%2:
+ ldw x, y
+%5:
+} by {
+ .byte 0x21
+ ; peephole jrf5 used jump-on-false opcode to shorten jump over 1-byte instruction.
+ %2:
+ ldw x, y
+ %5:
+} if labelRefCountChange(%5 -1)
+
+// We don't have an explicit instruction to jump over 2 bytes. But when flags are not used, we can use cp a, longmen instead.
+
+// Jumping over ld a, #0xmm bcp does a read from a memory location at 0xa6mm - which for all current STM8 is in Flash or unused. If a future STM8 places memory-mapped I/O there, we're in trouble.
+replace {
+ jra %5
+%1:
+ ld a, #%2
+%5:
+} by {
+ .byte 0xc5
+ ; peephole jrf6 used bcp opcode to jump over 2-byte instruction.
+%1:
+ ld a, #%2
+%5:
+} if notUsed('n'), notUsed('z'), labelRefCountChange(%5 -1)
+
+// Jumping over clr (mm, sp) bcp does a read from a memory location at 0x0fmm - which for all current STM8 is in RAM or unused. If a future STM8 places memory-mapped I/O there, we're in trouble.
+replace {
+ jra %5
+%1:
+ clr (%2, sp)
+%5:
+} by {
+ .byte 0xc5
+ ; peephole jrf7 used bcp opcode to jump over 2-byte instruction.
+%1:
+ clr (%2, sp)
+%5:
+} if notUsed('n'), notUsed('z'), labelRefCountChange(%5 -1)
+
+// Jumping over clrw x; incwx bcp does a read from a memory location at 0x5f5c - which for all current STM8 is unused. If a future STM8 places memory-mapped I/O there, we're in trouble.
+replace {
+ jra %5
+%1:
+ clrw x
+ incw x
+%5:
+} by {
+ .byte 0xc5
+ ; peephole jrf8 used bcp opcode to jump over 2-byte instruction sequence.
+%1:
+ clrw x
+ incw x
+%5:
+} if notUsed('n'), notUsed('z'), labelRefCountChange(%5 -1)
+
+// Jumping over ldw x, (mm, sp) bcp does a read from a memory location at 0x1emm - which for all current STM8 is unused. If a future STM8 places memory-mapped I/O there, we're in trouble.
+replace {
+ jra %5
+%1:
+ ldw x, (%2, sp)
+%5:
+} by {
+ .byte 0xc5
+ ; peephole jrf9 used bcp opcode to jump over 2-byte instruction.
+%1:
+ ldw x, (%2, sp)
+%5:
+} if notUsed('n'), notUsed('z'), labelRefCountChange(%5 -1)
+
+// We don't have an explicit instruction to jump over 3 bytes. But when flags and a are not used, we can use ldf a, extmem instead.
+
+// Jumping over ldw x, #mmmm ldf does a read from a memory location at 0xaemmmm - which for all current STM8 is unused. If a future STM8 places memory-mapped I/O there, we're in trouble.
+replace {
+ jra %5
+%1:
+ ldw x, #%2
+%5:
+} by {
+ .byte 0xbc
+ ; peephole jrf10 used ldf opcode to jump over 3-byte instruction.
+%1:
+ ldw x, #%2
+%5:
+} if notUsed('a'), notUsed('n'), notUsed('z'), labelRefCountChange(%5 -1)
+
+// Jumping over clrw x; ldw (mm, sp), x ldf does a read from a memory location at 0x5f1fmm - which for all current STM8 is unused. If a future STM8 places memory-mapped I/O there, we're in trouble.
+replace {
+ jra %5
+%1:
+ clrw x
+ ldw (%2, sp), x
+%5:
+} by {
+ .byte 0xbc
+ ; peephole jrf11 used ldf opcode to jump over 3-byte instruction.
+%1:
+ clrw x
+ ldw (%2, sp), x
+%5:
+} if notUsed('a'), notUsed('n'), notUsed('z'), labelRefCountChange(%5 -1)
+