What causes GCC 7.2.1 on ARM to use a load from memory (lr
) for certain constants, and an immediate (mov
) in some other cases? Concretely, I'm seeing the following:
GCC 7.2.1 for ARM compiles this:
extern void abc(int);
int test() { abc(1199); return 0; }
…into that:
test():
push {r4, lr}
ldr r0, .L4 // ??!
bl abc(int)
mov r0, #0
pop {r4, lr}
bx lr
.L4:
.word 1199
and this:
extern void abc(int);
int test() { abc(1200); return 0; }
…into that:
test():
push {r4, lr}
mov r0, #1200 // OK
bl abc(int)
mov r0, #0
pop {r4, lr}
bx lr
At first I expected 1200 to be some sort of unique cutoff, but there are other cut-offs like this at 1024 (1024 yields a mov r0, #1024
, whereas 1025 uses ldr
) and at other values.
Why would GCC use a load from memory to fetch a constant, rather than using an immediate?
GCC stands for “GNU Compiler Collection”. GCC is an integrated distribution of compilers for several major programming languages. These languages currently include C, C++, Objective-C, Objective-C++, Fortran, Ada, D, and Go.
When you invoke GCC, it normally does preprocessing, compilation, assembly and linking. The "overall options" allow you to stop this process at an intermediate stage. For example, the -c option says not to run the linker. Then the output consists of object files output by the assembler.
gcc -Wall enables all compiler's warning messages. This option should always be used, in order to generate better code.
This has to do with the way that constant operands are encoded in the ARM instruction set. They are encoded as an (unsigned) 8-bit constant combined with a 4 bit rotate field -- the 8 bit value will be rotated by 2 times the value in that 4 bit field. So any value that fits in that form can be used as a constant argument.
The constant 1200
is 10010110000 in binary, so it can be encoded as the 8-bit constant 01001011 combined with a rotate of 4.
The constant 1199
is 10010101111 in binary, so there's no way to fit it in an ARM constant operand.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With