LLVM后端移植笔记1 c910 riscv示例

目录

一、后端的六大部分

二、后端的七大环节

三、建立新后端的七大步骤

四、后端介绍

1.后端目录

2.LLVM后端简介

3.后端目录代码结构

4.目标指令集的描述实现

5.指令选择描述

5.riscv后端指令描述

6.玄铁C910指令扩展示例

7.玄铁C910在编译器中注册示例

五. auipc指令设计实现

1. RISCVInstrInfo.td

2. RISCVInstrFormats.td

3.RISCVExpandPseudoInsts.cpp

4. AsmParser/RISCVAsmParser.cpp

5. MCTargetDesc/RISCVMCCodeEmitter.cpp

六.xor指令设计实现

1. RISCVInstrInfo.td

七,RVV指令扩展


LLVM官方提供了两个关于后端的官方文档:

1、 The LLVM Target-Independent Code Generator

2Writing an LLVM Backend

阅读2之前要求阅读1。将这两个文档参照起来读,基本上可以获取新建后端所需要的各类信息。这两个文档从三个层面解析了后端的架构,将后端从代码组织、执行环节和建立步骤都讲的很清楚。我们在这里就一起看看这三个层面:

一、后端的六大部分

  • Target description classes: abstract target description interfaces (代码地址:include/llvm/Target/)
  • Marchine code description classes: classes used to repesent the code being generated for a target (代码地址:include/llvm/CodeGen/)
  • The "MC" Layer: use to represent and process code at the raw machine code level(代码地址:lib/MC include/llvm/MC)
  • Target-independent code generation algorithms (代码地址:lib/CodeGen)
  • Implementations of the abstract description interfaces for particular targets (代码地址: lib/Target)
  • The target-independent JIT components (代码地址:lib/ExecutionEngine/JIT)

二、后端的七大环节

  • Instruction Selection
  • Scheduling and Formation
  • SSA-based Machine Code Optimizations
  • Register Allocation
  • Prolog/Epilog Code Insertion
  • Late Machine Code Optimizations
  • Code Emission

三、建立新后端的七大步骤

1、建立一个TargetMachine的子类用于描述你的硬件特性。

2、描述目标机器的寄存器集。使用TableGen从目标机器的RegisterInfo.td中生成寄存器定义信息、同名信息、寄存器组信息。同时还需要编写TargetRegisterInfo子类来说明寄存器如何分派和 描述寄存器之间的关系。

3、描述目标机器的指令集。同样使用TableGen从目标机器的TargetInstrFormats.td和 TargetInstrInfo.td中生成指令信息。同时还需要编写TargetInstrInfo子类来说明目标机器所支持 的机器指令。

4、描述如何选择和转化LLVM IR,从一个DAG表示的指令到目标机器的本地指令。 基于 TargetInstrInfo.td提供的信息 ,使用TableGen生成模式匹配成功的指令。编写代码 XXXISelDAGToDAG.cpp来说明如何匹配模式和DAG-to-DAG指令选择等。同时还要编写 XXXISelLowering.cpp来替换或者移除目标机器不支持的类型操作。

5、编写汇编语言打印代码,来转换LLVM IR到GAS格式的汇编。

6、(可选)支持subtargets(***)。

7、(可选)增加JIT支持和建立一个机器码生成器,用于直接生成二进制码到内存。

四、后端介绍

1.后端目录

LLVM后端移植笔记1 c910 riscv示例

2.LLVM后端简介

LLVM后端移植笔记1 c910 riscv示例

利用llc工具生成汇编码:

$ llc test.bc -o test.s

$ llc test.bc -filetype=obj -o test.o //生成目标代

 

3.后端目录代码结构

后端实现分散在LLVM源树的不同目录中。 代码生成的主要库位于lib目录及其子文件夹CodeGen,MC,TableGen和 Target中:

•CodeGen目录包含所有通用代码生成算法的实现文件和头文件:指令选择, 调度程序,寄存器分配以及所有他们需要的分析。

•MC目录保留了汇编器(汇编解析器),松弛算法(反汇编器)和特定目 标文件惯用语(例如ELF,COFF,MachO等)的低级功能的实现。

•TableGen目录包含TableGen工具的完整实现,该工具用于根据.td文件中的 高级目标描述生成C代码。

•每个后端目标都在“Target”文件夹下的不同子文件夹中实现(例如,Target/Mips)

LLVM后端移植笔记1 c910 riscv示例

4.目标指令集的描述实现

在代码产生的早期阶段,LLVM IR代码会被转换成一个带节点的有选择的向无环图

(SelectionDAG)。这些节点含有目标指令的SDNote的实例。一个SDNode有一个操作

