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