From 1437cc9a5273f270736b55cb4a47bcf3df11d4a9 Mon Sep 17 00:00:00 2001 From: Alex Bradbury Date: Thu, 19 Oct 2017 14:29:03 +0000 Subject: [PATCH] [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 . git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316159 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../RISCV/Disassembler/RISCVDisassembler.cpp | 16 +- lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 5 +- .../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 2 +- .../RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp | 12 +- lib/Target/RISCV/RISCV.td | 28 ++- lib/Target/RISCV/RISCVInstrFormats.td | 100 +++++--- lib/Target/RISCV/RISCVInstrInfo.td | 218 ++++++++++-------- lib/Target/RISCV/RISCVRegisterInfo.td | 115 ++++----- 8 files changed, 276 insertions(+), 220 deletions(-) diff --git a/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index e64d875a567..003686ac2f3 100644 --- a/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/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/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index cfb124262c6..9fafbb0a95a 100644 --- a/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/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/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index f8212159331..f94c37aae8f 100644 --- a/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -159,7 +159,7 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, cast(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/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp index 2b35eab577b..45de976ec6c 100644 --- a/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp +++ b/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/lib/Target/RISCV/RISCV.td b/lib/Target/RISCV/RISCV.td index 19e11839ac3..7b61901915f 100644 --- a/lib/Target/RISCV/RISCV.td +++ b/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/lib/Target/RISCV/RISCVInstrFormats.td b/lib/Target/RISCV/RISCVInstrFormats.td index 383b73cf4e0..48f6cf8762d 100644 --- a/lib/Target/RISCV/RISCVInstrFormats.td +++ b/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 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 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 @@ -58,7 +86,7 @@ class RISCVInst 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 pattern, // Pseudo instructions class Pseudo pattern> - : RISCVInst { + : RVInst { let isPseudo = 1; let isCodeGenOnly = 1; } -class FR funct7, bits<3> funct3, bits<7> opcode, dag outs, dag ins, - string asmstr, list pattern> : RISCVInst -{ +// 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; @@ -83,12 +115,12 @@ class FR 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 funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list pattern> - : RISCVInst -{ +class RVInstI funct3, RISCVOpcode opcode, dag outs, dag ins, + string opcodestr, string argstr> + : RVInst { bits<12> imm12; bits<5> rs1; bits<5> rd; @@ -97,12 +129,12 @@ class FI 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 funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list pattern> - : RISCVInst -{ +class RVInstIShift funct3, RISCVOpcode opcode, + dag outs, dag ins, string opcodestr, string argstr> + : RVInst { bits<5> shamt; bits<5> rs1; bits<5> rd; @@ -114,12 +146,12 @@ class FI32Shift 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 funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list pattern> - : RISCVInst -{ +class RVInstS funct3, RISCVOpcode opcode, dag outs, dag ins, + string opcodestr, string argstr> + : RVInst { bits<12> imm12; bits<5> rs2; bits<5> rs1; @@ -129,12 +161,12 @@ class FS 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 funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list pattern> - : RISCVInst -{ +class RVInstB funct3, RISCVOpcode opcode, dag outs, dag ins, + string opcodestr, string argstr> + : RVInst { bits<12> imm12; bits<5> rs2; bits<5> rs1; @@ -146,23 +178,23 @@ class FSB 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 opcode, dag outs, dag ins, string asmstr, list pattern> - : RISCVInst -{ +class RVInstU + : RVInst { 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 opcode, dag outs, dag ins, string asmstr, list pattern> - : RISCVInst -{ +class RVInstJ + : RVInst { bits<20> imm20; bits<5> rd; @@ -171,5 +203,5 @@ class FUJ opcode, dag outs, dag ins, string asmstr, list 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/lib/Target/RISCV/RISCVInstrInfo.td b/lib/Target/RISCV/RISCVInstrInfo.td index 1a5f32ecabe..213ef63f5f9 100644 --- a/lib/Target/RISCV/RISCVInstrInfo.td +++ b/lib/Target/RISCV/RISCVInstrInfo.td @@ -13,6 +13,10 @@ include "RISCVInstrFormats.td" +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + class ImmAsmOperand : AsmOperandClass { let Name = prefix # "Imm" # width # suffix; let RenderMethod = "addImmOperands"; @@ -20,11 +24,11 @@ class ImmAsmOperand : AsmOperandClass { } class SImmAsmOperand - : ImmAsmOperand<"S", width, suffix> { + : ImmAsmOperand<"S", width, suffix> { } class UImmAsmOperand - : ImmAsmOperand<"U", width, suffix> { + : ImmAsmOperand<"U", width, suffix> { } def FenceArg : AsmOperandClass { @@ -33,107 +37,139 @@ def FenceArg : AsmOperandClass { let DiagnosticType = "InvalidFenceArg"; } -def fencearg : Operand { +def fencearg : Operand { let ParserMatchClass = FenceArg; let PrintMethod = "printFenceArg"; let DecoderMethod = "decodeUImmOperand<4>"; } -def uimm5 : Operand { +def uimm5 : Operand { let ParserMatchClass = UImmAsmOperand<5>; let DecoderMethod = "decodeUImmOperand<5>"; } -def simm12 : Operand { +def simm12 : Operand { let ParserMatchClass = SImmAsmOperand<12>; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<12>"; } -def uimm12 : Operand { +def uimm12 : Operand { let ParserMatchClass = UImmAsmOperand<12>; let DecoderMethod = "decodeUImmOperand<12>"; } // A 13-bit signed immediate where the least significant bit is zero. -def simm13_lsb0 : Operand { +def simm13_lsb0 : Operand { let ParserMatchClass = SImmAsmOperand<13, "Lsb0">; let EncoderMethod = "getImmOpValueAsr1"; let DecoderMethod = "decodeSImmOperandAndLsl1<13>"; } -def uimm20 : Operand { +def uimm20 : Operand { 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 { +def simm21_lsb0 : Operand { 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 -// 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 funct3, string opcodestr> + : RVInstB { + let isBranch = 1; + let isTerminator = 1; +} + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in +class Load_ri funct3, string opcodestr> + : RVInstI; + +// 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 funct3, string opcodestr> + : RVInstS; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class ALU_ri funct3, string opcodestr> + : RVInstI; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class Shift_ri funct3, string opcodestr> + : RVInstIShift; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class ALU_rr funct7, bits<3> funct3, string opcodestr> + : RVInstR; + +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class CSR_ir funct3, string opcodestr> : + RVInstI; + +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class CSR_ii funct3, string opcodestr> : + RVInstI; -def JALR : FI<0b000, 0b1100111, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), - "jalr\t$rd, $rs1, $imm12", []>; +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// -class Bcc funct3, string OpcodeStr> : - FSB { -} +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +def LUI : RVInstU; -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; -class LD_ri funct3, string OpcodeStr> : - FI { - let mayLoad = 1; -} +let isCall = 1 in +def JAL : RVInstJ; -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 funct3, string OpcodeStr> : - FS { - 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 funct3, string OpcodeStr> : - FI -{ -} +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 funct3, string OpcodeStr> : - FI32Shift -{ -} - -def SLLI : SHIFT32_ri<0, 0b001, "slli">; -def SRLI : SHIFT32_ri<0, 0b101, "srli">; -def SRAI : SHIFT32_ri<1, 0b101, "srai">; - -class ALU_rr funct7, bits<3> funct3, string OpcodeStr> : - FR -{ -} +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 funct3, string OpcodeStr> : - FI -{ +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 funct3, string OpcodeStr> : - FI -{ -} +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/lib/Target/RISCV/RISCVRegisterInfo.td b/lib/Target/RISCV/RISCVRegisterInfo.td index f04de217bf0..a5484130dfc 100644 --- a/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/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 Enc, string n, list alt = []> : Register { - 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 : Register<""> { - let HWEncoding{4-0} = subreg.HWEncoding{4-0}; - let SubRegs = [subreg]; - let SubRegIndices = [sub_32]; - } - - def ABIRegAltName : RegAltNameIndex; +class RISCVReg Enc, string n, list alt = []> : Register { + 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("X"#Index#"_32")>, DwarfRegNum<[Index]>; -} - -// We currently define separate register classes for the 32-bit and 64-bit -// GPRs. Once variable-sized register classes -// 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>]>; +} -- 2.40.0