• 【RISC-V】 li指令


    RISC-V中有这样一条伪指令:

    li a0, immediately
    
    • 1

    可以将任意的32位数据或者地址加载到指定的寄存器中

    在 RV32I中,它扩展到 lui 和/或 addi

    li 何时扩展为 lui 或者 addi呢?又何时扩展为lui 和 addi呢?

    我们观察lui 和 addi 的指令码即可得出结果
    在这里插入图片描述
    在这里插入图片描述
    由上图可知,lui加载的立即数为高20位,addi加载的立即数为低12位

    由此得出结论

    • li 加载的立即数范围为:0~4096 时,会扩展成 addi 指令

      li a0, immediately ⇒ addi a0, x0, imme

    • li 加载的立即数范围超过4096时,会扩展成 lui 指令addi 指令

      li a0, immediately 扩展成
      1、lui a0, (immediately >> 12)
      2、addi a0, a0, (immediately & 0xFFF)

    • li 加载的立即数范围超过4096时,并且低12位为0,会扩展成 lui 指令

      li a0, immediately
      扩展成
      lui a0, (immediately >> 12)


    接上文,观察 lui指令addi指令 会得到这个结果:lui指令加载的立即数为无符号,无需注意。addi指令加载的为有符号数,这个需要考虑一下立即数的符号位

    假如我们要加载大立即数到指定的寄存器,需要考虑两种情况

    1、第11位为0

    第11位为0,则指令:li a0, immediate 会直接扩展成:

    lui   a0,  immediate >> 12
    addi  a0, a0, (immediate & 0xFFF)
    
    • 1
    • 2

    2、第11位为1

    第11位为1,此时 li a0, immediate 就不会扩展成

    lui   a0,  immediate >> 12
    addi  a0, a0, (immediate & 0xFFF)
    
    • 1
    • 2

    而是扩展成

    lui   a0,  ((immediate >> 12) + 1)
    addi  a0, a0, ((immediate & 0xFFF) - 2^12)
    
    • 1
    • 2

    解释一下:

    addi指令所加载的立即数的第11位为1时,这个立即数是符号扩展的,因此加数将为负数。这意味着除了添加常量的最右边11位
    之外,我们还需要减去2^12。为了弥补这个错误,只需将lui 加载的常量添加一个1,因为 lui 常量缩小了 2 ^12倍

    例如:将 0xE76 加载到寄存器a0中
    答:

    lui   a0,  0x01
    addi  a0, a0, (0xE76 - 4096)
    
    • 1
    • 2

    代码实现

    #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"); 
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    基于深度学习的鸟类检测识别系统(含UI界面,Python代码)
    CesiumJS【Basic】- #024 加载webm文件(Primitive方式)
    【LeetCode】105.从前序与中序遍历序列构造二叉树
    微突发丢包的艺术
    Redis 在 C# 中的应用与集成
    数据结构:选择题+编程题(每日一练)
    贪吃蛇详解
    软考 - 计算机组成与结构
    Vue知识点总结-DX的笔记
    一套以云平台、云服务器为基础开发的智慧校园电子班牌系统源码 智慧校园源码 智慧班牌源码
  • 原文地址:https://blog.csdn.net/m0_47329175/article/details/127569824