diff options
| author | Alex Bradbury <asb@lowrisc.org> | 2017-10-19 14:29:03 +0000 |
|---|---|---|
| committer | Alex Bradbury <asb@lowrisc.org> | 2017-10-19 14:29:03 +0000 |
| commit | ee7c7ecd0366214d6f7a6d38fb4d8c16d98cbb85 (patch) | |
| tree | 200f2b22394cc9ed5d25bb19ea349287de54faff /llvm | |
| parent | 27c1f464e6aa287bfcfe775df10b5c92504a4534 (diff) | |
| download | bcm5719-llvm-ee7c7ecd0366214d6f7a6d38fb4d8c16d98cbb85.tar.gz bcm5719-llvm-ee7c7ecd0366214d6f7a6d38fb4d8c16d98cbb85.zip | |
[RISCV] Prepare for the use of variable-sized register classes
While parameterising by XLen, also take the opportunity to clean up the
formatting of the RISCV .td files.
This commit unifies the in-tree code with my patchset at
<https://github.com/lowrisc/riscv-llvm>.
llvm-svn: 316159
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCV.td | 28 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrFormats.td | 100 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfo.td | 218 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 115 |
8 files changed, 276 insertions, 220 deletions
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index e64d875a567..003686ac2f3 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -56,14 +56,14 @@ extern "C" void LLVMInitializeRISCVDisassembler() { } static const unsigned GPRDecoderTable[] = { - RISCV::X0_32, RISCV::X1_32, RISCV::X2_32, RISCV::X3_32, - RISCV::X4_32, RISCV::X5_32, RISCV::X6_32, RISCV::X7_32, - RISCV::X8_32, RISCV::X9_32, RISCV::X10_32, RISCV::X11_32, - RISCV::X12_32, RISCV::X13_32, RISCV::X14_32, RISCV::X15_32, - RISCV::X16_32, RISCV::X17_32, RISCV::X18_32, RISCV::X19_32, - RISCV::X20_32, RISCV::X21_32, RISCV::X22_32, RISCV::X23_32, - RISCV::X24_32, RISCV::X25_32, RISCV::X26_32, RISCV::X27_32, - RISCV::X28_32, RISCV::X29_32, RISCV::X30_32, RISCV::X31_32 + RISCV::X0, RISCV::X1, RISCV::X2, RISCV::X3, + RISCV::X4, RISCV::X5, RISCV::X6, RISCV::X7, + RISCV::X8, RISCV::X9, RISCV::X10, RISCV::X11, + RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, + RISCV::X16, RISCV::X17, RISCV::X18, RISCV::X19, + RISCV::X20, RISCV::X21, RISCV::X22, RISCV::X23, + RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27, + RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31 }; static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index cfb124262c6..9fafbb0a95a 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -26,9 +26,10 @@ enum { InstFormatR = 1, InstFormatI = 2, InstFormatS = 3, - InstFormatSB = 4, + InstFormatB = 4, InstFormatU = 5, - InstFormatOther = 6, + InstFormatJ = 6, + InstFormatOther = 7, InstFormatMask = 15 }; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index f8212159331..f94c37aae8f 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -159,7 +159,7 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, cast<MCSymbolRefExpr>(Expr)->getKind() == MCSymbolRefExpr::VK_None) { if (Desc.getOpcode() == RISCV::JAL) { FixupKind = RISCV::fixup_riscv_jal; - } else if (MIFrm == RISCVII::InstFormatSB) { + } else if (MIFrm == RISCVII::InstFormatB) { FixupKind = RISCV::fixup_riscv_branch; } } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp index 2b35eab577b..45de976ec6c 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp @@ -42,7 +42,7 @@ static MCInstrInfo *createRISCVMCInstrInfo() { static MCRegisterInfo *createRISCVMCRegisterInfo(const Triple &TT) { MCRegisterInfo *X = new MCRegisterInfo(); - InitRISCVMCRegisterInfo(X, RISCV::X1_32); + InitRISCVMCRegisterInfo(X, RISCV::X1); return X; } @@ -51,6 +51,14 @@ static MCAsmInfo *createRISCVMCAsmInfo(const MCRegisterInfo &MRI, return new RISCVMCAsmInfo(TT); } +static MCSubtargetInfo *createRISCVMCSubtargetInfo(const Triple &TT, + StringRef CPU, StringRef FS) { + std::string CPUName = CPU; + if (CPUName.empty()) + CPUName = TT.isArch64Bit() ? "generic-rv64" : "generic-rv32"; + return createRISCVMCSubtargetInfoImpl(TT, CPUName, FS); +} + static MCInstPrinter *createRISCVMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, @@ -67,6 +75,6 @@ extern "C" void LLVMInitializeRISCVTargetMC() { TargetRegistry::RegisterMCAsmBackend(*T, createRISCVAsmBackend); TargetRegistry::RegisterMCCodeEmitter(*T, createRISCVMCCodeEmitter); TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter); - TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfoImpl); + TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfo); } } diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td index 19e11839ac3..7b61901915f 100644 --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -9,19 +9,37 @@ include "llvm/Target/Target.td" -include "RISCVRegisterInfo.td" -include "RISCVInstrInfo.td" +//===----------------------------------------------------------------------===// +// RISC-V subtarget features and instruction predicates. +//===----------------------------------------------------------------------===// +def Feature64Bit : SubtargetFeature<"64bit", "HasRV64", "true", + "Implements RV64">; -def RISCVInstrInfo : InstrInfo; +def RV64 : HwMode<"+64bit">; +def RV32 : HwMode<"-64bit">; + +//===----------------------------------------------------------------------===// +// Register file, instruction descriptions. +//===----------------------------------------------------------------------===// + +include "RISCVRegisterInfo.td" +include "RISCVInstrInfo.td" -def Feature64Bit : SubtargetFeature<"64bit", "HasRV64", "true", - "Implements RV64">; +//===----------------------------------------------------------------------===// +// RISC-V processors supported. +//===----------------------------------------------------------------------===// def : ProcessorModel<"generic-rv32", NoSchedModel, []>; def : ProcessorModel<"generic-rv64", NoSchedModel, [Feature64Bit]>; +//===----------------------------------------------------------------------===// +// Define the RISC-V target. +//===----------------------------------------------------------------------===// + +def RISCVInstrInfo : InstrInfo; + def RISCVAsmParser : AsmParser { let ShouldEmitMatchRegisterAltName = 1; } diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index 383b73cf4e0..48f6cf8762d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -35,12 +35,40 @@ def InstFormatPseudo : InstFormat<0>; def InstFormatR : InstFormat<1>; def InstFormatI : InstFormat<2>; def InstFormatS : InstFormat<3>; -def InstFormatSB : InstFormat<4>; +def InstFormatB : InstFormat<4>; def InstFormatU : InstFormat<5>; -def InstFormatOther : InstFormat<6>; +def InstFormatJ : InstFormat<6>; +def InstFormatOther : InstFormat<7>; -class RISCVInst<dag outs, dag ins, string asmstr, list<dag> pattern, - InstFormat format> +// 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<bits<7> 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<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 @@ -58,7 +86,7 @@ class RISCVInst<dag outs, dag ins, string asmstr, list<dag> pattern, dag OutOperandList = outs; dag InOperandList = ins; - let AsmString = asmstr; + let AsmString = opcodestr # "\t" # argstr; let Pattern = pattern; let TSFlags{3-0} = format.Value; @@ -66,14 +94,18 @@ class RISCVInst<dag outs, dag ins, string asmstr, list<dag> pattern, // Pseudo instructions class Pseudo<dag outs, dag ins, list<dag> pattern> - : RISCVInst<outs, ins, "", pattern, InstFormatPseudo> { + : RVInst<outs, ins, "", "", pattern, InstFormatPseudo> { let isPseudo = 1; let isCodeGenOnly = 1; } -class FR<bits<7> funct7, bits<3> funct3, bits<7> opcode, dag outs, dag ins, - string asmstr, list<dag> pattern> : RISCVInst<outs, ins, asmstr, pattern, InstFormatR> -{ +// 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<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, dag outs, + dag ins, string opcodestr, string argstr> + : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { bits<5> rs2; bits<5> rs1; bits<5> rd; @@ -83,12 +115,12 @@ class FR<bits<7> funct7, bits<3> funct3, bits<7> opcode, dag outs, dag ins, let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; - let Opcode = opcode; + let Opcode = opcode.Value; } -class FI<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : RISCVInst<outs, ins, asmstr, pattern, InstFormatI> -{ +class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, + string opcodestr, string argstr> + : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { bits<12> imm12; bits<5> rs1; bits<5> rd; @@ -97,12 +129,12 @@ class FI<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list< let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; - let Opcode = opcode; + let Opcode = opcode.Value; } -class FI32Shift<bit arithshift, bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : RISCVInst<outs, ins, asmstr, pattern, InstFormatI> -{ +class RVInstIShift<bit arithshift, bits<3> funct3, RISCVOpcode opcode, + dag outs, dag ins, string opcodestr, string argstr> + : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { bits<5> shamt; bits<5> rs1; bits<5> rd; @@ -114,12 +146,12 @@ class FI32Shift<bit arithshift, bits<3> funct3, bits<7> opcode, dag outs, dag in let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; - let Opcode = opcode; + let Opcode = opcode.Value; } -class FS<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : RISCVInst<outs, ins, asmstr, pattern, InstFormatS> -{ +class RVInstS<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, + string opcodestr, string argstr> + : RVInst<outs, ins, opcodestr, argstr, [], InstFormatS> { bits<12> imm12; bits<5> rs2; bits<5> rs1; @@ -129,12 +161,12 @@ class FS<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list< let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = imm12{4-0}; - let Opcode = opcode; + let Opcode = opcode.Value; } -class FSB<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : RISCVInst<outs, ins, asmstr, pattern, InstFormatSB> -{ +class RVInstB<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, + string opcodestr, string argstr> + : RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> { bits<12> imm12; bits<5> rs2; bits<5> rs1; @@ -146,23 +178,23 @@ class FSB<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list let Inst{14-12} = funct3; let Inst{11-8} = imm12{3-0}; let Inst{7} = imm12{10}; - let Opcode = opcode; + let Opcode = opcode.Value; } -class FU<bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : RISCVInst<outs, ins, asmstr, pattern, InstFormatU> -{ +class RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, + string argstr> + : RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> { bits<20> imm20; bits<5> rd; let Inst{31-12} = imm20; let Inst{11-7} = rd; - let Opcode = opcode; + let Opcode = opcode.Value; } -class FUJ<bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : RISCVInst<outs, ins, asmstr, pattern, InstFormatU> -{ +class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, + string argstr> + : RVInst<outs, ins, opcodestr, argstr, [], InstFormatJ> { bits<20> imm20; bits<5> rd; @@ -171,5 +203,5 @@ class FUJ<bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{20} = imm20{10}; let Inst{19-12} = imm20{18-11}; let Inst{11-7} = rd; - let Opcode = opcode; + let Opcode = opcode.Value; } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 1a5f32ecabe..213ef63f5f9 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -13,6 +13,10 @@ include "RISCVInstrFormats.td" +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass { let Name = prefix # "Imm" # width # suffix; let RenderMethod = "addImmOperands"; @@ -20,11 +24,11 @@ class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass { } class SImmAsmOperand<int width, string suffix = ""> - : ImmAsmOperand<"S", width, suffix> { + : ImmAsmOperand<"S", width, suffix> { } class UImmAsmOperand<int width, string suffix = ""> - : ImmAsmOperand<"U", width, suffix> { + : ImmAsmOperand<"U", width, suffix> { } def FenceArg : AsmOperandClass { @@ -33,107 +37,139 @@ def FenceArg : AsmOperandClass { let DiagnosticType = "InvalidFenceArg"; } -def fencearg : Operand<i32> { +def fencearg : Operand<XLenVT> { let ParserMatchClass = FenceArg; let PrintMethod = "printFenceArg"; let DecoderMethod = "decodeUImmOperand<4>"; } -def uimm5 : Operand<i32> { +def uimm5 : Operand<XLenVT> { let ParserMatchClass = UImmAsmOperand<5>; let DecoderMethod = "decodeUImmOperand<5>"; } -def simm12 : Operand<i32> { +def simm12 : Operand<XLenVT> { let ParserMatchClass = SImmAsmOperand<12>; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<12>"; } -def uimm12 : Operand<i32> { +def uimm12 : Operand<XLenVT> { let ParserMatchClass = UImmAsmOperand<12>; let DecoderMethod = "decodeUImmOperand<12>"; } // A 13-bit signed immediate where the least significant bit is zero. -def simm13_lsb0 : Operand<i32> { +def simm13_lsb0 : Operand<XLenVT> { let ParserMatchClass = SImmAsmOperand<13, "Lsb0">; let EncoderMethod = "getImmOpValueAsr1"; let DecoderMethod = "decodeSImmOperandAndLsl1<13>"; } -def uimm20 : Operand<i32> { +def uimm20 : Operand<XLenVT> { let ParserMatchClass = UImmAsmOperand<20>; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeUImmOperand<20>"; } // A 21-bit signed immediate where the least significant bit is zero. -def simm21_lsb0 : Operand<i32> { +def simm21_lsb0 : Operand<XLenVT> { let ParserMatchClass = SImmAsmOperand<21, "Lsb0">; let EncoderMethod = "getImmOpValueAsr1"; let DecoderMethod = "decodeSImmOperandAndLsl1<21>"; } -// As noted in RISCVRegisterInfo.td, the hope is that support for -// variable-sized register classes will mean that instruction definitions do -// not need to be duplicated for 32-bit and 64-bit register classes. For now -// we use 'GPR', which is 32-bit. When codegen for both RV32 and RV64 is -// added, we will need to duplicate instruction definitions unless a proposal -// like <http://lists.llvm.org/pipermail/llvm-dev/2016-September/105027.html> -// is adopted. - -def LUI : FU<0b0110111, (outs GPR:$rd), (ins uimm20:$imm20), - "lui\t$rd, $imm20", []>; - -def AUIPC : FU<0b0010111, (outs GPR:$rd), (ins uimm20:$imm20), - "auipc\t$rd, $imm20", []>; +//===----------------------------------------------------------------------===// +// Instruction Class Templates +//===----------------------------------------------------------------------===// -def JAL : FUJ<0b1101111, (outs GPR:$rd), (ins simm21_lsb0:$imm20), - "jal\t$rd, $imm20", []>; +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class BranchCC_rri<bits<3> funct3, string opcodestr> + : RVInstB<funct3, OPC_BRANCH, (outs), + (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12), + opcodestr, "$rs1, $rs2, $imm12"> { + let isBranch = 1; + let isTerminator = 1; +} + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in +class Load_ri<bits<3> funct3, string opcodestr> + : RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), + opcodestr, "$rd, ${imm12}(${rs1})">; + +// Operands for stores are in the order srcreg, base, offset rather than +// reflecting the order these fields are specified in the instruction +// encoding. +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in +class Store_rri<bits<3> funct3, string opcodestr> + : RVInstS<funct3, OPC_STORE, (outs), + (ins GPR:$rs2, GPR:$rs1, simm12:$imm12), + opcodestr, "$rs2, ${imm12}(${rs1})">; + +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">; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class Shift_ri<bit arithshift, bits<3> funct3, string opcodestr> + : RVInstIShift<arithshift, funct3, OPC_OP_IMM, (outs GPR:$rd), + (ins GPR:$rs1, uimm5:$shamt), opcodestr, + "$rd, $rs1, $shamt">; + +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">; + +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class CSR_ir<bits<3> funct3, string opcodestr> : + RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins uimm12:$imm12, GPR:$rs1), + opcodestr, "$rd, $imm12, $rs1">; + +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class CSR_ii<bits<3> funct3, string opcodestr> : + RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), + (ins uimm12:$imm12, uimm5:$rs1), + opcodestr, "$rd, $imm12, $rs1">; -def JALR : FI<0b000, 0b1100111, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), - "jalr\t$rd, $rs1, $imm12", []>; +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// -class Bcc<bits<3> funct3, string OpcodeStr> : - FSB<funct3, 0b1100011, (outs), (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12), - OpcodeStr#"\t$rs1, $rs2, $imm12", []> { -} +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20:$imm20), + "lui", "$rd, $imm20">; -def BEQ : Bcc<0b000, "beq">; -def BNE : Bcc<0b001, "bne">; -def BLT : Bcc<0b100, "blt">; -def BGE : Bcc<0b101, "bge">; -def BLTU : Bcc<0b110, "bltu">; -def BGEU : Bcc<0b111, "bgeu">; +def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20:$imm20), + "auipc", "$rd, $imm20">; -class LD_ri<bits<3> funct3, string OpcodeStr> : - FI<funct3, 0b0000011, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), - OpcodeStr#"\t$rd, ${imm12}(${rs1})", []> { - let mayLoad = 1; -} +let isCall = 1 in +def JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0:$imm20), + "jal", "$rd, $imm20">; -def LB : LD_ri<0b000, "lb">; -def LH : LD_ri<0b001, "lh">; -def LW : LD_ri<0b010, "lw">; -def LBU : LD_ri<0b100, "lbu">; -def LHU : LD_ri<0b101, "lhu">; +let isCall = 1 in +def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd), + (ins GPR:$rs1, simm12:$imm12), + "jalr", "$rd, $rs1, $imm12">; +} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 -class ST_ri<bits<3> funct3, string OpcodeStr> : - FS<funct3, 0b0100011, (outs), (ins GPR:$rs1, GPR:$rs2, simm12:$imm12), - OpcodeStr#"\t$rs2, ${imm12}(${rs1})", []> { - let mayStore = 1; -} +def BEQ : BranchCC_rri<0b000, "beq">; +def BNE : BranchCC_rri<0b001, "bne">; +def BLT : BranchCC_rri<0b100, "blt">; +def BGE : BranchCC_rri<0b101, "bge">; +def BLTU : BranchCC_rri<0b110, "bltu">; +def BGEU : BranchCC_rri<0b111, "bgeu">; -def SB : ST_ri<0b000, "sb">; -def SH : ST_ri<0b001, "sh">; -def SW : ST_ri<0b010, "sw">; +def LB : Load_ri<0b000, "lb">; +def LH : Load_ri<0b001, "lh">; +def LW : Load_ri<0b010, "lw">; +def LBU : Load_ri<0b100, "lbu">; +def LHU : Load_ri<0b101, "lhu">; -class ALU_ri<bits<3> funct3, string OpcodeStr> : - FI<funct3, 0b0010011, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), - OpcodeStr#"\t$rd, $rs1, $imm12", []> -{ -} +def SB : Store_rri<0b000, "sb">; +def SH : Store_rri<0b001, "sh">; +def SW : Store_rri<0b010, "sw">; def ADDI : ALU_ri<0b000, "addi">; def SLTI : ALU_ri<0b010, "slti">; @@ -142,21 +178,9 @@ def XORI : ALU_ri<0b100, "xori">; def ORI : ALU_ri<0b110, "ori">; def ANDI : ALU_ri<0b111, "andi">; -class SHIFT32_ri<bit arithshift, bits<3> funct3, string OpcodeStr> : - FI32Shift<arithshift, funct3, 0b0010011, (outs GPR:$rd), (ins GPR:$rs1, uimm5:$shamt), - OpcodeStr#"\t$rd, $rs1, $shamt", []> -{ -} - -def SLLI : SHIFT32_ri<0, 0b001, "slli">; -def SRLI : SHIFT32_ri<0, 0b101, "srli">; -def SRAI : SHIFT32_ri<1, 0b101, "srai">; - -class ALU_rr<bits<7> funct7, bits<3> funct3, string OpcodeStr> : - FR<funct7, funct3, 0b0110011, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2), - OpcodeStr#"\t$rd, $rs1, $rs2", []> -{ -} +def SLLI : Shift_ri<0, 0b001, "slli">; +def SRLI : Shift_ri<0, 0b101, "srli">; +def SRAI : Shift_ri<1, 0b101, "srai">; def ADD : ALU_rr<0b0000000, 0b000, "add">; def SUB : ALU_rr<0b0100000, 0b000, "sub">; @@ -169,8 +193,10 @@ def SRA : ALU_rr<0b0100000, 0b101, "sra">; def OR : ALU_rr<0b0000000, 0b110, "or">; def AND : ALU_rr<0b0000000, 0b111, "and">; -def FENCE : FI<0b000, 0b0001111, (outs), (ins fencearg:$pred, fencearg:$succ), - "fence\t$pred, $succ", []> { +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { +def FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs), + (ins fencearg:$pred, fencearg:$succ), + "fence", "$pred, $succ"> { bits<4> pred; bits<4> succ; @@ -179,37 +205,29 @@ def FENCE : FI<0b000, 0b0001111, (outs), (ins fencearg:$pred, fencearg:$succ), let imm12 = {0b0000,pred,succ}; } -def FENCEI : FI<0b001, 0b0001111, (outs), (ins), "fence.i", []> { +def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", ""> { let rs1 = 0; let rd = 0; let imm12 = 0; } -let rs1=0, rd=0 in { - def ECALL : FI<0b000, 0b1110011, (outs), (ins), "ecall", []> { - let imm12=0; - } - def EBREAK : FI<0b000, 0b1110011, (outs), (ins), "ebreak", []> { - let imm12=1; - } +def ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", ""> { + let rs1 = 0; + let rd = 0; + let imm12 = 0; } -class CSR_rr<bits<3> funct3, string OpcodeStr> : - FI<funct3, 0b1110011, (outs GPR:$rd), (ins uimm12:$imm12, GPR:$rs1), - OpcodeStr#"\t$rd, $imm12, $rs1", []> -{ +def EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", ""> { + let rs1 = 0; + let rd = 0; + let imm12 = 1; } +} // hasSideEffects = 1, mayLoad = 0, mayStore = 0 -def CSRRW : CSR_rr<0b001, "csrrw">; -def CSRRS : CSR_rr<0b010, "csrrs">; -def CSRRC : CSR_rr<0b011, "csrrc">; - -class CSR_ri<bits<3> funct3, string OpcodeStr> : - FI<funct3, 0b1110011, (outs GPR:$rd), (ins uimm12:$imm12, uimm5:$rs1), - OpcodeStr#"\t$rd, $imm12, $rs1", []> -{ -} +def CSRRW : CSR_ir<0b001, "csrrw">; +def CSRRS : CSR_ir<0b010, "csrrs">; +def CSRRC : CSR_ir<0b011, "csrrc">; -def CSRRWI : CSR_ri<0b101, "csrrwi">; -def CSRRSI : CSR_ri<0b110, "csrrsi">; -def CSRRCI : CSR_ri<0b111, "csrrci">; +def CSRRWI : CSR_ii<0b101, "csrrwi">; +def CSRRSI : CSR_ii<0b110, "csrrsi">; +def CSRRCI : CSR_ii<0b111, "csrrci">; diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td index f04de217bf0..a5484130dfc 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -8,83 +8,62 @@ //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// -// Declarations that describe the RISC-V register file +// Declarations that describe the RISC-V register files //===----------------------------------------------------------------------===// let Namespace = "RISCV" in { - def sub_32 : SubRegIndex<32>; - - class RISCVReg32<bits<5> Enc, string n, list<string> alt = []> : Register<n> { - let HWEncoding{4-0} = Enc; - let AltNames = alt; - } - - // RISCV64 registers don't define an AsmName or AltName. If they specified - // names aliasing the RISCVReg32 registers, the generation of the default - // MatchRegisterName/MatchRegisterAltName would fail. When necessary, - // RISCVAsmParser will need to convert a register number from a RISCVReg32 - // to the equivalent RISCVReg64. - class RISCVReg64<RISCVReg32 subreg> : Register<""> { - let HWEncoding{4-0} = subreg.HWEncoding{4-0}; - let SubRegs = [subreg]; - let SubRegIndices = [sub_32]; - } - - def ABIRegAltName : RegAltNameIndex; +class RISCVReg<bits<5> Enc, string n, list<string> alt = []> : Register<n> { + let HWEncoding{4-0} = Enc; + let AltNames = alt; } +def ABIRegAltName : RegAltNameIndex; +} // Namespace = "RISCV" // Integer registers let RegAltNameIndices = [ABIRegAltName] in { - def X0_32 : RISCVReg32<0, "x0", ["zero"]>, DwarfRegNum<[0]>; - def X1_32 : RISCVReg32<1, "x1", ["ra"]>, DwarfRegNum<[1]>; - def X2_32 : RISCVReg32<2, "x2", ["sp"]>, DwarfRegNum<[2]>; - def X3_32 : RISCVReg32<3, "x3", ["gp"]>, DwarfRegNum<[3]>; - def X4_32 : RISCVReg32<4, "x4", ["tp"]>, DwarfRegNum<[4]>; - def X5_32 : RISCVReg32<5, "x5", ["t0"]>, DwarfRegNum<[5]>; - def X6_32 : RISCVReg32<6, "x6", ["t1"]>, DwarfRegNum<[6]>; - def X7_32 : RISCVReg32<7, "x7", ["t2"]>, DwarfRegNum<[7]>; - def X8_32 : RISCVReg32<8, "x8", ["s0"]>, DwarfRegNum<[8]>; - def X9_32 : RISCVReg32<9, "x9", ["s1"]>, DwarfRegNum<[9]>; - def X10_32 : RISCVReg32<10,"x10", ["a0"]>, DwarfRegNum<[10]>; - def X11_32 : RISCVReg32<11,"x11", ["a1"]>, DwarfRegNum<[11]>; - def X12_32 : RISCVReg32<12,"x12", ["a2"]>, DwarfRegNum<[12]>; - def X13_32 : RISCVReg32<13,"x13", ["a3"]>, DwarfRegNum<[13]>; - def X14_32 : RISCVReg32<14,"x14", ["a4"]>, DwarfRegNum<[14]>; - def X15_32 : RISCVReg32<15,"x15", ["a5"]>, DwarfRegNum<[15]>; - def X16_32 : RISCVReg32<16,"x16", ["a6"]>, DwarfRegNum<[16]>; - def X17_32 : RISCVReg32<17,"x17", ["a7"]>, DwarfRegNum<[17]>; - def X18_32 : RISCVReg32<18,"x18", ["s2"]>, DwarfRegNum<[18]>; - def X19_32 : RISCVReg32<19,"x19", ["s3"]>, DwarfRegNum<[19]>; - def X20_32 : RISCVReg32<20,"x20", ["s4"]>, DwarfRegNum<[20]>; - def X21_32 : RISCVReg32<21,"x21", ["s5"]>, DwarfRegNum<[21]>; - def X22_32 : RISCVReg32<22,"x22", ["s6"]>, DwarfRegNum<[22]>; - def X23_32 : RISCVReg32<23,"x23", ["s7"]>, DwarfRegNum<[23]>; - def X24_32 : RISCVReg32<24,"x24", ["s8"]>, DwarfRegNum<[24]>; - def X25_32 : RISCVReg32<25,"x25", ["s9"]>, DwarfRegNum<[25]>; - def X26_32 : RISCVReg32<26,"x26", ["s10"]>, DwarfRegNum<[26]>; - def X27_32 : RISCVReg32<27,"x27", ["s11"]>, DwarfRegNum<[27]>; - def X28_32 : RISCVReg32<28,"x28", ["t3"]>, DwarfRegNum<[28]>; - def X29_32 : RISCVReg32<29,"x29", ["t4"]>, DwarfRegNum<[29]>; - def X30_32 : RISCVReg32<30,"x30", ["t5"]>, DwarfRegNum<[30]>; - def X31_32 : RISCVReg32<31,"x31", ["t6"]>, DwarfRegNum<[31]>; + def X0 : RISCVReg<0, "x0", ["zero"]>, DwarfRegNum<[0]>; + def X1 : RISCVReg<1, "x1", ["ra"]>, DwarfRegNum<[1]>; + def X2 : RISCVReg<2, "x2", ["sp"]>, DwarfRegNum<[2]>; + def X3 : RISCVReg<3, "x3", ["gp"]>, DwarfRegNum<[3]>; + def X4 : RISCVReg<4, "x4", ["tp"]>, DwarfRegNum<[4]>; + def X5 : RISCVReg<5, "x5", ["t0"]>, DwarfRegNum<[5]>; + def X6 : RISCVReg<6, "x6", ["t1"]>, DwarfRegNum<[6]>; + def X7 : RISCVReg<7, "x7", ["t2"]>, DwarfRegNum<[7]>; + def X8 : RISCVReg<8, "x8", ["s0"]>, DwarfRegNum<[8]>; + def X9 : RISCVReg<9, "x9", ["s1"]>, DwarfRegNum<[9]>; + def X10 : RISCVReg<10,"x10", ["a0"]>, DwarfRegNum<[10]>; + def X11 : RISCVReg<11,"x11", ["a1"]>, DwarfRegNum<[11]>; + def X12 : RISCVReg<12,"x12", ["a2"]>, DwarfRegNum<[12]>; + def X13 : RISCVReg<13,"x13", ["a3"]>, DwarfRegNum<[13]>; + def X14 : RISCVReg<14,"x14", ["a4"]>, DwarfRegNum<[14]>; + def X15 : RISCVReg<15,"x15", ["a5"]>, DwarfRegNum<[15]>; + def X16 : RISCVReg<16,"x16", ["a6"]>, DwarfRegNum<[16]>; + def X17 : RISCVReg<17,"x17", ["a7"]>, DwarfRegNum<[17]>; + def X18 : RISCVReg<18,"x18", ["s2"]>, DwarfRegNum<[18]>; + def X19 : RISCVReg<19,"x19", ["s3"]>, DwarfRegNum<[19]>; + def X20 : RISCVReg<20,"x20", ["s4"]>, DwarfRegNum<[20]>; + def X21 : RISCVReg<21,"x21", ["s5"]>, DwarfRegNum<[21]>; + def X22 : RISCVReg<22,"x22", ["s6"]>, DwarfRegNum<[22]>; + def X23 : RISCVReg<23,"x23", ["s7"]>, DwarfRegNum<[23]>; + def X24 : RISCVReg<24,"x24", ["s8"]>, DwarfRegNum<[24]>; + def X25 : RISCVReg<25,"x25", ["s9"]>, DwarfRegNum<[25]>; + def X26 : RISCVReg<26,"x26", ["s10"]>, DwarfRegNum<[26]>; + def X27 : RISCVReg<27,"x27", ["s11"]>, DwarfRegNum<[27]>; + def X28 : RISCVReg<28,"x28", ["t3"]>, DwarfRegNum<[28]>; + def X29 : RISCVReg<29,"x29", ["t4"]>, DwarfRegNum<[29]>; + def X30 : RISCVReg<30,"x30", ["t5"]>, DwarfRegNum<[30]>; + def X31 : RISCVReg<31,"x31", ["t6"]>, DwarfRegNum<[31]>; } -foreach Index = 0-31 in { - def X#Index#_64 : RISCVReg64<!cast<RISCVReg32>("X"#Index#"_32")>, DwarfRegNum<[Index]>; -} - -// We currently define separate register classes for the 32-bit and 64-bit -// GPRs. Once variable-sized register classes -// <http://lists.llvm.org/pipermail/llvm-dev/2016-September/105027.html> or -// similar are implemented, we can just use one 'GPR' class for most -// instruction definitions. +def XLenVT : ValueTypeByHwMode<[RV32, RV64, DefaultMode], + [i32, i64, i32]>; // TODO: once codegen is implemented, registers should be listed in an order // reflecting the preferred register allocation sequence. -def GPR : RegisterClass<"RISCV", [i32], 32, (add - (sequence "X%u_32", 0, 31) -)>; - -def GPR64 : RegisterClass<"RISCV", [i64], 64, (add - (sequence "X%u_64", 0, 31) -)>; +def GPR : RegisterClass< "RISCV", [XLenVT], 32, (add + (sequence "X%u", 0, 31) + )> { + let RegInfos = RegInfoByHwMode< + [RV32, RV64, DefaultMode], + [RegInfo<32,32,32>, RegInfo<64,64,64>, RegInfo<32,32,32>]>; +} |

