//===-- RISCVInstrFormats.td - RISCV Instruction Formats ---*- tablegen -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // // 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. // //===----------------------------------------------------------------------===// // Format specifies the encoding used by the instruction. This is used by // RISCVMCCodeEmitter to determine which form of fixup to use. These // definitions must be kept in-sync with RISCVBaseInfo.h. class InstFormat val> { bits<5> Value = val; } def InstFormatPseudo : InstFormat<0>; def InstFormatR : InstFormat<1>; def InstFormatR4 : InstFormat<2>; def InstFormatI : InstFormat<3>; def InstFormatS : InstFormat<4>; def InstFormatB : InstFormat<5>; def InstFormatU : InstFormat<6>; def InstFormatJ : InstFormat<7>; def InstFormatCR : InstFormat<8>; def InstFormatCI : InstFormat<9>; def InstFormatCSS : InstFormat<10>; def InstFormatCIW : InstFormat<11>; def InstFormatCL : InstFormat<12>; def InstFormatCS : InstFormat<13>; def InstFormatCB : InstFormat<14>; def InstFormatCJ : InstFormat<15>; def InstFormatOther : InstFormat<16>; // The following opcode names and match those given in Table 19.1 in the // RISC-V User-level ISA specification ("RISC-V base opcode map"). class RISCVOpcode val> { bits<7> Value = val; } def OPC_LOAD : RISCVOpcode<0b0000011>; def OPC_LOAD_FP : RISCVOpcode<0b0000111>; def OPC_MISC_MEM : RISCVOpcode<0b0001111>; def OPC_OP_IMM : RISCVOpcode<0b0010011>; def OPC_AUIPC : RISCVOpcode<0b0010111>; def OPC_OP_IMM_32 : RISCVOpcode<0b0011011>; def OPC_STORE : RISCVOpcode<0b0100011>; def OPC_STORE_FP : RISCVOpcode<0b0100111>; def OPC_AMO : RISCVOpcode<0b0101111>; def OPC_OP : RISCVOpcode<0b0110011>; def OPC_LUI : RISCVOpcode<0b0110111>; def OPC_OP_32 : RISCVOpcode<0b0111011>; def OPC_MADD : RISCVOpcode<0b1000011>; def OPC_MSUB : RISCVOpcode<0b1000111>; def OPC_NMSUB : RISCVOpcode<0b1001011>; def OPC_NMADD : RISCVOpcode<0b1001111>; def OPC_OP_FP : RISCVOpcode<0b1010011>; def OPC_BRANCH : RISCVOpcode<0b1100011>; def OPC_JALR : RISCVOpcode<0b1100111>; def OPC_JAL : RISCVOpcode<0b1101111>; def OPC_SYSTEM : RISCVOpcode<0b1110011>; class RVInst 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; bits<7> Opcode = 0; let Inst{6-0} = Opcode; let Namespace = "RISCV"; dag OutOperandList = outs; dag InOperandList = ins; let AsmString = opcodestr # "\t" # argstr; let Pattern = pattern; let TSFlags{4-0} = format.Value; } // Pseudo instructions class Pseudo pattern> : RVInst { let isPseudo = 1; let isCodeGenOnly = 1; } // Instruction formats are listed in the order they appear in the RISC-V // instruction set manual (R, I, S, B, U, J) with sub-formats (e.g. RVInstR4, // RVInstRAtomic) sorted alphabetically. class RVInstR funct7, bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { 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; } class RVInstR4 funct2, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<5> rs3; bits<5> rs2; bits<5> rs1; bits<3> funct3; bits<5> rd; let Inst{31-27} = rs3; let Inst{26-25} = funct2; let Inst{24-20} = rs2; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; let Opcode = opcode.Value; } class RVInstRAtomic funct5, bit aq, bit rl, bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<5> rs2; bits<5> rs1; bits<5> rd; let Inst{31-27} = funct5; let Inst{26} = aq; let Inst{25} = rl; let Inst{24-20} = rs2; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; let Opcode = opcode.Value; } class RVInstRFrm funct7, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<5> rs2; bits<5> rs1; bits<3> funct3; 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; } class RVInstI funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { 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; } class RVInstIShift funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<6> shamt; bits<5> rs1; bits<5> rd; let Inst{31} = 0; let Inst{30} = arithshift; let Inst{29-26} = 0; let Inst{25-20} = shamt; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; let Opcode = opcode.Value; } class RVInstIShiftW funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<5> shamt; bits<5> rs1; bits<5> rd; let Inst{31} = 0; let Inst{30} = arithshift; let Inst{29-25} = 0; let Inst{24-20} = shamt; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; let Opcode = opcode.Value; } class RVInstS funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<12> imm12; bits<5> rs2; bits<5> rs1; let Inst{31-25} = imm12{11-5}; let Inst{24-20} = rs2; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = imm12{4-0}; let Opcode = opcode.Value; } class RVInstB funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<12> imm12; bits<5> rs2; bits<5> rs1; let Inst{31} = imm12{11}; let Inst{30-25} = imm12{9-4}; let Inst{24-20} = rs2; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-8} = imm12{3-0}; let Inst{7} = imm12{10}; let Opcode = opcode.Value; } class RVInstU : RVInst { bits<20> imm20; bits<5> rd; let Inst{31-12} = imm20; let Inst{11-7} = rd; let Opcode = opcode.Value; } class RVInstJ : RVInst { bits<20> imm20; bits<5> rd; let Inst{31} = imm20{19}; let Inst{30-21} = imm20{9-0}; let Inst{20} = imm20{10}; let Inst{19-12} = imm20{18-11}; let Inst{11-7} = rd; let Opcode = opcode.Value; }