寄存器窗口(register windows)
SPARC 最独特的特性是寄存器窗口,一种优化函数调用阶段的手段。 每次调用,都会分配一个新的缓存窗口,来缓存需要压栈的寄存器。 窗口的数量是一个限制,因此,实现上采用的是环形缓存。权衡消耗和性能之后,大概6到8个缓存窗口是最优的设计。
实际上SPARC支持2到32个窗口,每个窗口一般会缓存8个寄存器,包括全局变量,局部变量,传入参数,返回参数。(每个窗口最多可以有16个不同的寄存器,SPARC体系结构硬件实现最少会有40个寄存器,最多可以达到520个寄存器,到目前为止,大多数设计都采用128到136个寄存器。) 窗口的使用方面,调用和返回指令并不会触发窗口使用,SPARC 有专门的 SAVE 和 RESTORE 指令来触发窗口使用。 SAVE 会指向下一个寄存器窗口,也就相当于保存了调用函数的窗口。 有一个重点是源寄存器在调用者的窗口,而目标寄存器位于被调用者的窗口中。 SPARC编译器通常使用此指令来更改堆栈指针,以在新的堆栈帧中分配局部变量。 RESTORE 跟 SAVE 相反,从被调用者的窗口返回到调用者的窗口。 这将自动释放堆栈帧。 编译器也可以利用它来生成被调用方的最终返回值。
寄存器窗口的缺点是大量的寄存器可能会拖慢时钟频率。 虽然在早期这点看起来不是问题。 SPARC体系结构(有寄存器窗口)和 MIPS R2000 体系结构 (没有寄存器窗口) 都是从 1987 就存在。 几次更新换代下来, 虽然使用了类似的技术,但是 SPARC 的频率都没有比 MIPS 的时钟频率慢, 也许这是因为 cache 的存在掩盖了这一点。 最近一代计算机使用了不同的技术策略 —— 一个是顺序,一个是乱序 —— 但是看起来寄存器的数量也不大会影响到时钟频率。 最近,Tensilica和IA-64也添加了寄存器窗口。
寄存器窗口的缺点是大量的寄存器可能会拖慢时钟频率。 在早期频率低的时代,这点看起来当然不是问题。 实际上,SPARC体系结构(有寄存器窗口)和 MIPS R2000 体系结构 (没有寄存器窗口) 都是从 1987 就存在,几次更新换代下来,虽然使用了类似的技术,但是 SPARC 的频率都没有比 MIPS 的时钟频率慢, 也许这是因为 cache 的存在掩盖了这一点。 最近一代设计虽然使用了不同的技术策略 —— 一个是顺序,一个是乱序 —— 但是看起来寄存器的数量也不大会影响到时钟频率。 最近,Tensilica和IA-64也添加了寄存器窗口。
另一种数据传输的特性是load和store的可选项。 这可以简化外设输入输出和控制寄存器的操作。
快速 trap
SPARC 第9版支持了快速trap。 从单级trap扩展到到至少4级trap, 允许获取到窗口的上溢和下溢中断。 额外的级别意味着处理程序不需要在代码中显式地检查页面错误或未对齐的堆栈指针,从而使处理程序更快。 添加了两个新的指令,从这个多级处理程序返回:RETRY(重新进入中断的指令)和 DONE(不重新进入)。 为了支持用户级 trap ,RETURN 指令还可以从非特权模式 trap 返回。
支持 LISP 和 Smalltalk
剩下的主要特性是算术加法和减法。 SPARC 的设计者参考了LISP和Smalltalk等编程语言,并且影响了前面提到的一些功能:寄存器窗口,条件trap指令,带32位指令地址的调用和多字算术(参见Taylor et al [1986]和Ungar等[1984])。 对加法,减法和比较的操作, 添加了标记数据类型的支持。 两个最低有效位表示操作数是否为整数(编码为00), 因此如果任一操作数未被标记为整数或结果太大, 则TADDcc和TSUBCC将设置溢出位。 随后的条件分支或trap指令可以决定要做什么。 (如果操作数不是整数, 软件会恢复操作数, 检查操作数的类型, 并根据这些类型调用正确的操作。) 事实证明,不对齐的内存访问trap也可以用于标记的数据, 因为从具有错误标签的指针加载可能是无效的访问。
整数和浮点交叠操作
SPARC允许用浮点指令执行整数指令操作。 在这种情况下,要从中断恢复,SPARC有一个待处理的浮点指令队列及其地址。 RDPR允许处理器清空队列。 第二个浮点特征是包含浮点平方根指令FSQRTS,FSQRTD和FSQRTQ。
其余指令
SPARC 剩余的独有特性如下:
- JMPL 使用 Rd 来指定返回地址寄存器, 因此指定 r31 与 MIPS 中的 JAIR 相似, 指定 r0 与 JR 相似。
- LDSTUB 加载单个字节到 Rd , 并且保存 FF16 到地址字节。 这种指令可以用来实现信号量。
- CASA (CASXA) 是一条原子操作指令,比较寄存器中和内存中的32位(64位)值,如果相等,则交换第二个寄存器和内存中的值。 这条第九版的指令可以用来实现没有锁的无等待同步算法。
- XNOR 计算与第二个操作数的补码的异或。
- BPcc, BPr, 和 FBPcc 包括一个分支预测位,编译器可以利用这个位来告诉计算机哪个分支更可能执行。
- ILLTRAP 引发一个非法指令trap。 Muchnick [1988] 解释了如何将其正确运用在C的返回返回程序中。
- POPC 统计操作数中总共有多少个位被置位。 第三版 alpha 体系结构也有这条指令。
- 不会触发失败的 load 操作运行编译器将其移动到条件控制前。
- 四精度浮点算术和数据传输,允许浮点寄存器操作128位的浮点。
- 乘法的多精度浮点结果指的是,两个单精度相乘可以得到一个双精度结果,两个双精度结果相乘可以得到一个四精度结果。这些指令可以用在处理复杂和特定的一些浮点算术中。