gpt4 book ai didi

c - aeabi_fmul 从哪里链接?

转载 作者:太空宇宙 更新时间:2023-11-04 02:29:44 25 4
gpt4 key购买 nike

我一直在 ARM M0+ 内核上运行代码,我发现我的大部分时间都花在了浮点计算上。因此,我正在试验一种用于极低功耗应用的自定义浮点计算函数。

我一直在使用 ARM GCC 在 M0+(没有硬 FPU)上进行裸机编译。我看到浮点乘法链接到 __aeabi_fmul 然后链接以生成最终的 ELF 文件。

我的问题如下:

  1. __aeabi_fmul 在哪里定义?是在GCC自带的预编译库里吗?
  2. 是否有可能以某种方式改变这个定义?也许有一个预编译版本的 my_fp_mul 而不是链接到它而不是 __aeabi_fmul?

我知道第二部分需要我搞乱编译器。我一直在研究 CLANG/LLVM 来做这件事,因为普遍的共识似乎是它比 GCC 更容易修改!我只是想看看这是否有可能,或者我在这里咆哮完全错误的树。

谢谢

最佳答案

它是 gcc 的一部分,gcc 库,下载 gcc 源代码并搜索那些函数,您会找到它们。它们是软 float 例程并且是手动调整的,你不太可能做得更好,但会把你自己打倒。不知道为什么你会在这样的 MCU 上做任何 float ,但幸运的是语言和工具允许你,尽管它会消耗大量的闪存和执行时间。 (不做任何浮点变量,但自己用定点做 float 学是一种可能的妥协,或者只做定点)。

如果您使用 gcc 进行链接,那么 gcc 知道库的位置并会自动将它们拉入,如果您使用 ld 进行链接(使用 gcc 只是作为编译器而不是工具链中所有内容的调用者),那么 ld 不知道在哪里可以找到库,你可以简单地在命令行上添加你自己的对象,这是最简单的方法。

您可以获取特定功能的原样 gnu 源并将其添加到您的项目中,然后修改它或完全用您自己的功能替换它。

自然地,您可以进入编译器源代码并重命名然后重新构建编译器,不确定您要在这里做多少工作,如评论中所述,无误地替换浮点例程已经是一项艰巨的任务我会不理会编译器,只使用它(将名称与 ld 保持相同的链接)。

开始.s

.thumb
.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.thumb_func
reset:
bl notmain
.thumb_func
hang: b .

所以.c

float notmain ( float a, float b )
{
return(a+b);
}

内存映射

MEMORY
{
rom : ORIGIN = 0x00000000, LENGTH = 0x1000
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > rom
}

构建

arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -Xlinker -T -Xlinker memmap -nostdlib -nostartfiles -ffreestanding -mthumb start.o so.c -o so.elf -lgcc
arm-none-eabi-objdump -D so.elf

它没有提示,但生成了一个完美损坏的二进制文件

20000048 <__addsf3>:
20000048: e1b02080 lsls r2, r0, #1
2000004c: 11b03081 lslsne r3, r1, #1
20000050: 11320003 teqne r2, r3
20000054: 11f0cc42 mvnsne r12, r2, asr #24
20000058: 11f0cc43 mvnsne r12, r3, asr #24
2000005c: 0a000047 beq 20000180 <__addsf3+0x138>
20000060: e1a02c22 lsr r2, r2, #24
20000064: e0723c23 rsbs r3, r2, r3, lsr #24
20000068: c0822003 addgt r2, r2, r3
2000006c: c0201001 eorgt r1, r0, r1
20000070: c0210000 eorgt r0, r1, r0

那些是 ARM 指令而不是拇指。检查链接器传递了什么。

0:[/opt/gnuarm/lib/gcc/arm-none-eabi/7.1.0/../../../../arm-none-eabi/bin/ld]
1:[-plugin]
2:[/opt/gnuarm/libexec/gcc/arm-none-eabi/7.1.0/liblto_plugin.so]
3:[-plugin-opt=/opt/gnuarm/libexec/gcc/arm-none-eabi/7.1.0/lto-wrapper]
4:[-plugin-opt=-fresolution=/tmp/ccSyISCJ.res]
5:[-X]
6:[-o]
7:[so.elf]
8:[-L/opt/gnuarm/lib/gcc/arm-none-eabi/7.1.0/thumb]
9:[-L/opt/gnuarm/lib/gcc/arm-none-eabi/7.1.0]
10:[-L/opt/gnuarm/lib/gcc/arm-none-eabi/7.1.0/../../../../arm-none-eabi/lib]
11:[-T]
12:[memmap]
13:[start.o]
14:[/tmp/ccrdRU2s.o]
15:[-lgcc]

另一种方法

arm-none-eabi-gcc -O2 -c -mthumb so.c -o so.o
arm-none-eabi-ld -T memmap start.o so.o /opt/gnuarm/lib/gcc/arm-none-eabi/7.1.0/thumb/libgcc.a -o so.elf

但这还是坏了

20000038 <__addsf3>:
20000038: e1b02080 lsls r2, r0, #1
2000003c: 11b03081 lslsne r3, r1, #1
20000040: 11320003 teqne r2, r3
20000044: 11f0cc42 mvnsne r12, r2, asr #24
20000048: 11f0cc43 mvnsne r12, r3, asr #24
2000004c: 0a000047 beq 20000170 <__addsf3+0x138>
20000050: e1a02c22 lsr r2, r2, #24
20000054: e0723c23 rsbs r3, r2, r3, lsr #24

我没有做我需要做的事情来获得正确的库,必须运行稍后重新编辑...

但我建议的解决方案是:

.thumb_func
.globl __aeabi_fadd
__aeabi_fadd:
bx lr

我添加到 start.s 用于演示目的

arm-none-eabi-as start.s -o start.o
arm-none-eabi-ld -T memmap start.o so.o -o so.elf
arm-none-eabi-objdump -D so.elf

Disassembly of section .text:

20000000 <_start>:
20000000: 20001000 andcs r1, r0, r0
20000004: 20000015 andcs r0, r0, r5, lsl r0
20000008: 20000019 andcs r0, r0, r9, lsl r0
2000000c: 20000019 andcs r0, r0, r9, lsl r0
20000010: 20000019 andcs r0, r0, r9, lsl r0

20000014 <reset>:
20000014: f000 f802 bl 2000001c <notmain>

20000018 <hang>:
20000018: e7fe b.n 20000018 <hang>

2000001a <__aeabi_fadd>:
2000001a: 4770 bx lr

2000001c <notmain>:
2000001c: b510 push {r4, lr}
2000001e: f7ff fffc bl 2000001a <__aeabi_fadd>
20000022: bc10 pop {r4}
20000024: bc02 pop {r1}
20000026: 4708 bx r1

然后随便填什么,显然这不是一个真正的程序,违反了很多规则,没有传入数字等等......

但是编译器生成了 __aeabi_fadd,我提供了一个 __aeabi_fadd,它很高兴。

我过去所做的是,因为无论如何我构建了自己的 gnu 工具链,进入并在感兴趣的文件中放入语法错误,进行构建,然后用于构建该项目的长命令行是现在在它失败时出现在屏幕上,隔离感兴趣的功能,使用 gcc 的长命令行作为指导,根据需要进行调整和调整......比尝试自己在代码中找出所有定义更快地到达那里.

关于c - aeabi_fmul 从哪里链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45150959/

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