如何使用mipsel-openwrt-linux-gcc交叉编译器获得条件分支槽,在条件分支槽中,移动分支之前或之后的指令来填充槽?
我只是使用命令来获取MIPS代码:
./mipsel-openwrt-linux-gcc -O2 -fno-delayed-branch -S ha.c;
然而,我只是在收到bne指令后才收到nop指令。-O2和-fno延迟分支选项似乎不起作用。
以下是ha.c:的内容
int intcompare(int *x, int *y)
{
if (*x < *y)
return -1;
else if (*x > *y)
return 1;
else return 0;
}
int mod1(int x, int N)
{
if (x >= N)
x -= N;
return x;
}
int main()
{
return 0;
}
这是ha的的内容
.file 1 "ha.c"
.section .mdebug.abi32
.previous
.gnu_attribute 4, 3
.abicalls
.option pic0
.text
.align 2
.globl intcompare
.set nomips16
.ent intcompare
.type intcompare, @function
intcompare:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
lw $2,0($4)
lw $3,0($5)
nop
slt $4,$2,$3
bne $4,$0,$L3
nop
slt $2,$3,$2
j $31
nop
$L3:
li $2,-1 # 0xffffffffffffffff
j $31
nop
.set macro
.set reorder
.end intcompare
.size intcompare, .-intcompare
.align 2
.globl mod1
.set nomips16
.ent mod1
.type mod1, @function
mod1:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
slt $3,$4,$5
move $2,$4
bne $3,$0,$L6
nop
subu $2,$4,$5
$L6:
j $31
nop
.set macro
.set reorder
.end mod1
.size mod1, .-mod1
.section .text.startup,"ax",@progbits
.align 2
.globl main
.set nomips16
.ent main
.type main, @function
main:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
move $2,$0
j $31
nop
.set macro
.set reorder
.end main
.size main, .-main
.ident "GCC: (OpenWrt/Linaro GCC 4.8-2014.04 r44162) 4.8.3"
查看编译器的输出,前面的指令都不能移动到分支延迟槽中,因此编译器别无选择,只能用nop
指令填充延迟槽。
下面是一个将使用分支延迟槽的示例(当使用-O或更高版本编译时(:
int add_one(int i) {
return i+1;
}
mipsel-linux uclbc objdump输出:
Disassembly of section .text:
00000000 <add_one>:
0: 03e00008 jr ra
4: 24820001 addiu v0,a0,1
...
您使用了哪些gcc优化选项?
使用标志-fno-delayed-branch
可以禁用延迟槽优化。只需使用-fdelayed-branch
即可启用。
您可以将标志-Q--help=optimizer添加到gcc中,以便获得有关使用特定参数组合启用哪些优化的信息。
EDIT:-Q--help=优化器的输出可能会显示您希望gcc启用的选项。然而,gcc可以使用不同的配置/标志。