[英]ELLCC embedded LLVM compilation fails with certain asm instructions against Thumb2 Cortex-M0
[英]Cortex-m4 asm vs cortex-m0 asm
如何将 CM4 的这个汇编代码重写为 CM0? 这是来自 FreeRTOS 页面的硬故障处理示例。 它检查在硬故障发生之前哪个堆栈指针处于活动状态,并提供指向堆栈寄存器开头的指针:
" tst lr, #4 \n"
" ite eq \n"
" mrseq r0, msp \n"
" mrsne r0, psp \n"
" ldr r1, [r0, #24] \n"
" ldr r2, handler2_address_const \n"
" bx r2 \n"
" handler2_address_const: .word prvGetRegistersFromStack \n"
如果没有任何更改,它会产生多个错误:
Error: unshifted register required -- tst r0,#4''
Error: selected processor does not support 'ite eq' in Thumb mode
Error: Thumb does not support conditional execution
Error: Thumb does not support conditional execution
Error: invalid offset, target not word aligned (0x00000002)
Error: invalid offset, value too big (0x00000002)
我尝试过的:
以这种方式替换tst
并删除IT
" mov r1, lr\n"
" lsr r0, r1, #3\n" // Replace tst with lsr and cmp
" cmp r0, #1\n"
" mrseq r0, msp\n" // <- Error: Thumb does not support conditional execution
" mrsne r0, psp\n" // <- Error: Thumb does not support conditional execution
好的。 启用称为统一语法的东西:
".syntax unified\n"
".thumb\n"
" mov r1, lr\n"
" lsrs r0, r1, #3\n" // tst gives "Can not honor suffix width" so replaced it with lsrs and cmp
" cmp r0, #1\n"
" ite eq\n" // <- Error: selected processor does not support `ite eq' in Thumb mode. If I remove it compiler states that mrseq must be in IT block
" mrseq r0, msp\n"
" mrsne r0, psp\n"
" ldr r1, [r0, #24]\n"
" ldr r2, handler2_address_const\n"
" bx r2\n"
" handler2_address_const: .word prvGetRegistersFromStack\n"
这些错误的原因是什么以及如何修复它们? 仍然不知道导致对齐问题的原因。
当然,CM0 不支持某些指令。 但我不明白错误“Thumb 不支持条件执行”以及如何在没有条件执行的情况下生存。
还有错误“不能接受寄存器宽度”是什么意思,以及为什么在启用统一语法时会发生这种情况。 据我了解,它是关于 16/32 位指令的。 尝试添加 .W 后缀,但出现另一个错误。
Cortex-M0 显然根本不支持预测; 没有条件执行。 显而易见的选择是分支。
您的 lsrs 序列看起来没有正确实现测试正确的位或测试单个位。 看起来这取决于所有更高的位为零。
GCC 输出https://godbolt.org/z/aphU5G展示了一种巧妙的方法,可以通过一个移位指令在单个位上进行分支: lsls r3, r0, #29
; bpl .skip
- 将位移至符号位,其中仅根据该位设置标志。 r3
目标可以是任何可编码的虚拟寄存器; 你不在乎价值; 你只想要标志设置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.