a一级爱做片免费观看欧美,久久国产一区二区,日本一二三区免费,久草视频手机在线观看

新聞中心

EEPW首頁 > 模擬技術 > 設計應用 > Xtensa處理器窗寄存器函數調用機制與應用

Xtensa處理器窗寄存器函數調用機制與應用

作者: 時間:2012-10-10 來源:網絡 收藏

現代為了更好的支持高級編程語言的高效編譯,通常所擁有的通用的數目都有16個甚至32個之多,如此多的在比較復雜的應用程序上實現深度嵌套調用的時候,為了保證程序的正確執行,要頻繁的進行入棧和出棧操作,這樣頻繁的堆棧存儲器訪問將明顯降低應用程序的性能,為有效解決這一問題,tensilica的架構設計了一種Windows旋轉方式的寄存器管理機制,將邏輯寄存器和物理寄存器分開,在調用的時候通過windows滑動切換邏輯寄存器,從而避免寄存器覆蓋,減少壓棧和出棧的操作,更大限度的提高性能。

本文引用地址:http://www.j9360.com/article/185680.htm

  以一個MP3解碼器為例(如表1),假設外部存儲器的訪問的R/W等待cycles分別為100和20,可以看到采用Call8的windows旋轉大幅減少MCPS到9%之多。

表1:MP3解碼器。

表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.

圖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調用規范。

圖2:Window ABI調用規范。

  為方便寄存器正常的保存與恢復,以及調用棧的高效回溯,有必要對函數的Frame棧空間做統一的安排,在call8的Windows ABI規范下,Tensilica進行了如下設計(如圖3)。

圖3:Windows ABI堆棧布局。

圖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域,在進入函數的入口處ENTRY指令將首先進行Window重疊檢測,條件滿足的時候將觸發相應的windows overflow異常,引導程序進行覆蓋寄存器的入棧保護。

  正常模式下函數內部指令的寄存器引用,如xxx ar,as,at,處理器在非異常模式下將進行正常的window檢測,否則產生非法指令異常。

  4.Windows寄存器檢測方法

  寄存器覆蓋檢測通過如下硬件semantic實現:

  WindowCheck

  n ← if (wr ≠ 2'b00 or ws ≠ 2'b00 or wt ≠ 2'b00) and WindowStartWindowBase+1 then 2'b01

  else if (wr1 or ws1 or wt1) and WindowStartWindowBase+2 then 2'b10

  else if (wr = 2'b11 or ws = 2'b11 or wt = 2'b11) and WindowStartWindowBase+3 then 2'b11

  else 2'b00

  if CWOE = 1 and n ≠ 2'b00 then

  PS.OWB ← WindowBase

  m ← WindowBase + (2'b00||n)

  PS.EXCM ← 1

  EPC[1] ← PC

  nextPC ← if WindowStartm+1 then WindowOverflow4

  else if WindowStartm+2 then WindowOverflow8

  else WindowOverflow12

  WindowBase ← m(注:和Overflow跳轉并行)

  endif

  通過深入解析如上原語,有如下注意要點:任何地方引用a0~a3不會產生windows異常,因此在用戶的c或者匯編代碼里可以任意使用,為什么呢? 因為在a0~a3引用的任意環境里,當前函數的邏輯窗里的物理寄存器,要么是無覆蓋安全到達,要么是經過了函數調用entry指令觸發windows overflow異常,在異常里,a0~a3的所在物理AR寄存器已經安全地壓棧保存了。

  a15~a4之間的高位寄存器(比如a15)引用會觸發低位寄存器(如a4)的寄存器覆蓋檢測,哪怕沒有指令顯式的應用低位寄存器,觸發的順序將是先進行overflow4,overflow8,至overflow12,從而最有效和最安全地保存活動寄存器。通過了解以上兩點,讀者可以深入理解Tensilica提供的高效XTOS代碼,透徹體會相關代碼的精妙之處。

c語言相關文章:c語言教程



上一頁 1 2 下一頁

評論


相關推薦

技術專區

關閉