/c910-llvm

平头哥玄铁C910的LLVM工具链支持,由PLCT实验室提供,非官方版本

Primary LanguageLLVMOtherNOASSERTION

c910-llvm

本项目目标是基于LLVM,实现对平头哥玄铁C910指令集架构的支持。玄铁 C910在RISCV标准指令集架构的基础上,增加了自定义指令,包括 Cache 指令子集,同步指令子集,算术运算指令子集,位操作指令子集以及存储指令子集。本项目主要工作是在RISCV后端实现这些扩展指令支持。

(1) 以下按照不同指令子集扩展列出已实现llvm-mc汇编器支持的指令。

同步指令子集

指令 描述 状态
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无效所有表项指令 ☑️

(2) 玄铁 C910 对处理器和状态扩展了部分寄存器,以下列出已完成定义的寄存器,包括:

机器模式控制寄存器

机器模式扩展状态寄存器(MXSTATUS)

机器模式硬件控制寄存器(MHCR)

机器模式硬件操作寄存器(MCOR)

机器模式 L2cache 控制寄存器(MCCR2)

机器模式L2cache ECC 寄存器

机器模式隐式操作寄存器(MHINT)

机器模式复位寄存器(MRMR)

机器模式复位向量基址寄存器(MRVBR)

机器模式 Cache 指令寄存器(MCINS)

机器模式 Cache 访问索引寄存器(MCINDEX)

机器模式 Cache 数据寄存器(MCDATA0/1)

机器模式处理器型号寄存器(MCPUID)

超级用户模式控制寄存器

超级用户模式扩展状态寄存器(SXTATUS)

超级用户模式硬件配置寄存器(SHCR)

超级用户模式 L2Cache ECC 寄存器(SCER2)

用户模式控制寄存器

用户模式浮点扩展控制寄存器(FXCR)

(3) 测试运行

编译:

本仓库目前没有包含 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;
}