}
}
-// Helper function that emits error message for intrinsics with chain.
+// Helper function that emits error message for intrinsics with chain and return
+// merge values of a UNDEF and the chain.
static SDValue emitIntrinsicWithChainErrorMessage(SDValue Op,
StringRef ErrorMsg,
SelectionDAG &DAG) {
-
- DAG.getContext()->emitError("argument to '" + Op->getOperationName(0) + "' " +
- ErrorMsg);
+ DAG.getContext()->emitError(Op->getOperationName(0) + ": " + ErrorMsg + ".");
return DAG.getMergeValues({DAG.getUNDEF(Op.getValueType()), Op.getOperand(0)},
SDLoc(Op));
}
SelectionDAG &DAG) const {
SDLoc DL(Op);
MVT GRLenVT = Subtarget.getGRLenVT();
- SDValue Op0 = Op.getOperand(0);
- std::string Name = Op->getOperationName(0);
- const StringRef ErrorMsgOOR = "out of range";
+ EVT VT = Op.getValueType();
+ SDValue Chain = Op.getOperand(0);
+ const StringRef ErrorMsgOOR = "argument out of range";
+ const StringRef ErrorMsgReqLA64 = "requires loongarch64";
+ const StringRef ErrorMsgReqF = "requires basic 'f' target feature";
switch (Op.getConstantOperandVal(1)) {
default:
case Intrinsic::loongarch_crcc_w_b_w:
case Intrinsic::loongarch_crcc_w_h_w:
case Intrinsic::loongarch_crcc_w_w_w:
- case Intrinsic::loongarch_crcc_w_d_w: {
- std::string Name = Op->getOperationName(0);
- DAG.getContext()->emitError(Name + " requires target: loongarch64");
- return DAG.getMergeValues({DAG.getUNDEF(Op.getValueType()), Op0}, DL);
- }
+ case Intrinsic::loongarch_crcc_w_d_w:
+ return emitIntrinsicWithChainErrorMessage(Op, ErrorMsgReqLA64, DAG);
case Intrinsic::loongarch_csrrd_w:
case Intrinsic::loongarch_csrrd_d: {
unsigned Imm = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue();
- if (!isUInt<14>(Imm))
- return emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG);
- return DAG.getMergeValues(
- {DAG.getNode(LoongArchISD::CSRRD, DL, GRLenVT, Op0,
- DAG.getConstant(Imm, DL, GRLenVT)),
- Op0},
- DL);
+ return !isUInt<14>(Imm)
+ ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG)
+ : DAG.getMergeValues(
+ {DAG.getNode(LoongArchISD::CSRRD, DL, GRLenVT, Chain,
+ DAG.getConstant(Imm, DL, GRLenVT)),
+ Chain},
+ DL);
}
case Intrinsic::loongarch_csrwr_w:
case Intrinsic::loongarch_csrwr_d: {
unsigned Imm = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue();
- if (!isUInt<14>(Imm))
- return emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG);
- return DAG.getMergeValues(
- {DAG.getNode(LoongArchISD::CSRWR, DL, GRLenVT, Op0, Op.getOperand(2),
- DAG.getConstant(Imm, DL, GRLenVT)),
- Op0},
- DL);
+ return !isUInt<14>(Imm)
+ ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG)
+ : DAG.getMergeValues(
+ {DAG.getNode(LoongArchISD::CSRWR, DL, GRLenVT, Chain,
+ Op.getOperand(2),
+ DAG.getConstant(Imm, DL, GRLenVT)),
+ Chain},
+ DL);
}
case Intrinsic::loongarch_csrxchg_w:
case Intrinsic::loongarch_csrxchg_d: {
unsigned Imm = cast<ConstantSDNode>(Op.getOperand(4))->getZExtValue();
- if (!isUInt<14>(Imm))
- return emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG);
- return DAG.getMergeValues(
- {DAG.getNode(LoongArchISD::CSRXCHG, DL, GRLenVT, Op0, Op.getOperand(2),
- Op.getOperand(3), DAG.getConstant(Imm, DL, GRLenVT)),
- Op0},
- DL);
+ return !isUInt<14>(Imm)
+ ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG)
+ : DAG.getMergeValues(
+ {DAG.getNode(LoongArchISD::CSRXCHG, DL, GRLenVT, Chain,
+ Op.getOperand(2), Op.getOperand(3),
+ DAG.getConstant(Imm, DL, GRLenVT)),
+ Chain},
+ DL);
}
case Intrinsic::loongarch_iocsrrd_d: {
- if (Subtarget.is64Bit())
- return DAG.getMergeValues(
- {DAG.getNode(
- LoongArchISD::IOCSRRD_D, DL, GRLenVT, Op0,
- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(2))),
- Op0},
- DL);
- else {
- DAG.getContext()->emitError(
- "llvm.loongarch.crc.w.d.w requires target: loongarch64");
- return DAG.getMergeValues({DAG.getUNDEF(Op.getValueType()), Op0}, DL);
- }
+ return DAG.getMergeValues(
+ {DAG.getNode(
+ LoongArchISD::IOCSRRD_D, DL, GRLenVT, Chain,
+ DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(2))),
+ Chain},
+ DL);
}
#define IOCSRRD_CASE(NAME, NODE) \
case Intrinsic::loongarch_##NAME: { \
- return DAG.getMergeValues( \
- {DAG.getNode(LoongArchISD::NODE, DL, GRLenVT, Op0, Op.getOperand(2)), \
- Op0}, \
- DL); \
+ return DAG.getMergeValues({DAG.getNode(LoongArchISD::NODE, DL, GRLenVT, \
+ Chain, Op.getOperand(2)), \
+ Chain}, \
+ DL); \
}
IOCSRRD_CASE(iocsrrd_b, IOCSRRD_B);
IOCSRRD_CASE(iocsrrd_h, IOCSRRD_H);
IOCSRRD_CASE(iocsrrd_w, IOCSRRD_W);
#undef IOCSRRD_CASE
case Intrinsic::loongarch_cpucfg: {
- return DAG.getMergeValues(
- {DAG.getNode(LoongArchISD::CPUCFG, DL, GRLenVT, Op0, Op.getOperand(2)),
- Op0},
- DL);
+ return DAG.getMergeValues({DAG.getNode(LoongArchISD::CPUCFG, DL, GRLenVT,
+ Chain, Op.getOperand(2)),
+ Chain},
+ DL);
}
case Intrinsic::loongarch_lddir_d: {
unsigned Imm = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue();
- if (!isUInt<8>(Imm)) {
- DAG.getContext()->emitError("argument to '" + Op->getOperationName(0) +
- "' out of range");
- return DAG.getMergeValues({DAG.getUNDEF(Op.getValueType()), Op0}, DL);
- }
-
- return Op;
+ return !isUInt<8>(Imm)
+ ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG)
+ : Op;
}
case Intrinsic::loongarch_movfcsr2gr: {
- if (!Subtarget.hasBasicF()) {
- DAG.getContext()->emitError(
- "llvm.loongarch.movfcsr2gr expects basic f target feature");
- return DAG.getMergeValues(
- {DAG.getUNDEF(Op.getValueType()), Op.getOperand(0)}, SDLoc(Op));
- }
+ if (!Subtarget.hasBasicF())
+ return emitIntrinsicWithChainErrorMessage(Op, ErrorMsgReqF, DAG);
unsigned Imm = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue();
- if (!isUInt<2>(Imm)) {
- DAG.getContext()->emitError("argument to '" + Op->getOperationName(0) +
- "' " + ErrorMsgOOR);
- return DAG.getMergeValues(
- {DAG.getUNDEF(Op.getValueType()), Op.getOperand(0)}, SDLoc(Op));
- }
- return DAG.getMergeValues(
- {DAG.getNode(LoongArchISD::MOVFCSR2GR, DL, Op.getValueType(),
- DAG.getConstant(Imm, DL, GRLenVT)),
- Op.getOperand(0)},
- DL);
+ return !isUInt<2>(Imm)
+ ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG)
+ : DAG.getMergeValues(
+ {DAG.getNode(LoongArchISD::MOVFCSR2GR, DL, VT,
+ DAG.getConstant(Imm, DL, GRLenVT)),
+ Chain},
+ DL);
}
}
}
// Helper function that emits error message for intrinsics with void return
-// value.
+// value and return the chain.
static SDValue emitIntrinsicErrorMessage(SDValue Op, StringRef ErrorMsg,
SelectionDAG &DAG) {
- DAG.getContext()->emitError("argument to '" + Op->getOperationName(0) + "' " +
- ErrorMsg);
+ DAG.getContext()->emitError(Op->getOperationName(0) + ": " + ErrorMsg + ".");
return Op.getOperand(0);
}
SelectionDAG &DAG) const {
SDLoc DL(Op);
MVT GRLenVT = Subtarget.getGRLenVT();
- SDValue Op0 = Op.getOperand(0);
+ SDValue Chain = Op.getOperand(0);
uint64_t IntrinsicEnum = Op.getConstantOperandVal(1);
SDValue Op2 = Op.getOperand(2);
- const StringRef ErrorMsgOOR = "out of range";
+ const StringRef ErrorMsgOOR = "argument out of range";
+ const StringRef ErrorMsgReqLA64 = "requires loongarch64";
+ const StringRef ErrorMsgReqLA32 = "requires loongarch32";
+ const StringRef ErrorMsgReqF = "requires basic 'f' target feature";
switch (IntrinsicEnum) {
default:
return SDValue();
case Intrinsic::loongarch_cacop_d:
case Intrinsic::loongarch_cacop_w: {
- if (IntrinsicEnum == Intrinsic::loongarch_cacop_d && !Subtarget.is64Bit()) {
- DAG.getContext()->emitError(
- "llvm.loongarch.cacop.d requires target: loongarch64");
- return Op.getOperand(0);
- }
- if (IntrinsicEnum == Intrinsic::loongarch_cacop_w && Subtarget.is64Bit()) {
- DAG.getContext()->emitError(
- "llvm.loongarch.cacop.w requires target: loongarch32");
- return Op.getOperand(0);
- }
+ if (IntrinsicEnum == Intrinsic::loongarch_cacop_d && !Subtarget.is64Bit())
+ return emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG);
+ if (IntrinsicEnum == Intrinsic::loongarch_cacop_w && Subtarget.is64Bit())
+ return emitIntrinsicErrorMessage(Op, ErrorMsgReqLA32, DAG);
// call void @llvm.loongarch.cacop.[d/w](uimm5, rj, simm12)
unsigned Imm1 = cast<ConstantSDNode>(Op2)->getZExtValue();
- if (!isUInt<5>(Imm1))
+ int Imm2 = cast<ConstantSDNode>(Op.getOperand(4))->getSExtValue();
+ if (!isUInt<5>(Imm1) || !isInt<12>(Imm2))
return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
- SDValue Op4 = Op.getOperand(4);
- int Imm2 = cast<ConstantSDNode>(Op4)->getSExtValue();
- if (!isInt<12>(Imm2))
- return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
-
return Op;
}
-
case Intrinsic::loongarch_dbar: {
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
- if (!isUInt<15>(Imm))
- return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
-
- return DAG.getNode(LoongArchISD::DBAR, DL, MVT::Other, Op0,
- DAG.getConstant(Imm, DL, GRLenVT));
+ return !isUInt<15>(Imm)
+ ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG)
+ : DAG.getNode(LoongArchISD::DBAR, DL, MVT::Other, Chain,
+ DAG.getConstant(Imm, DL, GRLenVT));
}
case Intrinsic::loongarch_ibar: {
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
- if (!isUInt<15>(Imm))
- return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
-
- return DAG.getNode(LoongArchISD::IBAR, DL, MVT::Other, Op0,
- DAG.getConstant(Imm, DL, GRLenVT));
+ return !isUInt<15>(Imm)
+ ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG)
+ : DAG.getNode(LoongArchISD::IBAR, DL, MVT::Other, Chain,
+ DAG.getConstant(Imm, DL, GRLenVT));
}
case Intrinsic::loongarch_break: {
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
- if (!isUInt<15>(Imm))
- return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
-
- return DAG.getNode(LoongArchISD::BREAK, DL, MVT::Other, Op0,
- DAG.getConstant(Imm, DL, GRLenVT));
+ return !isUInt<15>(Imm)
+ ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG)
+ : DAG.getNode(LoongArchISD::BREAK, DL, MVT::Other, Chain,
+ DAG.getConstant(Imm, DL, GRLenVT));
}
case Intrinsic::loongarch_movgr2fcsr: {
- if (!Subtarget.hasBasicF()) {
- DAG.getContext()->emitError(
- "llvm.loongarch.movgr2fcsr expects basic f target feature");
- return Op0;
- }
+ if (!Subtarget.hasBasicF())
+ return emitIntrinsicErrorMessage(Op, ErrorMsgReqF, DAG);
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
- if (!isUInt<2>(Imm))
- return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
-
- return DAG.getNode(
- LoongArchISD::MOVGR2FCSR, DL, MVT::Other, Op0,
- DAG.getConstant(Imm, DL, GRLenVT),
- DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT, Op.getOperand(3)));
+ return !isUInt<2>(Imm)
+ ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG)
+ : DAG.getNode(LoongArchISD::MOVGR2FCSR, DL, MVT::Other, Chain,
+ DAG.getConstant(Imm, DL, GRLenVT),
+ DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT,
+ Op.getOperand(3)));
}
case Intrinsic::loongarch_syscall: {
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
- if (!isUInt<15>(Imm))
- return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
-
- return DAG.getNode(LoongArchISD::SYSCALL, DL, MVT::Other, Op0,
- DAG.getConstant(Imm, DL, GRLenVT));
+ return !isUInt<15>(Imm)
+ ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG)
+ : DAG.getNode(LoongArchISD::SYSCALL, DL, MVT::Other, Chain,
+ DAG.getConstant(Imm, DL, GRLenVT));
}
#define IOCSRWR_CASE(NAME, NODE) \
case Intrinsic::loongarch_##NAME: { \
SDValue Op3 = Op.getOperand(3); \
- if (Subtarget.is64Bit()) \
- return DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Op0, \
- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \
- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op3)); \
- else \
- return DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Op0, Op2, Op3); \
+ return Subtarget.is64Bit() \
+ ? DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Chain, \
+ DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \
+ DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op3)) \
+ : DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Chain, Op2, \
+ Op3); \
}
IOCSRWR_CASE(iocsrwr_b, IOCSRWR_B);
IOCSRWR_CASE(iocsrwr_h, IOCSRWR_H);
IOCSRWR_CASE(iocsrwr_w, IOCSRWR_W);
#undef IOCSRWR_CASE
case Intrinsic::loongarch_iocsrwr_d: {
- if (Subtarget.is64Bit())
- return DAG.getNode(
- LoongArchISD::IOCSRWR_D, DL, MVT::Other, Op0, Op2,
- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(3)));
- else {
- DAG.getContext()->emitError(
- "llvm.loongarch.iocsrwr.d requires target: loongarch64");
- return Op.getOperand(0);
- }
+ return !Subtarget.is64Bit()
+ ? emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG)
+ : DAG.getNode(LoongArchISD::IOCSRWR_D, DL, MVT::Other, Chain,
+ Op2,
+ DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64,
+ Op.getOperand(3)));
}
#define ASRT_LE_GT_CASE(NAME) \
case Intrinsic::loongarch_##NAME: { \
- if (!Subtarget.is64Bit()) { \
- DAG.getContext()->emitError(Op->getOperationName(0) + \
- " requires target: loongarch64"); \
- return Op.getOperand(0); \
- } \
- return Op; \
+ return !Subtarget.is64Bit() \
+ ? emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG) \
+ : Op; \
}
ASRT_LE_GT_CASE(asrtle_d)
ASRT_LE_GT_CASE(asrtgt_d)
#undef ASRT_LE_GT_CASE
case Intrinsic::loongarch_ldpte_d: {
unsigned Imm = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue();
- if (!isUInt<8>(Imm))
- return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
- if (!Subtarget.is64Bit()) {
- DAG.getContext()->emitError(Op->getOperationName(0) +
- " requires target: loongarch64");
- return Op.getOperand(0);
- }
- return Op;
+ return !Subtarget.is64Bit()
+ ? emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG)
+ : !isUInt<8>(Imm) ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG)
+ : Op;
}
}
}
return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewRes);
}
+// Helper function that emits error message for intrinsics with chain and return
+// a UNDEF and the chain as the results.
+static void emitErrorAndReplaceIntrinsicWithChainResults(
+ SDNode *N, SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG,
+ StringRef ErrorMsg) {
+ DAG.getContext()->emitError(N->getOperationName(0) + ": " + ErrorMsg + ".");
+ Results.push_back(DAG.getUNDEF(N->getValueType(0)));
+ Results.push_back(N->getOperand(0));
+}
+
void LoongArchTargetLowering::ReplaceNodeResults(
SDNode *N, SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG) const {
SDLoc DL(N);
break;
}
case ISD::INTRINSIC_W_CHAIN: {
- SDValue Op0 = N->getOperand(0);
- EVT VT = N->getValueType(0);
- uint64_t Op1 = N->getConstantOperandVal(1);
+ SDValue Chain = N->getOperand(0);
+ SDValue Op2 = N->getOperand(2);
MVT GRLenVT = Subtarget.getGRLenVT();
- if (Op1 == Intrinsic::loongarch_movfcsr2gr) {
+ const StringRef ErrorMsgOOR = "argument out of range";
+ const StringRef ErrorMsgReqLA64 = "requires loongarch64";
+ const StringRef ErrorMsgReqF = "requires basic 'f' target feature";
+
+ switch (N->getConstantOperandVal(1)) {
+ default:
+ llvm_unreachable("Unexpected Intrinsic.");
+ case Intrinsic::loongarch_movfcsr2gr: {
if (!Subtarget.hasBasicF()) {
- DAG.getContext()->emitError(
- "llvm.loongarch.movfcsr2gr expects basic f target feature");
- Results.push_back(DAG.getMergeValues(
- {DAG.getUNDEF(N->getValueType(0)), N->getOperand(0)}, SDLoc(N)));
- Results.push_back(N->getOperand(0));
+ emitErrorAndReplaceIntrinsicWithChainResults(N, Results, DAG,
+ ErrorMsgReqF);
return;
}
- unsigned Imm = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue();
+ unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
if (!isUInt<2>(Imm)) {
- DAG.getContext()->emitError("argument to '" + N->getOperationName(0) +
- "' " + "out of range");
- Results.push_back(DAG.getMergeValues(
- {DAG.getUNDEF(N->getValueType(0)), N->getOperand(0)}, SDLoc(N)));
- Results.push_back(N->getOperand(0));
+ emitErrorAndReplaceIntrinsicWithChainResults(N, Results, DAG,
+ ErrorMsgOOR);
return;
}
Results.push_back(
DAG.getNode(ISD::TRUNCATE, DL, VT,
DAG.getNode(LoongArchISD::MOVFCSR2GR, SDLoc(N), MVT::i64,
DAG.getConstant(Imm, DL, GRLenVT))));
- Results.push_back(N->getOperand(0));
- return;
+ Results.push_back(Chain);
+ break;
}
- SDValue Op2 = N->getOperand(2);
- std::string Name = N->getOperationName(0);
-
- switch (Op1) {
- default:
- llvm_unreachable("Unexpected Intrinsic.");
#define CRC_CASE_EXT_BINARYOP(NAME, NODE) \
case Intrinsic::loongarch_##NAME: { \
Results.push_back(DAG.getNode( \
LoongArchISD::NODE, DL, MVT::i64, \
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3))))); \
- Results.push_back(N->getOperand(0)); \
+ Results.push_back(Chain); \
break; \
}
CRC_CASE_EXT_BINARYOP(crc_w_b_w, CRC_W_B_W)
DAG.getNode(LoongArchISD::NODE, DL, MVT::i64, Op2, \
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, \
N->getOperand(3))))); \
- Results.push_back(N->getOperand(0)); \
+ Results.push_back(Chain); \
break; \
}
CRC_CASE_EXT_UNARYOP(crc_w_d_w, CRC_W_D_W)
#undef CRC_CASE_EXT_UNARYOP
#define CSR_CASE(ID) \
case Intrinsic::loongarch_##ID: { \
- if (!Subtarget.is64Bit()) { \
- DAG.getContext()->emitError(Name + " requires target: loongarch64"); \
- Results.push_back(DAG.getUNDEF(VT)); \
- Results.push_back(N->getOperand(0)); \
- } \
+ if (!Subtarget.is64Bit()) \
+ emitErrorAndReplaceIntrinsicWithChainResults(N, Results, DAG, \
+ ErrorMsgReqLA64); \
break; \
}
CSR_CASE(csrrd_d);
case Intrinsic::loongarch_csrrd_w: {
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
if (!isUInt<14>(Imm)) {
- DAG.getContext()->emitError("argument to '" + Name + "' out of range");
- Results.push_back(DAG.getUNDEF(VT));
- Results.push_back(N->getOperand(0));
- break;
+ emitErrorAndReplaceIntrinsicWithChainResults(N, Results, DAG,
+ ErrorMsgOOR);
+ return;
}
-
Results.push_back(
DAG.getNode(ISD::TRUNCATE, DL, VT,
- DAG.getNode(LoongArchISD::CSRRD, DL, GRLenVT, Op0,
+ DAG.getNode(LoongArchISD::CSRRD, DL, GRLenVT, Chain,
DAG.getConstant(Imm, DL, GRLenVT))));
- Results.push_back(N->getOperand(0));
+ Results.push_back(Chain);
break;
}
case Intrinsic::loongarch_csrwr_w: {
unsigned Imm = cast<ConstantSDNode>(N->getOperand(3))->getZExtValue();
if (!isUInt<14>(Imm)) {
- DAG.getContext()->emitError("argument to '" + Name + "' out of range");
- Results.push_back(DAG.getUNDEF(VT));
- Results.push_back(N->getOperand(0));
- break;
+ emitErrorAndReplaceIntrinsicWithChainResults(N, Results, DAG,
+ ErrorMsgOOR);
+ return;
}
-
Results.push_back(DAG.getNode(
ISD::TRUNCATE, DL, VT,
- DAG.getNode(LoongArchISD::CSRWR, DL, GRLenVT, Op0,
+ DAG.getNode(LoongArchISD::CSRWR, DL, GRLenVT, Chain,
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2),
DAG.getConstant(Imm, DL, GRLenVT))));
- Results.push_back(N->getOperand(0));
+ Results.push_back(Chain);
break;
}
case Intrinsic::loongarch_csrxchg_w: {
unsigned Imm = cast<ConstantSDNode>(N->getOperand(4))->getZExtValue();
if (!isUInt<14>(Imm)) {
- DAG.getContext()->emitError("argument to '" + Name + "' out of range");
- Results.push_back(DAG.getUNDEF(VT));
- Results.push_back(N->getOperand(0));
- break;
+ emitErrorAndReplaceIntrinsicWithChainResults(N, Results, DAG,
+ ErrorMsgOOR);
+ return;
}
-
Results.push_back(DAG.getNode(
ISD::TRUNCATE, DL, VT,
DAG.getNode(
- LoongArchISD::CSRXCHG, DL, GRLenVT, Op0,
+ LoongArchISD::CSRXCHG, DL, GRLenVT, Chain,
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2),
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3)),
DAG.getConstant(Imm, DL, GRLenVT))));
- Results.push_back(N->getOperand(0));
+ Results.push_back(Chain);
break;
}
#define IOCSRRD_CASE(NAME, NODE) \
case Intrinsic::loongarch_##NAME: { \
Results.push_back(DAG.getNode( \
- ISD::TRUNCATE, DL, N->getValueType(0), \
- DAG.getNode(LoongArchISD::NODE, DL, MVT::i64, Op0, \
+ ISD::TRUNCATE, DL, VT, \
+ DAG.getNode(LoongArchISD::NODE, DL, MVT::i64, Chain, \
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2)))); \
- Results.push_back(N->getOperand(0)); \
+ Results.push_back(Chain); \
break; \
}
IOCSRRD_CASE(iocsrrd_b, IOCSRRD_B);
case Intrinsic::loongarch_cpucfg: {
Results.push_back(DAG.getNode(
ISD::TRUNCATE, DL, VT,
- DAG.getNode(LoongArchISD::CPUCFG, DL, GRLenVT, Op0,
+ DAG.getNode(LoongArchISD::CPUCFG, DL, GRLenVT, Chain,
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2))));
- Results.push_back(Op0);
+ Results.push_back(Chain);
break;
}
case Intrinsic::loongarch_lddir_d: {
if (!Subtarget.is64Bit()) {
- DAG.getContext()->emitError(N->getOperationName(0) +
- " requires target: loongarch64");
- Results.push_back(DAG.getUNDEF(VT));
- Results.push_back(Op0);
- break;
+ emitErrorAndReplaceIntrinsicWithChainResults(N, Results, DAG,
+ ErrorMsgReqLA64);
+ return;
}
break;
}