如何在玄铁gcc工具链中添加自定义指令

编程入门 行业动态 更新时间:2024-10-09 09:24:20

如何在玄铁gcc工具链中添加<a href=https://www.elefans.com/category/jswz/34/1771438.html style=自定义指令"/>

如何在玄铁gcc工具链中添加自定义指令

需要用到的工具

  • 玄铁gcc工具链源码
  • riscv-opcodes工具

获取玄铁工具链源码

因为需要魔改编译器,所以不能用他提供的预编译版本:

git clone .git

将文件夹下的.gitmodules中的内容换成以下镜像站:

[submodule "riscv-binutils"]path = riscv-binutilsurl = .git
[submodule "riscv-gcc"]path = riscv-gccurl = ../gcc.git
[submodule "riscv-glibc"]path = riscv-glibcurl = .git
[submodule "riscv-dejagnu"]path = riscv-dejagnuurl = .gitbranch = riscv-dejagnu-1.6
[submodule "riscv-newlib"]path = riscv-newliburl = .git
[submodule "riscv-gdb"]path = riscv-gdburl = .git
[submodule "qemu"]path = qemuurl = .git

然后初始化项目仓库(根据网速大概10min?):

git submodule update --init

使用riscv-opcodes工具创建自定义指令

获取工具:

git clone git@github:riscv/riscv-opcodes.git
cd riscv-opcodes
code rv_test

根据模版,编辑rv_test内容如下:

cube rd rs1 rs2 31..25=0x0c 14..12=0x6 6..2=0x1e 1..0=3

随后make一下就可以得到encoding.out.h文件,可以找一下刚刚加的指令相关的关键字:

//可以找到两行define
#define MATCH_CUBE 0x1800607b
#define MASK_CUBE 0xfe00707f//以及一个宏
DECLARE_INSN(cube, MATCH_CUBE, MASK_CUBE)

接下来,要利用gcc工具链的binutils工具把我们的自定义指令正式加入到gcc工具链中,打开riscv-binutils/include/opcode/riscv-opc.h,加入上面的几行代码。其中,DECLARE_INSN宏要加在#ifdef DECLARE_INSN#endif中间。
另外,我们还要在riscv-binutils/opcodes/riscv-opc.c文件中,加入我们自定义指令的机器码格式。
可以看到这里有一个结构体常量数组定义了所有opcodes:

const struct riscv_opcode riscv_opcodes[] =
{
/* name,     xlen, isa,   operands, match, mask, match_func, pinfo.  */

我们仿照其它I-Type的指令格式编写我们的指令的该结构体下的定义:

{"cube",       0, INSN_CLASS_I, "d,s,t",  MATCH_CUBE, MASK_CUBE, match_opcode, 0 },

参考如下:

{"hinval.gvma",     0, INSN_CLASS_SVINVAL, "s,t", MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA, match_opcode, 0 },{"cube",       0, INSN_CLASS_I, "d,s,t",  MATCH_CUBE, MASK_CUBE, match_opcode, 0 },
/* Terminate the list.  */
{0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
};

其中INSN_CLASS_I代表指令为基础整数指令集(也有其他扩展指令集:A(原子指令集)、M(乘法指令集)、C(压缩指令集)、F(单精度浮点)等,如下图),MATCH_CUBEMASK_CUBE来自刚刚riscv-opcodes工具生成的宏定义,match_opcode表示指令通过opcode匹配(即32位指令的低7位)。

到此,一条自定义指令便在gcc工具链中添加成功了,另外,我们也可以在刚才的两个文件中看到平头哥自定义指令集的相关内容,接下来,我们还需要重新编译一下工具链:

#--prefix就是安装目录自己定好即可,待会还要用到
./configure --prefix=/home/qw/xuantie-test-gcc
#-j几根据自己电脑来,我大概花了一个小时才编译完
make -j8

在C910项目中实验自己定义的指令

smart_run/setup/example_setup.csh中设置刚刚gcc工具链的安装位置:

setenv TOOL_EXTENSION /自己的/安装/路径/bin

然后,在smart_run/tests/cases/hello_world/hello_world.c这个测试中,添加以下内容,cube即我们刚刚添加的自定义指令:

  asm volatile("lable_test: \n""cube a0,a1,zero\n");

然后编译hello_world测试用例:

make buildcase CASE=hello_world

然后,打开smart_run/work/hello_world.obj这个反汇编文件,就能看到我们添加的label以及指令了:

0000000000000708 <lable_test>:708:	1805e57b          	cube	x10,x11,x0

当然,因为还没有在硬件上提供这条指令的相关支持,目前我们还没发真正的在C910上运行这条指令(还要魔改C910源码,悲)。

参考

cyy大佬文章
b乎上的文章

更多推荐

如何在玄铁gcc工具链中添加自定义指令

本文发布于:2024-02-11 21:21:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1683569.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   指令   工具   链中   如何在

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!