我已经用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
e.g. lui $2,%hi(output_layer.3511)
addiu $2,$2,%lo(output_layer.3511)
注意:output_layer是一个32位整数数组。
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。
答案 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)
我在开发新微处理器的实验室工作,所以这种微型处理器无法在市场上买到。
根据我对您的陈述的理解,编译器也在开发中。您应该与开发编译器的团队讨论这个问题,以便他们可以考虑您的需求。