gpt4 book ai didi

assembly - 强制 arm64 gcc 使用指令构造 double float ,无 .rodata 部分

转载 作者:行者123 更新时间:2023-12-05 05:30:42 34 4
gpt4 key购买 nike

ARM64 指令是 32 位长,所以如果要使用 64 位浮点常数,通常使用数据段来存储文字。

但是,我发现在某些情况下,AArch64 gcc 编译器使用多条指令从立即数构造 double float ,而不是将常量存储在数据部分中。有没有办法强制执行此功能?

我不想在我的嵌入式代码中引入数据部分。

000000000044fda0 <foo>: 1.1, 2.2
44fda0: d2800000 mov x0, #0x0 // #0
44fda4: b0000002 adrp x2, 450000 <pmalloc+0x78> // cal data address
44fda8: b0000001 adrp x1, 450000 <pmalloc+0x78>
44fdac: fd472c41 ldr d1, [x2, #3672] // load the double
44fdb0: fd473020 ldr d0, [x1, #3680]
44fdb4: 6d000001 stp d1, d0, [x0]
...
44fdbc: d65f03c0 ret


000000000044fda0 <foo>: 5.5, 6.6
44fda0: d2800000 mov x0, #0x0 // #0
44fda4: b203e7e1 mov x1, #0x6666666666666666 // #7378697629483820646
44fda8: 1e62d001 fmov d1, #5.500000000000000000e+00
44fdac: f2e80341 movk x1, #0x401a, lsl #48
44fdb0: 9e670020 fmov d0, x1
44fdb4: 6d000001 stp d1, d0, [x0]
...
44fdbc: d65f03c0 ret

我希望 gcc 不要像我展示的第二个 foo 函数那样使用任何数据部分来构造双浮点文字或整型文字。

我使用的是以下 gcc 编译器

$ aarch64-linux-gnu-gcc --version
aarch64-linux-gnu-gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.

我的 C 代码是 float.c

void foo(void* base_ptr)
{
double buffer[2]= {5.5, 6.6};
double* q = (double*)base_ptr;
*q++ = buffer[0];
*q = buffer[1];
return ;
}

int main() {
double f[2];
foo(f);
}

对于{5.5, 6.6},编译器将通过移位和位或指令构造文字。但是,当您将 {5.5, 6.6} 更改为 {1.1, 2.2} 时,编译器会将常量文字存储在数据部分并使用 adrp指令加载地址并获取它们。

{5.5, 6.6}

$ aarch64-linux-gnu-gcc float.c
$ aarch64-linux-gnu-objdump -d a.out | grep -A15 '<foo>:'
00000000000007b4 <foo>:
7b4: a9bc7bfd stp x29, x30, [sp, #-64]!
7b8: 910003fd mov x29, sp
7bc: f9000fa0 str x0, [x29, #24]
7c0: 90000080 adrp x0, 10000 <__FRAME_END__+0xf6d8>
7c4: f947f000 ldr x0, [x0, #4064]
7c8: f9400001 ldr x1, [x0]
7cc: f9001fa1 str x1, [x29, #56]
7d0: d2800001 mov x1, #0x0 // #0
7d4: 1e62d000 fmov d0, #5.500000000000000000e+00
7d8: fd0017a0 str d0, [x29, #40]
7dc: b203e7e0 mov x0, #0x6666666666666666 // #7378697629483820646
7e0: f2e80340 movk x0, #0x401a, lsl #48
7e4: 9e670000 fmov d0, x0
7e8: fd001ba0 str d0, [x29, #48]
7ec: f9400fa0 ldr x0, [x29, #24]

{1.1, 2.2}

$ aarch64-linux-gnu-objdump -d a.out  | grep -A15 '<foo>:'
00000000000007b4 <foo>:
7b4: a9bc7bfd stp x29, x30, [sp, #-64]!
7b8: 910003fd mov x29, sp
7bc: f9000fa0 str x0, [x29, #24]
7c0: 90000080 adrp x0, 10000 <__FRAME_END__+0xf6b8>
7c4: f947f000 ldr x0, [x0, #4064]
7c8: f9400001 ldr x1, [x0]
7cc: f9001fa1 str x1, [x29, #56]
7d0: d2800001 mov x1, #0x0 // #0
7d4: 90000000 adrp x0, 0 <_init-0x620>
7d8: 9124e000 add x0, x0, #0x938
7dc: fd400000 ldr d0, [x0]
7e0: fd0017a0 str d0, [x29, #40]
7e4: 90000000 adrp x0, 0 <_init-0x620>
7e8: 91250000 add x0, x0, #0x940
7ec: fd400000 ldr d0, [x0]

这是一个非常奇怪的功能。我想要一个编译器选项来打开和关闭它。

最佳答案

你想要的选项叫做 -mslow-flash-data 但我的 gcc 版本的手册至少说这只支持 ARMv7M 架构。

关于assembly - 强制 arm64 gcc 使用指令构造 double float ,无 .rodata 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74614929/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com