0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

RISC-V ABI約定

嵌入式USB開發(fā) ? 來源:嵌入式USB開發(fā) ? 作者:嵌入式USB開發(fā) ? 2023-06-08 09:58 ? 次閱讀

本文轉(zhuǎn)自公眾號,歡迎關(guān)注

RISC-V ABI約定 (qq.com)

  • 一.C數(shù)據(jù)類型和對齊
  • 二.RVG調(diào)用約定
  • 三.Soft-Float調(diào)用約定
  • 四.總結(jié)
  • 使用編譯器生成匯編代碼分析調(diào)用過程
  • 五.參考

一.C數(shù)據(jù)類型和對齊

所有數(shù)據(jù)保持自然對齊。

ILP32,LP64

C type Description Bytes in RV32 Bytes in RV64
char/unsigned char 8-bit unsigned integer,zero-extended 1 1
signed char 8-bit signed integer,sign-extended
short 16-bit signed integer,sign-extended 2 2
unsigned short 16-bit unsigned integer,zeroextended
int int都是32位 4 4
long 指針和long和整數(shù)寄存器一樣寬 4 8
long long long long都是64位 8 8
void * 指針和long和整數(shù)寄存器一樣寬 4 8
float 32-bit IEEE 754-2008 4 4
double 64-bit IEEE 754-2008 8 8
long double 128-bit IEEE floating-point
IEEE floating-point 16 16

在RV64中,32位類型不管是int還是unsigned都是符號擴(kuò)展到64位。

二.RVG調(diào)用約定

  1. a0-a7,fa0-fa7:用于函數(shù)傳遞參數(shù),其中0-1用于返回值,a表示arguments。

都是調(diào)用者負(fù)責(zé)保存,因?yàn)槭莻鲄⒖隙ㄊ窃诤瘮?shù)調(diào)用前就要準(zhǔn)備好,所部不可能是被調(diào)用者去負(fù)責(zé)保存。

  1. 如果函數(shù)參數(shù)為結(jié)構(gòu)體的字段,每一個(gè)都是指針對齊的,則參數(shù)寄存器是結(jié)構(gòu)體前面8個(gè)指針字pointer-words的影子shadow

如果是小于8個(gè)的浮點(diǎn)值,則使用fai傳遞;小于8個(gè)的整數(shù)則使用ai傳遞。

如果浮點(diǎn)參數(shù)是聯(lián)合體unions的字段,或者結(jié)構(gòu)體的數(shù)組字段,則使用整數(shù)寄存器傳遞。

