news 2026/8/1 18:40:46

auipc指令在NEMU中的执行过程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
auipc指令在NEMU中的执行过程

指令集为RV64I

内存地址开始于0x8000 0000

使用如下的代码:

static const uint32_t img [] = {

0x00000297, // auipc t0,0

0x00028823, // sb zero,16(t0)

0x0102c503, // lbu a0,16(t0)

0x00100073, // ebreak (used as nemu_trap)

0xdeadbeef, // some data

};

Decode的定义如下

typedef struct Decode {

uint64_t pc;

uint64_t snpc; // static next pc

uint64_t dnpc; // dynamic next pc

struct {

uint32_t inst;

} isa;

} Decode;

cpu.pc初始值为0x8000 0000

从调用exec_once()并开始执行auipc开始考虑

忽略trace和difftest相关的操作

exec_once(&s, cpu.pc);#

调用exec_once(&s, cpu.pc),当前cpu.pc值为0x8000 0000

进入exec_once()后,更新s:

s->pc = 0x80000000;

s->snpc = 0x80000000;

调用isa_exec_once(s)

isa_exec_once(s)#

利用inst_fetch(&s->snpc, 4)更新s。inst_fetch返回snpc对应的指令地址(uint32_t类型),并且更新snpc为下一条指令所在地址(s->snpc += 4, 即0x8000 0004)。

更新后的s:

s->pc = 0x80000000;

s->snpc = 0x80000004;

s->isa.inst = 0x80000000;

之后执行decode_exec(s)并将其结果返回.

decode_exec(s)#

更新s->dnpc = s->snpc, 此时s:

s->pc = 0x80000000;

s->snpc = 0x80000004;

s->dnpc = 0x80000004;

s->isa.inst = 0x80000000;

定义标签地址, 用于之后跳转:

const void * __instpat_end = &&__instpat_end_;

指令匹配:

INSTPAT("??????? ????? ????? ??? ????? 00101 11", auipc , U, R(rd) = s->pc + imm);

INSTPAT("??????? ????? ????? 100 ????? 00000 11", lbu , I, R(rd) = Mr(src1 + imm, 1));

INSTPAT("??????? ????? ????? 000 ????? 01000 11", sb , S, Mw(src1 + imm, 1, src2));

INSTPAT("0000000 00001 00000 000 00000 11100 11", ebreak , N, NEMUTRAP(s->pc, R(10))); // R(10) is $a0

INSTPAT("??????? ????? ????? ??? ????? ????? ??", inv , N, INV(s->pc));

INSTPAT() 指令匹配宏#

宏展开后, 匹配成功第一条规则:

do {

uint64_t key, mask, shift;

pattern_decode("??????? ????? ????? ??? ????? 00101 11",

(sizeof("??????? ????? ????? ??? ????? 00101 11") - 1), &key, &mask, &shift);

if ((((uint64_t)((s)->isa.inst) >> shift) & mask) == key) {

{

int rd = 0;

word_t src1 = 0, src2 = 0, imm = 0;

decode_operand(s, &rd, &src1, &src2, &imm, TYPE_U);

(cpu.gpr[check_reg_idx(rd)]) = s->pc + imm ;

};

goto *(__instpat_end);

}

} while (0)

其中(sizeof("??????? ????? ????? ??? ????? 00101 11") - 1) == 38

pattern_decode() 解码宏#

进入pattern_decode()宏后, 定义临时变量uint64_t __key = 0, __mask = 0, __shift = 0;. 之后pattern_decode() 会利用辅助宏macro(i).

在macro(i)中:

若str[i]是'1', __key左移并且低位补1; 若不是, __key左移并且低位补0;

若str[i]是'?', __mask左移并且低位补0;

若不是, __mask左移并且低位补1

若str[i]是'?', __shift加1, 否则立刻清0

通过:

#define macro2(i) macro(i); macro((i) + 1)

#define macro4(i) macro2(i); macro2((i) + 2)

