summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp46
-rw-r--r--llvm/lib/Target/RISCV/RISCV.td2
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrFormats.td17
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfo.td64
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
OpenPOWER on IntegriCloud