When APP_ABI
includes armeabi-v7a
, Android's build system will include -mthumb
as a compile option.
ARMv7-a is a 32-bit processor family. Why does Android use -mthumb
rather than -marm
?
Must native components compiled with the NDK use -mthumb
? Or is it OK to use -marm
?
If -marm
is OK, do any interworking options need to be present?
Android uses -mthumb
because it produces more compact code. The bitness of the processor has nothing to do with it.
In the normal ARM instruction set, each instruction is 32 bit, and each instruction is quite expressive (there's different instructions to do a lot of different things). Unfortunatey this also means that the code can be a bit large, since every single instruction takes 4 bytes.
The thumb instruction set was introduced to work around this issue - here each instruction is only 16 bits long, thus you can fit twice as many instructions in the same space, but since the instructions are shorter, there's not as many different instructions. Each instruction still operates on 32 bit registers and otherwise behaves exactly like the ARM instructions, so it's just a different, more compact way to write (mostly) a subset of the ARM instructions. Due to the limited number of instructions, most things tend to need a bit more instructions than in ARM mode. So depending on what the code actually does, the actual reduction in code size isn't exactly 50%. Also, since there may be more instructions than before, it may actually run slower than before. (But since it's smaller, it uses less instruction cache, which might on the other hand benefit performance.)
In practice, Thumb code tended to be slower than ARM code, but more compact, so for code where size mattered more than speed, you'd use Thumb.
Since Thumb2 (which is available in ARMv7), there's a bit more expressiveness in the Thumb instruction set, so the performance difference is smaller - this is why it's enabled by default in Android - in almost all cases it reduces the code size without significantly affecting the performance. If you've got some really performance critical code, you might want to benchmark to see if it hurts or helps for you. (For building with ndk-build and Android.mk, check the LOCAL_ARM_MODE variable.)
If you build code manually, you can choose whether you add -mthumb
or -marm
, and AFAIK you don't need any extra interworking options regardless of which one of them you choose.