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 标签。任何解决此问题的帮助将不胜感激。
是的,支持。我认为问题出在你的代码上,它有几个错误:
要使用 goto 功能,您需要以 asm goto
关键字开始内联汇编语句。您缺少 goto
.
标签操作数在输入操作数之后依次编号(当然不能有输出)。所以 failed
是操作数 4,因此您需要用 bcc %l4
引用它,而不是 %l0
.
通过这些更改,我能够编译代码。
顺便说一句,我不太了解 m68k 汇编,但看起来你正在破坏寄存器 d1
,以及任何 _BURAM
子程序破坏,但那些还没有宣布为clobbers。难道你不应该加上 "d1"
和其余的连同 "cc"
吗?
此外,您似乎希望将操作数 d0_fcode
、a0_info
等放入那些特定的寄存器中,大概是因为 _BURAM
希望它们放在那里。您是否定义了这些变量 register asm
来告诉编译器,例如register int d0_fcode asm("d0");
?否则它可以选择 d4
作为 d0_fcode
操作数。在我的测试中,它们偶然被放入了所需的寄存器,没有明确询问,但这并不安全。
我正在开发一个项目,其中包含大量围绕 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 标签。任何解决此问题的帮助将不胜感激。
是的,支持。我认为问题出在你的代码上,它有几个错误:
要使用 goto 功能,您需要以
asm goto
关键字开始内联汇编语句。您缺少goto
.标签操作数在输入操作数之后依次编号(当然不能有输出)。所以
failed
是操作数 4,因此您需要用bcc %l4
引用它,而不是%l0
.
通过这些更改,我能够编译代码。
顺便说一句,我不太了解 m68k 汇编,但看起来你正在破坏寄存器 d1
,以及任何 _BURAM
子程序破坏,但那些还没有宣布为clobbers。难道你不应该加上 "d1"
和其余的连同 "cc"
吗?
此外,您似乎希望将操作数 d0_fcode
、a0_info
等放入那些特定的寄存器中,大概是因为 _BURAM
希望它们放在那里。您是否定义了这些变量 register asm
来告诉编译器,例如register int d0_fcode asm("d0");
?否则它可以选择 d4
作为 d0_fcode
操作数。在我的测试中,它们偶然被放入了所需的寄存器,没有明确询问,但这并不安全。