【问题标题】:Get conditional branch slot from MIPS cross compiler从 MIPS 交叉编译器获取条件分支槽
【发布时间】:2015-08-23 17:09:25
【问题描述】:

如何使用 mipsel-openwrt-linux-gcc 交叉编译器获得条件分支槽,其中来自分支之前或之后的指令被移动以填充槽?

我只是使用命令获取MIPS代码:

./mipsel-openwrt-linux-gcc -O2 -fno-delayed-branch -S ha.c;

但是,我只是在 bne 指令之后得到 nop 指令。 -O2 和 -fno-delayed-branch 选项似乎不起作用。

这里是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.s的内容

    .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"

【问题讨论】:

  • 看起来一切都被优化了。没有 bne 说明。
  • @RichardPennington,我只是修改了问题中的C代码和MIPS代码。它们旁边确实有 ben 指令和 nop 指令。我该怎么办?

标签: architecture mips cross-compiling pipeline branch-prediction


【解决方案1】:

查看编译器输出,前面的指令都不能移动到分支延迟槽中,因此编译器别无选择,只能用nop指令填充延迟槽。

这是一个将使用分支延迟槽的示例(使用 -O 或更高版本编译时):

int add_one(int i) {
  return i+1;
}

mipsel-linux-uclibc-objdump 输出:

Disassembly of section .text:

00000000 <add_one>:
   0:   03e00008        jr      ra
   4:   24820001        addiu   v0,a0,1
        ...

您使用了哪些 gcc 优化选项?

【讨论】:

  • 我终于用-O2选项解决了这个问题。无论如何,谢谢!
【解决方案2】:

使用-fno-delayed-branch 标志,您将禁用延迟槽优化。只需使用-fdelayed-branch 即可启用它。

您可以向 gcc 添加标志 -Q --help=optimizers 以获取有关使用特定参数组合启用哪些优化的信息。

编辑: -Q --help=optimizers 的输出可能会显示您希望 gcc 启用的选项。但是 gcc 可以使用不同的配置/标志。

【讨论】:

    猜你喜欢
    • 2011-06-12
    • 1970-01-01
    • 2011-07-14
    • 2019-01-18
    • 2018-05-31
    • 2017-08-29
    • 2019-09-27
    • 2019-01-21
    • 1970-01-01
    相关资源
    最近更新 更多