另外可變參數(shù)函數(shù)中除了顯示指定的參數(shù)外的參數(shù),如果是浮點(diǎn)數(shù)也是使用整數(shù)寄存器傳遞。

  1. 小于指針字pointer-word的參數(shù)使用低位傳遞,子指針字sub-pointer-word的參數(shù)通過棧傳遞時(shí),使用指針字pointer-word的低地址,因?yàn)?code>RISC-V是小端的存儲(chǔ)系統(tǒng)。
  2. 當(dāng)原始參數(shù)兩倍于指針字pointer-word時(shí)通過棧傳遞,使用自然對齊。當(dāng)它們使用整數(shù)寄存器傳遞時(shí),使用對齊的偶-奇寄存器對,偶寄存器存低位。比如RV32void foo(int, long long)使用a0傳遞第一個(gè)參數(shù),a2-a3傳遞第二個(gè)參數(shù),因?yàn)橛膳技拇嫫鲗R,且a2存低位,返回值通過a0傳遞。
  3. 兩倍于指針字pointer-word的參數(shù)通過引用傳遞。
  4. 結(jié)構(gòu)體中部分參數(shù)未使用整數(shù)寄存器傳遞的使用棧傳遞,棧指針sp指向第一個(gè)未使用整數(shù)寄存器傳遞的參數(shù)。
  5. a0,a1,fa0,fa1用于函數(shù)返回值。只有結(jié)構(gòu)體成員只有一個(gè)或者兩個(gè)浮點(diǎn)成員,或者primitives時(shí)才使用浮點(diǎn)寄存器返回;其他的由a0-a1組成的兩倍指針字的two pointer-words大小返回;更大的返回值通過內(nèi)存?zhèn)鬟f;調(diào)用者負(fù)責(zé)分配這個(gè)內(nèi)存,并傳遞指向該內(nèi)存的指針,隱含的作為第一個(gè)參數(shù)傳遞給被調(diào)用者。
  6. 標(biāo)準(zhǔn)RISC-V調(diào)用中,棧向下生長,并且保持16字節(jié)對齊。
  7. 7個(gè)臨時(shí)整數(shù)寄存器t0-t6,12個(gè)臨時(shí)浮點(diǎn)寄存器ft0-ft11在調(diào)用過程是可變的,如果后面需要使用則必須由調(diào)用者負(fù)責(zé)保存。其中t表示Temporaries
  • 這里有點(diǎn)疑惑,臨時(shí)寄存器是被調(diào)用者使用的,只有被調(diào)用者才知道自己要用哪些寄存器,為什么不是被調(diào)用者負(fù)責(zé)保存?
    這樣理解,因?yàn)檫@些寄存器是可變的,對于被調(diào)用者來說既然是可變的則可以隨便使用,也就是可能被被調(diào)用者修改,所以對于調(diào)用者來說,如果這些寄存器的值不能被破壞則自己需要負(fù)責(zé)保存。
  1. 12個(gè)整數(shù)寄存器s0-s11,12個(gè)浮點(diǎn)寄存器fs0-fs11在調(diào)用過程是必須保持的,所以如果被調(diào)用者需要使用則必須由被調(diào)用者保存。

實(shí)際上上面的89.,ts寄存器的可變volatile和保持preserved是對被調(diào)用者來說的,也就是對被調(diào)用者申明,告訴被調(diào)用者,

t這些寄存器是可變的,那么被調(diào)用者可以隨便使用,此時(shí)調(diào)用者則必須考慮被被調(diào)用者隨便使用而修改,需要調(diào)用者保存;

s這些寄存器是保持的,那么被調(diào)用者不能隨便使用,如果要用就要負(fù)責(zé)保存。

所以對于a寄存器也可以這樣理解,因?yàn)?code>a寄存器用于傳遞參數(shù),所以是被調(diào)用者隨便使用的,即不保持的,所以需要調(diào)用者負(fù)責(zé)保存,并賦參數(shù)值。

Register ABI Name Description Saver
x0 zero 硬件固定為0 /
x1 ra 返回地址 Caller調(diào)用者
x2 sp 棧指針 Callee被調(diào)用者
x3 gp 全局指針 /
x4 tp 線程指針 /
x5-x7 t0-t2 臨時(shí)使用 Caller調(diào)用者
x8 s0/fp 保存寄存器/幀指針 Callee被調(diào)用者
x9 s1 保存寄存器 Callee被調(diào)用者
x10-x11 a0-a1 函數(shù)參數(shù)/返回值 Caller調(diào)用者
x12-x17 a2-a7 函數(shù)參數(shù) Caller調(diào)用者
x18-x27 s2-s11 保存寄存器 Callee被調(diào)用者
x28-x31 t3-t6 臨時(shí)使用 Caller調(diào)用者
f0-f7 ft0-ft7 FP臨時(shí)使用 Caller調(diào)用者
f8-f9 fs0-fs1 FP保存寄存器 Callee被調(diào)用者
f10-f11 fa0-fa1 FP函數(shù)參數(shù)/返回值 Caller調(diào)用者
f12-f17 fa2-fa7 FP參數(shù) Caller調(diào)用者
f18-f27 fs2-fs11 FP保存寄存器 Callee被調(diào)用者
f28-f31 ft8-ft11 FP臨時(shí)使用 Caller調(diào)用者

