自己動手寫CPU之第八階段(1) 轉移指令介紹

2021-06-25 16:20:50 字數 2609 閱讀 3560

感興趣的朋友可以在亞馬遜、噹噹、京東等查詢。

另外,開展曬書評送書活動,在亞馬遜、京東、噹噹三大圖書**上,發表《自己動手寫cpu》書評的前十名讀者,均可獲贈《步步驚芯——軟核處理器內部設計

本章將為openmips處理器新增轉移指令,轉移指令包括跳轉、分支兩種,區別在於前者是絕對轉移,後者是相對轉移,但實現方法是相似的。轉移指令涉及延遲槽,所以首先在8.1節介紹了延遲槽的概念,接著在8.2節對mips32指令集架構中定義的所有轉移指令的格式、作用、用法進行了說明。在8.3節介紹了openmips實現轉移指令的思路,以及對資料流圖、系統結構的修改。8.4節通過修改**實現了轉移指令,最後通過兩個測試程式,驗證轉移指令是否實現正確。

在實現轉移指令之前,先介紹一下延遲槽的概念。在第5章已經介紹了流水線中存在的三種相關:資料相關、結構相關、控制相關。其中控制相關是指流水線中的轉移指令或者其他需要改寫pc的指令造成的相關。這些指令改寫了pc的值,所以導致後面已經進入流水線的幾條指令無效,比如:如果轉移指令在流水線的執行階段進行轉移條件判斷,在發生轉移時,會導致當前處於取指、解碼階段的指令無效,需要重新取指。如圖8-1所示。

也就是在流水線執行階段進行轉移判斷,並且轉移發生,那麼會有2條無效指令,導致浪費了兩個時鐘週期。為了減少損失,規定轉移指令後面的指令位置為「延遲槽」,延遲槽中的指令被稱為「延遲指令」(也可稱之為「延遲槽指令」)。延遲指令總是被執行,與轉移發生與否沒有關係。引入延遲槽後的指令執行順序如圖8-2所示。openmips處理器就計畫使用延遲槽技術。

但是,即使引入延遲槽,在轉移發生時仍然會導致已經進入取指階段的指令無效,也就是仍浪費乙個時鐘週期,要解決這個問題,可以在解碼階段進行轉移判斷,這樣就可以避免浪費時鐘週期。openmips處理器就設計為在解碼階段進行轉移判斷。

mips32指令集架構中定義的轉移指令共有14條,可分為如下兩類。

其中,跳轉指令是絕對轉移,分支指令是相對轉移。本節分別介紹這兩類指令。

1、跳轉指令

跳轉指令的格式如圖8-3所示。

從圖8-3可知,j、jal指令可以通過指令碼進行判斷,jr、jalr指令的指令碼為special,還需要依據功能碼進一步判斷。

指令用法為:jr rs

指令用法為:jalr rs 或者jalr rd, rs

指令作用為:rd

指令用法為:j target

指令作用為:pc

指令用法為:jal target

指令作用為:pc

j、jal、jr、jalr指令在轉移之前都要先執行延遲槽指令。

2、分支指令

分支指令的格式如圖8-4所示。

從圖8-4可知,前5條指令beq、b、bgtz、blez、bne可以直接依據指令中的指令碼進行判斷,確定是哪一條指令,而後5條指令bltz、bltzal、bgez、bgezal、bal的指令碼都是regimm,這是乙個巨集定義,值為6'b000001,需要根據指令中16-20bit的值進一步判斷,從而確定是哪一條指令。

從圖8-4還可知,所有分支指令的0-15bit儲存的都是offset,如果發生轉移,那麼將offset左移2位,並符號擴充套件至32位,然後與延遲槽指令的位址相加,加法的結果就是轉移目的位址,從該位址取指令。

轉移目標位址 = (signed_extend)( offset || 『00』 ) + (pc+4)

指令用法為:beq rs, rt, offset

指令用法為:b offset

指令作用為:無條件轉移,從圖8-4可知,b指令可以認為是beq指令的特殊情況,當beq指令的rs、rt都等於0時,即為b指令,所以在openmips實現的時候不需要特意實現b指令,只需要實現beq指令即可。

指令用法為:bgtz rs, offset

指令用法為:blez rs, offset

指令用法為:bne rs, rt, offset

指令用法為:bltz rs, offset

指令用法為:bltzal rs, offset

指令用法為:bgez rs, offset

指令用法為:bgezal rs, offset

指令用法為:bal offset

指令作用為:無條件轉移,並且將轉移指令後面第2條指令的位址作為返回位址,儲存到通用暫存器$31。從圖8-4的指令格式可知,bal指令是bgezal指令的特殊情況,當bgezal指令的rs為0時,就是bal指令,所以在openmips實現時,不用特意考慮bal指令,只要實現bgezal指令即可。

綜上,b、bal指令不用單獨實現,需要openmips實現的分支指令只有8條。

所有的分支指令在轉移到目標位址前都要先執行延遲槽中的指令。

自己動手寫docker之cgroup

實驗環境 ubuntu 18.10 作業系統已經預設把各種controller都掛載到 sys fs cgroup 目錄下了。ls sys fs cgroup 可以檢視有哪些controller mount grep cgroup 可以檢視掛載資訊 可以看到有乙個是cgroup2,其它都是cgrou...

自己動手寫CPU(5) 移動指令說明

不涉及特殊暫存器lo hi movn 判斷位址為rt的通用暫存器的值,如果不為零,將位址為rs的通用暫存器的值賦給位址為rd的通用暫存器 反之,儲存rd的值 movz 與movn相反。判斷位址為rt的通用暫存器的值,如果為零,將位址為rs的通用暫存器的值賦給位址為rd的通用暫存器 反之,儲存rd的值...

瘋子在思考之自己動手寫MVC

mvc 1 url mvc 2 url 第二篇介紹了為什麼要用mvc以及mvc的概念,即什麼是mvc。通過以上的了解,我個人認為,對於開發者來講,mvc的filter即我們在web.xml中配置的 是不重要的,框架為我們寫好了,我們做的事情就是配置一下就可以了,而我們更關注具體的業務邏輯和view,...