本项目目标是基于LLVM,实现对平头哥玄铁C910指令集架构的支持。玄铁 C910在RISCV标准指令集架构的基础上,增加了自定义指令,包括 Cache 指令子集,同步指令子集,算术运算指令子集,位操作指令子集以及存储指令子集。本项目主要工作是在RISCV后端实现这些扩展指令支持。
同步指令子集
指令 | 描述 | 状态 |
---|---|---|
SYNC | 同步指令 | ☑️ |
SYNC.I | 同步清空指令 | ☑️ |
SYNC.IS | 同步清空广播指令 | ☑️ |
SYNC.S | 同步广播指令 | ☑️ |
算术运算指令子集
指令 | 描述 | 状态 |
---|---|---|
ADDSL | 寄存器移位相加指令 | ☑️ |
MULA | 乘累加指令 | ☑️ |
MULAH | 低 16 位乘累加指令 | ☑️ |
MULAW | 低 32 位乘累加指令 | ☑️ |
MULS | 乘累减指令 | ☑️ |
MULSH | 低 16 位乘累减指令 | ☑️ |
MULSW | 低 32 位乘累减指令 | ☑️ |
MVEQZ | 寄存器为 0 传送指令 | ☑️ |
MVNEZ | 寄存器非 0 传送指令 | ☑️ |
SRRI | 循环右移指令 | ☑️ |
SRRIW | 低 32 位循环右移指令 | ☑️ |
位操作指令子集
指令 | 描述 | 状态 |
---|---|---|
EXT | 寄存器连续位提取符号位扩展指令 | ☑️ |
EXTU | 寄存器连续位提取零扩展指令 | ☑️ |
FF0 | 快速找 0 指令 | ☑️ |
FF1 | 快速找 1 指令 | ☑️ |
REV | 字节倒序指令 | ☑️ |
REVW | 低 32 位字节倒序指令 | ☑️ |
TST | 比特为 0 测试指令 | ☑️ |
存储指令子集
指令 | 描述 | 状态 |
---|---|---|
FLRD | 浮点寄存器移位双字加载指令 | ☑️ |
FLRW | 浮点寄存器移位字加载指令 | ☑️ |
FLURD | 浮点寄存器低 32 位移位双字加载指令 | ☑️ |
FLURW | 浮点寄存器低 32 位移位字加载指令 | ☑️ |
LRB | 寄存器移位符号位扩展字节加载指令 | ☑️ |
LRH | 寄存器移位符号位扩展半字加载指令 | ☑️ |
LRW | 寄存器移位符号位扩展字加载指令 | ☑️ |
LRD | 寄存器移位双字加载指令 | ☑️ |
LRBU | 寄存器移位零扩展字节加载指令 | ☑️ |
LRHU | 寄存器移位零扩展半字加载指令 | ☑️ |
LRWU | 寄存器移位零扩展字加载指令 | ☑️ |
LURB | 寄存器低 32 位移位符号位扩展字节加载指令 | ☑️ |
LURH | 寄存器低 32 位移位符号位扩展半字加载指令 | ☑️ |
LURW | 寄存器低 32 位移位符号位扩展字加载指令 | ☑️ |
LURD | 寄存器低 32 位移位双字加载指令 | ☑️ |
LURBU | 寄存器低 32 位移位零扩展字节加载指令 | ☑️ |
LURHU | 寄存器低 32 位移位零扩展半字加载指令 | ☑️ |
LURWU | 寄存器低 32 位移位零扩展字加载指令 | ☑️ |
LBIA | 符号位扩展字节加载基地址自增指令 | ☑️ |
LBIB | 基地址自增符号位扩展字节加载指令 | ☑️ |
LHIA | 符号位扩展半字加载基地址自增指令 | ☑️ |
LHIB | 基地址自增符号位扩展半字加载指令 | ☑️ |
LWIA | 符号位扩展字加载基地址自增指令 | ☑️ |
LWIB | 基地址自增符号位扩展字加载指令 | ☑️ |
LDIA | 符号位扩展双字加载基地址自增指令 | ☑️ |
LDIB | 基地址自增符号位扩展双字加载指令 | ☑️ |
LBUIA | 零扩展字节加载基地址自增指令 | ☑️ |
LBUIB | 基地址自增零扩展字节加载指令 | ☑️ |
LHUIA | 零扩展半字加载基地址自增指令 | ☑️ |
LHUIB | 基地址自增零扩展半字加载指令 | ☑️ |
LWUIA | 零扩展字加载基地址自增指令 | ☑️ |
LWUIB | 基地址自增零扩展字加载指令 | ☑️ |
LDD | 双寄存器加载指令 | ☑️ |
LWD | 符号位扩展双寄存器字加载指令 | ☑️ |
LWUD | 零扩展双寄存器字加载指令 | ☑️ |
FSRD | 浮点寄存器移位双字存储指令 | ☑️ |
FSRW | 浮点寄存器移位字存储指令 | ☑️ |
FSUSR | 浮点寄存器低 32 位移位双字存储指令 | ☑️ |
FSURW | 浮点寄存器低 32 位移位字存储指令 | ☑️ |
SRB | 寄存器移位字节存储指令 | ☑️ |
SRH | 寄存器移位半字存储指令 | ☑️ |
SRW | 寄存器移位字存储指令 | ☑️ |
SRD | 寄存器移位双字存储指令 | ☑️ |
SURB | 寄存器低 32 位移位字节存储指令 | ☑️ |
SURH | 寄存器低 32 位移位半字存储指令 | ☑️ |
SURW | 寄存器低 32 位移位字存储指令 | ☑️ |
SURD | 寄存器低 32 位移位双字存储指令 | ☑️ |
SBIA | 字节存储基地址自增指令 | ☑️ |
SBIB | 基地址自增字节存储指令 | ☑️ |
SHIA | 半字存储基地址自增指令 | ☑️ |
SHIB | 基地址自增半字存储指令 | ☑️ |
SWIA | 字存储基地址自增指令 | ☑️ |
SWIB | 基地址自增字存储指令 | ☑️ |
SDIA | 双字存储基地址自增指令 | ☑️ |
SDIB | 基地址自增双字存储指令 | ☑️ |
SDD | 双寄存器存储指令 | ☑️ |
SWD | 双寄存器低 32 位存储指令 | ☑️ |
Cache指令子集
指令 | 描述 | 状态 |
---|---|---|
DCACHE.CALL | DCACHE 清全部脏表项指令 | ☑️ |
DCACHE.CIALL | DCACHE 清全部脏表项并无效表项指令 | ☑️ |
DCACHE.CIPA | DCACHE 按物理地址清脏表项并无效表项指令 | ☑️ |
DCACHE.CISW | DCACHE 按 way/set 清脏表项并无效表项指令 | ☑️ |
DCACHE.CIVA | DCACHE 按虚拟地址清脏表项并无效表项指令 | ☑️ |
DCACHE.CPA | DCACHE 按物理地址清脏表项指令 | ☑️ |
DCACHE.CPAL1 | L1DCACHE 按物理地址清脏表项指令 | ☑️ |
DCACHE.CVA | DCACHE 按虚拟地址清脏表项指令 | ☑️ |
DCACHE.CVAL1 | L1DCACHE 按虚拟地址清脏表项指令 | ☑️ |
DCACHE.IPA | DCACHE 按物理地址无效指令 | ☑️ |
DCHCHE.ISW | DCACHE按set/way无效指令 | ☑️ |
DCACHE.IVA | DCACHE 按虚拟地址无效指令 | ☑️ |
DCACHE.IALL | DCACHE 无效所有表项指令 | ☑️ |
ICACHE.IALL | ICACHE 无效所有表项指令 | ☑️ |
ICACHE.IALLS | ICACHE 广播无效所有表项指令 | ☑️ |
ICACHE.IPA | ICACHE按物理地址无效表项指令 | ☑️ |
ICACHE.IVA | ICACHE按虚拟地址无效表项指令 | ☑️ |
L2CACHE.CALL | L2CACHE清所有脏表项指令 | ☑️ |
L2CACHE.CIALL | L2CACHE清所有脏表项指令并无效指令 | ☑️ |
L2CACHE.IALL | L2CACHE无效所有表项指令 | ☑️ |
机器模式控制寄存器
机器模式扩展状态寄存器(MXSTATUS)
机器模式硬件控制寄存器(MHCR)
机器模式硬件操作寄存器(MCOR)
机器模式 L2cache 控制寄存器(MCCR2)
机器模式L2cache ECC 寄存器
机器模式隐式操作寄存器(MHINT)
机器模式复位寄存器(MRMR)
机器模式复位向量基址寄存器(MRVBR)
机器模式 Cache 指令寄存器(MCINS)
机器模式 Cache 访问索引寄存器(MCINDEX)
机器模式 Cache 数据寄存器(MCDATA0/1)
机器模式处理器型号寄存器(MCPUID)
超级用户模式控制寄存器
超级用户模式扩展状态寄存器(SXTATUS)
超级用户模式硬件配置寄存器(SHCR)
超级用户模式 L2Cache ECC 寄存器(SCER2)
用户模式控制寄存器
用户模式浮点扩展控制寄存器(FXCR)
编译:
本仓库目前没有包含 clang 代码,用户可以选择使用自己的 clang 前端来一起构建。也可以仅构建本仓库代码。
(1)不用clang,直接构建本仓库代码:
git clone https://github.com/isrc-cas/c910-llvm
$ cd c910-llvm
$ mkdir build
$ cd build
$ cmake -DLLVM_TARGETS_TO_BUILD="RISCV" -G "Unix Makefiles" ..
$ make -j $(nproc)
(2)和clang一起构建:如果没有自定义的前端,那么可以使用LLVM官方的Clang-9.0.0版本。
$ wget https://releases.llvm.org/9.0.0/cfe-9.0.0.src.tar.xz
$ tar xf cfe-9.0.0.src.tar.xz
$ mv cfe-9.0.0.src clang
$ git clone https://github.com/isrc-cas/c910-llvm
$ cd c910-llvm
$ mkdir build
$ cd build
$ cmake -DLLVM_TARGETS_TO_BUILD="RISCV" -DLLVM_ENABLE_PROJECTS=clang -G "Unix Makefiles" ..
$ make -j $(nproc)
执行测试用例:
$ ./bin/llvm-lit -v ../test/MC/RISCV/c910-valid.s
执行的结果如下:
-- Testing: 1 tests, single process --
PASS: LLVM :: MC/RISCV/c910-valid.s (1 of 1)
Testing Time: 0.30s
Expected Passes : 1
c910指令汇编生成二进制文件:
$ ./bin/llvm-mc test.s -triple=riscv64 -mcpu=c910 -show-encoding -show-inst --filetype=obj -o=test.o
注:这里的 test.s
意指包含C910扩展指令的汇编文件。(可以在c/c++代码中使用内联汇编添加一条上述已定义的C910指令,然后使用clang编译生成./bin/clang --target=riscv64-unknown-elf test.c -S -o test.s
,如下所示:)
int main(){
int a,b,c;
a = 1;
b = 2;
asm volatile
(
"mula %[z], %[x], %[y]\n\t"
: [z] "=r" (c)
: [x] "r" (a), [y] "r" (b)
);
if ( c == 0 ){
return -1;
}
return 0;
}