We have observed that for Arm targets (e.g. cortex-r5), using the “.arm” directive in hand-coded assembly does not have the same behavior in LLVM as for other vendors, like gcc. It will ensure that succeeding instructions are correctly interpreted as Arm-mode instructions, but it won’t enforce a 4byte alignment on instructions (or sections). In order to do this, we have to explicitly align sections using an alignment directive.
Is there a reason for this difference in behavior? Or is it a defect?
MCU Compiler Team
Texas Instruments, Inc.
I’d say it’s a defect.
Probably best to raise a bug report for it at Issues · llvm/llvm-project · GitHub.
Thank you! What’s interesting is that other downstream Arm compilers and projects that rely on LLVM, like Arm’s armclang, document it as a behavior difference but not necessarily a defect. E.g.:
The integrated assembler sets a minimum alignment of 4 bytes for a
.text section. However, if you define your own sections with the integrated assembler, then you must include the
.balign directive to set the correct alignment. For a section containing T32 instructions, set the alignment to 2 bytes. For a section containing A32 instructions, set the alignment to 4 bytes.
Switching from Thumb to ARM mode implicitly forces 4-byte alignment with GAS but doesn’t with LLVM. You may need to use an explicit
.p2align directive in such cases.
Upstream defect filed: https://github.com/llvm/llvm-project/issues/53386
Note that I also confirmed with Arm Ltd. that there is no Arm-determined specification governing the “.arm” directive alignment behavior. Further, the documentation for the .arm and .thumb directives in the GNU assembler makes no mention of alignment.
However, because the GNU assembler (GAS) implements the 4-byte alignment behavior, the LLVM integrated Arm assembler should match that behavior. This was recommended by Arm in a (now-abandoned) code review: ⚙ D110580 [THUMB2] default .text alignment to 2B