GCC 避免将分支编译为 link 寄存器 (blr) 语句

GCC Avoid compiling branch to link register (blr) statements

我正在编写 C 代码并为 PowerPC 架构编译它。我想告诉编译器将所有类似 return 的指令替换为函数代码末尾的分支。这是由于一些奇怪的要求,我不能在这段代码中使用任何 return 来确保之后执行更多的汇编行。

比如我将C代码编译成下面的汇编代码:

lis r9,4096
lis r8,255
lwz r10,0(r9)
ori r8,r8,65535
addi r9,r10,192
cmplw cr7,r9,r8
blelr- cr7 # Return if the cr7 register is "less than or equal"
lis r8,512
cmplw cr7,r9,r8
bgtlr- cr7 # Return if the cr7 register is "greater than or equal"
lwz r10,192(r10)
lis r8,303
ori r8,r8,65535
addi r9,r10,320
cmplw cr7,r9,r8
blelr- cr7 # Return if the cr7 register is "less than or equal"
lis r8,528
cmplw cr7,r9,r8
bgtlr- cr7 # Return if the cr7 register is "greater than or equal"
lwz r10,320(r10)
lis r8,287
ori r8,r8,65535
subi r9,r10,448
cmplw cr7,r9,r8
blelr- cr7
lis r8,544
cmplw cr7,r9,r8
bgtlr- cr7 # Return if the cr7 register is "greater than or equal"
lis r9,4919
ori r9,r9,4919
stw r9,-448(r10)
blr # Return

我想要的是将所有类似 return 的语句替换为函数代码末尾的始终分支,如下所示:

lis r9,4096
lis r8,255
lwz r10,0(r9)
ori r8,r8,65535
addi r9,r10,192
cmplw cr7,r9,r8
ble _END # Branch to the _END label if "less than"
lis r8,512
cmplw cr7,r9,r8
bgt _END # Branch to the _END label if "greater than"
lwz r10,192(r10)
lis r8,303
ori r8,r8,65535
addi r9,r10,320
cmplw cr7,r9,r8
ble cr7 # Branch to the _END label if "less than"
lis r8,528
cmplw cr7,r9,r8
bgt _END # Branch to the _END label if "greater than"
lwz r10,320(r10)
lis r8,287
ori r8,r8,65535
subi r9,r10,448
cmplw cr7,r9,r8
blelr- cr7
lis r8,544
cmplw cr7,r9,r8
bgt _END # Branch to the _END label if "greater than"
lis r9,4919
ori r9,r9,4919
stw r9,-448(r10)
_END:
blr # I guess it should stay otherwise the function call will continue executing "random" garbage such as the next function in the .text section. Via post-processing this would be easy to strip though!

有什么方法可以自动执行此编译首选项?

@Jester和@fuz的评论给出了答案,我就写下来吧

您需要:

  1. 避免在 C 代码中的函数中间返回。所以将 return 替换为 goto.
  2. 防止编译器发现 goto end;return; 是同一回事。内联汇编是告诉编译器的好方法 "don't mess with this".

使用一些宏:

#define RETURN goto _end
#define END _end: asm volatile("")
void foo(int x) { if (x==1) RETURN; if (x==2) RETURN; printf("Hello, world\n"); END; }

asm volatile("") 指示编译器插入一些汇编代码。编译器不知道这段汇编代码的作用,因此它无法进行任何会跳过它的优化(即使它是 0 条指令)。