ARM Cortex-A5 矢量化浮点运算与GCC编译选项
项目中遇到这样一段代码:
i2c_msg_s msg[2];
uint8_t tx[2][32]={0};
uint8_t rx[32]={0};
当执行到rx[32]={0}时,CPU进入TRAP,提示undefined instruction,该代码运行环境为arm cortex-A5,gcc编译。
调出汇编代码
i2c_msg_s msg[2];
uint8_t tx[2][32]={0};
400078f8: e28d5020 add r5, sp, #32
400078fc: e3a02040 mov r2, #64 ; 0x40
40007900: e3a01000 mov r1, #0
40007904: e1a00005 mov r0, r5
40007908: eb0061ad bl 4001ffc4 <memset>
uint8_t rx[32]={0};
4000790c: e3a04000 mov r4, #0
40007910: e58d4000 str r4, [sp]
40007914: f2c00010 vmov.i32 d16, #0 ; 0x00000000
40007918: edcd0b01 vstr d16, [sp, #4]
4000791c: edcd0b03 vstr d16, [sp, #12]
40007920: edcd0b05 vstr d16, [sp, #20]
40007924: edcd0b06 vstr d16, [sp, #24]
代码中初始化tx[2][32]中调用memset,但是初始化rx[32]时用的vmov指令。
这两个变量初始化方式不同,memset使用很多次,不会产生undefined instruction,那是否CPU不识别vmov指令呢。未验证该猜测,不初始化该变量重新编译
uint8_t tx[2][32]={0};
400078f8: e28d5020 add r5, sp, #32
400078fc: e3a02040 mov r2, #64 ; 0x40
40007900: e3a01000 mov r1, #0
40007904: e1a00005 mov r0, r5
40007908: eb0061a7 bl 4001ffac <memset>
uint8_t rx[32];
int i =0;
代码执行,没有报错。确定是vmov指令的问题。
由于vmov是NEON的扩展指令,该CPU可能不支持NEON加速,查询手册得知,该CPU不支持硬件浮点运算,故而也不会特别的去支持NEON。
查看编译选项,其中-mfloat-abi=softfp,编译中也没有开启NEON。
通过查询,找到如下描述:
出于历史原因,GCC 只在被明确告知可以安全使用浮点和 NEON 指令时才会使用这些指令。在此进行控制的选项有些令人混淆,选项的一部分也可更改编译器所遵守的 ABI。-mfloat-abi 选项有三种可能的选项:
-mfloat-abi=soft -- 忽略所有 FPU 和 NEON 指令,仅使用核心寄存器集并利用库调用模拟所有浮点运算。
-mfloat-abi=softfp -- 使用与 -float-abi=soft 相同的调用规则,但会在适用情况下使用浮点和 NEON 指令。此选项为二进制,与 -mfloat-abi=soft 兼容,并且可以用于提高必须遵循软浮点环境的代码的性能,但需要是已知相关硬件指令也可用的环境。
-mfloat-abi=hard -- 在适用情况下使用浮点和 NEON 指令,并且还更改ABI 调用规则以便生成更高效的函数调用;现在可以在扩展寄存器中的函数之间传递浮点和矢量类型,不仅节约大量复制操作,而且也意味着需要在堆栈上传递参数的调用变少。
改成-mfloat-abi=soft,汇编中没有出现vmov指令。
更多推荐


所有评论(0)