在RISC-V中有這樣一條偽指令:
li a0, immediately
可以將任意的32位數(shù)據(jù)或者地址加載到指定的寄存器中
在 RV32I中,它擴展到 lui 和/或 addi
li 何時擴展為 lui 或者 addi呢?又何時擴展為lui 和 addi呢?
我們觀察lui 和 addi 的指令碼即可得出結(jié)果
由上圖可知,lui加載的立即數(shù)為高20位,addi加載的立即數(shù)為低12位
由此得出結(jié)論
- 若 li 加載的立即數(shù)范圍為:0~4096 時,會擴展成 addi 指令
li a0, immediately ? addi a0, x0, imme
- 若 li 加載的立即數(shù)范圍超過4096時,會擴展成 lui 指令 和 addi 指令
li a0, immediately 擴展成
1、lui a0, (immediately >> 12)
2、addi a0, a0, (immediately & 0xFFF)
- 若 li 加載的立即數(shù)范圍超過4096時,并且低12位為0,會擴展成 lui 指令
li a0, immediately
擴展成
lui a0, (immediately >> 12)
接上文,觀察 lui指令 、addi指令 會得到這個結(jié)果:lui指令加載的立即數(shù)為無符號,無需注意。addi指令加載的為有符號數(shù),這個需要考慮一下立即數(shù)的符號位
假如我們要加載大立即數(shù)到指定的寄存器,需要考慮兩種情況
1、第11位為0
第11位為0,則指令:li a0, immediate
會直接擴展成:
lui a0, immediate >> 12
addi a0, a0, (immediate & 0xFFF)
2、第11位為1
第11位為1,此時 li a0, immediate
就不會擴展成
lui a0, immediate >> 12
addi a0, a0, (immediate & 0xFFF)
而是擴展成
lui a0, ((immediate >> 12) + 1)
addi a0, a0, ((immediate & 0xFFF) - 2^12)
解釋一下:
addi指令所加載的立即數(shù)的第11位為1時,這個立即數(shù)是符號擴展的,因此加數(shù)將為負數(shù)。這意味著除了添加常量的最右邊11位
之外,我們還需要減去2^12。為了彌補這個錯誤,只需將lui 加載的常量添加一個1,因為 lui 常量縮小了 2 ^12倍
例如:將 0xE76 加載到寄存器a0中
答:
lui a0, 0x01
addi a0, a0, (0xE76 - 4096)
代碼實現(xiàn)
#define immediate XXXX
uint32_t MSB, LSB;
MSB = immediate >> 12;
LSB = immediate & 0xFFF;
if (MSB == 0) {
if (LSB & 0x800) {
asm volatile("lui a0, 0x01");
asm volatile("addi a0, a0, LSB - 4096");
} else {
asm volatile("addi a0, x0, LSB");
}
} else {
if (LSB & 0x800) {
asm volatile("lui a0, MSB + 0x01");
asm volatile("addi a0, a0, LSB - 4096");
} else {
asm volatile("lui a0, MSB");
asm volatile("addi a0, x0, LSB");
}
}
審核編輯:湯梓紅
-
寄存器
+關(guān)注
關(guān)注
31文章
5361瀏覽量
120877 -
指令
+關(guān)注
關(guān)注
1文章
611瀏覽量
35787 -
RISC-V
+關(guān)注
關(guān)注
45文章
2313瀏覽量
46333
發(fā)布評論請先 登錄
相關(guān)推薦
評論