首页 > 解决方案 > m68k-elf 目标是否支持 GCC 内联 asm goto?

问题描述

我正在开发一个项目,其中包含许多围绕 M68000 asm 调用的 C 包装器。其中一些调用在条件代码寄存器上返回成功/失败状态,因此根据 CC 的状态“转到”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);

我在这里找到的唯一其他一些相关的信息是: Extended asm with goto,包括来自 gcc 文档的示例,无法编译

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

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

标签: cassemblygccinline-assembly68000

解决方案


是的,它受支持。我认为问题在于您的代码,它有几个错误:

  1. 要使用 goto 功能,您需要使用asm goto关键字启动内联汇编语句。你错过了goto.

  2. 标签操作数在输入操作数之后按顺序编号(当然不能有输出)。操作数 4 也是如此failed,因此您需要使用 而bcc %l4不是来引用它%l0

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


顺便说一句,我对 m68k 汇编不太了解,但看起来你正在破坏 register d1,以及_BURAM任何子例程 clobbers ,但这些还没有被声明为 clobbers 。你不应该加上"d1"其余的"cc"吗?

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


推荐阅读