MIPS32的ADDI和ADDIU的实现要点(加法指令)

《自己动手写CPU》一书中对指令ADDI和ADDIU的实现方式是一样的。

对16位立即数imm,在执行加法指令之前都符号扩展成32位数(与符号扩展对应的是零扩展)。

这样看来ADDI和ADDIU指令都用于有符号数的加法,在指令集实现的时候没有任何区别。

如果是这种情况,那么ADDI和ADDIU都仅支持有符号数的加法,否则ADDI和ADDIU指令执行无符号加法的时候就会出错:

如32'b0001+16'b1000_0000_0000_0001

按照无符号加法,这是 1 + 32769 = 32770。

然而 16'b1000_0000_0000_0001 经过符号扩展变成 32'b1111_1111_1111_1111_1000_0000_0000_0001(4294934529)

相加的结果变成 1 + 4294934529 = 4294934530,显然不正确。

 

那么ADDI和ADDIU是否仅能够支持有符号加法?ADDIU中的U是否unsigned的意思?

在《MD00565-2B-MIPS32-QRC-01.01》文档中对ADDI和ADDIU有明确的说明:

这里±的意思是:

另外在《MIPS Instruction Reference》文档中对此也有明确的说明:

这两个文档都突出说明了ADDI和ADDIU的最大区别是有没有溢出标志(overflow)。

 

《MIPS体系结构剖析》(英文书名是see mips run linux)中对于带U和不带U的助记符描述如下:

这里将加法指令ADD和ADDU的区别描述为是否带“自陷”(异常,如检查除数为0)或者溢出检测,而非有符号无符号加法的区别。

 

那么ADDI的溢出判断需要怎么做?可以参考以下两个文档:

http://blog.csdn.net/u011225147/article/details/53707614

https://wenku.baidu.com/view/bbad4e73f46527d3240ce04d.html

 

那么最后总结ADDI和ADDIU的实现有以下2个要点:

1)仅支持有符号运算(补码运算),16位立即数需要进行符号扩展;

2)ADDI带有溢出检测(或者说带“自陷”功能,虽然不常用)。

 

posted on 2017-09-13 10:22  再见,列宁  阅读(12145)  评论(0编辑  收藏  举报

导航