GCC扩展了asm区分文字与注册

时间:2017-07-25 04:39:28

标签: gcc embedded inline-assembly microchip xc16

我发现自己广泛使用内联asm,并且经常希望能够在asm的给定位中使用寄存器一个文字,但是我无法看到如何使这个选项成为一个选项。 Microchip XC16套件。

据我所知,您需要手动编码文字符号#,这与前缀不兼容。这意味着以下代码无法编译:

asm("MOV %1, %0" : "=r" (res) : "i" (1));
Invalid operands specified ('mov 1,w0').

但是以下是:

asm("MOV #%1, %0" : "=r" (res) : "i" (1));

这当然与寄存器不兼容:

asm("MOV #%1, %0" : "=r" (res) : "ri" (x));
Invalid operands specified ('mov #w0,w0').

因此在我看来,Microchip不遵循GCC惯例,我认为文字符号应该嵌入到操作数中,这使得它特别难以使用。

我想知道这个机会..有没有人对如何解决这个问题有任何好主意?

现在我将__builtin_constant_p作为附加参数传递给我,然后{as} {i}}在asm中,如下所示,但是说它变得笨拙很快就会轻描淡写。

.if

我甚至不相信,如果asm(".if %[isk] \n" "MOV #%1, %0 \n" ".elseif \n" "MOV %1, %0 \n" ".endif \n" : "=r" (res) : "ri" (x), [isk] "i" (__builtin_constant_p(x)); 成立,GCC会保证%1将是一个文字,这意味着必须将if-then-else阻止它全部出C侧。叹了口气。

澄清isk只是一个示例指令。这些处理器(dsPIC33E)具有零开销单指令和多指令循环,需要asm才能利用,其语法如下所示:

MOV

这个memcpy循环需要执行/* this code demonstrates compilation failure if cnt is a constant * as there is no # prefix before the %[cnt] */ asm("REPEAT %[cnt] \n" " MOV [%0++], [%1++] \n" : "+r" (src), "+r" (dst), "=m" (*dst) : "m" (*src), [cnt] "ri" (cnt)); 个循环,由于流水线操作实际上是完全展开循环的速度的两倍,比分支每次迭代快6倍。除了他们的多指令DO循环变体,它们对于充分利用这些处理器非常重要。

1 个答案:

答案 0 :(得分:1)

我找到了一种在asm中检测给定参数是否为文字的方法,它远非理想但它似乎有效。

首先,在asm头文件中,为每个寄存器标记符号:

.ifdecl _IS_REG_%0
  REPEAT %0
.else
  REPEAT #%0
.endif

然后使用:

.macro REPEATN cnt
    .ifdecl _IS_REG_&cnt&
        REPEAT \cnt
    .else
        REPEAT #\cnt
    .endif
.endm

哪个可以包含在asm宏中:

void DelayCycles(int count)
{
    asm("REPEATN %[cnt]    \n"
        "    NOP           \n"
        :
        : [cnt] "ri" (count));
}

在内联asm中轻松嵌入:

nouislider
相关问题