问题描述
我正在尝试将源代码编译从armcc编译器v5.06迁移到armclang v6。而且我看到armclang错误指出它无法识别cp15寄存器。看起来如何声明寄存器的armcc vs clang可能有所变化。但是,我在迁移文档或编译器文档中找不到任何内容。
这是代码段-
void reset_clock_count(void)
{
register uint32_t reg_cp15_pmcr __asm("cp15:0:c9:c12:0");
reg_cp15_pmcr |= RESET_CYCLE_COUNTER;
}
error: unkNown register name 'cp15:0:c9:c12:0' in asm
register uint32_t reg_cp15_pmcr __asm("cp15:0:c9:c12:0");
^
对于类似声明的寄存器,我在其他地方看到相同的错误。任何可能出问题的指针都会有所帮助。
编辑:实际答案如下。
register uint32_t val;
__asm volatile ("mrc p15,%0,c9,c13,0": "=r"(val));
val |= RESET_CYCLE_COUNTER;
__asm volatile ("mcr p15,0":: "r"(val));
解决方法
请先阅读手册,注释中也提到了该手册。
To access the PMCR,read or write the CP15 registers with:
MRC p15,<Rt>,c9,c12,0; Read Performance Monitor Control Register
MCR p15,0; Write Performance Monitor Control Register
将其剪切并粘贴到我的代码中,选择一个寄存器
MRC p15,r0,0
使用gnu汇编程序:
Disassembly of section .text:
00000000 <.text>:
0: ee190f1c mrc 15,cr9,cr12,{0}
使用clang作为汇编器
Disassembly of section .text:
00000000 <.text>:
0: ee190f1c mrc 15,{0}
没有警告也没有错误。
请先阅读文档。
由于未指定寄存器,因此我看不到该语法如何与任何工具一起使用。但也要记住,内联汇编是编译器特有的,不能以任何方式假定为可移植的。因此,如果armcc支持该奇怪的语法,就不会有任何理由期望clang。
总是先使用真实的程序集,然后才使用内联程序,但是内联程序很少值得付出努力。您必须经常对其进行拆卸,以确保它在构建正确的说明。
您需要为该内联asm做更多有用的事情,无论如何做,有用的组装将使您更快地获得成功。
.globl read_pmcr
read_pmcr:
MRC p15,0
bx lr
.globl write_pmcr
write_pmcr:
MCR p15,0
bx lr
当然,在开始任何组装之前,您必须先拥有相关的文档。