在 rocket-chip 中对 opcodes 进行定制化的过程主要是在 riscv-tools/riscv-opcodes 目录中:

.
├── encoding.h                 --- 基础编码工具
├── LICENSE
├── Makefile                   --- 编译脚本
├── opcodes                    --- opcodes 定义,下同
├── opcodes-custom
├── opcodes-pseudo
├── opcodes-rvc
├── opcodes-rvc-pseudo
├── parse-opcodes              ---  opcodes 自动化生成工具
└── README.md                  ---  说明文档

接下来解读下 Makefile 文件中的内容:

SHELL := /bin/sh# 定义目标 encoding.h 目标文件位置
ISASIM_H := ../riscv-isa-sim/riscv/encoding.h
PK_H := ../riscv-pk/machine/encoding.h
FESVR_H := ../riscv-fesvr/fesvr/encoding.h
ENV_H := ../riscv-tests/env/encoding.h
OPENOCD_H := ../riscv-openocd/src/target/riscv/encoding.hALL_OPCODES := opcodes-pseudo opcodes opcodes-rvc opcodes-rvc-pseudo opcodes-custominstall: $(ISASIM_H) $(PK_H) $(FESVR_H) $(ENV_H) $(OPENOCD_H) inst.chisel instr-table.tex priv-instr-table.tex# 安装所有指令码到 c 语言库,并拷贝 encoding.h 文件到目标目录
$(ISASIM_H) $(PK_H) $(FESVR_H) $(ENV_H) $(OPENOCD_H): $(ALL_OPCODES) parse-opcodes encoding.hcp encoding.h $@cat opcodes opcodes-rvc-pseudo opcodes-rvc opcodes-custom | ./parse-opcodes -c >> $@# 安装所有的指令码到 Chisel 代码中,通过 parse-opcodes 脚本生成 Instructions 类
inst.chisel: $(ALL_OPCODES) parse-opcodescat opcodes opcodes-custom opcodes-pseudo | ./parse-opcodes -chisel > $@# 安装所有的指令码到 Go 代码中,通过 parse-opcodes 脚本生成
inst.go: opcodes opcodes-pseudo parse-opcodescat opcodes opcodes-pseudo | ./parse-opcodes -go > $@instr-table.tex: $(ALL_OPCODES) parse-opcodescat opcodes opcodes-pseudo | ./parse-opcodes -tex > $@priv-instr-table.tex: $(ALL_OPCODES) parse-opcodescat opcodes opcodes-pseudo | ./parse-opcodes -privtex > $@.PHONY : install

执行 make install 之后,在 riscv-fesvr/fesvr/encoding.h 文件中,存在机器码的定义过程,比如:

#ifdef DECLARE_INSN
DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
...省略...
#endif

解析过程

简单分析下 parse-opcodes 文件中生成 encoding.h 文件部分的实现:

...此前省略...
def make_c(match,mask):print '/* Automatically generated by parse-opcodes.  */'print '#ifndef RISCV_ENCODING_H'print '#define RISCV_ENCODING_H'
// 递归指令名称列表,组装 MATCH_*, MASK_*, CSR_*, CAUSE_* 等宏定义for name in namelist:name2 = name.upper().replace('.','_')print '#define MATCH_%s %s' % (name2, hex(match[name]))print '#define MASK_%s  %s' % (name2, hex(mask[name]))for num, name in csrs+csrs32:print '#define CSR_%s %s' % (name.upper(), hex(num))for num, name in causes:print '#define CAUSE_%s %s' % (name.upper().replace(' ', '_'), hex(num))print '#endif'// 定义 INSN 指令print '#ifdef DECLARE_INSN'for name in namelist:name2 = name.replace('.','_')print 'DECLARE_INSN(%s, MATCH_%s, MASK_%s)' % (name2, name2.upper(), name2.upper())print '#endif'// 声明 CSR print '#ifdef DECLARE_CSR'for num, name in csrs+csrs32:print 'DECLARE_CSR(%s, CSR_%s)' % (name, name.upper())print '#endif'// 声明 CAUSE print '#ifdef DECLARE_CAUSE'for num, name in causes:print 'DECLARE_CAUSE("%s", CAUSE_%s)' % (name, name.upper().replace(' ', '_'))print '#endif'
...此后省略...

Opcodes 定义文件

opcodes-rvc-pseudo 文件为例,其中包含了一些特定的指令:

# these aren't really pseudo-ops, but they overlay other encodings,
# so they are here to prevent parse-opcodes from barfing@c.nop      1..0=1 15..13=0 12=0      11..7=0      6..2=0
@c.addi16sp 1..0=1 15..13=3 12=ignore 11..7=2      6..2=ignore
@c.jr       1..0=2 15..13=4 12=0      11..7=ignore 6..2=0
@c.jalr     1..0=2 15..13=4 12=1      11..7=ignore 6..2=0
@c.ebreak   1..0=2 15..13=4 12=1      11..7=0      6..2=0# RV64C
@c.ld      1..0=0 15..13=3 12=ignore 11..2=ignore # c.flw for RV32
@c.sd      1..0=0 15..13=7 12=ignore 11..2=ignore # c.fsw for RV32
@c.addiw   1..0=1 15..13=1 12=ignore 11..2=ignore # c.jal for RV32
@c.ldsp    1..0=2 15..13=3 12=ignore 11..2=ignore # c.flwsp for RV32
@c.sdsp    1..0=2 15..13=7 12=ignore 11..2=ignore # c.fswsp for RV32

