summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRangi <remy.oukaour+rangi42@gmail.com>2021-07-31 21:12:34 -0400
committerRangi <remy.oukaour+rangi42@gmail.com>2021-07-31 21:17:18 -0400
commit9d2e30aa7060240475a509c566ec20b9acccdffa (patch)
tree1d215d917d03596237891b94fb876b1c138d19e8
parentf2c5bbdc375cdbb759d4730e1d763fbf9ed12572 (diff)
XOR swap
-rw-r--r--Optimizing-assembly-code.md44
1 files changed, 44 insertions, 0 deletions
diff --git a/Optimizing-assembly-code.md b/Optimizing-assembly-code.md
index 017085e..5ed248a 100644
--- a/Optimizing-assembly-code.md
+++ b/Optimizing-assembly-code.md
@@ -26,6 +26,7 @@ WikiTI's advice fully applies here:
- [Set `a` to some constant minus `a`](#set-a-to-some-constant-minus-a)
- [Set `a` to one constant or another depending on the carry flag](#set-a-to-one-constant-or-another-depending-on-the-carry-flag)
- [Increment or decrement `a` when the carry flag is set](#increment-or-decrement-a-when-the-carry-flag-is-set)
+ - [Toggle `a` between two different constants](#toggle-a-between-two-different-constants)
- [Divide `a` by 8 (shift `a` right 3 bits)](#divide-a-by-8-shift-a-right-3-bits)
- [Divide `a` by 16 (shift `a` right 4 bits)](#divide-a-by-16-shift-a-right-4-bits)
- [Set `a` to some value plus or minus carry](#set-a-to-some-value-plus-or-minus-carry)
@@ -555,6 +556,49 @@ Instead, do this:
```
+### Toggle `a` between two different constants
+
+Don't do this:
+
+```asm
+ ; 12 bytes, 9 or 10 cycles
+ cp FOO
+ jr z, .foo_to_bar
+ jr .bar_to_foo
+.foo_to_bar
+ ld a, BAR
+ jr .done
+.bar_to_foo
+ ld a, FOO
+.done
+ ...
+```
+
+And don't do this:
+
+```asm
+ ; 10 bytes, 7 or 9 cycles
+ cp FOO
+ jr z, .foo_to_bar ; nor jr nz, .bar_to_foo
+ ld a, FOO ; nor ld a, BAR
+ jr .done
+.foo_to_bar ; nor .bar_to_foo
+ ld a, BAR ; nor ld a, FOO
+.done
+ ...
+```
+
+(That would be applying the "[Conditional fallthrough](#conditional-fallthrough)" optimization to the first way.)
+
+Instead, do this:
+
+```asm
+ xor FOO ^ BAR ; 2 bytes, 2 cycles
+```
+
+(This works for the same reason as the [XOR swap algorithm](https://en.wikipedia.org/wiki/XOR_swap_algorithm) for swapping the values of two variables.)
+
+
### Divide `a` by 8 (shift `a` right 3 bits)
Don't do this: