jjzjj

【RISC-V】 li指令

点灯大师~ 2023-06-29 原文

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

li a0, immediately

可以将任意的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)

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

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

lui   a0,  0x01
addi  a0, a0, (0xE76 - 4096)

代码实现

#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"); 
	}
}

有关【RISC-V】 li指令的更多相关文章

  1. 【Linux】初识Linux --指令Ⅰ - 2

    Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法,Linux…感兴趣就关注我吧!你定不会失望。目录1.ls显示当前目录下的文件内内容2.pwd-显示用户当前所在的目录3.cd-改变工作目录。将当前工作目录改变到指定的目录下1.cd-回到上一次待的工作空间2.cd..返回上一层目录1.相对路径:cd../aurora2.绝对路径:cd/home/aurora/lesson1/aurora3.cd~进入用户家目录4.cd/进入root目录4.mkdir-新建目录5.rmdir/rm-删除1.rmdir删除空文件夹2.rm删除1.rm-f2.rm-i3.rm-r1.ls显示当前目

  2. iOS快捷指令:执行Python脚本(利用iSH Shell) - 2

    文章目录前言核心逻辑配置iSH安装Python创建Python脚本配置启动文件测试效果快捷指令前言iOS快捷指令所能做的操作极为有限。假如快捷指令能运行Python程序,那么可操作空间就瞬间变大了。iSH是一款免费的iOS软件,它模拟了一个类似Linux的命令行解释器。我们将在iSH中运行Python程序,然后在快捷指令中获取Python程序的输出。核心逻辑我们用一个“获取当前日期”的Python程序作为演示(其实快捷指令中本身存在“获取当前日期”的操作,因而此需求可以不用Python,这里仅仅为了演示方便),核心代码如下。>>>importtime>>>time.strftime('%Y-%

  3. ruby-on-rails - 设计 skip_confirmation!未能避免发送确认指令 - 2

    我的应用程序设置为如果用户使用Oauth或Openid登录,他们不必确认他们的电子邮件地址。但是,Devise仍在发送电子邮件确认。当我调用User.skip_confirmation时!我得到一个未定义的方法错误。我的模型:classUserfalsedefself.find_for_facebook_oauth(access_token,signed_in_resource=nil)data=access_token.extra.raw_infoifuser=User.where(:email=>data.email).firstuserelse#User.skip_confirm

  4. ruby-on-rails - Rails 路由中的 "mount"指令是什么意思? - 2

    我在Railsroutingsystem中找不到关键字“mount”的含义.我已经设置了Mercury在我的Rails应用程序中使用。它将这一行添加到我的routes.rb配置文件中:Appname::Application.routes.drawdomountMercury::Engine=>'/'mount关键字是什么意思? 最佳答案 Mount在Rails路由中相当于Unixmount。它实际上告诉应用程序该位置存在另一个应用程序(通常是Rack应用程序)。它主要用于Rails引擎。

  5. APP连接ESP8266——采用AT指令 - 2

    1.主要实验设备及器材1.1一块ESP8266(如图1)图1 ESP8266模块1.2一个USB转TTL模块(如图2)图2 USB转TTL模块2.测试ESP8266模块 2.1连接设备        WIFI模块与USB转TTL模块进行连接,连接实物图如图3所示,硬件连线框图如图4所示。图3 连接实物图图4 硬件连接框图2.2打开串口调试助手        本次实验使用的软件是XCOMV2.3,默认波特率为115200,停止位为1,数据位为8,校验位为None(如图5)。图5 XCOMV2.32.3输入测试指令AT        测试AT启动,返回OK(如图6)图6 AT测试2.4复位指令AT

  6. Ruby代码美化,将长指令拆分成多行 - 2

    我们如何编写下面的语句来提高可读性?Promotion.joins(:category).where(["lft>=?andrgt{:shop_id=>shops_id}).count('id',:distinct=>true)以下不编译Promotion.joins(:category).where(["lft>=?andrgt{:shop_id=>shops_id}).count('id',:distinct=>true)syntaxerror,unexpected'.',expectingkEND.where(["lft>=?andrgt 最佳答案

  7. 【HAL库】STM32CubeMX开发----delay延时实验----NOP空指令 - 2

    STM32CubeMX下载和安装详细教程【HAL库】STM32CubeMX开发----STM32F103/F207/F407----目录前言HAL库有自带的ms级延时函数:HAL_Delay();缺点1:无法实现us级延时缺点2:此延时函数是由SysTick滴答定时器中断产生的,滴答定时器的中断优先级是所有中断中最低的,无法在其他中断中产生延时。一、STM32F407----delay延时实验本次实验以STM32F407VET6芯片为MCU,使用25MHz外部时钟源。系统时钟SYSCLK=168MHz,使用__NOP();空指令实现延时。User_delay.c#include"User_de

  8. javascript - 如何在 AngularJS 中有条件地应用指令? - 2

    我想使用ngAttr有条件地应用一个简单的指令。我不明白为什么总是显示我的指令。因此,如果我有一个undefined/false变量,我想应用我的指令:dirr。WhenusingngAttr,theallOrNothingflagof$interpolateisused,soifanyexpressionintheinterpolatedstringresultsinundefined,theattributeisremovedandnotaddedtotheelement.MycodepenDefaultdivangular.module('myApp',[]).directive

  9. javascript - 如何使用 Angular 2/4 的鼠标滚轮事件测试指令 - 2

    我有一个带有鼠标滚轮事件的指令,它用于放大和缩小Canvas。我想知道如何为此类事件编写单元测试。我在网上找不到任何示例,谁能给我指出正确的方向?我的指令:import{Directive,ElementRef,HostListener}from"@angular/core";import{MyService}from"./my-service";@Directive({selector:"[testDirec]"})exportclassTest{privateinitPointX:number;privateinitPointY:number;constructor(private

  10. javascript - 是否有可能知道 AngularJS 指令中元素的旧值? - 2

    元素旧值和新值动态变化时是否可以知道?举个例子,我有一个值为190的按钮190并且这个按钮会被socket.io动态改变。当它改变时,我需要比较这些值,如果新值高于旧值。谢谢! 最佳答案 如果您$watch您范围内的值,它将为您提供旧值和新值。所以你在指令中的链接函数看起来像这样link:function(scope,element,attrs){scope.$watch("foo",function(newVal,oldVal){//logicbasedonoldVal}}然后在您的HTML中{{foo}}参见http://doc

随机推荐