#define macro8(i) macro4(i); macro4((i) + 4)

#define macro16(i) macro8(i); macro8((i) + 8)

#define macro32(i) macro16(i); macro16((i) + 16)

#define macro64(i) macro32(i); macro32((i) + 32)

macro64(0);

处理指令掩码中的38个字符.

本例中, __key最终为0010111, __mask最终为000...00(共25个0)1111111, __shift最终为0

跳转到finish标签后执行:

finish:

*key = __key >> __shift;

*mask = __mask >> __shift;

*shift = __shift;

然后退出pattern_decode()宏, 进入INSTPAT宏的:

if ((((uint64_t)INSTPAT_INST(s) >> shift) & mask) == key) { \

INSTPAT_MATCH(s, ##__VA_ARGS__); \

goto *(__instpat_end); \

} \

(uint64_t)INSTPAT_INST(s)即执行的指令inst. inst被右移shift位, 然后和mask按位与, 判断是否和key完全相等

如果相等, 则执行:

INSTPAT_MATCH(s, ##__VA_ARGS__); \

goto *(__instpat_end); \

ISNT_MATCH() 执行指令宏#

在这个宏里, 会利用decode_operand()函数来译码出rd, src, src2, imm. 然后执行__VA_ARGS__ ;. __VA_ARGS__就是在INSTPAT()中传入的指令的具体操作. 对于auipc这条指令, __VA_ARGS就是R(rd) = s->pc + imm.

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/1 2:32:43

vivo HDFS EC大规模落地实践

Hadoop3.0版本中,作为一种新的冗余存储的方式引入进来。使用EC编码的方式替代原来的三副本存储,保证数据可靠性的同时可以节约存储。相应地,付出的代价是读取性能的下降,对于访问频率不高的数据,使用EC编码很合适。viv…

作者头像 李华
网站建设 2026/8/2 4:20:32

HOScrcpy鸿蒙远程投屏工具:从入门到精通全攻略

HOScrcpy鸿蒙远程投屏工具:从入门到精通全攻略 【免费下载链接】鸿蒙远程真机工具 该工具主要提供鸿蒙系统下基于视频流的投屏功能,帧率基本持平真机帧率,达到远程真机的效果。 项目地址: https://gitcode.com/OpenHarmonyToolkitsPlaza/HO…

作者头像 李华
网站建设 2026/7/31 19:48:00

MPU6050在四轴飞行器中的实战应用指南

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个四轴飞行器姿态控制项目,使用MPU6050作为主传感器。要求:1. 实现I2C通信代码 2. 包含传感器数据校准流程 3. 整合互补滤波算法 4. 输出俯仰/横滚/偏…

作者头像 李华
网站建设 2026/8/1 2:05:19

Node.js数字信封错误:小白也能懂的解决方案

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个交互式学习模块,通过图文并茂的方式向编程新手解释error:03000086错误的含义。包含简单的动画演示加密原理,逐步指导如何检查Node.js版本&#xff0…

作者头像 李华
网站建设 2026/8/1 9:52:11

AUS GLOBAL正式受邀出席2025年克林顿全球倡议(CGI)年会

我们荣幸宣布,AUS GLOBAL(澳洲环球) 首席执行官 Naima Dayf 女士正式受邀出席 2025 年克林顿全球倡议(Clinton Global Initiative,简称CGI)年会。本次年会将于 2025 年 9 月 24 日至 25 日在美国纽约市隆重…

作者头像 李华
网站建设 2026/8/1 21:48:31

Qwen2-VL微调终极指南:轻松掌握视觉语言模型训练

Qwen2-VL微调终极指南:轻松掌握视觉语言模型训练 【免费下载链接】Qwen2-VL-Finetune An open-source implementaion for fine-tuning Qwen2-VL and Qwen2.5-VL series by Alibaba Cloud. 项目地址: https://gitcode.com/gh_mirrors/qw/Qwen2-VL-Finetune Qw…

作者头像 李华