RISC-V精簡到何種程度?能省的都省了!

點擊查看-->:半導體人必關注的三個公眾號

本文綜合整理自:半鬥米的CSDN博客、ZOL、中國電子報、EETOP論壇等

RISC-V是一個典型三操作數、加載-存儲形式的RISC架構,包括三個基本指令集和6個擴展指令集,如表1所示,其中RV32E是RV32I的子集,不單獨計算。

RISC-V精簡到何種程度?能省的都省了!

其中RV32I指令集僅有47條指令,卻能夠滿足現代操作系統運行的基本要求,47條指令按照功能可以分為如下幾類。

(1)整數運算指令:實現算術、邏輯、比較等運算。

(2)分支轉移指令:實現條件轉移、無條件轉移等運算,並且沒有延遲槽。

(3)加載存儲指令:實現字節、半字、字的加載、存儲操作,採用的都是寄存器相對尋址方式。

(4)控制與狀態寄存器訪問指令:實現對系統控制與狀態寄存器的原子讀-寫、原子讀-修改、原子讀-清零等操作。

(5)系統調用指令:實現系統調用、調試等功能。

指令格式

先來看看指令格式,這格式規律地一塌糊塗啊,看著這張圖,我的強迫症瞬間消失了。有規律的指令編碼不僅是讓強迫症患者舒服,也讓處理器很舒服,指令越有規律,解碼器所要的gate越少,芯片面積越小,運行速度越快。

RISC-V精簡到何種程度?能省的都省了!

沒有立即數減法?

只有addi沒有subi,減法怎麼辦?無論是數學上還是程序上,x - y都等價於x + (-y),也就是說可以把減法變成加法的,把被減數轉成負數然後再加上減數就實現了和減法一樣的功能了。正是基於這個原理,RISC-V只提供立即數加法,沒有提供立即數減法,如果需要立即數減法,那麼就要麻煩編譯器把這個立即數轉化成負數,然後繼續使用加法。這也是RISC-V將立即數作為有符號數處理的原因吧。

x0簡化指令集

通過引入x0寄存器,很多特殊指令用普通的指令加上x0做操作數就給解決了。指令的數量大大降低,指令數降低了,這處理器的解碼電路不就簡化了嘛。

32位常量

之前用ARM的處理器,ARM都是將立即數表示不下的常量存到常量池,然後用PC相關的LDR指令加載到寄存器的。RISC-V的常量完全是用指令拼接的,不需要Load指令,要知道使用Load指令是需要額外的訪問週期的。RISC-V單條指令可以表示12位的有符號常量,超過12位需要兩條指令來合成。其中一條指令是lui,lui指令加載常量的高20位,低12位可以用addi指令加上去,當然了這個過程又要麻煩編譯器仔細算一算立即數到底是什麼了,因為addi指令執行的是有符號加法,其中的12位立即數是會先被符號擴展成32位的有符號數再參與計算的。ARM的常量加載需要8個字節,一條指令+一個常量;RISC-V的常量加載也是需要8個字節,兩條指令。佔用的程序空間是一樣的。

只有小於和大於等於

RISC-V的比較跳轉指令只有blt和bge,即只有小於和大於等於。那大於和小於等於就不需要了嗎?也是需要的,不過RISC-V用了個很巧妙的辦法,將blt的兩個參與比較的操作數位置換一下,就有了bgt,將bge的兩個參與比較的操作數位置換一下,就有了ble。真是個好辦法。用兩條指令實現了四條指令的工作,其中兩條是偽指令,實際的指令只有兩條。

讓編譯器做更多

我對RISC的理解就是:處理器儘量少做,讓編譯器儘量多做。這是非常有道理的,畢竟編譯的次數遠少於執行的次數啊。上面幾個段落就提到不少要讓編譯器多做的工作,再例舉個為了簡化處理器的設計而讓編譯器多做的工作。

RISC-V精簡到何種程度?能省的都省了!

B-type是比較跳轉指令的格式,J-type是長跳轉或函數調用指令格式,注意它們的立即數排列次序,我都有點同情編譯器設計師了,這怎麼搞啊?具體一點講,填充這裡的立即數的應該是鏈接器的工作。這麼排放偏移地址立即數的目的還是為了簡化處理器的設計,但明顯給編譯器增加了工作了。

其它省掉的指令

還有很多常用的指令也被省掉了,比如nop、move、not、neg,當然不是說這些功能沒有,所有這些功能都是有的,不過都是用其它的指令來等價實現的,比如not指令是用xori rd, rs, -1實現的。每看到這樣的指令,我對Berkeley的大神都是佩服地五體投地。

總結

能省的指令都省了。能讓編譯器做的都讓編譯器做了。絕對精簡。

*免責聲明:本文由作者原創。文章內容系作者個人觀點,轉載目的在於傳遞更多信息,並不代表EETOP贊同其觀點和對其真實性負責。如涉及作品內容、版權和其它問題,請及時聯繫我們,我們將在第一時間刪除!

點擊閱讀原文查看半導體行業相關公眾號有哪些?

相關推薦

推薦中...