-1

我正在尝试将我的源代码编译从 armcc 编译器 v5.06 迁移到 armclang v6。而且我看到 armclang 错误说它无法识别 cp15 寄存器。看起来 armcc 与 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, %0, c9, c13, 0": "=r"(val));
val |= RESET_CYCLE_COUNTER;
__asm volatile ("mcr p15, 0, %0, c9, c13, 0":: "r"(val));
4

1 回答 1

1

请先阅读手册,评论中也提到了这一点。

To access the PMCR, read or write the CP15 registers with: 
MRC p15, 0, <Rt>, c9, c12, 0; Read Performance Monitor Control Register 
MCR p15, 0, <Rt>, c9, c12, 0; Write Performance Monitor Control Register

将其剪切并粘贴到我的代码中,选择一个寄存器

MRC p15, 0, r0, c9, c12, 0

使用 gnu 汇编程序:

Disassembly of section .text:

00000000 <.text>:
   0:   ee190f1c    mrc 15, 0, r0, cr9, cr12, {0}

使用 clang 作为汇编程序

Disassembly of section .text:

00000000 <.text>:
   0:   ee190f1c    mrc 15, 0, r0, cr9, cr12, {0}

没有警告也没有错误。

请先阅读文档。

由于未指定寄存器,因此我看不到该语法如何与任何工具一起使用。但也请记住,内联汇编非常特定于编译器,并且不假定以任何方式可移植。因此,如果 armcc 支持这种奇怪的语法,那么就没有理由期望 clang 会支持这种语法。

始终首先使用真正的汇编,然后才使用内联,但内联很少值得努力。您必须经常反汇编它才能看到它正在构建正确的指令。

无论如何,您需要为这个内联汇编做更多的工作来做任何有用的事情,通过真正的汇编,您将更快地取得成功。

.globl read_pmcr
read_pmcr:
    MRC p15, 0, r0, c9, c12, 0
    bx lr
    
.globl write_pmcr   
write_pmcr:
    MCR p15, 0, r0, c9, c12, 0
    bx lr

当然,在开始任何组装之前,您必须首先拥有相关文档。

于 2020-11-11T09:12:25.170 回答