SPARC 体系结构之寄存器窗口结构

SPARC 体系结构之寄存器窗口结构

 

当前版本: 1.0
完成日期: 2009-04-01
作者: Jack Tan
Email: jiankemeng@gmail.com
版权声明: 转载请注明出处,商业用途请联系作者

 

A. 窗口结构

任一时刻 SPARC 的 GPR “视图” 为:

 

 

其中 r8 ~ r31 为一个窗口,实际实现时 V9 规定需有 3 ~ 32 个窗口。

引入多窗口的初衷主要是为了尽可能规避函数调用时保存用户上下文的存储器访问。

为了平滑父子函数间的参数传递和返回值传递,SPARC 将多个窗口组织为:

 

 

相邻窗口间 8 个寄存器重叠,即:

当前窗口的 o0~ o7 和下一个窗口的 i0 ~ i7 对应于同一组物理寄存器;
当前窗口的 i0 ~ i7 和上一窗口的 o0 ~ o7 也是对应于同一组物理寄存器;
所有窗口的 local 寄存器绝对独立,这也是其取名为 local 的原因 :)

结合 ABI 粗略来看,就是当前的输入参数来自于上一个窗口的输出参数,当前的输出参数即是下一个窗口的输入参数!

另外需要特别留意的是,最后一个窗口的输出寄存器组 (o0 ~ o7) 与第一个窗口的输入寄存器组 (i0 ~ i7) 也是重叠的,这样整个寄存器窗口看起来就是一个圆。

则对于 SPARC V9,其 GPR 的数目范围为:

64 ~ 528
(3 x 16 + (8 + 8)) <= N_GPR <= (32 x 16 + (8 + 8))
窗口范围为 3 ~ 32,相邻的窗口 8 个重叠,则实际窗口内的“独立”寄存器为 16,加上 16 个全局寄存器即得。

而对于 UltraSPARC 2007 其 GPR 数目的范围为:

72 ~ 640
(3 x 16 + (8 x 3)) <= N_GPR <= (32 x 16 + (8 x 16)),只因其全局寄存器组数的范围为 3 ~ 16

 

B. 窗口管理初步

为了支持窗口的管理,SPARC 引入了 5 个特权寄存器,一组指令和几个异常来管理窗口。

其中 CWP (Current Window Pointer) 寄存器指定当前使用的窗口(实际置窗口的编号,从 0 开始),则正常情形下,函数调用时都需转动 CWP,以获取一个新的窗口,则在设计 ‘CALL’ 指令(用于支持函数调用)时,理应让其内含 CWP += 1 操作,一如用于函数返回的 ‘RETURN’ 指令内含 CWP -= 1 操作一样,但 SPARC 设计时,为了支持一些特殊的叶函数能直接使用父函数的窗口,尽可能降低开销,其让所有用于函数调用的指令 ‘CALL’ 和 ‘JMPL’ 都不去影响 CWP,而要子函数自己负责,则非叶子函数的第一条指令就是用’SAVE’ 转动 CWP 同时分配栈空间(更新 sp 的值)

可以想见,当调用链达到一定的深度后,窗口肯定会不够用,这个时候,处理器就会抛出一个异常,由 OS 来负责保存窗口到栈并释放窗口,关于这个层面的窗口管理,留待以后讨论吧。

 

 

发表评论

6 + 7 = ?