GCC避免编译分支到链接寄存器(blr)语句

时间:2017-08-18 19:48:49

标签: c gcc assembly powerpc

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

例如,我将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

我想要的是所有类似返回的语句被一个always分支替换为函数代码的末尾,如下所示:

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!

是否可以自动化此编译首选项?

1 个答案:

答案 0 :(得分:2)

来自@Jester和@fuz的评论提供了答案,我只是把它写下来。

你需要:

  1. 避免在C代码中的函数中间返回。因此,请将return替换为goto
  2. 阻止编译器确定goto end;return;是一回事。内联汇编是一种告诉编译器的好方法,不要搞乱这个"。
  3. 使用一些宏:

    #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的指令)。