Что заставляет GCC 7.2.1 на ARM использовать нагрузку из памяти (lr
) для определенных констант и немедленную (mov
) в некоторых других случаях? Конкретно, я вижу следующее:
GCC 7.2.1 для ARM компилирует это:
extern void abc(int);
int test() { abc(1199); return 0; }
... в это:
test():
push {r4, lr}
ldr r0, .L4 // ??!
bl abc(int)
mov r0, #0
pop {r4, lr}
bx lr
.L4:
.word 1199
и это:
extern void abc(int);
int test() { abc(1200); return 0; }
... в это:
test():
push {r4, lr}
mov r0, #1200 // OK
bl abc(int)
mov r0, #0
pop {r4, lr}
bx lr
Сначала я ожидал, что 1200 будет своего рода уникальным обрезанием, но есть и другие срезы, подобные этому при 1024 (1024 дает a mov r0, #1024
, тогда как 1025 использует ldr
) и при других значениях.
Почему GCC использует нагрузку из памяти для извлечения константы, а не с помощью немедленного?