The Thumb instruction set is a compressed 16-bit instruction set that is supported by the ARM Cortex-M3 processor alongside the standard 32-bit ARM instruction set. The key benefit of Thumb is that it provides improved code density and reduced memory footprint compared to the 32-bit ARM code. This makes it well-suited for embedded applications where memory size is a critical constraint.
Overview of Thumb Instruction Set
The Thumb instruction set was introduced in ARMv4T architecture in the late 1990s. It uses 16-bit instructions instead of 32-bit instructions used in the ARM code. This allows Thumb code to be denser than ARM code, requiring fewer bytes to store the same instructions. The ARM Cortex-M3 implements the Thumb-2 instruction set, which is an enhanced variant of original Thumb with additional 16-bit and 32-bit instructions.
The key features of Thumb-2 instruction set are:
- Uses a mix of 16-bit and 32-bit instructions
- Provides higher code density than ARM code
- Supports full ARM instruction set with some restrictions
- Uses 16-bit instructions for most common operations
- Uses 32-bit instructions for more complex operations
- Provides near ARM performance with code size saving
In the ARM Cortex-M3, the processor always executes Thumb-2 instructions regardless of the setting. The mixture of 16-bit and 32-bit instructions allows Thumb-2 to achieve better performance without sacrificing code density.
Code Density Benefits
The key benefit of Thumb instruction set is improved code density and smaller code size. Here are some examples:
- A simple ‘add r0, r1, r2’ instruction requires 4 bytes in ARM but just 2 bytes in Thumb.
- For a function with 100 ARM instructions, Thumb equivalent may require only 60-70 instructions.
- Real-world benchmarks show >30% code size reduction with Thumb code.
- This directly results in lower RAM usage and lowers costs for embedded devices.
Thumb code density benefits stem from the 16-bit format of Thumb instructions. This results in smaller opcode size, fewer bytes required for register encoding and more. Modern compilers are optimized to generate efficient Thumb-2 code that maximizes the 16-bit instructions usage.
The compressed 16-bit Thumb format increases code density but also introduces some performance tradeoffs:
- Only limited subset of ARM instructions can be represented in 16-bit format
- Thumb lacks powerful ARM instructions like multiplier, barrel shifter etc
- Thumb has fewer registers and narrower memory addressing modes
- Requires more instructions to do same task as ARM code
- Indirectly affects performance due to increased instruction count
However, the Thumb-2 instruction set tries to reduce these performance impacts by allowing mix of 16-bit and 32-bit instructions. The 32-bit instructions are used selectively for complex operations. Still, pure Thumb-2 code typically has 10-15% lower performance than ARM code. This tradeoff is acceptable for embedded systems where code size is at a premium.
Intermixing ARM and Thumb Code
The ARM and Thumb instruction sets can be intermixed freely by using the BX and BLX instructions. Some examples:
- BX instruction can switch between ARM and Thumb state
- BLX can call Thumb function from ARM and vice versa
- This allows optimized mix of ARM and Thumb code
- Performance-critical code can use ARM instructions
- Thumb code maximizes code density for bulk of code
The intermixing allows developers to create libraries with both Thumb and ARM functions. However, ARM Cortex-M3 always executes only Thumb-2 instructions. The intermixing flexibility is useful when reusing code written for older ARM processors supporting both ARM and Thumb instruction sets.
Using Thumb Code in Cortex-M3
The ARM Cortex-M3 processor always executes Thumb-2 instructions. Developers don’t need to do anything special to start using Thumb-2 code:
- Cortex-M3 implementations only support Thumb mode
- All code compiled for Cortex-M3 targets Thumb-2 by default
- Toolchain automatically produces Thumb-2 instructions
- For assembly code, .thumb directive selects Thumb mode
- No mode switching required when calling functions
Hence, Thumb usage is transparent to the developers. Write normal code in C/C++ or assembly, and the compiler and assembler will generate Thumb-2 instructions automatically. Linkers combine Thumb and ARM libraries seamlessly.
In summary, key points about Thumb instruction set in ARM Cortex-M3 are:
- Thumb is a 16-bit compressed instruction set supported in Cortex-M3
- Provides higher code density and reduced memory footprint
- Thumb-2 improves performance through mix of 16-bit and 32-bit instructions
- Thumb usage is transparent – enabled automatically by compiler/assembler
- Ideal for embedded systems where code size matters
So for embedded projects using ARM Cortex-M3, Thumb-2 instruction set can help reduce memory requirements and lower costs without significant performance impacts. The code density benefits make it a default choice for Cortex-M3 programming.