~x, and where it goes when it disappears
mvn Rd, Rs writes the bitwise complement of Rs into Rd. It is the direct translation of C's ~:
0 mvn r0, r0
2 bx lr
neg is a different instruction for a different operator, and the two are easy to mix up in a listing because they sit next to each other so often:
0 neg r0, r0
2 bx lr
That one is -x, an arithmetic negation. The values differ by exactly one: ~x is -x - 1. Reading the wrong one costs you a mismatch of a single instruction that is very hard to spot.
You might expect the compiler to notice that ~x + 1 is the same value as -x and emit the shorter form. It does not:
0 mvn r0, r0
2 add r0, #1
4 bx lr
Two instructions where neg would have done. gcc 2.9's simplifier is strong on pure boolean algebra and much weaker on identities that cross between bitwise and arithmetic operators, so what you write here is what you get.
The other half of reading mvn is knowing when it will not be there. A complement of a register on either side of an & gets absorbed by bic, and a complement of a literal gets absorbed by complementing the literal. Neither orr nor eor has a complementing form, so a ~ that feeds one of those has nowhere to hide and you see a real mvn in the listing. The instruction's presence tells you what the complement was combined with.
Your task
Write func_080e0554 to reproduce the target assembly.