当前位置: 首页 > news >正文

auipc指令在NEMU中的执行过程 - Zeeh

假设

  1. 指令集为RV64I

  2. 内存地址开始于0x8000 0000

  3. 使用如下的代码:

    static const uint32_t img [] = {0x00000297,  // auipc t0,00x00028823,  // sb  zero,16(t0)0x0102c503,  // lbu a0,16(t0)0x00100073,  // ebreak (used as nemu_trap)0xdeadbeef,  // some data
    };
    
  4. Decode的定义如下

    typedef struct Decode {uint64_t pc;uint64_t snpc; // static next pcuint64_t dnpc; // dynamic next pcstruct {uint32_t inst;} isa;
    } Decode;
    
  5. cpu.pc初始值为0x8000 0000

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

  7. 忽略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)更新sinst_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)中:

  1. str[i]'1', __key左移并且低位补1; 若不是, __key左移并且低位补0;
  2. str[i]'?', __mask左移并且低位补0;
    若不是, __mask左移并且低位补1
  3. 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.

http://www.hskmm.com/?act=detail&tid=32231

相关文章:

  • 如何在AutoCAD中进行GIS空间查询?
  • initContainers实现整个数据目录的挂载
  • 2025年屋脊通风天窗厂家最新权威推荐榜:工业厂房自然通风解决方案优选品牌
  • 2025年10月电子散热器行业权威报告:十大品牌技术创新、性能表现与市场布局全景解析及选购指南
  • 迁移boot分区解决brtfs引起的Sparse File Not Allowed问题
  • 阿里面试:Redis挂了怎么办?集群主节点挂了怎么 恢复数据?可能有多长时间 数据丢失?【转自】
  • 2025年10月北京开锁公司最新服务商平台推荐排行榜,北京紧急开锁换锁上门服务推荐!
  • 学霸的期末 解题报告
  • 一种适用于正整数值域的无旋平衡树
  • 2025 年电子散热器厂家 TOP 企业品牌推荐排行榜,电子 / 型材 / 插片 / 电源 / 固态 / 变频器 / 铝合金 / 逆变器散热器 / 散热器铝型材公司推荐
  • 禁用sentinel
  • 静态网站宣言:用IPFS重建开放网络的乐趣
  • 收敛数列的性质
  • Eclipse Mosquitto MQTT 代理中持久性引擎(database.c 概念)的作用分析报告 - 指南
  • FFmpeg 实现视频批量剪辑
  • 2023盘古石 物联网取证部分
  • 2025 年自润滑轴承厂家联系方式推荐,宁波索力特复合材料有限公司专业产品与可靠服务指南
  • MATLAB PSO-PF 融合滤波
  • SaltStack 集群安装指南
  • nginx基本配置详解
  • NCS 3.1.1 蓝牙如何设置 public 地址
  • C# Avalonia 16- Animation- BlurringButtons
  • iOS 26 崩溃日志导出全流程,多工具实践 辅助分析策略
  • 小白也能学会的 rime + 万象拼音 输入法安装教程
  • 别再争了,“Prompt已死”是个伪命题
  • 2025.10.16——1绿
  • 2025年通风气楼厂家最新权威推荐榜:工业厂房自然通风与消防排烟系统专业解决方案精选
  • 2025 年展柜定制厂家最新推荐排行榜:聚焦全链条服务与大规模生产能力的优质品牌精选
  • 了解漏洞管理和补丁管理
  • 于鸿硕项目案例作业03