微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 模拟电路设计 > Xtensa处理器窗寄存器函数调用机制与应用

Xtensa处理器窗寄存器函数调用机制与应用

时间:10-10 来源:互联网 点击:

现代处理器为了更好的支持高级编程语言的高效编译,通常处理器所拥有的通用寄存器的数目都有16个甚至32个之多,如此多的寄存器在比较复杂的应用程序上实现深度嵌套调用的时候,为了保证程序的正确执行,寄存器要频繁的进行入栈和出栈操作,这样频繁的堆栈存储器访问将明显降低应用程序的性能,为有效解决这一问题,tensilica的Xtensa架构设计了一种Windows旋转方式的寄存器管理机制,将逻辑寄存器和物理寄存器分开,在函数调用的时候通过windows滑动切换逻辑寄存器,从而避免寄存器覆盖,减少压栈和出栈的操作,更大限度的提高性能。

  以一个MP3解码器为例(如表1),假设外部存储器的访问的R/W等待cycles分别为100和20,可以看到采用Call8的windows旋转大幅减少MCPS到9%之多。

表1:MP3解码器。

  那么Windows寄存器机制是如何工作的,它又有那些典型应用呢? 本文将详细阐述这一主题。

  寄存器Windows函数调用机制原理

  1.AR物理寄存器环形Buffer

  该方法的基本实现原理是用更多的物理AR寄存器组成一个环形的buffer,这些物理寄存器每4个为一组(pane),用一个WindowStart的每个比特依次表示是否该组作为逻辑寄存器窗口的起始位置或者占用,当前的逻辑寄存器的起始位置则用WindowBase状态寄存器来表示。如图1,在发生函数调用的时候则通过修改WindowBase寄存器,滑动逻辑寄存器窗口,设置相应的WindowStart比特标识当前逻辑窗口在环形物理AR寄存器buffer中的位置。这样父子函数看到的是不同的物理寄存器,避免了寄存器的压栈和出栈。要说明的是,如果AR物理寄存器的数目为NAREG,则WindowStart的比特数则为NAREG/4,而WindowBase的比特位数则为log(NAREG/4),如图1所示,物理寄存器数为32,则WindowStart比特数为8,WindowBase比特数则为3.

图1:Windows AR寄存器环形buffer.

  2.Windows ABI函数调用规范

  以每4个寄存器(pane)为单位,函数调用的时候窗口可以滑动4个、8个、或者12个物理寄存器,分别可以用call4、call8、call12指令来实现,而最典型的应用则为call8,在c语言层面,编译器通过XPG的core配置,可以为函数调用分别产生非windows机制的call0和call8,那么call8的Windows ABI函数调用规范是怎样的呢? 参考图2,左上角说明的是子函数调用约用规范,a0被用来保存返回地址,a1则为sp堆栈指针,a2~a7则用来传递函数入参,参数超过6个的时候则需要使用堆栈了,以对调用者函数和被调用函数来说,a0~a7为独立的寄存器,可以自由使用,而a8~a15则为scratch寄存器,随时会被子函数使用,调用者函数如果要使用,则在调用子函数前要压栈保存。

图2:Window ABI调用规范。

  为方便寄存器正常的保存与恢复,以及调用栈的高效回溯,有必要对函数的Frame栈空间做统一的安排,在call8的Windows ABI规范下,Tensilica进行了如下设计(如图3)。

图3:Windows ABI堆栈布局。

  每级函数FrAME下包含有Base Area用于存储其父函数的基本寄存器a0~a3,可能的extra area保存其子函数的扩展寄存器a4~a7(call8),或者a4~a11(call12),函数局部变量(非寄存器变量)和alloc分配空间,及用于传子函数所需要的栈空间等等。

  当较新的深度函数Fun(i)的寄存器窗口覆盖到过去的函数Fun(p)时,基本寄存器a0~a3保存到Fun(p+1)的basic area,额外的寄存器则存入Fun(p)的extra area,当函数Fun(p+1)返回时,如果检测到underflow则相应地将base area和extra area的寄存器恢复到Fun(p)的活动窗口,读者可以参考Tensilica的代码体会一下,这样的布局在压栈和恢复的时候代码是最高效和节省空间的。

3.Windows寄存器覆盖问题

  物理AR寄存器的数目是有限的,典型情况下,32个物理寄存器发生深度为3次,64个AR发生7次的函数调用后将会覆盖到原来的函数寄存器窗,那么如何有效检测和处理寄存器overflow问题呢?

  寄存器的覆盖检测只发生在如下两种情况:

  函数调用时,参考如下硬件semanTIcs:

  CALLn/CALLXn

  PS.CALLINC ← n32

  AR[n||2'b00] ← n || (PC + 3)290

  ENTRY s,imm12

  WindowCheck (00,PS.CALLINC,00)

  if as > 3 | PS.WOE = 0 | PS.EXCM = 1 then

  -- undefined operatiON

  -- may raise illegal instruction exception

  else

  AR[PS.CALLINC||s10] ← AR[s]- (017||imm12||03)

  WindowBase ← WindowBase + (02||PS.CALLINC)

  WindowStartWindowBase ← 1

  endif

在发生函数调用,执行call指令的时候,窗递增值(call4、call8、call12分别对应1、2、3)存入PS处理器状态寄存器的CALLINC域,在进入函数的入

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top