m68k-elf 目标是否支持 GCC 内联 asm goto?

Is GCC inline asm goto supported in the m68k-elf target?

我正在开发一个项目,其中包含大量围绕 M68000 asm 调用的 C 包装器。其中一些调用 return 条件代码寄存器上的 success/fail 状态,因此根据 CC 的状态 'goto' C 标签是理想的。然而,无论我尝试什么排列,我总是从编译器中得到语法错误。

(这是gcc 10.2.0 --with-cpu= m68000)

示例代码:

  asm(R"(
  moveq #0, d1
  jsr %p0
  bcc %l0
2:
    )":
        :
      "i"(_BURAM),
        "d"(d0_fcode),
        "a"(a0_info),
        "a"(a1_data)
        :
        "cc"
        : failed);

  return true;

  failed:
  return false;

生成的错误是:

/home/ryou/Projects/megadev/lib/sub/bram.h: In function 'bram_brmwrite':
/home/ryou/Projects/megadev/lib/sub/bram.h:156:7: error: expected ')' before ':' token
  156 |   "cc"
      |       ^
      |       )
  157 |   : failed);
      |   ~
/home/ryou/Projects/megadev/lib/sub/bram.h:144:5: note: to match this '('
  144 |  asm(R"(
      |     ^

我尝试用最简单的例子来做测试:

asm("bra %l0" :::: failed);

我仍然得到:

/home/ryou/Projects/megadev/lib/sub/bram.h:144:18: error: expected ')' before '::' token
  144 |  asm("bra %l0" :::: failed);

我在这里找到的唯一其他有点相关的信息是:

但是,正如您在两个示例中看到的,我没有使用任何输出。我假设 m68k-elf 目标不特别支持这一点,但我真的不明白为什么不支持,我也没有找到任何文档说明这一点。

有很多方法可以解决这个问题(即通过检查 asm 片段本身中的 CC 状态并将状态推送到输出寄存器),但如果可能的话,我想使用 goto 标签。任何解决此问题的帮助将不胜感激。

是的,支持。我认为问题出在你的代码上,它有几个错误:

  1. 要使用 goto 功能,您需要以 asm goto 关键字开始内联汇编语句。您缺少 goto.

  2. 标签操作数在输入操作数之后依次编号(当然不能有输出)。所以 failed 是操作数 4,因此您需要用 bcc %l4 引用它,而不是 %l0.

通过这些更改,我能够编译代码。


顺便说一句,我不太了解 m68k 汇编,但看起来你正在破坏寄存器 d1,以及任何 _BURAM 子程序破坏,但那些还没有宣布为clobbers。难道你不应该加上 "d1" 和其余的连同 "cc" 吗?

此外,您似乎希望将操作数 d0_fcodea0_info 等放入那些特定的寄存器中,大概是因为 _BURAM 希望它们放在那里。您是否定义了这些变量 register asm 来告诉编译器,例如register int d0_fcode asm("d0");?否则它可以选择 d4 作为 d0_fcode 操作数。在我的测试中,它们偶然被放入了所需的寄存器,没有明确询问,但这并不安全。