三.Soft-Float調(diào)用約定

在沒有浮點(diǎn)硬件,或者不使用F,D,Q擴(kuò)展的硬件浮點(diǎn),不使用浮點(diǎn)寄存器,完全由軟件實(shí)現(xiàn)浮點(diǎn)。

整數(shù)參數(shù)的傳入和返回值和RVG一樣。

浮點(diǎn)參數(shù)和返回值,通過整數(shù)寄存器傳遞,原則是使用大小相同的整數(shù)寄存器傳遞。

比如RV32

double foo(int, double, long double)

則第一個(gè)參數(shù)通過a0傳遞;

第二個(gè)參數(shù)通過a2a3傳遞;

第三個(gè)參數(shù)通過a4傳引用傳遞;

結(jié)果通過a0a1傳遞。

如果是RV64

則第一個(gè)參數(shù)通過a0傳遞;

第二個(gè)參數(shù)通過a1傳遞;

第三個(gè)參數(shù)通過a2-a3傳遞;

結(jié)果通過a0傳遞。

動(dòng)態(tài)舍入模式和產(chǎn)生的異常標(biāo)志通過C99fenv.h提供的接口訪問。

四.總結(jié)

從以下幾個(gè)部分去理解

  1. 寄存器

理解函數(shù)參數(shù)的傳遞與返回值,a0-a1,a2-a7,fa0-fa1,fa2-fa7,0-1用于返回值。

理解ra寄存器,函數(shù)的返回地址

理解SP棧指針,理解棧的向下生長,理解進(jìn)入子函數(shù)時(shí)減少sp分配空間,分配的空間用于存儲(chǔ)s寄存器和局部變量使用,和退出子函數(shù)時(shí)增加sp恢復(fù)sp。也就是調(diào)用完子函數(shù)返回后sp要保持不變。

理解t0-t6,ft0-ft11;s0-s11.fs0-fs11,這里重點(diǎn)站在被調(diào)用者角度去理解可變和保持,進(jìn)而理解誰負(fù)責(zé)保存寄存器。

  1. 函數(shù)調(diào)用

jal ra label或者jal ra rd imm簡化為偽指令jal label或者jalr rd(立即數(shù)為0)。jal跳轉(zhuǎn)即將PC + 4存儲(chǔ)到ra寄存器,即函數(shù)返回后的下一條執(zhí)行的指令。jalr類似只是設(shè)置PCrd + imm

注意與無條件跳轉(zhuǎn)jal x0 labeljalr x0 rd imm,偽指令j label ,jr rd(立即數(shù)為0)的區(qū)別,無條件跳轉(zhuǎn)是不返回了的所以不保存返回地址到ra,而是保存到了x0寄存器,而x0寄存器是硬件固定為0的,所以相當(dāng)于不保存,

兩者指令是統(tǒng)一的,這也體現(xiàn)了RISC-V指令設(shè)計(jì)的簡潔統(tǒng)一的美學(xué)。

其中jall可以理解為link,類似于ARMLR寄存器的L。

  1. 進(jìn)入和退出函數(shù)

除非使用棧傳遞參數(shù),否則子函數(shù)返回后sp必須保持不變。

所有的s寄存器在子函數(shù)返回后必須保持,這也是其保持的含義,也是為什么被調(diào)用者需要負(fù)責(zé)保存。

子函數(shù)退出時(shí)返回ra處執(zhí)行

函數(shù)進(jìn)入時(shí)的處理:減少sp,s寄存器個(gè)數(shù)和局部變量大小的空間,存儲(chǔ)使用到的s寄存器到棧中。如果還有子函數(shù)調(diào)用則存儲(chǔ)ra到棧中(因?yàn)樽雍瘮?shù)的子函數(shù)的返回值要存到ra會(huì)覆蓋ra)。

