自己动手写CPU之第九阶段(2)——加载存储指令说明2(lwl、lwr)

将陆续上传新书《自己动手写CPU》,今天是第38篇,我尽量每周四篇,但是最近已经很久没有实现这个目标了,一直都有事,不好意思哈。

开展晒书评送书活动,在亚马逊、京东、当当三大图书网站上,发表《自己动手写CPU》书评的前十名读者,均可获赠《步步惊芯——软核处理器内部设计分析》一书,大家踊跃参与吧!活动时间:2014-9-11至2014-10-20


今天继续对MIPS32中加载存储指令进行说明(主要是lwl、lwr),上次已经介绍一些其他的加载存储指令,大家可以回顾。


9.1.4 加载指令lwllwr说明

      加载指令lwllwr的格式如图9-6所示。


  •  当指令中的指令码为6'b100010时,是lwl指令,非对齐加载指令,向左加载

      指令用法为:lwl rt, offset(base)

      指令作用为:从内存中指定的加载地址处,加载一个字的最高有效部分。lwl指令对加载地址没有要求,从而允许地址非对齐加载,这是与前面介绍的lhlhulw指令的不同之处。在大端模式、小端模式下,lwl指令的效果不同,因为OpenMIPS是大端模式,所以此处只介绍在大端模式下lwl指令的效果。假设计算出来的加载地址是loadaddrloadaddr的最低两位的值为n,将loadaddr最低两位设为0后的值称为loadaddr_align,如下。

加载地址loadaddr = signed_extended(offset) + GPR[base]

n = loadaddr[1:0]

loadaddr_align = loadaddr – n

      例如:假设计算出来的加载地址是5lwl指令要从地址5加载数据,那么loadaddr就等于5n等于1loadaddr_align等于4

      lwl指令的作用是从地址为loadaddr_align处加载一个字,也就是4个字节,然后将这个字的最低4-n个字节保存到地址为rt的通用寄存器的高位,并且保持低位不变。

      继续上例,此时loadaddr_align4,所以从地址4处加载一个字,对应的是地址为4567的字节,因为n等于1,所以将加载到的字的最低3个字节保存到地址rt的通用寄存器的高3个字节。如图9-7所示。一个更加通用的描述如图9-8所示。


  •  当指令中的指令码为6'b100110时,是lwr指令,非对齐加载指令,向右加载

      指令用法为:lwr rt, offset(base)

      指令作用为:从内存中指定的加载地址处,加载一个字的最低有效部分。还是假设计算出来的加载地址是loadaddrloadaddr的最低两位的值为n,将loadaddr最低两位设为0后的值称为loadaddr_align,如下。

加载地址loadaddr = signed_extended(offset) + GPR[base]

n = loadaddr[1:0]

loadaddr_align = loadaddr – n

      例如:假设计算出来的加载地址是9lwr指令要从地址9加载数据,那么loadaddr就等于9n等于1loadaddr_align等于8

      lwr指令的作用是从地址为loadaddr_align处加载一个字,也就是4个字节,然后将这个字的最高n+1个字节保存到地址为rt的通用寄存器的低位,并且保持高位不变。

      继续上例,此时loadaddr_align8,所以从地址8处加载一个字,对应的是地址为891011的字节,因为n等于1,所以将加载到的字的最高2个字节保存到地址rt的通用寄存器的低2个字节。如图9-9所示。一个更加通用的描述如图9-10所示。


      lwllwr指令配合可以实现从一个非对齐地址加载一个字,而且只需要使用2条指令,提高了效率。例如:使用一般指令从地址7处加载一个字,那么可以使用以下代码实现,共5条指令。

lw  $1, 4($0)          # 取得地址0x4处的字,保存在$1中
lw  $2, 8($0)          # 取得地址0x8处的字,保存在$2中
sll $1, $1, 24         # $1左移24位
slr $2, $2, 8          # $2右移8位
or  $1, $1, $2         # $1与$2进行逻辑“或”运算,得到最终结果

      而有了lwllwr指令后,只需要2条指令即可。如下,图9-11是对这个过程的描述。

lwl $1, 7($0)
lwr $1,10($0)



展开阅读全文

没有更多推荐了,返回首页