gpt4 book ai didi

c - 在 MIPS 中扩展或避免 addiu

转载 作者:行者123 更新时间:2023-12-04 16:22:04 25 4
gpt4 key购买 nike

我已经用 C 语言实现了一个程序(一个全连接层),它需要编译成 MIPS 才能在特定的微处理器上运行,以便测试微处理器的功能。由于 ADDIU 指令不是该处理器指令集的一部分,我正在编辑 C 程序以在编译时生成更少的 ADDIU 指令,并尝试从 MIPS 代码中编辑剩余的指令(允许 ADD 和 ADDU)。但是,我是 MIPS 的新手,希望确保我的编辑不会改变程序的功能。是否有使用其他指令的 ADDIU 扩展?如果没有,关于如何更改程序逻辑以避免使用它们的任何想法?

我正在为具有有限 MIPS 指令集的特定微处理器开发测试。编译代码中的许多有问题的指令可以扩展为仅使用集合中的指令,因此我将编辑编译代码以包含这些扩展。但是,根据我看到的扩展指南,ADDIU 似乎没有扩展。

我已经通过将常用值存储为常量来摆脱一些 ADDIU 指令,因此我可以在其余 C 代码中引用变量而不是文字,从而产生 ADDU 指令(这是允许的)。我无法编辑的 ADDIU 指令出现在以下位置:

  • 操作或访问堆栈和帧指针的值。我曾考虑将加数硬编码为常量,但我不确定这是否可行,或者是否会改变相关值。
  •     e.g. addiu   $sp,$sp,-3840
    e.g. addiu $3,$fp,52
  • 使用 %hi 和 %lo 分别访问 32 位整数的高/低部分并将它们加在一起 ​​
  • e.g.    lui     $2,%hi(output_layer.3511)
    addiu $2,$2,%lo(output_layer.3511)

    注意:output_layer 是一个 32 位整数数组。
  • 当我在 C 中编译“mod”函数时出现的 Addiu 指令(扩展 mod 函数以“艰难的方式”获得剩余部分没有帮助)例如fracPart = currentInput % 256;在 C
    编译为
  • lw      $3,40($fp)
    li $2,-2147483648 # 0xffffffff80000000
    ori $2,$2,0xff
    and $2,$3,$2
    bgez $2,$L17
    nop

    addiu $2,$2,-1
    li $3,-256 # 0xffffffffffffff00
    or $2,$2,$3
    addiu $2,$2,1
    $L17:
    sw $2,48($fp)

    目标是工作 MIPS 代码,它只包含这个特定微处理器指令集中的指令,不包括 ADDIU。

    最佳答案

    addiu 和 addi 几乎相同。唯一的区别是addi在加法出现溢出时会产生异常,而addiu不会产生溢出。

    所以,你可以用addi替换所有addiu。

    Manipulating or accessing the values of the stack and frame pointers. I've thought about hard-coding the addends as constants, but I'm not sure if that's even possible or if it would change the values in question.



    用 addi 替换 addi 没问题。任何健全的软件都无法在 sp/fp 中创建在这种情况下会产生溢出的地址。

    Accessing the high/low parts of 32-bit integers separately using %hi and %lo and adding them together



    您可以使用 addi,但人们通常使用 ori 进行此操作。
    lui     $2,%hi(output_layer.3511)
    ori $2,$2,%lo(output_layer.3511)

    在任何一种情况下,都不存在溢出的风险(因为 16 LSB 被 lui 清除)并且 addi、addiu 和 ori 是严格等效的。

    Addiu instructions that occur when I compile the "mod" function in C (expanding the mod function to get the remainder "the hard way" didn't help) e.g. fracPart = currentInput % 256; in C compiles to


       lw      $3,40($fp)
    li $2,-2147483648 # 0xffffffff80000000
    ori $2,$2,0xff
    and $2,$3,$2
    bgez $2,$L17
    nop

    addiu $2,$2,-1
    li $3,-256 # 0xffffffffffffff00
    or $2,$2,$3
    addiu $2,$2,1
    $L17:
    sw $2,48($fp)

    这段代码看起来很奇怪。为什么不将两行 (li+ori) 替换为
        li      $2, 0xffffffff800000ff

    最后一部分(在 bgez 之后)仅由严格的负数执行,对它们来说,它相当于 or用0xffffffffffffff00,这对addiu似乎没用……
    反正他们也可以用addi代替。

    编辑:

    如果 addi 不可用,您可以在空闲寄存器中复制立即数,然后使用该寄存器执行 add/addu。在大多数 MIPS 约定中,$1 用于存储 asm 的临时数据,并且从未被编译器使用。所以你可以自由使用它(前提是你不使用可能使用这个寄存器的宏)。

    addiu 的系统翻译可以是
        addiu $d, $s, imm
    ## ->
    ori $1, $0, imm
    add $d, $s, $1

    ori 和 add 都是真正的指令,$1 可以安全使用。在某些汇编器中,您必须使用 $at(汇编器临时)而不是 $1。

    关于c - 在 MIPS 中扩展或避免 addiu,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56900055/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com