diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 106 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfo.td | 20 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVMCInstLower.cpp | 8 |
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; } |