[英]RISC-V generate -1 / 0xFFFFFFFF in a register with LUI / ADDI?
我正在學習如何為RISC-V處理器編寫代碼。 我想將0xFFFFFFFF
的值存儲到內存/寄存器中。
我可以通過在其前面添加一個lui
來擴展addi
指令的12個立即數,如下所示:
lui t0, 0xFFFFF
addi t0, t0, 0x7FF
但是結果最終將類似於0xFFFFF7FF
。
那么,我該如何產生該價值呢?
詢問C編譯器:
unsigned foo(){return 0xFFFFFFFF;}
使用Clang -O3
針對RISC-V編譯到此asm (在Godbolt上) :
foo():
addi a0, zero, -1
ret
(gcc僅使用li a0, -1
偽指令並將細節留給匯編器。通常,您應該執行相同的操作,除非您想考慮選擇可以更高效地生成的常量。)
RISC-V addi
將其立即數符號擴展為32(或64)位 ,因此,如果要在第12位中添加一個,則需要在選擇高位時加以考慮。
在這種情況下,高位的正確起始值為0
因此您可以完全優化lui
。
RISC-V使用2的補碼有符號整數,因此符號擴展僅表示加寬時將符號位復制到所有較高位置。
首先讓我們分析代碼的問題所在:
lui t0, 0xFFFFF
addi t0, t0, 0x7FF
lui
指令將20位立即數0xFFFFF
左移12位后得到的值加載到t0
。 因此, t0
導致0xFFFFF000
。 addi
號擴展了12位立即數0x7FF
,並將其添加到寄存器t0
。 由於立即數的最高有效位(即符號位)為零,因此其符號擴展的32位值為0x000007FF
。 然后將此值添加到t0
,之前為0xFFFFF000
。 因此, t0
的結果值為0xFFFFF7FF
。 如該答案中已經解釋的,您可以通過利用符號擴展的工作方式來優化lui
指令:符號擴展會傳播符號位,這是最高有效位。
12位立即數0xFFF
由1
組成,包括最高有效位(即符號位)。 因此,其32位符號擴展名是0xFFFFFFFF
,它已經對應於您想要的值:
addi t0, zero, 0xFFF
如果您一直堅持使用lui
和addi
這兩個指令,只需將所有0
加載到t0
的高位:
lui t0, 0
addi t0, t0, 0xFFF
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.