为arm64生成代码时,为什么gcc + clang使用adrp + add而不是adr来处理附近的变量?

问题描述 投票:1回答:1

使用arm64,可以使用adr指令将附近地址的文字加载到寄存器中。根据ARM-V8体系结构参考手册,adr指令:

ADR <Xd>, <label>   Address of label at a PC-relative offset

可以引用+/- 1MB内的标签。有一个带有bit-31 set的页面版本adrp,用于构建更大的偏移量。

我不明白为什么没有用于ARM64的gcc 8.2clang 7.0使用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"

他们不能推断这个字符串文字在+/- 1MB之内吗?是否有编译器属性/开关告诉他们这个?

gcc clang arm64
1个回答
1
投票

GCC将使用-mcmodel=tiny生成此类代码:

    .global xyz
    .type   xyz, %function
xyz:
.LFB0:
    .cfi_startproc
    mov w2, 4
    adr x1, .LC0
    mov w0, 2
    b   write
    .cfi_endproc
.LFE0:
    .size   xyz, .-xyz
    .section    .rodata.str1.8,"aMS",@progbits,1
    .align  3
.LC0:
    .string "abc"
© www.soinside.com 2019 - 2024. All rights reserved.