如何为 ARMCC 声明全局浮点寄存器

Posted

技术标签:

【中文标题】如何为 ARMCC 声明全局浮点寄存器【英文标题】:how to declare global float register for ARMCC 【发布时间】:2015-10-01 12:07:50 【问题描述】:

对于电源转换应用,我们需要在 ARM Cortex-M4 平台上尽快进行各种浮点计算。

我们正在使用 Keil uVision 进行开发。

我们想将一些变量声明为寄存器变量,但从编译器中得到的只是错误。

这似乎很有用,因为 FPU 有 32 个寄存器,我们可以通过将数据存储在这些寄存器中来节省大量周期,而不是每次调用 ISR 时都从 RAM 重新加载。

我们尝试使用:

register float a1 __asm__("s0");

但收到错误:未知的寄存器名称“s0”

这看起来很奇怪,因为在调试器界面中我可以看到编译器正在使用 s0 寄存器。如果我将寄存器声明为“r0”,则没有错误,因此似乎某处缺少 FPU 支持,但不确定在哪里。

我查看了 Assembler 控制字符串,似乎支持浮点:

--cpu Cortex-M4.fp --pd "__EVAL SETA 1" -g --apcs=interwork 
-I D:\my_project
-I D:\Keil_v5\ARM\PACK\ARM\CMSIS\4.4.0\CMSIS\Include 

我们也试过了:

__global_freg(1) float a1;

这也没有用。

有什么想法吗?

【问题讨论】:

你在用armcc吗? ARMCC manual 列出了可以命名的 FPU 寄存器,该列表不包括 sX 或 dX 寄存器。 是的,我正在使用 ARMCC,我看到了。我们还尝试使用 gcc 进行编译并得到错误:为 'a1' 指定的寄存器不适合数据类型 gcc.godbolt.org work 上的 gcc 版本。 我看到 here 编译器确实支持内联汇编中的 VFP 指令。但是如果我们在汇编程序中编写例程,那么我们如何阻止编译器在其他地方破坏我们的寄存器呢? @Jester 感谢您提出非常有趣的观点。我尝试使用 arm-none-eabi-gcc-4.8.4。 Godbolt 上的编译器是 arm-linux-gnueabi-g++-4.5。也许这是相关的?我不确定我们是否可以使用这个版本,但我会试一试。 【参考方案1】:

您需要遵守 EABI,详见此处:http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf

通过仔细阅读,您似乎可以使用(如您在上面的评论中提到的)s16-s31。其余的不保证被其他代码保留。

如果您的应用程序处理允许,您可以通过仅在支持 VFP 的情况下编译您的 ISR 来解决此问题,而无需其他所有内容。这将防止您不知道的任何代码使用 VFP 寄存器并破坏它们。

【讨论】:

这是一个非常有趣的想法!我会试试的。

以上是关于如何为 ARMCC 声明全局浮点寄存器的主要内容,如果未能解决你的问题,请参考以下文章

为什么浮点寄存器与通用寄存器不同

浮点类型是如何存储的

如何为 Raspberry pi 3 编译 ARMv8 代码

如何将浮点常量移入 FP 寄存器?

如何将浮点常量值移动到 xmm 寄存器中?

第3章 Java基本程序设计结构