A Quantitative Approach-appendix K(3)——RISC指令系统的特有指令

A Quantitative Approach-appendix K(3)——RISC指令系统的特有指令

  1. MIPS 64的特有指令

    • 非对齐数据传输指令

      • 大部分程序不会使用这些指令,只有在16位小型机的应用程序,以及快速memcpy/strcpy时,才可能使用到

      • 大部分RISC在遇到非对齐的数据访问时,通常会发生trap。解决办法是分别获取两个字,然后拼接得到结果

      • MIPS的解决方案:提供了四条特殊的加载和存储指令,通过组合可以只用两条指令解决非对齐访问:LWL加载寄存器的左半边,LWR加载寄存器的右半边,SWL/SWR与之对应
        A Quantitative Approach-appendix K(3)——RISC指令系统的特有指令

    • NOR,或非逻辑运算,~(Rs1 | Rs2)

    • 寄存器移位指令中包含了不可用的5位的固定字段

    • syscall,特殊的trap指令,用于实现系统调用

    • CTCi/CFCi,读取或者设置控制寄存器的值

    • Jump/call指令是非PC相关的,直接将立即数移位后和PC拼接使用

    • TLB指令,TLB缺失在MIPS I中由软件处理,因此ISA中包括了操作TLB的指令

    • 倒数和倒数的平方根指令,没有遵从IEEE 754的舍入标准,主要用于执行快速除法和平方根的代码,但是没有高精度要求

    • 条件过程调用指令,BGEZAL当rs1大于等于0时,保存返回地址并且跳转,BLTZAL则是判断rs1是否小于等于0

    • 并行单精度浮点操作指令,MIPS支持使用一条指令在64位寄存器中并行完成两个32位浮点的操作

  2. Alpha的特有指令

    • 不精确的浮点异常(为了高性能)
      • 一般的体系结构要求在触发异常时,异常指令之前的指令都已经执行完,之后的指令都不执行
      • 为了简化流水线执行,Alpha不要求异常需要满足之前的指令都执行完,之后的指令都不执行的要求,但是Alpha提供了TRAPB指令,帮助实现精确异常。TRAPB能够保证之前的算术指令都能够无异常的执行完成,否则将一直停顿。
    • 不支持字节/半字的数据访问(为了高性能,只支持word访问)
      • Alpha认为字节读写会降低数据传输速度。因为字节的读需要增加一个额外的移位,字节的写入,需要从内存中读出后再写入,同时需要重新计算ECC值
      • 为了完成字节的获取和写入,Alpha提供了一组详细的字节操作指令:寄存器的位域扩展和清零(EXTxx),插入位域(INSxx),掩码清零(MSKxx)等
      • 这种方式在初版中有体现,但是结果不好,因此之后又添加进来
    • PAL code指令,为了提供VAX的微指令操作,Alpha提供了一个关闭中断和虚拟地址映射的特权模式。PAL(特权指令库)可以用作TLB管理,内存原子操作,操作系统原语。通过call_pal指令调用PAL码
    • 不支持整数的除法
    • 不对齐读写:LDQ_U和STQ_U,忽略地址的低三位,读写64位数据,然后利用提取指令获取不对齐word
    • 单精度浮点表示为双精度浮点:单精度在内存中为32位,读取到寄存器时,自动转换为64位
    • 浮点寄存器F31固定为0
    • VAX浮点格式:兼容VAX体系结构,同时支持IEEE 754
    • bit count指令,第三版结构中添加的,CTLZ(计算前导0),CTTZ(计算尾部零),CTPOP(word中1的个数)等。这些指令最早在cray的计算机中,用于加解密
  3. SPARC v9的特有指令

    • 寄存器窗口:
      • 用于减少在过程调用时的寄存器traffic(拥挤)。SPARC提供了多个寄存器窗口,每个过程调用分配一个新的寄存器窗口。最后一个过程的公用寄存器与第一个过程的公用寄存器重叠起来,形成一个循环圈。在调用层数很多时,可以循环使用。
      • SPARC支持2到32个窗口,每个窗口可以缓存8个寄存器(最多16个)
      • SPARC使用专门的save/restore指令来显式指示窗口的使用。
      • 指令窗口的缺点在于大量的寄存器会拖慢时钟频率
      • 重叠寄存器窗口的基本思想是:在处理机中设置一个数量比较大的寄存器堆,并把它划分成很多个窗口。每个过程使用其中相邻的3个窗口和一个公共的窗口,而在这些窗口中有一个窗口是与前一个过程共用,还有一个窗口是与下一个过程共用的。与前一过程共用的窗口可以用来存放前一过程传送给本过程的参数,同时也存放本过程传送给前一过程的计算结果。同样,与下一过程共用窗口可以用来存放本过程传送给下一过程的参数和存放下一过程传送给本过程的计算结果。
      • RISC II中采用的重叠寄存器窗口共有138个寄存器,分成17个窗口,其中,有一个由10个寄存器组成的窗口是全局窗口,能被所有过程访问。另外有8个窗口,每个窗口各10个寄存器,分别作为8个过程的局部寄存器。还有8个窗口,每个窗口各有6个寄存器,是相邻两个过程公用的,称为重叠寄存器窗口。每个过程均可以访问32个寄存器,其中,有10个是所有过程公用的全局寄存器,有10个是只供本过程使用的局部寄存器,有6个是与上一过程公用的寄存器,还有6个是与下一过程公用的寄存器
    • fast traps:从单级trap扩展到至少四级trap,允许中断窗口的上溢和下溢的trap处理程序。增加的级别意味着处理程序不需要在代码中显式地检查页面错误或者未对齐的堆栈指针,从而使得中断处理程序更快。SPARC添加了两条指令,用于从多级处理程序返回:retry(重新进入中断)和done(不重新进入)
    • 支持LISP和smalltalk语言:在加法,减法和比较的操作,添加了标记数据类型的支持。最低的两位用于表示操作数是否为整数,因此如果任一操作数未标记为整数或者结果太大,则TADDcc/TSUBcc将设置溢出位,此后的branch指令或者trap指令决定如何解决。(可以解决程序利用一个整数作为地址访问内存的问题)
    • 整数和浮点交叠操作:允许浮点指令和整数指令同时重叠执行。同时浮点也支持求平方根的指令
    • JMPL使用rd保存返回地址寄存器,当rd=r31时,效果和MIPS的JAIR相似,rd=r0时,与JR相似
    • LDSTUB取一个字节到rd中,然后将FF16存储到对应的地址上。可以用于实现信号量
    • 原子操作指令CASA(CASXA),用于比较寄存器中和内存中的32位/64位的大小,如果相等,则交换第二个寄存器和内存中的值
    • XNOR计算与第二个操作数的补码的异或
    • BPcc,BPr,FBPcc包括一个分支预测位,编译器可以利用这个位进行分支提示
    • ILLTRAP引发一个非法指令trap,用于C语言中的总的返回程序的合理执行
    • POPC用于统计操作数*有多少个1
    • nonfaulting loads可以由编译器将其从分支指令之后移动到分支指令之前,进行推测式非故障执行
    • 四精度浮点算术运算和数据传输,即128位浮点操作
    • 乘法的多精度结果:单精度乘法结果为双精度结果,双精度乘法可以得到四精度结果
  4. Power PC的特有指令

    • Branch Registers: Link and Counter(分支寄存器:链接和计数器)
      • 链接寄存器,用于程序调用保存返回地址,不是通用寄存器中的一个。目的:使得返回跳转速度更快,不需要查找寄存器的步骤
      • 计数寄存器:用于循环执行,加快循环的分支执行
      • 更早的获取目标地址,PowerPC提供了两条指令(BCLR,BCCTR)可以从寄存器中获取跳转的目标地址
    • 0号寄存器不强制为0
    • 可以使用单条指令读取或者保存多个寄存器,最多可以是32个寄存器
    • LSW和STSW可以用于获取或者存储定长或者变长的字符串
    • 移位掩码指令可以用于抽取或者插入数值从/到某个位域
    • 代数右移:当操作数为负,并且右移出去一个1,进位位(CA)将会设置为1。目的:可以用于有符号数除以任何2的常数幂
    • CBTLZ计算操作数中的前导零个数
    • SUBFIC用于计算(立即数-RA)
    • 逻辑立即数移位指令:将16位立即数向左移动16位,在执行AND/OR/XOR操作之前
  5. PA-RISC 2.0特有指令

    • nullification:普遍的用于各种算术和逻辑指令中。例如,一条加法指令可以将两个操作数相加,保存相加结果,如果结果为0,则可以跳过之后的一条指令。通过这样的方式,可以省略掉只有一条执行指令的分支

    • PA-RISC 2.0定义了非常丰富的条件分支指令
      A Quantitative Approach-appendix K(3)——RISC指令系统的特有指令

    • PA-RISC在浮点单元中提供了完整的32为整数乘法,但是整数数据必须首先移动到浮点寄存器

    • 十进制操作:COBOL程序(数据处理领域的语言)在计算十进制时,将十进制的数字放到4bits中,而不进行转换,因此PA-RISC提供了32位到十进制之间的加法转换指令,逻辑和运算指令等

    • 跳转指令可以左移索引寄存器三位,然后根据基址寄存器寻址,一般用于case语句

    • PA-RISC有12条提取和插入指令,允许从寄存器中选择或者插入任意位字段

    • PA-RISC提供ADDIL指令来简化32位地址常数的使用。ADDIL将寄存器中值和一个向左调整的21位常量相加,并保存。之后的数据传输指令使用相对于之前保存的值的11位的偏移地址,进行地址索引

    • PA-RISC有9条调试指令,可以在指令或数据地址上设置断点并返回被捕获的地址

    • Load/clear指令能够提供信号量或者锁的功能,能够从内存中读取一个值,然后写入0

    • 针对于存储短字节,优化了未对齐的数据移动,根据指令选项和条件码,可以将一个字中的最左或者最右的字节移动到有效地址

    • 软件控制的预取,例如将寄存器0作为目标地址的load即为预取

    • PA-RISC 2.0扩展了cache hints,提供了更多的cache操作,例如指示存储器如果当前cache中不包含某个数据,则不要将其放入cache中

    • 可选的分支目标堆栈,用于预测子例程返回。软件可以建议将哪些地址放置在分支目标栈中并从其移除,但硬件控制这些地址是否有效

    • PA-RISC 2.0 增加了浮点的乘加和乘减运算

  6. ARM的特有指令(v4)

    • 条件执行指令,每条指令的开头有4位可以标识执行条件
    • 12位立即数的特有解释方式。
    • 操作数移位不局限于立即数,所有的算术和逻辑操作的第二个寄存器都可以在操作之前进行移位。
    • block loads和stores:在指令中的16位掩码的控制下,16个寄存器任意组合都可以被存储/读取,并且只需要一条指令。这些指令可以用于过程调用,块内存复制等
    • reverse subtract(反向减法,RSB)允许使用立即数或者是移位之后的寄存器减去第一个寄存器
    • 长乘法,类似于MIPS的乘法,利用两个特定的寄存器保存乘法的结果
    • 没有整数除法的硬件支持
    • 条件trap,(所有的ARM指令都可以支持条件执行)
    • 协处理器接口,ARM定义了一整套协处理器指令:数据传输,通用寄存器和协处理器寄存器之间的移动,以及协处理器操作
    • 利用协处理器的接口定义了浮点体系结构
    • 跳转和切换指令集: BX 指令可以切换ARM和Thumb模式, 低31位表示跳转的目标地址, 最高位决定是ARM(1)还是 Thumb(0)
  7. Thumb的特有指令

    • Thumb的指令在硬件上被转换为常规的ARM指令执行,但是有一些区别
      • 条件执行被删除
      • 只提供了前8个寄存器的使用,某些指令隐式使用特殊寄存器
      • 使用两操作数节省空间
      • 使用单独的移位指令完成移位操作
      • 寻址模式更加简单,指令格式更多
    • 相对于ARM的变化
      • 逻辑立即数指令被删除
      • 条件码称为隐式的,不是可选的设置条件码,需要由操作码定义之前的功能。所有Alu指令和数据传输指令都不设置条件码
      • Hi/Lo寄存器的访问形式:16个ARM寄存器被分为Hi和Lo寄存器,8个Hi寄存器包括SP,链接寄存器,PC。ALU可以使用所有Lo寄存器
      • 分支和过程调用的距离:branch的8位立即数左移1位作为偏址。过程调用需要两条指令指令,每条指令提供11位,组合之后形成22位,然后移动1位。
      • 数据传输偏移量:对于普通寄存器的load/store是5位的偏移量,对于SP/PC是8位的偏移量(隐含在操作码中)
  8. SuperH的特有指令

    • Decrement and test:将一个寄存器的内容递减,如果结果为0,特殊的标志为T bit会被设置为1
    • 可选的延迟分支,BT和BF
    • 许多类型的乘法,针对于有符号和无符号,数据宽度等
    • 支持零扩展和符号扩展
    • 单位移位指令每次只能够移动一位(可能是为了适应指令长度为16 bits)
    • 可变的移位指令,根据寄存器中的数值的符号,判断移动的方向,支持逻辑和算术移位
    • swap:交换32位字或者是16位半字的高一半和低一半
    • 提取32位字,将两个寄存器组成的64位长字中间的32位提取到另一个寄存器
    • cache 预取指令,PREF
    • test-and-set指令
  9. M32R的特有指令

    • 指令之间可以通过一个指令中的指示位来标明相互之间是否可以并行,从而形成类似于VLIW的效果
    • 所有的分支偏移会向左移动两位之后再使用,但是指令长度是16位,因此意味着有些地址是无法跳转到的
    • 除法的结果是余数而不是商
  10. MIPS 16的特有指令

    • 32位MIPS体系结构的16位扩展,兼容32位地址的MIPS(I,II)和64位(III,IV,V)
    • MIPS不支持在单个过程中混合两种长度的指令,除了JAL和JALX,因为这两条指令在16位模式下,也需要32位(更长的跳转地址)
    • MIPS 16支持三操作数指令,每个操作数是8个寄存器。但是MIPS16 支持将这8个寄存器和完整的MIPS体系结构的剩余24个寄存器之间进行值复制。
    • SP被看作是一个单独的寄存器,使用操作码进行指令,从而减少8个可见寄存器的压力
    • MIPS 16的立即数域宽度为5-8位,但是提供了扩展短立即数的方法。使用EXTEND指令增加立即数的宽度
    • MIPS 16相对于MIPS的变化
      • 删除有符号的算术指令
      • 删除了立即数逻辑运算指令
      • BEQ,BNE等类型的指令没有支持,而是使用set-on-less指令,并且使用新的T寄存器和新的分支指令用于测试T寄存器,然后进行跳转
      • 分支跳转距离:立即数左移1位
      • 延迟分支消失,跳转仍然有一个延迟分支槽
      • 数据传输的偏移地址扩展是零扩展,而不是32位模式下的符号扩展
      • 重新定义0,在移位指令中,3位的移位域如果为0代表需要移动8位
      • 0号寄存器不再代表零,所以需要一些新的指令
  11. RISC的发展系谱图
    A Quantitative Approach-appendix K(3)——RISC指令系统的特有指令