С помощью arm64 литерал для соседнего адреса можно загрузить в регистр с помощью инструкции adr . Согласно Справочному руководству по архитектуре ARM-V8 инструкция adr :
ADR <Xd>, <label> Address of label at a PC-relative offset
может ссылаться на метки в пределах +/- 1 МБ. Существует версия страницы с установленным битом 31 adrp для создания больших смещений.
Я не понимаю, почему ни gcc 8.2 , ни clang 7.0 для ARM64 не используют adr вместо adrp и добавить пару для соседних переменных. Уровни оптимизации не меняют этого.
int write(int fd, const void *buf, int count);
void xyz(void)
{
write(2, "abc", 4);
}
xyz(): // @xyz()
adrp x1, .L.str
add x1, x1, :lo12:.L.str
orr w0, wzr, #0x2
orr w2, wzr, #0x4
b write(int, void const*, int)
.L.str:
.asciz "abc"
Неужели они не считают, что этот строковый литерал находится в пределах +/- 1 МБ? Есть ли атрибут компилятора / ключ, чтобы сказать им это?