diff options
Diffstat (limited to 'llvm/lib/Target/BPF/BPFISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/BPF/BPFISelLowering.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp index 3322b8d93b3a..c543dfcfca95 100644 --- a/llvm/lib/Target/BPF/BPFISelLowering.cpp +++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp @@ -78,6 +78,24 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM, setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); + // Set unsupported atomic operations as Custom so + // we can emit better error messages than fatal error + // from selectiondag. + for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) { + if (VT == MVT::i32) { + if (STI.getHasAlu32()) + continue; + } else { + setOperationAction(ISD::ATOMIC_LOAD_ADD, VT, Custom); + } + + setOperationAction(ISD::ATOMIC_LOAD_AND, VT, Custom); + setOperationAction(ISD::ATOMIC_LOAD_OR, VT, Custom); + setOperationAction(ISD::ATOMIC_LOAD_XOR, VT, Custom); + setOperationAction(ISD::ATOMIC_SWAP, VT, Custom); + setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, VT, Custom); + } + for (auto VT : { MVT::i32, MVT::i64 }) { if (VT == MVT::i32 && !STI.getHasAlu32()) continue; @@ -202,6 +220,20 @@ bool BPFTargetLowering::isZExtFree(EVT VT1, EVT VT2) const { return NumBits1 == 32 && NumBits2 == 64; } +BPFTargetLowering::ConstraintType +BPFTargetLowering::getConstraintType(StringRef Constraint) const { + if (Constraint.size() == 1) { + switch (Constraint[0]) { + default: + break; + case 'w': + return C_RegisterClass; + } + } + + return TargetLowering::getConstraintType(Constraint); +} + std::pair<unsigned, const TargetRegisterClass *> BPFTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, @@ -211,6 +243,10 @@ BPFTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, switch (Constraint[0]) { case 'r': // GENERAL_REGS return std::make_pair(0U, &BPF::GPRRegClass); + case 'w': + if (HasAlu32) + return std::make_pair(0U, &BPF::GPR32RegClass); + break; default: break; } @@ -218,6 +254,30 @@ BPFTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); } +void BPFTargetLowering::ReplaceNodeResults( + SDNode *N, SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG) const { + const char *err_msg; + uint32_t Opcode = N->getOpcode(); + switch (Opcode) { + default: + report_fatal_error("Unhandled custom legalization"); + case ISD::ATOMIC_LOAD_ADD: + case ISD::ATOMIC_LOAD_AND: + case ISD::ATOMIC_LOAD_OR: + case ISD::ATOMIC_LOAD_XOR: + case ISD::ATOMIC_SWAP: + case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: + if (HasAlu32 || Opcode == ISD::ATOMIC_LOAD_ADD) + err_msg = "Unsupported atomic operations, please use 32/64 bit version"; + else + err_msg = "Unsupported atomic operations, please use 64 bit version"; + break; + } + + SDLoc DL(N); + fail(DL, DAG, err_msg); +} + SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { case ISD::BR_CC: |