在MIPS中扩展或避免addiu

时间:2019-07-05 09:14:01

标签: c mips

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

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

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

  1. 操纵或访问堆栈指针和框架指针的值。我曾考虑过将加数硬编码为常量,但是我不确定这是否有可能或是否会更改所讨论的值。
    e.g. addiu   $sp,$sp,-3840
    e.g. addiu   $3,$fp,52
  1. 使用%hi和%lo分别访问32位整数的高/低部分并将它们加在一起
e.g.    lui     $2,%hi(output_layer.3511)
        addiu   $2,$2,%lo(output_layer.3511)

注意:output_layer是一个32位整数数组。

  1. 我在C语言中编译“ mod”函数时出现的addiu指令(扩展mod函数以“以困难的方式”获得其余部分无济于事),例如C中的fracPart = currentInput % 256; 编译为
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。

2 个答案:

答案 0 :(得分:1)

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

因此,您可以将所有addiu替换为addi。

  

操纵或访问堆栈指针和框架指针的值。我曾考虑过将加数硬编码为常量,但是我不确定这是否有可能或是否会更改所讨论的值。

用addi替换addi没问题。没有理智的软件可以在sp / fp中创建在这种情况下可能产生溢出的地址。

  

使用%hi和%lo分别访问32位整数的高/低部分并将它们加在一起

您可以使用addi,但是人们通常使用ori来执行此操作。

lui     $2,%hi(output_layer.3511)
ori     $2,$2,%lo(output_layer.3511)

无论哪种情况,都没有溢出的风险(因为lui清除了16 LSB),并且addi,addiu和ori严格相等。

  

当我在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)

这段代码似乎很奇怪。为什么不用

替换两行(li + ori)
    li      $2, 0xffffffff800000ff

最后一部分(在bgez之后)仅由严格的负数执行,对于它们,它等效于带有0xffffffffffffff00的or,并且成对的addiu似乎没用...
无论如何,它们也可以由addi代替。

编辑:

如果addi不可用,则可以将立即数复制到一个空闲寄存器中,然后对该寄存器执行添加/添加。在大多数MIPS约定中,$ 1由asm用于存储临时文件,而编译器从不使用它们。因此,您可以自由使用它(前提是您不使用可能会使用此寄存器的宏)。

addiu的系统翻译可以是

    addiu $d, $s, imm
## ->
    ori   $1, $0, imm
    add   $d, $s, $1

ori和add都是真实的指令,可以安全地使用$ 1。在某些汇编程序中,必须使用$ at(临时汇编程序)代替$ 1。

答案 1 :(得分:0)

  

我在开发新微处理器的实验室工作,所以这种微型处理器无法在市场上买到。

根据我对您的陈述的理解,编译器也在开发中。您应该与开发编译器的团队讨论这个问题,以便他们可以考虑您的需求。