Opcodes 说明相关推荐

  1. 深入理解PHP原理之Opcodes

    2019独角兽企业重金招聘Python工程师标准>>> 最近要给Yahoo的同事们做一个关于PHP和Apache处理请求的内部机制的讲座,刚好写了些关于Opcodes的文字,就发上来 ...

  2. bipush java,Java Opcodes.BIPUSH屬性代碼示例

    本文整理匯總了Java中org.objectweb.asm.Opcodes.BIPUSH屬性的典型用法代碼示例.如果您正苦於以下問題:Java Opcodes.BIPUSH屬性的具體用法?Java O ...

  3. php opcodes 还原代码,深入理解PHP原理之Opcodes(PHP执行代码会经过的4个步骤是什么)...

    深入理解PHP原理之Opcodes(PHP执行代码会经过的4个步骤是什么) 一.总结 一句话总结: 1.Scanning(Lexing) ,将PHP代码转换为语言片段(Tokens) 2.Parsin ...

  4. OPCODES学习网址

    OPCODES手册 http://byhh.net/f/CS/1175690465/opcodes.rar 先看老罗的缤纷天地中OPCODES的解析,写得相当好. 老罗的缤纷天地 http://www ...

  5. PHP使用vld扩展查看opcodes

    PHP使用vld扩展查看opcodes 需要分析PHP代码的性能,或者说实现同样功能的代码到底哪个更好呢?或者说想知道底层的实现可以使用VLD查看opcode. 下载安装vld扩展 该扩展以收录在 P ...

  6. 揭秘EVM Opcodes

    1. 引言 本文主要源自Macro团队的Gilbert在ETHNewYork 2022分享 Demystifying EVM Opcodes,同时结合evm.codes来理解. 下图摘自Evoluti ...

  7. IL,Emit之OpCodes说明(备查)

    名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add_Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. Add_Ovf_Un 将两个无符号整数值相加,执行溢出检查,并且 ...

  8. linux epoll用法

    epoll 是 linux 特有的 I/O 复用函数.它是把用户关心的文件描述符事件放在内核的一个事件列表中,故而,无须像select和poll一样每次调用都重复传入文件描述符或事件集.但是, epo ...

  9. oracle block media recovery,Oracle非归档模式Media Recovery错误之--ORA-26040

    11.转储对应的logfile 14:35:48 SYS@ prod>alter system dump logfile '/dsk1/oradata/prod/redo01a.log': Sy ...

最新文章

  1. 如何在命令行上创建符合特定规范的密码?
  2. HDU1443(约瑟夫环问题)
  3. Android 对okhttp的封装
  4. Android基于mAppWidget实现手绘地图(二)--概要
  5. 标准exception类层次图
  6. easyexcel和poi是否有版本冲突_easyexcel--解决poi大文件发生OOM问题
  7. Electro桌面应用开发之HelloWorld
  8. Ubuntu16.04版安装VMwareTools的步骤和没法挂载目录问题的解决
  9. THUPC2019划水记
  10. wps直接打开CVS文件会把长串数字订单号最后4位变为0
  11. 【C语言】流程图符号及流程图
  12. 不可不知的量化因子模型选股策略
  13. 湖南大学计算机学硕推免率,好几个帖子都在讨论清北华五的推免生源我来发一下b类大学湖大今...
  14. element tree不刷新视图_我不告诉你的话,你不会知道iPad原来也有这么多窍门,学起来...
  15. 巴特沃斯(Butterworth)滤波器 (2) - 双线性变换
  16. Makefile3、书写规则(文件搜寻、伪目标、多目标、静态模式、自动生成依赖性)
  17. 推动计算机革命的幕后黑手
  18. mysql 1.4安装步骤_从零开始搭建系统1.4——MySql安装及配置
  19. 第一批90后30岁了,该有多少存款?
  20. 最大访客数(c/python)

热门文章

  1. 开源免费的WEB应用防火墙
  2. 朴素贝叶斯-后验概率最大化的含义(公式最后的推导)
  3. 一分钟一个Pandas小技巧(一)
  4. 【数据结构】广义表的基本概念
  5. 【JavaScript】32_解构对象与对象的解构
  6. 读《矿矿上高中一年级》所得到的收获
  7. unity 2d角色移动卡住的原因
  8. js 谷歌浏览器 关闭当前页
  9. 怎样使用GetAsyncKeyState()
  10. Auto CAD三维图怎么画?cad三维图怎么画教程