码,操作数,类型要求,操作属性。各种操作节点类型在include/lIvm/CodeGen/Selectio-

nDAGNodes.h中描述。

TableGen用如下的目标描述(输入文件来产生大部分的指令定义的代码:

1.Target. td-—定义Instruction,Operand,InstrInfo和其他基本类。

2.TargetSelectionDAG. td——SelectionDAG指令选择生成器使用。包含了SDTC*类(选择DAG类型约束条件),SelectionDAG节点的定义(如imm,cond,bb, add,fadd,sub)和模式支持(Pattern,Pat,PatFrag,PatLeaf,ComplexPattern);

3.XXXInstrFormats.td--一目标相关指令的定义模式;

4.xXXInstrInfo. td一-指令模板、条件代码、指令集的指令的目标相关定义。可以用不同的文件名表示体系结构的特征。例如,带有SSE(Streaming SIMD Extensions)指令的Pentium处理器,这个文件为SSE(Streaming SIMD Extensions)。如果是带MMX的Pentium处理器,则为X86InstrMMX. td。

另外还有一个目标相关文件XXX.td,XXX代表目标的名称。XXX.td文件包括了其

他.td 输入文件,相当于所有td文件的汇总在这个文件里,以便更好的管理td文件。此

外需要描述一个具体的目标相关类XXXInstrInfo,代表目标机器支持的机器指令。

xXXinstrinfo包含了XXXInstrDescriptor对象的一个数组。每个XXXInstrDescriptor对象

描述了一个指令。一个指令描述符定义了:

操作码助记符。

操作数的数量。

隐含寄存器定义和使用的列表。

目标无关的特性(如内存访问,是可以交换的)。

目标相关的标志。

指令类(Target.td中定义)是一个基础的类。其他复杂的指令类都基于此。指令类定义如下:

LLVM后端移植笔记1 c910 riscv示例

5.指令选择描述

 

5.riscv后端指令描述

5.1RISCVInstrForMatsC910.td

LLVM后端移植笔记1 c910 riscv示例

这个class定义了指令模板RVInstC910LS_1,其中的各个字段定义了这条指令的不同位置对应的二进制码.

5.2RISCVInstrInfoC910.td

在这个文件中定义了具体的指令描述

LLVM后端移植笔记1 c910 riscv示例

图中基于指令模板RVInstC910LS_1进一步定义了指令类Store_ss.

LLVM后端移植笔记1 c910 riscv示例

而这些指令就是Store_ss类的指令.

6.玄铁C910指令扩展示例

LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例

7.玄铁C910在编译器中注册示例

LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例LLVM后端移植笔记1 c910 riscv示例

五. auipc指令设计实现

1. RISCVInstrInfo.td

// This file describes the RISC-V instructions in TableGen format.

// RISC-V specific DAG Nodes.

LLVM后端移植笔记1 c910 riscv示例

LLVM后端移植笔记1 c910 riscv示例

 

2. RISCVInstrFormats.td

//  These instruction format definitions are structured to match the

//  description in the RISC-V User-Level ISA specification as closely as

//  possible. For instance, the specification describes instructions with the

//  MSB (31st bit) on the left and the LSB (0th bit) on the right. This is

//  reflected in the order of parameters to each instruction class.

//

//  One area of divergence is in the description of immediates. The

//  specification describes immediate encoding in terms of bit-slicing

//  operations on the logical value represented. The immediate argument to

//  these instruction formats instead represents the bit sequence that will be

//  inserted into the instruction. e.g. although JAL's immediate is logically

//  a 21-bit value (where the LSB is always zero), we describe it as an imm20

//  to match how it is encoded.

LLVM后端移植笔记1 c910 riscv示例

 

3.RISCVExpandPseudoInsts.cpp

// This file contains a pass that expands pseudo instructions into target

// instructions. This pass should be run after register allocation but before

// the post-regalloc scheduling pass.

LLVM后端移植笔记1 c910 riscv示例

4. AsmParser/RISCVAsmParser.cpp

Parse RISCV assembly to MCInst instructions

LLVM后端移植笔记1 c910 riscv示例

5. MCTargetDesc/RISCVMCCodeEmitter.cpp

Convert RISCV code to machine code

LLVM后端移植笔记1 c910 riscv示例

 

六.xor指令设计实现

1. RISCVInstrInfo.td

LLVM后端移植笔记1 c910 riscv示例

LLVM后端移植笔记1 c910 riscv示例

LLVM后端移植笔记1 c910 riscv示例

LLVM后端移植笔记1 c910 riscv示例

LLVM后端移植笔记1 c910 riscv示例

 

RISCVInstrInfoC.td

LLVM后端移植笔记1 c910 riscv示例

 

七,RVV指令扩展