如何强制 IAR 使用所需的 Cortex-M0+ 指令(此功能将禁用优化。)

Posted

技术标签:

【中文标题】如何强制 IAR 使用所需的 Cortex-M0+ 指令(此功能将禁用优化。)【英文标题】:How to force IAR to use desired Cortex-M0+ instructions (optimization will be disabled for this func.) 【发布时间】:2018-05-20 07:03:24 【问题描述】:

在使用 C 编码时,我需要强制 IAR tp 在我的代码的某些部分使用某些 Cortex-M0+ 指令。

请不要提供纯 asm 函数或内联 asm 等。

我已经设法为 51 指令执行此操作,但无法为 ; ADR、BLX、RSBS、SBCS、SXTH 指令。

已禁用此函数的优化 (#pragma optimization=none)

通过考虑指令行为,我尝试了很多事情。 但 IAR 更喜欢使用不同指令的相同功能。

以前有没有其他人为这种不必要的事情而苦苦挣扎或有任何想法?

【问题讨论】:

不能保证它可以发出所有这些,但我希望rsbs 应该是可行的。不过,也许不会禁用优化;只有当它可以在设置标志和单独的减法结果之间进行 CSE 时,您才可能得到它。 在任何地方都有 IAR 的在线编译器吗?即像Matt Godbolt's compiler explorer,只是它只安装了gcc。 gcc 使用 rsbs-mcpu=cortex-m4,但不使用 -mcpu=cortext-m0 来实现此功能:godbolt.org/g/xUraX9。也许 IAR 出于某种原因故意避开它? 这个练习的目的是什么? asm 是获得所需说明的唯一方法。如果你想要特定的指令,如果你想要编译器选择,那么你就放弃了对特定指令的权利。 【参考方案1】:

除了在 cortex-m 上不可用的 BLX 之外,此代码可能会让您到达那里。 也许你必须开启一些优化。

char const * getstr(void)

    return "ADR";


long long llfunc(long long v1, long long v2)

    return v1 - v2;


int neg(int i)

    return -i;



void efunc(short);

void func(short s)

    efunc(s + 5);

【讨论】:

BLX 在 Cortex-M 上可用。事实上,它被大量使用! 是的,你是对的。我在考虑改变模式的 BLX 。要使用它,只需通过函数指针调用。【参考方案2】:

请不要提供纯 asm 函数或内联 asm 等。

但这些是您的问题的唯一解决方案,不依赖于编译器版本。

你可能有

设法为 51 条指令做到这一点

..但是下一个(主要)编译器版本可能对如何为您的 C 代码生成指令有一个非常不同的想法,即使优化器已关闭。 GCC 的 BTDT。

用汇编语言编写代码直接完全消除了这种编译器版本依赖性。您甚至应该有一些示例代码,因为大多数 C 启动(重置处理程序)代码都是作为汇编语言文件提供的。

【讨论】:

我同意。如果您必须确保使用指令,则汇编(内联或非内联)是唯一的方法。 这是一个C类安全应用程序,所以一旦我们完成并认证,单行代码不会改变,也不会被不同版本的编译器编译。一切都会被冻结。所以我没有上面的顾虑。 处理器指令测试是少数应该用汇编语言完成的事情之一。您可能能够在纯 C 中获得 100% 的覆盖率,因为只要存在其他冗余,编译器就根本无法从 C 代码生成某些指令。 与您需要 C 编译器通过以生成“您的”指令的循环相比,汇编源代码也将更简单、更清晰。

以上是关于如何强制 IAR 使用所需的 Cortex-M0+ 指令(此功能将禁用优化。)的主要内容,如果未能解决你的问题,请参考以下文章

[转发]在main()之前,IAR都做了啥?

如何强制 Bazel 将库路径设置为所需的路径?

当所需的文本框为空时,如何强制页面回发

ARM中Cortex-A8,Cortex-M0,Cortex-M3 他们的区别在哪?

如何使用 Ruby OptionParser 指定所需的开关(不是参数)?

如何使类工厂创建所需的派生类