RISC-V是當(dāng)下熱門的技術(shù),值得大家學(xué)習(xí),這里分享一份關(guān)于RISC-V指令的內(nèi)容給大家。
1. 指令集
1.1 指令集
指令集是一個(gè)CPU的基石,要實(shí)現(xiàn)CPU 計(jì)算和控制功能,就必須定義好一系列與硬件電路相匹配的指令系統(tǒng).
指令就是我們交代CPU 要執(zhí)行的操作,指令集就可以簡(jiǎn)單理解為指令的集合。我們把cpu 能夠識(shí)別的指令匯總在一起就構(gòu)成了一個(gè)指令集。
不同的CPU 有不同的指令集,根據(jù)他們的繁簡(jiǎn)程度可以分為兩種:復(fù)雜指令集CISC 和精簡(jiǎn)指令集 RISC
1.2 指令集架構(gòu)
指令架構(gòu)(Instruction Set Architecture, 縮寫(xiě)為ISA),是軟件和硬件的接口,不同的應(yīng)用需求,會(huì)有不同的指令架構(gòu)。要設(shè)計(jì)一款CPU 指令體系就是設(shè)計(jì)的出發(fā)點(diǎn)。
2. RISC-V 指令集架構(gòu)
RISC-V 指令有以下特點(diǎn):
完全開(kāi)放
指令簡(jiǎn)單
模塊化設(shè)計(jì),易于擴(kuò)展
名稱 | 類別 | 說(shuō)明 |
---|---|---|
RV32I | 基礎(chǔ)指令 | 整數(shù)指令:包含算法、分支、邏輯、訪存指令,有32個(gè)32位寄存器。能尋址32位地址空間 |
RV64I | 基礎(chǔ)指令 | 整數(shù)指令:包含算法、分支、邏輯、訪存指令,有32個(gè)64位寄存器。能尋址64位地址空間 |
RV128I | 基礎(chǔ)指令 | 整數(shù)指令:包含算法、分支、邏輯、訪存指令,有32個(gè)128位寄存器。能尋址128位地址空間 |
RV32E | 基礎(chǔ)指令 | 與RV32I一樣,只不過(guò)只使用前16個(gè)(0~15)32位寄存器 |
M | 擴(kuò)展指令 | 包含乘法、除法、取模求余指令 |
F | 擴(kuò)展指令 | 單精度浮點(diǎn)指令 |
D | 擴(kuò)展指令 | 雙精度浮點(diǎn)指令 |
Q | 擴(kuò)展指令 | 四倍精度浮點(diǎn)指令 |
A | 擴(kuò)展指令 | 原子操作指令:比如比較并交換,讀改寫(xiě)等指令 |
C | 擴(kuò)展指令 | 壓縮指令:?jiǎn)沃噶铋L(zhǎng)度為16位,主要用于改善程序大小 |
P | 擴(kuò)展指令 | 單指令多數(shù)據(jù)(Packed-SIMD)指令 |
B | 擴(kuò)展指令 | 位操作指令 |
H | 擴(kuò)展指令 | 支持(Hypervisor)管理指令 |
J | 擴(kuò)展指令 | 支持動(dòng)態(tài)翻譯語(yǔ)言指令 |
L | 擴(kuò)展指令 | 十進(jìn)制浮點(diǎn)指令 |
N | 擴(kuò)展指令 | 用戶中斷指令 |
G | 通用指令 | 包含I、M、A、F、D 指令 |
要滿足現(xiàn)在操作系統(tǒng)和應(yīng)用程序的基本運(yùn)行,RV32G指令集或者RV64G指令集就夠了。RV32G和RV64G指令集只有寄存器位寬和尋址大小不同。這些指令按照功能可以分為如下幾類:
整數(shù)運(yùn)算指令:算術(shù)、邏輯、比較等基礎(chǔ)運(yùn)算功能。
分支轉(zhuǎn)移指令:實(shí)現(xiàn)條件轉(zhuǎn)移、無(wú)條件轉(zhuǎn)移操作
加載存儲(chǔ)指令:實(shí)現(xiàn)字節(jié)、半字(half word)、字(word)、雙字(RV64I)的加載,存儲(chǔ)操作,采用的都是寄存器相對(duì)尋址方式
控制與狀態(tài)寄存器訪問(wèn)指令:實(shí)現(xiàn)對(duì)系統(tǒng)控制與系統(tǒng)狀態(tài)寄存器的原子讀-寫(xiě)、原子讀-修改、原子讀-清零等操作
系統(tǒng)調(diào)用指令:實(shí)現(xiàn)系統(tǒng)調(diào)用功能。
原子指令:用于各種同步鎖
單雙浮點(diǎn)指令:實(shí)現(xiàn)浮點(diǎn)運(yùn)算操作
從上表我們可以看到,RISC-V 指令集具有模塊化特點(diǎn)。這就允許我們根據(jù)自己的需求,選擇一個(gè)基礎(chǔ)指令集,加上若干個(gè)擴(kuò)展指令集靈活搭配,就可以得到我們想要的指令集架構(gòu),進(jìn)而根據(jù)這樣的指令架構(gòu),設(shè)計(jì)出貼合我們需求的CPU.
作為初學(xué)者,我們了解RISC-V 的核心即可。它的最核心部分是一個(gè)基礎(chǔ)指令集,叫做RV32I.
RV32I 包含的指令是固定不變的,這為編譯器設(shè)計(jì)人員,操作系統(tǒng)開(kāi)發(fā)人員和匯編語(yǔ)言程序員提供了穩(wěn)定的基礎(chǔ)框架。
RV32I 指令集:
RV32I 指令集如圖所示,把帶下劃線的字母從左至右連接組合就是組成了RV32I指令。{}表示集合中垂直方向的每個(gè)項(xiàng)目指令不同變體。變體用下劃線字母或者下劃線表示表示,如果大括號(hào)里面只有下劃線,則表示對(duì)此變體不需要用字母表示
我們結(jié)合具體例子來(lái)看:下圖表示了bge、blt、bgeu、bltu四個(gè)指令。
3. 指令格式
下圖是RISC-V 指令格式,從下圖可以看到RSIC-V共六種指令格式。
opcode :指令操作碼
imm:代碼立即數(shù)
func3和funct7:代表指令對(duì)應(yīng)的功能
rs1:源寄存器1
rs2:源寄存器2
rd:目標(biāo)寄存器(RSIC-V 一個(gè)指令可以提供三個(gè)寄存器操作)
六種指令格式作用如下:
序號(hào) | 指令類型 | 作用 |
---|---|---|
1 | R 型指令 | 用于寄存器和寄存器操作 |
2 | I 型指令 | 用于短立即數(shù)和內(nèi)存載入指令load操作 |
3 | S 型指令 | 用于內(nèi)存存儲(chǔ)store操作 |
4 | B 型指令 | 用于有條件跳轉(zhuǎn)操作 |
5 | U 型指令 | 用于長(zhǎng)立即數(shù)操作 |
6 | J 型指令 | 用于無(wú)條件跳轉(zhuǎn)操作 |
4.寄存器
在RISC-V 的規(guī)范里面定義了32 個(gè)通用寄存器。其中31個(gè)是常規(guī)寄存器,1個(gè)恒為0值的x0寄存器。
0值寄存器是為了滿足匯編語(yǔ)言程序員和編譯器編寫(xiě)者的使用需要,他們可以使用x0寄存器作為操作數(shù),來(lái)完成功能相同的操作。
addix0,x0,0;0=0+0,相當(dāng)于nop空指令
RSIC-V 寄存器說(shuō)明
寄存器 | ABI 名稱 | 說(shuō)明 |
---|---|---|
x0 | zero | 0值寄存器,硬編碼為0,寫(xiě)入數(shù)據(jù)忽略,讀取數(shù)據(jù)為0 |
x1 | ra | 用于返回地址(return address) |
x2 | sp | 用于棧指針(stack pointer) |
x3 | gp | 用于通用指針 (global pointer) |
x4 | tp | 用于線程指針 (thread pointer) |
x5 | t0 | 用于存放臨時(shí)數(shù)據(jù)或者備用鏈接寄存器 |
x6~x7 | t1~t2 | 用于存放臨時(shí)數(shù)據(jù)寄存器 |
x8 | s0/fp | 需要保存的寄存器或者幀指針寄存器 |
x9 | s1 | 需要保存的寄存器 |
x10~x11 | a0~a1 | 函數(shù)傳遞參數(shù)寄存器或者函數(shù)返回值寄存器 |
x12~x17 | a2~a7 | 函數(shù)傳遞參數(shù)寄存器 |
x18~x27 | s2-s11 | 需要保存的寄存器 |
x28~x31 | t3~t6 | 用于存放臨時(shí)數(shù)據(jù)寄存器 |
5. RV32I 指令解讀
5.1 算術(shù)與邏輯指令
在RV32I 中包括算術(shù)指令(add/sub)、數(shù)值比較指令(slt)、邏輯指令(and/or/xor)以及移位指令(sll/srl/sra)這幾種指令。
這些指令和其他指令集差不多,它們從寄存器讀取兩個(gè)32位的值,并將32位運(yùn)算結(jié)果再寫(xiě)回到目標(biāo)寄存器。
I型指令:立即數(shù)算術(shù)運(yùn)算
R型指令:寄存器與寄存器操作指令
需要指出的是,在寄存器與寄存器操作的算術(shù)指令中。必須要有減法指令。這和立即數(shù)操作指令不同。
5.2 Load 和 Store 指令
在RISC-V 指令集中,對(duì)內(nèi)存的讀寫(xiě)只能通過(guò)LOAD 和 STORE 指令實(shí)現(xiàn)。而其他的指令只能以寄存器為操作對(duì)象。
如上圖所示,load 和 store 的尋址模式只能是符號(hào)擴(kuò)展12位的立即數(shù),加上基地址寄存器得到訪存的存儲(chǔ)器地址。因?yàn)闆](méi)有了復(fù)雜的內(nèi)存尋址方式,這讓CPU 流水線可以對(duì)數(shù)據(jù)沖突提前做出判斷,并通過(guò)流水線各級(jí)轉(zhuǎn)送加以處理,而不需要加入空操作(NOP),極大的提高了代碼的執(zhí)行效率。
5.3 分支跳轉(zhuǎn)指令
5.3.1 有條件的分支跳轉(zhuǎn)
RV32I 中的條件跳轉(zhuǎn)就是通過(guò)比較兩個(gè)寄存器的值,進(jìn)行分支跳轉(zhuǎn):
beq:相等
bne:不相等
bge/bgeu:大于等于
blt/bltu:小于
5.3.2 無(wú)條件的分支跳轉(zhuǎn)
無(wú)條件跳轉(zhuǎn)指令可以細(xì)分為直接跳轉(zhuǎn)和間接跳轉(zhuǎn)。直接跳轉(zhuǎn)指令JAL 如下圖所示:
JAL 指令執(zhí)行過(guò)程是這樣的。它會(huì)把20位立即數(shù)做符號(hào)位擴(kuò)展。并左移一位,產(chǎn)生一個(gè)32位符號(hào)數(shù)。然后,將該32位符號(hào)數(shù)和PC相加來(lái)產(chǎn)生目標(biāo)地址(這樣,JAL 可以作為短跳轉(zhuǎn)指令,跳至PC+1MB的地址范圍內(nèi))
同時(shí)JAL 會(huì)把緊隨其后的那條指令地址,存入目標(biāo)寄存器中。這樣,如果目標(biāo)寄存器是零,則JAL就等同GOTO指令;如果目標(biāo)寄存器不為零,JAL可以實(shí)現(xiàn)函數(shù)調(diào)用功能。
間接跳轉(zhuǎn)直接JALR如下:
JALR指令會(huì)把12位立即數(shù)和源寄存器相加,并把相加結(jié)果末位清零,作為新的跳轉(zhuǎn)地址。同時(shí)和JAL指令一樣,也會(huì)把緊隨其后的那條指令地址,存入目標(biāo)寄存器中。
5.4 其他指令
除了內(nèi)存地址空間和通用寄存器地址空間外,RISC-V 還定義了一個(gè)獨(dú)立的控制和狀態(tài)寄存器地址空間(Control Status Register)每個(gè)處理器實(shí)現(xiàn)的CSR會(huì)因設(shè)計(jì)目標(biāo)不同而有差異,但是這些CSR的訪問(wèn)方式卻是一樣的,訪問(wèn)這些CSR指令定義在了用戶指令集中(Zicsr指令集擴(kuò)展)
有了上圖這些CSR 指令,能夠讓我們輕松的訪問(wèn)一些程序性能計(jì)數(shù)器。這些計(jì)數(shù)器包括系統(tǒng)時(shí)間、時(shí)間周期以及執(zhí)行的指令數(shù)目。
-
cpu
+關(guān)注
關(guān)注
68文章
10854瀏覽量
211570 -
接口
+關(guān)注
關(guān)注
33文章
8575瀏覽量
151014 -
指令集
+關(guān)注
關(guān)注
0文章
222瀏覽量
23378 -
RISC-V
+關(guān)注
關(guān)注
45文章
2270瀏覽量
46125
原文標(biāo)題:RISC-V 指令詳解
文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論