diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/stm8/peeph.def | |
| download | sdcc-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.def | 1592 |
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) + |
