diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 46 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCV.td | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrFormats.td | 17 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfo.td | 64 |
4 files changed, 111 insertions, 18 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index ab5880a3646..588e39ee3cf 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -31,6 +31,7 @@ struct RISCVOperand; class RISCVAsmParser : public MCTargetAsmParser { SMLoc getLoc() const { return getParser().getTok().getLoc(); } + bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind) override; @@ -91,6 +92,8 @@ struct RISCVOperand : public MCParsedAsmOperand { Immediate, } Kind; + bool IsRV64; + struct RegOp { unsigned RegNum; }; @@ -111,6 +114,7 @@ struct RISCVOperand : public MCParsedAsmOperand { public: RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { Kind = o.Kind; + IsRV64 = o.IsRV64; StartLoc = o.StartLoc; EndLoc = o.EndLoc; switch (Kind) { @@ -202,6 +206,16 @@ public: return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; } + bool isUImmLog2XLen() const { + int64_t Imm; + RISCVMCExpr::VariantKind VK; + if (!isImm()) + return false; + if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None) + return false; + return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); + } + bool isUImm5() const { int64_t Imm; RISCVMCExpr::VariantKind VK; @@ -259,6 +273,8 @@ public: SMLoc getStartLoc() const override { return StartLoc; } /// getEndLoc - Gets location of the last token of this operand SMLoc getEndLoc() const override { return EndLoc; } + /// True if this operand is for an RV64 instruction + bool isRV64() const { return IsRV64; } unsigned getReg() const override { assert(Kind == Register && "Invalid type access!"); @@ -290,29 +306,33 @@ public: } } - static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) { + static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, + bool IsRV64) { auto Op = make_unique<RISCVOperand>(Token); Op->Tok = Str; Op->StartLoc = S; Op->EndLoc = S; + Op->IsRV64 = IsRV64; return Op; } static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, - SMLoc E) { + SMLoc E, bool IsRV64) { auto Op = make_unique<RISCVOperand>(Register); Op->Reg.RegNum = RegNo; Op->StartLoc = S; Op->EndLoc = E; + Op->IsRV64 = IsRV64; return Op; } static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, - SMLoc E) { + SMLoc E, bool IsRV64) { auto Op = make_unique<RISCVOperand>(Immediate); Op->Imm.Val = Val; Op->StartLoc = S; Op->EndLoc = E; + Op->IsRV64 = IsRV64; return Op; } @@ -482,6 +502,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, } return Error(ErrorLoc, "invalid operand for instruction"); } + case Match_InvalidUImmLog2XLen: + if (isRV64()) + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); case Match_InvalidUImm5: return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); case Match_InvalidSImm12: @@ -562,16 +586,16 @@ OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, } } if (HadParens) - Operands.push_back(RISCVOperand::createToken("(", FirstS)); + Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); getLexer().Lex(); - Operands.push_back(RISCVOperand::createReg(RegNo, S, E)); + Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); } if (HadParens) { getParser().Lex(); // Eat ')' - Operands.push_back(RISCVOperand::createToken(")", getLoc())); + Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); } return MatchOperand_Success; @@ -605,7 +629,7 @@ OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { return parseOperandWithModifier(Operands); } - Operands.push_back(RISCVOperand::createImm(Res, S, E)); + Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); return MatchOperand_Success; } @@ -645,7 +669,7 @@ RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { } const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); - Operands.push_back(RISCVOperand::createImm(ModExpr, S, E)); + Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); return MatchOperand_Success; } @@ -657,7 +681,7 @@ RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { } getParser().Lex(); // Eat '(' - Operands.push_back(RISCVOperand::createToken("(", getLoc())); + Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); if (parseRegister(Operands) != MatchOperand_Success) { Error(getLoc(), "expected register"); @@ -670,7 +694,7 @@ RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { } getParser().Lex(); // Eat ')' - Operands.push_back(RISCVOperand::createToken(")", getLoc())); + Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); return MatchOperand_Success; } @@ -700,7 +724,7 @@ bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) { // First operand is token for instruction - Operands.push_back(RISCVOperand::createToken(Name, NameLoc)); + Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); // If there are no more operands, then finish if (getLexer().is(AsmToken::EndOfStatement)) diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td index 3ebf76b8e59..88cf8c1831d 100644 --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -40,6 +40,8 @@ def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">, def Feature64Bit : SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">; +def IsRV64 : Predicate<"Subtarget->is64Bit()">, + AssemblerPredicate<"Feature64Bit">; def RV64 : HwMode<"+64bit">; def RV32 : HwMode<"-64bit">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index ca368792340..83a62cdb52f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -188,6 +188,23 @@ class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, class RVInstIShift<bit arithshift, bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { + 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<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; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index cd500876c62..37e66a8faa6 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -69,6 +69,22 @@ def fencearg : Operand<XLenVT> { let DecoderMethod = "decodeUImmOperand<4>"; } +def UImmLog2XLenAsmOperand : AsmOperandClass { + let Name = "UImmLog2XLen"; + let RenderMethod = "addImmOperands"; + let DiagnosticType = "InvalidUImmLog2XLen"; +} + +def uimmlog2xlen : Operand<XLenVT>, ImmLeaf<XLenVT, [{ + if (Subtarget->is64Bit()) + return isUInt<6>(Imm); + return isUInt<5>(Imm); +}]> { + let ParserMatchClass = UImmLog2XLenAsmOperand; + // TODO: should ensure invalid shamt is rejected when decoding. + let DecoderMethod = "decodeUImmOperand<6>"; +} + def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> { let ParserMatchClass = UImmAsmOperand<5>; let DecoderMethod = "decodeUImmOperand<5>"; @@ -161,7 +177,7 @@ class ALU_ri<bits<3> funct3, string opcodestr> 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, + (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr, "$rd, $rs1, $shamt">; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in @@ -180,6 +196,17 @@ class CSR_ii<bits<3> funct3, string opcodestr> : (ins uimm12:$imm12, uimm5:$rs1), opcodestr, "$rd, $imm12, $rs1">; +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class ShiftW_ri<bit arithshift, bits<3> funct3, string opcodestr> + : RVInstIShiftW<arithshift, funct3, OPC_OP_IMM_32, (outs GPR:$rd), + (ins GPR:$rs1, uimm5:$shamt), opcodestr, + "$rd, $rs1, $shamt">; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr> + : RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd), + (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -279,6 +306,29 @@ def CSRRWI : CSR_ii<0b101, "csrrwi">; def CSRRSI : CSR_ii<0b110, "csrrsi">; def CSRRCI : CSR_ii<0b111, "csrrci">; +/// RV64I instructions + +let Predicates = [IsRV64] in { +def LWU : Load_ri<0b110, "lwu">; +def LD : Load_ri<0b011, "ld">; +def SD : Store_rri<0b011, "sd">; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd), + (ins GPR:$rs1, simm12:$imm12), + "addiw", "$rd, $rs1, $imm12">; + +def SLLIW : ShiftW_ri<0, 0b001, "slliw">; +def SRLIW : ShiftW_ri<0, 0b101, "srliw">; +def SRAIW : ShiftW_ri<1, 0b101, "sraiw">; + +def ADDW : ALUW_rr<0b0000000, 0b000, "addw">; +def SUBW : ALUW_rr<0b0100000, 0b000, "subw">; +def SLLW : ALUW_rr<0b0000000, 0b001, "sllw">; +def SRLW : ALUW_rr<0b0000000, 0b101, "srlw">; +def SRAW : ALUW_rr<0b0100000, 0b101, "sraw">; +} // Predicates = [IsRV64] + //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns // @@ -293,9 +343,9 @@ class PatGprGpr<SDPatternOperator OpNode, RVInstR Inst> : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>; class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst> : Pat<(OpNode GPR:$rs1, simm12:$imm12), (Inst GPR:$rs1, simm12:$imm12)>; -class PatGprUimm5<SDPatternOperator OpNode, RVInstIShift Inst> - : Pat<(OpNode GPR:$rs1, uimm5:$shamt), - (Inst GPR:$rs1, uimm5:$shamt)>; +class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst> + : Pat<(OpNode GPR:$rs1, uimmlog2xlen:$shamt), + (Inst GPR:$rs1, uimmlog2xlen:$shamt)>; /// Immediates @@ -315,11 +365,11 @@ def : PatGprSimm12<and, ANDI>; def : PatGprGpr<xor, XOR>; def : PatGprSimm12<xor, XORI>; def : PatGprGpr<shl, SLL>; -def : PatGprUimm5<shl, SLLI>; +def : PatGprUimmLog2XLen<shl, SLLI>; def : PatGprGpr<srl, SRL>; -def : PatGprUimm5<srl, SRLI>; +def : PatGprUimmLog2XLen<srl, SRLI>; def : PatGprGpr<sra, SRA>; -def : PatGprUimm5<sra, SRAI>; +def : PatGprUimmLog2XLen<sra, SRAI>; /// Setcc |

