summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp106
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.h2
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfo.td20
-rw-r--r--llvm/lib/Target/RISCV/RISCVMCInstLower.cpp8
4 files changed, 121 insertions, 15 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 606365ea59b..4801884e242 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -53,17 +53,54 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setLoadExtAction(N, XLenVT, MVT::i1, Promote);
// TODO: add all necessary setOperationAction calls.
- setOperationAction(ISD::GlobalAddress, XLenVT, Custom);
-
+ setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, XLenVT, Expand);
setOperationAction(ISD::SELECT, XLenVT, Custom);
setOperationAction(ISD::SELECT_CC, XLenVT, Expand);
+ for (auto VT : {MVT::i1, MVT::i8, MVT::i16})
+ setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand);
+
+ setOperationAction(ISD::ADDC, XLenVT, Expand);
+ setOperationAction(ISD::ADDE, XLenVT, Expand);
+ setOperationAction(ISD::SUBC, XLenVT, Expand);
+ setOperationAction(ISD::SUBE, XLenVT, Expand);
+
+ setOperationAction(ISD::SREM, XLenVT, Expand);
+ setOperationAction(ISD::SDIVREM, XLenVT, Expand);
+ setOperationAction(ISD::SDIV, XLenVT, Expand);
+ setOperationAction(ISD::UREM, XLenVT, Expand);
+ setOperationAction(ISD::UDIVREM, XLenVT, Expand);
+ setOperationAction(ISD::UDIV, XLenVT, Expand);
+
+ setOperationAction(ISD::MUL, XLenVT, Expand);
+ setOperationAction(ISD::SMUL_LOHI, XLenVT, Expand);
+ setOperationAction(ISD::UMUL_LOHI, XLenVT, Expand);
+ setOperationAction(ISD::MULHS, XLenVT, Expand);
+ setOperationAction(ISD::MULHU, XLenVT, Expand);
+
+ setOperationAction(ISD::SHL_PARTS, XLenVT, Expand);
+ setOperationAction(ISD::SRL_PARTS, XLenVT, Expand);
+ setOperationAction(ISD::SRA_PARTS, XLenVT, Expand);
+
+ setOperationAction(ISD::ROTL, XLenVT, Expand);
+ setOperationAction(ISD::ROTR, XLenVT, Expand);
+ setOperationAction(ISD::BSWAP, XLenVT, Expand);
+ setOperationAction(ISD::CTTZ, XLenVT, Expand);
+ setOperationAction(ISD::CTLZ, XLenVT, Expand);
+ setOperationAction(ISD::CTPOP, XLenVT, Expand);
+
+ setOperationAction(ISD::GlobalAddress, XLenVT, Custom);
+ setOperationAction(ISD::BlockAddress, XLenVT, Custom);
+
setBooleanContents(ZeroOrOneBooleanContent);
// Function alignments (log2).
setMinFunctionAlignment(3);
setPrefFunctionAlignment(3);
+
+ // Effectively disable jump table generation.
+ setMinimumJumpTableEntries(INT_MAX);
}
// Changes the condition code and swaps operands if necessary, so the SetCC
@@ -112,6 +149,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
report_fatal_error("unimplemented operand");
case ISD::GlobalAddress:
return lowerGlobalAddress(Op, DAG);
+ case ISD::BlockAddress:
+ return lowerBlockAddress(Op, DAG);
case ISD::SELECT:
return lowerSELECT(Op, DAG);
}
@@ -125,18 +164,56 @@ SDValue RISCVTargetLowering::lowerGlobalAddress(SDValue Op,
const GlobalValue *GV = N->getGlobal();
int64_t Offset = N->getOffset();
- if (!isPositionIndependent() && !Subtarget.is64Bit()) {
- SDValue GAHi =
- DAG.getTargetGlobalAddress(GV, DL, Ty, Offset, RISCVII::MO_HI);
- SDValue GALo =
- DAG.getTargetGlobalAddress(GV, DL, Ty, Offset, RISCVII::MO_LO);
- SDValue MNHi = SDValue(DAG.getMachineNode(RISCV::LUI, DL, Ty, GAHi), 0);
- SDValue MNLo =
- SDValue(DAG.getMachineNode(RISCV::ADDI, DL, Ty, MNHi, GALo), 0);
- return MNLo;
- } else {
+ if (isPositionIndependent() || Subtarget.is64Bit())
report_fatal_error("Unable to lowerGlobalAddress");
- }
+
+ SDValue GAHi =
+ DAG.getTargetGlobalAddress(GV, DL, Ty, Offset, RISCVII::MO_HI);
+ SDValue GALo =
+ DAG.getTargetGlobalAddress(GV, DL, Ty, Offset, RISCVII::MO_LO);
+ SDValue MNHi = SDValue(DAG.getMachineNode(RISCV::LUI, DL, Ty, GAHi), 0);
+ SDValue MNLo =
+ SDValue(DAG.getMachineNode(RISCV::ADDI, DL, Ty, MNHi, GALo), 0);
+ return MNLo;
+}
+
+SDValue RISCVTargetLowering::lowerBlockAddress(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ EVT Ty = Op.getValueType();
+ BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
+ const BlockAddress *BA = N->getBlockAddress();
+ int64_t Offset = N->getOffset();
+
+ if (isPositionIndependent() || Subtarget.is64Bit())
+ report_fatal_error("Unable to lowerBlockAddress");
+
+ SDValue BAHi = DAG.getTargetBlockAddress(BA, Ty, Offset, RISCVII::MO_HI);
+ SDValue BALo = DAG.getTargetBlockAddress(BA, Ty, Offset, RISCVII::MO_LO);
+ SDValue MNHi = SDValue(DAG.getMachineNode(RISCV::LUI, DL, Ty, BAHi), 0);
+ SDValue MNLo =
+ SDValue(DAG.getMachineNode(RISCV::ADDI, DL, Ty, MNHi, BALo), 0);
+ return MNLo;
+}
+
+SDValue RISCVTargetLowering::lowerExternalSymbol(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ EVT Ty = Op.getValueType();
+ ExternalSymbolSDNode *N = cast<ExternalSymbolSDNode>(Op);
+ const char *Sym = N->getSymbol();
+
+ // TODO: should also handle gp-relative loads.
+
+ if (isPositionIndependent() || Subtarget.is64Bit())
+ report_fatal_error("Unable to lowerExternalSymbol");
+
+ SDValue GAHi = DAG.getTargetExternalSymbol(Sym, Ty, RISCVII::MO_HI);
+ SDValue GALo = DAG.getTargetExternalSymbol(Sym, Ty, RISCVII::MO_LO);
+ SDValue MNHi = SDValue(DAG.getMachineNode(RISCV::LUI, DL, Ty, GAHi), 0);
+ SDValue MNLo =
+ SDValue(DAG.getMachineNode(RISCV::ADDI, DL, Ty, MNHi, GALo), 0);
+ return MNLo;
}
SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
@@ -369,8 +446,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
if (isa<GlobalAddressSDNode>(Callee)) {
Callee = lowerGlobalAddress(Callee, DAG);
} else if (isa<ExternalSymbolSDNode>(Callee)) {
- report_fatal_error(
- "lowerExternalSymbol, needed for lowerCall, not yet handled");
+ Callee = lowerExternalSymbol(Callee, DAG);
}
// The first call operand is the chain and the second is the target address.
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 4d7b4697fa7..933bc6218d5 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -65,6 +65,8 @@ private:
return true;
}
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
};
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 6e5b4b12f5c..f0015021c16 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -328,6 +328,17 @@ def : PatGprSimm12<setlt, SLTI>;
def : PatGprGpr<setult, SLTU>;
def : PatGprSimm12<setult, SLTIU>;
+// Define pattern expansions for setcc operations that aren't directly
+// handled by a RISC-V instruction.
+def : Pat<(seteq GPR:$rs1, GPR:$rs2), (SLTIU (XOR GPR:$rs1, GPR:$rs2), 1)>;
+def : Pat<(setne GPR:$rs1, GPR:$rs2), (SLTU X0, (XOR GPR:$rs1, GPR:$rs2))>;
+def : Pat<(setugt GPR:$rs1, GPR:$rs2), (SLTU GPR:$rs2, GPR:$rs1)>;
+def : Pat<(setuge GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs1, GPR:$rs2), 1)>;
+def : Pat<(setule GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs2, GPR:$rs1), 1)>;
+def : Pat<(setgt GPR:$rs1, GPR:$rs2), (SLT GPR:$rs2, GPR:$rs1)>;
+def : Pat<(setge GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs1, GPR:$rs2), 1)>;
+def : Pat<(setle GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs2, GPR:$rs1), 1)>;
+
let usesCustomInserter = 1 in
def Select_GPR_Using_CC_GPR
: Pseudo<(outs GPR:$dst),
@@ -370,6 +381,15 @@ def PseudoBR : Pseudo<(outs), (ins simm21_lsb0:$imm20), [(br bb:$imm20)]>,
PseudoInstExpansion<(JAL X0, simm21_lsb0:$imm20)>;
let isCall = 1, Defs=[X1] in
+let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
+def PseudoBRIND : Pseudo<(outs), (ins GPR:$rs1, simm12:$imm12), []>,
+ PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
+
+def : Pat<(brind GPR:$rs1), (PseudoBRIND GPR:$rs1, 0)>;
+def : Pat<(brind (add GPR:$rs1, simm12:$imm12)),
+ (PseudoBRIND GPR:$rs1, simm12:$imm12)>;
+
+let isCall = 1, Defs = [X1] in
def PseudoCALL : Pseudo<(outs), (ins GPR:$rs1), [(Call GPR:$rs1)]>,
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
diff --git a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
index ef0051ed56e..d8ae11f2bd9 100644
--- a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
@@ -81,6 +81,14 @@ bool llvm::LowerRISCVMachineOperandToMCOperand(const MachineOperand &MO,
case MachineOperand::MO_GlobalAddress:
MCOp = lowerSymbolOperand(MO, AP.getSymbol(MO.getGlobal()), AP);
break;
+ case MachineOperand::MO_BlockAddress:
+ MCOp = lowerSymbolOperand(
+ MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP);
+ break;
+ case MachineOperand::MO_ExternalSymbol:
+ MCOp = lowerSymbolOperand(
+ MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
+ break;
}
return true;
}
OpenPOWER on IntegriCloud