Table of Contents
- 1. RISCV Instruction Format Type:
- 2. ADD instruction and its variant:
- 3. RISCV Instruction in Tablegen:
- 4. RISCV Instruction Encoding Format R in Tablegen:
- 5. RISCV Instruction Encoding Format I in Tablegen:
- 6. RISCV ALUrr:
- 7. RISCV ALUri:
- 8. RISCV ADD and its varinats in Tablegen:
- 9. RISCV Patterns for ADD:
1 RISCV Instruction Format Type:
Type | Encoding [31 - 0] |
R | funct7 rs2 rs1 funct3 rd opcode |
I | imm[11:0] rs1 funct3 rd opcode |
S | imm[11:5] rs2 rs1 funct3 rd opcode |
B | imm[12] imm[10:5] rs2 rs1 funct3 imm[4:1] imm[11] opcode |
U | imm[31:12] rd opcode |
J | imm[20] imm[10:1] imm[11] imm[19:12] rd opcode |
opcode: 7 bits register: 5 bits funct3: 3 bits funct7: 7 bits
2 ADD instruction and its variant:
Instr | AsmName | Asm format | Encoding Format Type | Encoding [31 - 0] |
ADD | add | add rd, rs1, rs2 | R | 0000000 rs2 rs1 000 rd 0110011 |
ADDI | addi | add rd, rs1, imm | I | imm[11:0] rs1 000 rd 0010011 |
ADDW | addw | addw rd, rs1, rs2 | R | 0000000 rs2 rs1 000 rd 0111011 |
ADDIW | addiw | addiw rd, rs1, imm | I | imm[11:0] rs1 000 rd 0011011 |
3 RISCV Instruction in Tablegen:
class RVInst<dag outs, dag ins, string opcodestr, string argstr, list<dag> pattern, InstFormat format> : Instruction { field bits<32> Inst; // SoftFail is a field the disassembler can use to provide a way for // instructions to not match without killing the whole decode process. It is // mainly used for ARM, but Tablegen expects this field to exist or it fails // to build the decode table. field bits<32> SoftFail = 0; let Size = 4; // in Bytes bits<7> Opcode = 0; // 7-bits opcode let Inst{6-0} = Opcode; let Namespace = "RISCV"; dag OutOperandList = outs; // output operands dag InOperandList = ins; // input oprands let AsmString = opcodestr # "\t" # argstr; // asm format string let Pattern = pattern; // pattern for IR instruction to match let TSFlags{4-0} = format.Value; // Defaults RISCVVConstraint RVVConstraint = NoConstraint; let TSFlags{8-5} = RVVConstraint.Value; }
4 RISCV Instruction Encoding Format R in Tablegen:
class RISCVOpcode<bits<7> val> { bits<7> Value = val; }; class RVInstR<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { // unbound field for operands that will be filled later // when the instruction is assigned a value bits<5> rs2; bits<5> rs1; bits<5> rd;let Inst{31-25} = funct7; let Inst{24-20} = rs2; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; let Opcode = opcode.Value; }
Notes: the pattern part of Instruction is left empty in order to set pattern explicitly later on.
5 RISCV Instruction Encoding Format I in Tablegen:
class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { // unbound field for operands that will be filled later // when the instruction is assigned a value bits<12> imm12; bits<5> rs1; bits<5> rd;let Inst{31-20} = imm12; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; let Opcode = opcode.Value; }
6 RISCV ALUrr:
def OPC_OP : RISCVOpcode<0b0110011>; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr> : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">;
7 RISCV ALUri:
def OPC_OP_IMM : RISCVOpcode<0b0010011>; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class ALU_ri<bits<3> funct3, string opcodestr> : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), opcodestr, "$rd, $rs1, $imm12">, Sched<[WriteIALU, ReadIALU]>;
8 RISCV ADD and its varinats in Tablegen:
def ADD : ALU_rr<0b0000000, 0b000, "add">, Sched<[WriteIALU, ReadIALU, ReadIALU]>; def ADDI : ALU_ri<0b000, "addi">; def ADDW : ALUW_rr<0b0000000, 0b000, "addw">, Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), "addiw", "$rd, $rs1, $imm12">,Sched<[WriteIALU32, ReadIALU32]>;
9 RISCV Patterns for ADD:
class PatGprGpr<SDPatternOperator OpNode, RVInst Inst> : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>; def : PatGprGpr<add, ADD>;
Notes: More information about Pattern Syntax in LLVM Pattern syntax