函數(shù)退出時(shí)的處理:恢復(fù)棧中保存的s寄存器,更新sp值。如果有需要恢復(fù)ra值,恢復(fù)sp值到函數(shù)進(jìn)入之前的值,返回到ra處執(zhí)行。

最好通過編寫c代碼,使用編譯工具生成匯編代碼,對照c和匯編代碼的方式去理解。

五.參考

  1. riscv-calling.pdf [Volume I: RISC-V User-Level ISA V2.1draft:Chapter 18Calling Convention]

  2. Understanding RISC-V Calling Convention.pdf [Nick Riasanovsky]

    審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4671

    瀏覽量

    67770
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1602

    瀏覽量

    48896
  • 數(shù)據(jù)類型
    +關(guān)注

    關(guān)注

    0

    文章

    236

    瀏覽量

    13567
  • RISC-V
    +關(guān)注

    關(guān)注

    44

    文章

    2141

    瀏覽量

    45712
收藏 人收藏

    評論

    相關(guān)推薦

    什么是RISC-V

    siFive搞RISC-V 賽昉搞RISC-V 香山搞RISC-V 到底什么是RISC-V? 先不問有什么用,RISC-V目前的能力來說,工
    發(fā)表于 02-02 10:41

    為什么選擇RISC-V

    RISC-V是一種開放式ISA(指令集體系結(jié)構(gòu)),為處理器體系結(jié)構(gòu)的創(chuàng)新開創(chuàng)了新紀(jì)元。RISC-V基金會(huì)由325多家成員公司組成。這是該技術(shù)的主要優(yōu)勢。軟件架構(gòu)師/固件工程師/軟件開發(fā)
    發(fā)表于 07-27 17:38

    一文看懂RISC-V代碼密度

    要的指標(biāo)之一。那么,代碼密度由什么決定?如何提高代碼密度呢?RISC-V的代碼密度現(xiàn)狀又如何?代碼密度的決定因素如上面的倒金字塔所示,代碼密度主要由指令集、ABI、編譯器、Runtime庫、程序代碼五個(gè)
    發(fā)表于 09-01 14:29

    什么是RISC-VRISC-V指令具有哪些特點(diǎn)應(yīng)用?

    什么是RISC-VRISC-V指令具有哪些特點(diǎn)應(yīng)用?自己怎么才能設(shè)計(jì)出設(shè)計(jì)一套指令集?
    發(fā)表于 10-14 09:05

    RISC-V 發(fā)展

    通用寄存器,每個(gè)通用寄存器都有各自的用途。例如x2是作為sp棧指針、a0-a1用來保存函數(shù)參數(shù)或返回值。x0寄存器被硬編碼為了0,就是個(gè)0值寄存器。ABI名稱相當(dāng)于這些通用寄存器的別名,在RISC-V
    發(fā)表于 04-14 10:18

    RISC-V規(guī)范的演進(jìn) RISC-V何時(shí)爆發(fā)?

    RISC-V的關(guān)注度越來越高,開源的理念也正在被越來越多的開發(fā)者和公司接受。對于尚不成熟的RISC-V而言,無論是規(guī)范和技術(shù)的演進(jìn)還是生態(tài)的建設(shè),還有人才和專利都還有不小挑戰(zhàn)。2021年RISC-V
    的頭像 發(fā)表于 02-11 10:10 ?3024次閱讀

    RISC-V中國峰會(huì):RISC-V產(chǎn)業(yè)及生態(tài)發(fā)展

    RISC-V中國峰會(huì):RISC-V產(chǎn)業(yè)及生態(tài)發(fā)展,CPU創(chuàng)新應(yīng)用,能為大眾所用。
    的頭像 發(fā)表于 06-22 11:28 ?2857次閱讀
    <b class='flag-5'>RISC-V</b>中國峰會(huì):<b class='flag-5'>RISC-V</b>產(chǎn)業(yè)及生態(tài)發(fā)展

    如何建設(shè)RISC-V軟件生態(tài)?

    本文從RISC-V軟件開源基礎(chǔ)平臺、RISC-V多樣化軟件生態(tài)以及RISC-V開源社區(qū)等三個(gè)方面詳細(xì)介紹了如何建設(shè)RISC-V軟件生態(tài)。
    的頭像 發(fā)表于 06-23 11:21 ?3167次閱讀
    如何建設(shè)<b class='flag-5'>RISC-V</b>軟件生態(tài)?

    RISC-V學(xué)習(xí)筆記【1】RISC-V概述

    國產(chǎn)處理器芯片起步較晚,從2013年至今,集成電路每年的進(jìn)口額均超過了 2000 億美元。RISC-V和AI(人工智能)芯片是我國最有希望突破的領(lǐng)域之一。RISC-V使用的領(lǐng)域還是對于生態(tài)依賴比較
    發(fā)表于 11-24 09:28 ?2482次閱讀

    openEuler加入RISC-V Landscape

    北京時(shí)間2023年3月8日,openEuler加入RISC-V Landscape。 此次加入RISC-V Landscape,意味著openEuler在對RISC-V架構(gòu)的生態(tài)適配
    的頭像 發(fā)表于 03-13 18:40 ?1212次閱讀

    RISC-VRISC-V AI的未來(特邀講座)

    主題演講:RISC-VRISC-V AI的未來(特邀講座)ppt分享
    發(fā)表于 07-14 17:15 ?11次下載

    RISC-V設(shè)計(jì)支持工具,支持RISC-V技術(shù)的基礎(chǔ)

    RISC-V設(shè)計(jì)支持工具,支持RISC-V技術(shù)的基礎(chǔ) ppt分享
    發(fā)表于 07-14 17:15 ?12次下載

    解鎖RISC-V技術(shù)力量丨曹英杰:RISC-V與大模型探索

    4月12日,第二期“大家來談芯|解鎖RISC-V技術(shù)力量”在上海臨港新片區(qū)頂科永久會(huì)址舉辦,本期沙龍聚焦RISC-V技術(shù),圍繞AI時(shí)代的RISC-V市場機(jī)會(huì)、RISC-V在汽車領(lǐng)域的應(yīng)
    的頭像 發(fā)表于 04-16 08:16 ?480次閱讀
    解鎖<b class='flag-5'>RISC-V</b>技術(shù)力量丨曹英杰:<b class='flag-5'>RISC-V</b>與大模型探索

    RISC-V Summit China 2024 青稞RISC-V+接口PHY,賦能RISC-V高效落地

    沁恒在歷屆峰會(huì)上分享RISC-V在MCU領(lǐng)域的創(chuàng)新成果,和大家共同見證了本土RISC-V產(chǎn)業(yè)的成長。早在第一屆RISC-V中國峰會(huì)上,沁恒就公開了青稞RISC-V系列量產(chǎn)芯片的關(guān)鍵技術(shù)
    的頭像 發(fā)表于 08-30 18:18 ?1094次閱讀
    <b class='flag-5'>RISC-V</b> Summit China 2024  青稞<b class='flag-5'>RISC-V</b>+接口PHY,賦能<b class='flag-5'>RISC-V</b>高效落地

    加入全球 RISC-V Advocate 行列,共筑 RISC-V 的未來 !

    加入RISC-VAdvocate行列!我們正在尋找來自世界各地的RISC-V愛好者,通過全球推廣和參與,成為支持RISC-V進(jìn)步的關(guān)鍵參與者。作為一名RISC-VAdvocate,您將
    的頭像 發(fā)表于 09-10 08:08 ?124次閱讀
    加入全球 <b class='flag-5'>RISC-V</b> Advocate 行列,共筑 <b class='flag-5'>RISC-V</b> 的未來 !