RISC处理器中32/64位立即数操作可行性及主流架构实现问询
RISC架构大立即数操作实现方案
当立即数无法放入32位指令字时,所有主流RISC架构都无法通过单条指令完成大立即数(32位/64位)的加载或算术操作,均需通过多指令合成或内存加载的方式模拟实现。以下是各平台针对指定伪代码的具体实现:
MIPS(32位/64位)
- r1 = imm32
32位MIPS需两条指令合成:
MIPS64可直接使用lui $r1, %hi(imm32) # 加载imm32的高16位到r1高16位,低16位清0 ori $r1, $r1, %lo(imm32) # 合并imm32的低16位到r1dli $r1, imm32伪指令,汇编器自动展开为上述两条指令。 - r1 = imm64
通过四条指令拆分加载:
或使用lui $r1, %highest(imm64) ori $r1, $r1, %higher(imm64) dsll $r1, $r1, 16 ori $r1, $r1, %lo(imm64)ldi $r1, imm64伪指令自动展开。 - r1 = r2 + imm32
无单条指令支持,需先将imm32加载到临时寄存器,再执行加法:lui $t0, %hi(imm32) ori $t0, $t0, %lo(imm32) addu $r1, $r2, $t0 - r1 = r2 - imm64
先加载imm64到临时寄存器,再执行减法:ldi $t0, imm64 subu $r1, $r2, $t0
RISC-V(32位/64位)
- r1 = imm32
RV32需两条指令合成:
RV64可使用lui x1, %hi(imm32) # 加载imm32的高20位 addi x1, x1, %lo(imm32) # 合并低12位(addi支持12位立即数)li x1, imm32伪指令自动展开。 - r1 = imm64
RV64通过三条指令拆分加载:
或使用lui x1, %highest(imm64) addi x1, x1, %higher(imm64) slli x1, x1, 12 addi x1, x1, %lo(imm64)li x1, imm64伪指令自动展开。 - r1 = r2 + imm32
RV32需先合成imm32到临时寄存器再相加;RV64若为符号扩展的32位立即数,可直接用addiw x1, x2, imm32,否则仍需临时寄存器中转。 - r1 = r2 - imm64
先将imm64加载到临时寄存器,再执行减法:li x5, imm64 sub x1, x2, x5
SPARC(32位/64位)
- r1 = imm32
通过两条指令拆分加载:sethi %hi(imm32), %r1 # 加载imm32的高22位并左移10位 or %r1, %lo(imm32), %r1 # 合并低10位 - r1 = imm64
拆分64位为多段,通过sethi+逻辑指令合成,或直接从常量池加载:sethi %hh(imm64), %r1 or %r1, %hm(imm64), %r1 sll %r1, %r1, 22 or %r1, %lo(imm64), %r1 - r1 = r2 + imm32
先加载imm32到临时寄存器,再执行加法:sethi %hi(imm32), %t0 or %t0, %lo(imm32), %t0 add %r1, %r2, %t0 - r1 = r2 - imm64
加载imm64到临时寄存器后执行减法:mov %t0, imm64 # 伪指令,汇编器自动展开 sub %r1, %r2, %t0
DEC Alpha64
Alpha为纯64位RISC,所有指令字长32位,立即数最多支持16位:
- r1 = imm32
两条指令合成:ldah r1, %hi(imm32)(r0) # 加载高16位并符号扩展 lda r1, %lo(imm32)(r1) # 合并低16位 - r1 = imm64
拆分4段16位,通过四次加载合成:ldah r1, %highest(imm64)(r0) lda r1, %higher(imm64)(r1) sll r1, r1, 32 ldah r1, %lower(imm64)(r1) lda r1, %low(imm64)(r1) - r1 = r2 + imm32
加载imm32到临时寄存器后执行加法:ldah t0, %hi(imm32)(r0) lda t0, %lo(imm32)(t0) addq r1, r2, t0 - r1 = r2 - imm64
加载imm64到临时寄存器后执行减法:mov t0, imm64 # 伪指令,汇编器自动展开 subq r1, r2, t0
ARM(ARMv7/AArch64)
ARMv7(32位)
- r1 = imm32
两条指令拆分加载:MOVW r1, #imm16_low # 加载低16位 MOVT r1, #imm16_high # 加载高16位到r1的高16位 - r1 = imm64
从内存常量池加载:LDR r1, =imm64 # 汇编器自动生成常量池地址加载 - r1 = r2 + imm32
先加载imm32到临时寄存器,再执行加法:MOVW r3, #imm16_low MOVT r3, #imm16_high ADD r1, r2, r3 - r1 = r2 - imm64
加载imm64到临时寄存器后执行减法:LDR r3, =imm64 SUB r1, r2, r3
AArch64(64位)
- r1 = imm32
若为任意32位立即数,通过两条指令合成:MOVZ X1, #imm16_low, LSL #0 MOVK X1, #imm16_high, LSL #16 - r1 = imm64
四条指令拆分加载:MOVZ X1, #imm16_0, LSL #0 MOVK X1, #imm16_1, LSL #16 MOVK X1, #imm16_2, LSL #32 MOVK X1, #imm16_3, LSL #48 - r1 = r2 + imm32
若为符号扩展的32位立即数,可直接执行:
否则需先合成到临时寄存器再加。ADD X1, X2, #imm32 - r1 = r2 - imm64
加载imm64到临时寄存器后执行减法:MOVZ X3, #imm16_0, LSL #0 MOVK X3, #imm16_1, LSL #16 MOVK X3, #imm16_2, LSL #32 MOVK X3, #imm16_3, LSL #48 SUB X1, X2, X3
Power(PowerPC/Power ISA)
32位PowerPC
- r1 = imm32
两条指令合成:lis r1, %hi(imm32) # 加载高16位到r1高16位 ori r1, r1, %lo(imm32) # 合并低16位 - r1 = imm64
从TOC(表项计数)常量池加载:ld r1, imm64@toc(r2)
64位Power ISA
- r1 = imm32
使用li r1, imm32伪指令,汇编器自动展开为lis+ori。 - r1 = imm64
用li r1, imm64伪指令,汇编器拆分四段16位加载合成,或从TOC加载。 - r1 = r2 + imm32
先加载imm32到临时寄存器,再执行加法:lis r3, %hi(imm32) ori r3, r3, %lo(imm32) add r1, r2, r3 - r1 = r2 - imm64
加载imm64到临时寄存器后执行减法:li r3, imm64 sub r1, r2, r3
内容的提问来源于stack exchange,提问作者JSpruce
相关产品推荐
相关产品推荐

