28#include "llvm/IR/IntrinsicsLoongArch.h"
37#define DEBUG_TYPE "loongarch-isel-lowering"
42 cl::desc(
"Trap on integer division by zero."),
60 MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64};
62 MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64, MVT::v8f32, MVT::v4f64};
69 for (
MVT VT : LASXVTs)
241 for (
MVT VT : LSXVTs) {
250 for (
MVT VT : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64}) {
261 for (
MVT VT : {MVT::v4f32, MVT::v2f64}) {
271 for (
MVT VT : LASXVTs) {
280 for (
MVT VT : {MVT::v4i64, MVT::v8i32, MVT::v16i16, MVT::v32i8}) {
291 for (
MVT VT : {MVT::v8f32, MVT::v4f64}) {
339 switch (
Op.getOpcode()) {
341 return lowerATOMIC_FENCE(
Op, DAG);
343 return lowerEH_DWARF_CFA(
Op, DAG);
345 return lowerGlobalAddress(
Op, DAG);
347 return lowerGlobalTLSAddress(
Op, DAG);
349 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
351 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
353 return lowerINTRINSIC_VOID(
Op, DAG);
355 return lowerBlockAddress(
Op, DAG);
357 return lowerJumpTable(
Op, DAG);
359 return lowerShiftLeftParts(
Op, DAG);
361 return lowerShiftRightParts(
Op, DAG,
true);
363 return lowerShiftRightParts(
Op, DAG,
false);
365 return lowerConstantPool(
Op, DAG);
367 return lowerFP_TO_SINT(
Op, DAG);
369 return lowerBITCAST(
Op, DAG);
371 return lowerUINT_TO_FP(
Op, DAG);
373 return lowerSINT_TO_FP(
Op, DAG);
375 return lowerVASTART(
Op, DAG);
377 return lowerFRAMEADDR(
Op, DAG);
379 return lowerRETURNADDR(
Op, DAG);
381 return lowerWRITE_REGISTER(
Op, DAG);
383 return lowerINSERT_VECTOR_ELT(
Op, DAG);
385 return lowerBUILD_VECTOR(
Op, DAG);
387 return lowerVECTOR_SHUFFLE(
Op, DAG);
401 if (isa<ConstantSDNode>(
Op))
403 if (isa<ConstantFPSDNode>(
Op))
418 EVT ResTy =
Op->getValueType(0);
420 APInt SplatValue, SplatUndef;
421 unsigned SplatBitSize;
426 if ((!Subtarget.
hasExtLSX() || !Is128Vec) &&
430 if (
Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
432 SplatBitSize <= 64) {
434 if (SplatBitSize != 8 && SplatBitSize != 16 && SplatBitSize != 32 &&
440 switch (SplatBitSize) {
444 ViaVecTy = Is128Vec ? MVT::v16i8 : MVT::v32i8;
447 ViaVecTy = Is128Vec ? MVT::v8i16 : MVT::v16i16;
450 ViaVecTy = Is128Vec ? MVT::v4i32 : MVT::v8i32;
453 ViaVecTy = Is128Vec ? MVT::v2i64 : MVT::v4i64;
461 if (ViaVecTy != ResTy)
474 EVT ResTy =
Node->getValueType(0);
480 for (
unsigned i = 0; i < NumElts; ++i) {
492LoongArchTargetLowering::lowerINSERT_VECTOR_ELT(
SDValue Op,
494 if (isa<ConstantSDNode>(
Op->getOperand(2)))
518 if (Subtarget.
is64Bit() &&
Op.getOperand(2).getValueType() == MVT::i32) {
520 "On LA64, only 64-bit registers can be written.");
521 return Op.getOperand(0);
524 if (!Subtarget.
is64Bit() &&
Op.getOperand(2).getValueType() == MVT::i64) {
526 "On LA32, only 32-bit registers can be written.");
527 return Op.getOperand(0);
535 if (!isa<ConstantSDNode>(
Op.getOperand(0))) {
537 "be a constant integer");
544 EVT VT =
Op.getValueType();
547 unsigned Depth = cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue();
548 int GRLenInBytes = Subtarget.
getGRLen() / 8;
551 int Offset = -(GRLenInBytes * 2);
566 if (cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue() != 0) {
568 "return address can only be determined for the current frame");
602 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
610 !Subtarget.
hasBasicD() &&
"unexpected target features");
615 auto *
C = dyn_cast<ConstantSDNode>(Op0.
getOperand(1));
616 if (
C &&
C->getZExtValue() < UINT64_C(0xFFFFFFFF))
626 dyn_cast<VTSDNode>(Op0.
getOperand(1))->getVT().bitsLT(MVT::i32))
630 EVT RetVT =
Op.getValueType();
632 MakeLibCallOptions CallOptions;
633 CallOptions.setTypeListBeforeSoften(OpVT, RetVT,
true);
636 std::tie(Result, Chain) =
644 !Subtarget.
hasBasicD() &&
"unexpected target features");
651 dyn_cast<VTSDNode>(Op0.
getOperand(1))->getVT().bitsLE(MVT::i32))
655 EVT RetVT =
Op.getValueType();
657 MakeLibCallOptions CallOptions;
658 CallOptions.setTypeListBeforeSoften(OpVT, RetVT,
true);
661 std::tie(Result, Chain) =
672 if (
Op.getValueType() == MVT::f32 && Op0.
getValueType() == MVT::i32 &&
685 if (
Op.getValueSizeInBits() > 32 && Subtarget.
hasBasicF() &&
711 N->getOffset(), Flags);
719template <
class NodeTy>
721 bool IsLocal)
const {
731 assert(Subtarget.
is64Bit() &&
"Large code model requires LA64");
767 return getAddr(cast<BlockAddressSDNode>(
Op), DAG);
772 return getAddr(cast<JumpTableSDNode>(
Op), DAG);
777 return getAddr(cast<ConstantPoolSDNode>(
Op), DAG);
783 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
784 return getAddr(
N, DAG,
N->getGlobal()->isDSOLocal());
830 Args.push_back(Entry);
844LoongArchTargetLowering::lowerGlobalTLSAddress(
SDValue Op,
851 assert((!Large || Subtarget.
is64Bit()) &&
"Large code model requires LA64");
854 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
862 Addr = getDynamicTLSAddr(
N, DAG,
863 Large ? LoongArch::PseudoLA_TLS_GD_LARGE
864 : LoongArch::PseudoLA_TLS_GD,
870 Addr = getDynamicTLSAddr(
N, DAG,
871 Large ? LoongArch::PseudoLA_TLS_LD_LARGE
872 : LoongArch::PseudoLA_TLS_LD,
877 Addr = getStaticTLSAddr(
N, DAG,
878 Large ? LoongArch::PseudoLA_TLS_IE_LARGE
879 : LoongArch::PseudoLA_TLS_IE,
887 Addr = getStaticTLSAddr(
N, DAG, LoongArch::PseudoLA_TLS_LE);
897 auto *CImm = cast<ConstantSDNode>(
Op->getOperand(ImmOp));
899 if ((IsSigned && !isInt<N>(CImm->getSExtValue())) ||
900 (!IsSigned && !isUInt<N>(CImm->getZExtValue()))) {
902 ": argument out of range.");
909LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
912 switch (
Op.getConstantOperandVal(0)) {
915 case Intrinsic::thread_pointer: {
919 case Intrinsic::loongarch_lsx_vpickve2gr_d:
920 case Intrinsic::loongarch_lsx_vpickve2gr_du:
921 case Intrinsic::loongarch_lsx_vreplvei_d:
922 case Intrinsic::loongarch_lasx_xvrepl128vei_d:
923 return checkIntrinsicImmArg<1>(
Op, 2, DAG);
924 case Intrinsic::loongarch_lsx_vreplvei_w:
925 case Intrinsic::loongarch_lasx_xvrepl128vei_w:
926 case Intrinsic::loongarch_lasx_xvpickve2gr_d:
927 case Intrinsic::loongarch_lasx_xvpickve2gr_du:
928 case Intrinsic::loongarch_lasx_xvpickve_d:
929 case Intrinsic::loongarch_lasx_xvpickve_d_f:
930 return checkIntrinsicImmArg<2>(
Op, 2, DAG);
931 case Intrinsic::loongarch_lasx_xvinsve0_d:
932 return checkIntrinsicImmArg<2>(
Op, 3, DAG);
933 case Intrinsic::loongarch_lsx_vsat_b:
934 case Intrinsic::loongarch_lsx_vsat_bu:
935 case Intrinsic::loongarch_lsx_vrotri_b:
936 case Intrinsic::loongarch_lsx_vsllwil_h_b:
937 case Intrinsic::loongarch_lsx_vsllwil_hu_bu:
938 case Intrinsic::loongarch_lsx_vsrlri_b:
939 case Intrinsic::loongarch_lsx_vsrari_b:
940 case Intrinsic::loongarch_lsx_vreplvei_h:
941 case Intrinsic::loongarch_lasx_xvsat_b:
942 case Intrinsic::loongarch_lasx_xvsat_bu:
943 case Intrinsic::loongarch_lasx_xvrotri_b:
944 case Intrinsic::loongarch_lasx_xvsllwil_h_b:
945 case Intrinsic::loongarch_lasx_xvsllwil_hu_bu:
946 case Intrinsic::loongarch_lasx_xvsrlri_b:
947 case Intrinsic::loongarch_lasx_xvsrari_b:
948 case Intrinsic::loongarch_lasx_xvrepl128vei_h:
949 case Intrinsic::loongarch_lasx_xvpickve_w:
950 case Intrinsic::loongarch_lasx_xvpickve_w_f:
951 return checkIntrinsicImmArg<3>(
Op, 2, DAG);
952 case Intrinsic::loongarch_lasx_xvinsve0_w:
953 return checkIntrinsicImmArg<3>(
Op, 3, DAG);
954 case Intrinsic::loongarch_lsx_vsat_h:
955 case Intrinsic::loongarch_lsx_vsat_hu:
956 case Intrinsic::loongarch_lsx_vrotri_h:
957 case Intrinsic::loongarch_lsx_vsllwil_w_h:
958 case Intrinsic::loongarch_lsx_vsllwil_wu_hu:
959 case Intrinsic::loongarch_lsx_vsrlri_h:
960 case Intrinsic::loongarch_lsx_vsrari_h:
961 case Intrinsic::loongarch_lsx_vreplvei_b:
962 case Intrinsic::loongarch_lasx_xvsat_h:
963 case Intrinsic::loongarch_lasx_xvsat_hu:
964 case Intrinsic::loongarch_lasx_xvrotri_h:
965 case Intrinsic::loongarch_lasx_xvsllwil_w_h:
966 case Intrinsic::loongarch_lasx_xvsllwil_wu_hu:
967 case Intrinsic::loongarch_lasx_xvsrlri_h:
968 case Intrinsic::loongarch_lasx_xvsrari_h:
969 case Intrinsic::loongarch_lasx_xvrepl128vei_b:
970 return checkIntrinsicImmArg<4>(
Op, 2, DAG);
971 case Intrinsic::loongarch_lsx_vsrlni_b_h:
972 case Intrinsic::loongarch_lsx_vsrani_b_h:
973 case Intrinsic::loongarch_lsx_vsrlrni_b_h:
974 case Intrinsic::loongarch_lsx_vsrarni_b_h:
975 case Intrinsic::loongarch_lsx_vssrlni_b_h:
976 case Intrinsic::loongarch_lsx_vssrani_b_h:
977 case Intrinsic::loongarch_lsx_vssrlni_bu_h:
978 case Intrinsic::loongarch_lsx_vssrani_bu_h:
979 case Intrinsic::loongarch_lsx_vssrlrni_b_h:
980 case Intrinsic::loongarch_lsx_vssrarni_b_h:
981 case Intrinsic::loongarch_lsx_vssrlrni_bu_h:
982 case Intrinsic::loongarch_lsx_vssrarni_bu_h:
983 case Intrinsic::loongarch_lasx_xvsrlni_b_h:
984 case Intrinsic::loongarch_lasx_xvsrani_b_h:
985 case Intrinsic::loongarch_lasx_xvsrlrni_b_h:
986 case Intrinsic::loongarch_lasx_xvsrarni_b_h:
987 case Intrinsic::loongarch_lasx_xvssrlni_b_h:
988 case Intrinsic::loongarch_lasx_xvssrani_b_h:
989 case Intrinsic::loongarch_lasx_xvssrlni_bu_h:
990 case Intrinsic::loongarch_lasx_xvssrani_bu_h:
991 case Intrinsic::loongarch_lasx_xvssrlrni_b_h:
992 case Intrinsic::loongarch_lasx_xvssrarni_b_h:
993 case Intrinsic::loongarch_lasx_xvssrlrni_bu_h:
994 case Intrinsic::loongarch_lasx_xvssrarni_bu_h:
995 return checkIntrinsicImmArg<4>(
Op, 3, DAG);
996 case Intrinsic::loongarch_lsx_vsat_w:
997 case Intrinsic::loongarch_lsx_vsat_wu:
998 case Intrinsic::loongarch_lsx_vrotri_w:
999 case Intrinsic::loongarch_lsx_vsllwil_d_w:
1000 case Intrinsic::loongarch_lsx_vsllwil_du_wu:
1001 case Intrinsic::loongarch_lsx_vsrlri_w:
1002 case Intrinsic::loongarch_lsx_vsrari_w:
1003 case Intrinsic::loongarch_lsx_vslei_bu:
1004 case Intrinsic::loongarch_lsx_vslei_hu:
1005 case Intrinsic::loongarch_lsx_vslei_wu:
1006 case Intrinsic::loongarch_lsx_vslei_du:
1007 case Intrinsic::loongarch_lsx_vslti_bu:
1008 case Intrinsic::loongarch_lsx_vslti_hu:
1009 case Intrinsic::loongarch_lsx_vslti_wu:
1010 case Intrinsic::loongarch_lsx_vslti_du:
1011 case Intrinsic::loongarch_lsx_vbsll_v:
1012 case Intrinsic::loongarch_lsx_vbsrl_v:
1013 case Intrinsic::loongarch_lasx_xvsat_w:
1014 case Intrinsic::loongarch_lasx_xvsat_wu:
1015 case Intrinsic::loongarch_lasx_xvrotri_w:
1016 case Intrinsic::loongarch_lasx_xvsllwil_d_w:
1017 case Intrinsic::loongarch_lasx_xvsllwil_du_wu:
1018 case Intrinsic::loongarch_lasx_xvsrlri_w:
1019 case Intrinsic::loongarch_lasx_xvsrari_w:
1020 case Intrinsic::loongarch_lasx_xvslei_bu:
1021 case Intrinsic::loongarch_lasx_xvslei_hu:
1022 case Intrinsic::loongarch_lasx_xvslei_wu:
1023 case Intrinsic::loongarch_lasx_xvslei_du:
1024 case Intrinsic::loongarch_lasx_xvslti_bu:
1025 case Intrinsic::loongarch_lasx_xvslti_hu:
1026 case Intrinsic::loongarch_lasx_xvslti_wu:
1027 case Intrinsic::loongarch_lasx_xvslti_du:
1028 case Intrinsic::loongarch_lasx_xvbsll_v:
1029 case Intrinsic::loongarch_lasx_xvbsrl_v:
1030 return checkIntrinsicImmArg<5>(
Op, 2, DAG);
1031 case Intrinsic::loongarch_lsx_vseqi_b:
1032 case Intrinsic::loongarch_lsx_vseqi_h:
1033 case Intrinsic::loongarch_lsx_vseqi_w:
1034 case Intrinsic::loongarch_lsx_vseqi_d:
1035 case Intrinsic::loongarch_lsx_vslei_b:
1036 case Intrinsic::loongarch_lsx_vslei_h:
1037 case Intrinsic::loongarch_lsx_vslei_w:
1038 case Intrinsic::loongarch_lsx_vslei_d:
1039 case Intrinsic::loongarch_lsx_vslti_b:
1040 case Intrinsic::loongarch_lsx_vslti_h:
1041 case Intrinsic::loongarch_lsx_vslti_w:
1042 case Intrinsic::loongarch_lsx_vslti_d:
1043 case Intrinsic::loongarch_lasx_xvseqi_b:
1044 case Intrinsic::loongarch_lasx_xvseqi_h:
1045 case Intrinsic::loongarch_lasx_xvseqi_w:
1046 case Intrinsic::loongarch_lasx_xvseqi_d:
1047 case Intrinsic::loongarch_lasx_xvslei_b:
1048 case Intrinsic::loongarch_lasx_xvslei_h:
1049 case Intrinsic::loongarch_lasx_xvslei_w:
1050 case Intrinsic::loongarch_lasx_xvslei_d:
1051 case Intrinsic::loongarch_lasx_xvslti_b:
1052 case Intrinsic::loongarch_lasx_xvslti_h:
1053 case Intrinsic::loongarch_lasx_xvslti_w:
1054 case Intrinsic::loongarch_lasx_xvslti_d:
1055 return checkIntrinsicImmArg<5>(
Op, 2, DAG,
true);
1056 case Intrinsic::loongarch_lsx_vsrlni_h_w:
1057 case Intrinsic::loongarch_lsx_vsrani_h_w:
1058 case Intrinsic::loongarch_lsx_vsrlrni_h_w:
1059 case Intrinsic::loongarch_lsx_vsrarni_h_w:
1060 case Intrinsic::loongarch_lsx_vssrlni_h_w:
1061 case Intrinsic::loongarch_lsx_vssrani_h_w:
1062 case Intrinsic::loongarch_lsx_vssrlni_hu_w:
1063 case Intrinsic::loongarch_lsx_vssrani_hu_w:
1064 case Intrinsic::loongarch_lsx_vssrlrni_h_w:
1065 case Intrinsic::loongarch_lsx_vssrarni_h_w:
1066 case Intrinsic::loongarch_lsx_vssrlrni_hu_w:
1067 case Intrinsic::loongarch_lsx_vssrarni_hu_w:
1068 case Intrinsic::loongarch_lsx_vfrstpi_b:
1069 case Intrinsic::loongarch_lsx_vfrstpi_h:
1070 case Intrinsic::loongarch_lasx_xvsrlni_h_w:
1071 case Intrinsic::loongarch_lasx_xvsrani_h_w:
1072 case Intrinsic::loongarch_lasx_xvsrlrni_h_w:
1073 case Intrinsic::loongarch_lasx_xvsrarni_h_w:
1074 case Intrinsic::loongarch_lasx_xvssrlni_h_w:
1075 case Intrinsic::loongarch_lasx_xvssrani_h_w:
1076 case Intrinsic::loongarch_lasx_xvssrlni_hu_w:
1077 case Intrinsic::loongarch_lasx_xvssrani_hu_w:
1078 case Intrinsic::loongarch_lasx_xvssrlrni_h_w:
1079 case Intrinsic::loongarch_lasx_xvssrarni_h_w:
1080 case Intrinsic::loongarch_lasx_xvssrlrni_hu_w:
1081 case Intrinsic::loongarch_lasx_xvssrarni_hu_w:
1082 case Intrinsic::loongarch_lasx_xvfrstpi_b:
1083 case Intrinsic::loongarch_lasx_xvfrstpi_h:
1084 return checkIntrinsicImmArg<5>(
Op, 3, DAG);
1085 case Intrinsic::loongarch_lsx_vsat_d:
1086 case Intrinsic::loongarch_lsx_vsat_du:
1087 case Intrinsic::loongarch_lsx_vrotri_d:
1088 case Intrinsic::loongarch_lsx_vsrlri_d:
1089 case Intrinsic::loongarch_lsx_vsrari_d:
1090 case Intrinsic::loongarch_lasx_xvsat_d:
1091 case Intrinsic::loongarch_lasx_xvsat_du:
1092 case Intrinsic::loongarch_lasx_xvrotri_d:
1093 case Intrinsic::loongarch_lasx_xvsrlri_d:
1094 case Intrinsic::loongarch_lasx_xvsrari_d:
1095 return checkIntrinsicImmArg<6>(
Op, 2, DAG);
1096 case Intrinsic::loongarch_lsx_vsrlni_w_d:
1097 case Intrinsic::loongarch_lsx_vsrani_w_d:
1098 case Intrinsic::loongarch_lsx_vsrlrni_w_d:
1099 case Intrinsic::loongarch_lsx_vsrarni_w_d:
1100 case Intrinsic::loongarch_lsx_vssrlni_w_d:
1101 case Intrinsic::loongarch_lsx_vssrani_w_d:
1102 case Intrinsic::loongarch_lsx_vssrlni_wu_d:
1103 case Intrinsic::loongarch_lsx_vssrani_wu_d:
1104 case Intrinsic::loongarch_lsx_vssrlrni_w_d:
1105 case Intrinsic::loongarch_lsx_vssrarni_w_d:
1106 case Intrinsic::loongarch_lsx_vssrlrni_wu_d:
1107 case Intrinsic::loongarch_lsx_vssrarni_wu_d:
1108 case Intrinsic::loongarch_lasx_xvsrlni_w_d:
1109 case Intrinsic::loongarch_lasx_xvsrani_w_d:
1110 case Intrinsic::loongarch_lasx_xvsrlrni_w_d:
1111 case Intrinsic::loongarch_lasx_xvsrarni_w_d:
1112 case Intrinsic::loongarch_lasx_xvssrlni_w_d:
1113 case Intrinsic::loongarch_lasx_xvssrani_w_d:
1114 case Intrinsic::loongarch_lasx_xvssrlni_wu_d:
1115 case Intrinsic::loongarch_lasx_xvssrani_wu_d:
1116 case Intrinsic::loongarch_lasx_xvssrlrni_w_d:
1117 case Intrinsic::loongarch_lasx_xvssrarni_w_d:
1118 case Intrinsic::loongarch_lasx_xvssrlrni_wu_d:
1119 case Intrinsic::loongarch_lasx_xvssrarni_wu_d:
1120 return checkIntrinsicImmArg<6>(
Op, 3, DAG);
1121 case Intrinsic::loongarch_lsx_vsrlni_d_q:
1122 case Intrinsic::loongarch_lsx_vsrani_d_q:
1123 case Intrinsic::loongarch_lsx_vsrlrni_d_q:
1124 case Intrinsic::loongarch_lsx_vsrarni_d_q:
1125 case Intrinsic::loongarch_lsx_vssrlni_d_q:
1126 case Intrinsic::loongarch_lsx_vssrani_d_q:
1127 case Intrinsic::loongarch_lsx_vssrlni_du_q:
1128 case Intrinsic::loongarch_lsx_vssrani_du_q:
1129 case Intrinsic::loongarch_lsx_vssrlrni_d_q:
1130 case Intrinsic::loongarch_lsx_vssrarni_d_q:
1131 case Intrinsic::loongarch_lsx_vssrlrni_du_q:
1132 case Intrinsic::loongarch_lsx_vssrarni_du_q:
1133 case Intrinsic::loongarch_lasx_xvsrlni_d_q:
1134 case Intrinsic::loongarch_lasx_xvsrani_d_q:
1135 case Intrinsic::loongarch_lasx_xvsrlrni_d_q:
1136 case Intrinsic::loongarch_lasx_xvsrarni_d_q:
1137 case Intrinsic::loongarch_lasx_xvssrlni_d_q:
1138 case Intrinsic::loongarch_lasx_xvssrani_d_q:
1139 case Intrinsic::loongarch_lasx_xvssrlni_du_q:
1140 case Intrinsic::loongarch_lasx_xvssrani_du_q:
1141 case Intrinsic::loongarch_lasx_xvssrlrni_d_q:
1142 case Intrinsic::loongarch_lasx_xvssrarni_d_q:
1143 case Intrinsic::loongarch_lasx_xvssrlrni_du_q:
1144 case Intrinsic::loongarch_lasx_xvssrarni_du_q:
1145 return checkIntrinsicImmArg<7>(
Op, 3, DAG);
1146 case Intrinsic::loongarch_lsx_vnori_b:
1147 case Intrinsic::loongarch_lsx_vshuf4i_b:
1148 case Intrinsic::loongarch_lsx_vshuf4i_h:
1149 case Intrinsic::loongarch_lsx_vshuf4i_w:
1150 case Intrinsic::loongarch_lasx_xvnori_b:
1151 case Intrinsic::loongarch_lasx_xvshuf4i_b:
1152 case Intrinsic::loongarch_lasx_xvshuf4i_h:
1153 case Intrinsic::loongarch_lasx_xvshuf4i_w:
1154 case Intrinsic::loongarch_lasx_xvpermi_d:
1155 return checkIntrinsicImmArg<8>(
Op, 2, DAG);
1156 case Intrinsic::loongarch_lsx_vshuf4i_d:
1157 case Intrinsic::loongarch_lsx_vpermi_w:
1158 case Intrinsic::loongarch_lsx_vbitseli_b:
1159 case Intrinsic::loongarch_lsx_vextrins_b:
1160 case Intrinsic::loongarch_lsx_vextrins_h:
1161 case Intrinsic::loongarch_lsx_vextrins_w:
1162 case Intrinsic::loongarch_lsx_vextrins_d:
1163 case Intrinsic::loongarch_lasx_xvshuf4i_d:
1164 case Intrinsic::loongarch_lasx_xvpermi_w:
1165 case Intrinsic::loongarch_lasx_xvpermi_q:
1166 case Intrinsic::loongarch_lasx_xvbitseli_b:
1167 case Intrinsic::loongarch_lasx_xvextrins_b:
1168 case Intrinsic::loongarch_lasx_xvextrins_h:
1169 case Intrinsic::loongarch_lasx_xvextrins_w:
1170 case Intrinsic::loongarch_lasx_xvextrins_d:
1171 return checkIntrinsicImmArg<8>(
Op, 3, DAG);
1172 case Intrinsic::loongarch_lsx_vrepli_b:
1173 case Intrinsic::loongarch_lsx_vrepli_h:
1174 case Intrinsic::loongarch_lsx_vrepli_w:
1175 case Intrinsic::loongarch_lsx_vrepli_d:
1176 case Intrinsic::loongarch_lasx_xvrepli_b:
1177 case Intrinsic::loongarch_lasx_xvrepli_h:
1178 case Intrinsic::loongarch_lasx_xvrepli_w:
1179 case Intrinsic::loongarch_lasx_xvrepli_d:
1180 return checkIntrinsicImmArg<10>(
Op, 1, DAG,
true);
1181 case Intrinsic::loongarch_lsx_vldi:
1182 case Intrinsic::loongarch_lasx_xvldi:
1183 return checkIntrinsicImmArg<13>(
Op, 1, DAG,
true);
1198LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
1202 EVT VT =
Op.getValueType();
1204 const StringRef ErrorMsgOOR =
"argument out of range";
1205 const StringRef ErrorMsgReqLA64 =
"requires loongarch64";
1206 const StringRef ErrorMsgReqF =
"requires basic 'f' target feature";
1208 switch (
Op.getConstantOperandVal(1)) {
1211 case Intrinsic::loongarch_crc_w_b_w:
1212 case Intrinsic::loongarch_crc_w_h_w:
1213 case Intrinsic::loongarch_crc_w_w_w:
1214 case Intrinsic::loongarch_crc_w_d_w:
1215 case Intrinsic::loongarch_crcc_w_b_w:
1216 case Intrinsic::loongarch_crcc_w_h_w:
1217 case Intrinsic::loongarch_crcc_w_w_w:
1218 case Intrinsic::loongarch_crcc_w_d_w:
1220 case Intrinsic::loongarch_csrrd_w:
1221 case Intrinsic::loongarch_csrrd_d: {
1222 unsigned Imm = cast<ConstantSDNode>(
Op.getOperand(2))->getZExtValue();
1223 return !isUInt<14>(Imm)
1225 : DAG.getNode(LoongArchISD::
CSRRD,
DL, {GRLenVT, MVT::Other},
1228 case Intrinsic::loongarch_csrwr_w:
1229 case Intrinsic::loongarch_csrwr_d: {
1230 unsigned Imm = cast<ConstantSDNode>(
Op.getOperand(3))->getZExtValue();
1231 return !isUInt<14>(Imm)
1233 : DAG.getNode(LoongArchISD::
CSRWR,
DL, {GRLenVT, MVT::Other},
1234 {Chain,
Op.getOperand(2),
1237 case Intrinsic::loongarch_csrxchg_w:
1238 case Intrinsic::loongarch_csrxchg_d: {
1239 unsigned Imm = cast<ConstantSDNode>(
Op.getOperand(4))->getZExtValue();
1240 return !isUInt<14>(Imm)
1242 : DAG.getNode(LoongArchISD::
CSRXCHG,
DL, {GRLenVT, MVT::Other},
1243 {Chain,
Op.getOperand(2),
Op.getOperand(3),
1246 case Intrinsic::loongarch_iocsrrd_d: {
1251#define IOCSRRD_CASE(NAME, NODE) \
1252 case Intrinsic::loongarch_##NAME: { \
1253 return DAG.getNode(LoongArchISD::NODE, DL, {GRLenVT, MVT::Other}, \
1254 {Chain, Op.getOperand(2)}); \
1260 case Intrinsic::loongarch_cpucfg: {
1262 {Chain,
Op.getOperand(2)});
1264 case Intrinsic::loongarch_lddir_d: {
1265 unsigned Imm = cast<ConstantSDNode>(
Op.getOperand(3))->getZExtValue();
1266 return !isUInt<8>(Imm)
1270 case Intrinsic::loongarch_movfcsr2gr: {
1273 unsigned Imm = cast<ConstantSDNode>(
Op.getOperand(2))->getZExtValue();
1274 return !isUInt<2>(Imm)
1276 : DAG.getNode(LoongArchISD::
MOVFCSR2GR,
DL, {VT, MVT::Other},
1279 case Intrinsic::loongarch_lsx_vld:
1280 case Intrinsic::loongarch_lsx_vldrepl_b:
1281 case Intrinsic::loongarch_lasx_xvld:
1282 case Intrinsic::loongarch_lasx_xvldrepl_b:
1283 return !isInt<12>(cast<ConstantSDNode>(
Op.getOperand(3))->getSExtValue())
1286 case Intrinsic::loongarch_lsx_vldrepl_h:
1287 case Intrinsic::loongarch_lasx_xvldrepl_h:
1288 return !isShiftedInt<11, 1>(
1289 cast<ConstantSDNode>(
Op.getOperand(3))->getSExtValue())
1291 Op,
"argument out of range or not a multiple of 2", DAG)
1293 case Intrinsic::loongarch_lsx_vldrepl_w:
1294 case Intrinsic::loongarch_lasx_xvldrepl_w:
1295 return !isShiftedInt<10, 2>(
1296 cast<ConstantSDNode>(
Op.getOperand(3))->getSExtValue())
1298 Op,
"argument out of range or not a multiple of 4", DAG)
1300 case Intrinsic::loongarch_lsx_vldrepl_d:
1301 case Intrinsic::loongarch_lasx_xvldrepl_d:
1302 return !isShiftedInt<9, 3>(
1303 cast<ConstantSDNode>(
Op.getOperand(3))->getSExtValue())
1305 Op,
"argument out of range or not a multiple of 8", DAG)
1316 return Op.getOperand(0);
1324 uint64_t IntrinsicEnum =
Op.getConstantOperandVal(1);
1326 const StringRef ErrorMsgOOR =
"argument out of range";
1327 const StringRef ErrorMsgReqLA64 =
"requires loongarch64";
1328 const StringRef ErrorMsgReqLA32 =
"requires loongarch32";
1329 const StringRef ErrorMsgReqF =
"requires basic 'f' target feature";
1331 switch (IntrinsicEnum) {
1335 case Intrinsic::loongarch_cacop_d:
1336 case Intrinsic::loongarch_cacop_w: {
1337 if (IntrinsicEnum == Intrinsic::loongarch_cacop_d && !Subtarget.
is64Bit())
1339 if (IntrinsicEnum == Intrinsic::loongarch_cacop_w && Subtarget.
is64Bit())
1342 unsigned Imm1 = cast<ConstantSDNode>(Op2)->getZExtValue();
1343 int Imm2 = cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue();
1344 if (!isUInt<5>(Imm1) || !isInt<12>(Imm2))
1348 case Intrinsic::loongarch_dbar: {
1349 unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
1350 return !isUInt<15>(Imm)
1353 DAG.getConstant(
Imm,
DL, GRLenVT));
1355 case Intrinsic::loongarch_ibar: {
1356 unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
1357 return !isUInt<15>(Imm)
1360 DAG.getConstant(
Imm,
DL, GRLenVT));
1362 case Intrinsic::loongarch_break: {
1363 unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
1364 return !isUInt<15>(Imm)
1367 DAG.getConstant(
Imm,
DL, GRLenVT));
1369 case Intrinsic::loongarch_movgr2fcsr: {
1372 unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
1373 return !isUInt<2>(Imm)
1376 DAG.getConstant(
Imm,
DL, GRLenVT),
1380 case Intrinsic::loongarch_syscall: {
1381 unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
1382 return !isUInt<15>(Imm)
1385 DAG.getConstant(
Imm,
DL, GRLenVT));
1387#define IOCSRWR_CASE(NAME, NODE) \
1388 case Intrinsic::loongarch_##NAME: { \
1389 SDValue Op3 = Op.getOperand(3); \
1390 return Subtarget.is64Bit() \
1391 ? DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Chain, \
1392 DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \
1393 DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op3)) \
1394 : DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Chain, Op2, \
1401 case Intrinsic::loongarch_iocsrwr_d: {
1409#define ASRT_LE_GT_CASE(NAME) \
1410 case Intrinsic::loongarch_##NAME: { \
1411 return !Subtarget.is64Bit() \
1412 ? emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG) \
1417#undef ASRT_LE_GT_CASE
1418 case Intrinsic::loongarch_ldpte_d: {
1419 unsigned Imm = cast<ConstantSDNode>(
Op.getOperand(3))->getZExtValue();
1425 case Intrinsic::loongarch_lsx_vst:
1426 case Intrinsic::loongarch_lasx_xvst:
1427 return !isInt<12>(cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue())
1430 case Intrinsic::loongarch_lasx_xvstelm_b:
1431 return (!isInt<8>(cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1432 !isUInt<5>(cast<ConstantSDNode>(
Op.getOperand(5))->getZExtValue()))
1435 case Intrinsic::loongarch_lsx_vstelm_b:
1436 return (!isInt<8>(cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1437 !isUInt<4>(cast<ConstantSDNode>(
Op.getOperand(5))->getZExtValue()))
1440 case Intrinsic::loongarch_lasx_xvstelm_h:
1441 return (!isShiftedInt<8, 1>(
1442 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1443 !isUInt<4>(cast<ConstantSDNode>(
Op.getOperand(5))->getZExtValue()))
1445 Op,
"argument out of range or not a multiple of 2", DAG)
1447 case Intrinsic::loongarch_lsx_vstelm_h:
1448 return (!isShiftedInt<8, 1>(
1449 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1450 !isUInt<3>(cast<ConstantSDNode>(
Op.getOperand(5))->getZExtValue()))
1452 Op,
"argument out of range or not a multiple of 2", DAG)
1454 case Intrinsic::loongarch_lasx_xvstelm_w:
1455 return (!isShiftedInt<8, 2>(
1456 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1457 !isUInt<3>(cast<ConstantSDNode>(
Op.getOperand(5))->getZExtValue()))
1459 Op,
"argument out of range or not a multiple of 4", DAG)
1461 case Intrinsic::loongarch_lsx_vstelm_w:
1462 return (!isShiftedInt<8, 2>(
1463 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1464 !isUInt<2>(cast<ConstantSDNode>(
Op.getOperand(5))->getZExtValue()))
1466 Op,
"argument out of range or not a multiple of 4", DAG)
1468 case Intrinsic::loongarch_lasx_xvstelm_d:
1469 return (!isShiftedInt<8, 3>(
1470 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1471 !isUInt<2>(cast<ConstantSDNode>(
Op.getOperand(5))->getZExtValue()))
1473 Op,
"argument out of range or not a multiple of 8", DAG)
1475 case Intrinsic::loongarch_lsx_vstelm_d:
1476 return (!isShiftedInt<8, 3>(
1477 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1478 !isUInt<1>(cast<ConstantSDNode>(
Op.getOperand(5))->getZExtValue()))
1480 Op,
"argument out of range or not a multiple of 8", DAG)
1491 EVT VT =
Lo.getValueType();
1531 EVT VT =
Lo.getValueType();
1615 NewOp0 = DAG.
getNode(ExtOpc,
DL, MVT::i64,
N->getOperand(0));
1616 NewRes = DAG.
getNode(WOpcode,
DL, MVT::i64, NewOp0);
1620 NewOp0 = DAG.
getNode(ExtOpc,
DL, MVT::i64,
N->getOperand(0));
1622 NewRes = DAG.
getNode(WOpcode,
DL, MVT::i64, NewOp0, NewOp1);
1637 StringRef ErrorMsg,
bool WithChain =
true) {
1642 Results.push_back(
N->getOperand(0));
1645template <
unsigned N>
1650 const StringRef ErrorMsgOOR =
"argument out of range";
1651 unsigned Imm = cast<ConstantSDNode>(
Node->getOperand(2))->getZExtValue();
1652 if (!isUInt<N>(Imm)) {
1685 switch (
N->getConstantOperandVal(0)) {
1688 case Intrinsic::loongarch_lsx_vpickve2gr_b:
1689 replaceVPICKVE2GRResults<4>(
N,
Results, DAG, Subtarget,
1692 case Intrinsic::loongarch_lsx_vpickve2gr_h:
1693 case Intrinsic::loongarch_lasx_xvpickve2gr_w:
1694 replaceVPICKVE2GRResults<3>(
N,
Results, DAG, Subtarget,
1697 case Intrinsic::loongarch_lsx_vpickve2gr_w:
1698 replaceVPICKVE2GRResults<2>(
N,
Results, DAG, Subtarget,
1701 case Intrinsic::loongarch_lsx_vpickve2gr_bu:
1702 replaceVPICKVE2GRResults<4>(
N,
Results, DAG, Subtarget,
1705 case Intrinsic::loongarch_lsx_vpickve2gr_hu:
1706 case Intrinsic::loongarch_lasx_xvpickve2gr_wu:
1707 replaceVPICKVE2GRResults<3>(
N,
Results, DAG, Subtarget,
1710 case Intrinsic::loongarch_lsx_vpickve2gr_wu:
1711 replaceVPICKVE2GRResults<2>(
N,
Results, DAG, Subtarget,
1714 case Intrinsic::loongarch_lsx_bz_b:
1715 case Intrinsic::loongarch_lsx_bz_h:
1716 case Intrinsic::loongarch_lsx_bz_w:
1717 case Intrinsic::loongarch_lsx_bz_d:
1718 case Intrinsic::loongarch_lasx_xbz_b:
1719 case Intrinsic::loongarch_lasx_xbz_h:
1720 case Intrinsic::loongarch_lasx_xbz_w:
1721 case Intrinsic::loongarch_lasx_xbz_d:
1725 case Intrinsic::loongarch_lsx_bz_v:
1726 case Intrinsic::loongarch_lasx_xbz_v:
1730 case Intrinsic::loongarch_lsx_bnz_b:
1731 case Intrinsic::loongarch_lsx_bnz_h:
1732 case Intrinsic::loongarch_lsx_bnz_w:
1733 case Intrinsic::loongarch_lsx_bnz_d:
1734 case Intrinsic::loongarch_lasx_xbnz_b:
1735 case Intrinsic::loongarch_lasx_xbnz_h:
1736 case Intrinsic::loongarch_lasx_xbnz_w:
1737 case Intrinsic::loongarch_lasx_xbnz_d:
1741 case Intrinsic::loongarch_lsx_bnz_v:
1742 case Intrinsic::loongarch_lasx_xbnz_v:
1752 EVT VT =
N->getValueType(0);
1753 switch (
N->getOpcode()) {
1761 "Unexpected custom legalisation");
1769 if ((CN = dyn_cast<ConstantSDNode>(
N->getOperand(1)))) {
1776 "Unexpected custom legalisation");
1790 EVT OpVT = Src.getValueType();
1794 std::tie(Result, Chain) =
1801 EVT SrcVT = Src.getValueType();
1802 if (VT == MVT::i32 && SrcVT == MVT::f32 && Subtarget.
is64Bit() &&
1812 "Unexpected custom legalisation");
1815 TLI.expandFP_TO_UINT(
N, Tmp1, Tmp2, DAG);
1821 assert((VT == MVT::i16 || VT == MVT::i32) &&
1822 "Unexpected custom legalization");
1843 assert((VT == MVT::i8 || (VT == MVT::i32 && Subtarget.
is64Bit())) &&
1844 "Unexpected custom legalization");
1864 "Unexpected custom legalisation");
1872 const StringRef ErrorMsgOOR =
"argument out of range";
1873 const StringRef ErrorMsgReqLA64 =
"requires loongarch64";
1874 const StringRef ErrorMsgReqF =
"requires basic 'f' target feature";
1876 switch (
N->getConstantOperandVal(1)) {
1879 case Intrinsic::loongarch_movfcsr2gr: {
1884 unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
1885 if (!isUInt<2>(Imm)) {
1897#define CRC_CASE_EXT_BINARYOP(NAME, NODE) \
1898 case Intrinsic::loongarch_##NAME: { \
1899 SDValue NODE = DAG.getNode( \
1900 LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \
1901 {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \
1902 DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3))}); \
1903 Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NODE.getValue(0))); \
1904 Results.push_back(NODE.getValue(1)); \
1913#undef CRC_CASE_EXT_BINARYOP
1915#define CRC_CASE_EXT_UNARYOP(NAME, NODE) \
1916 case Intrinsic::loongarch_##NAME: { \
1917 SDValue NODE = DAG.getNode( \
1918 LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \
1920 DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3))}); \
1921 Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NODE.getValue(0))); \
1922 Results.push_back(NODE.getValue(1)); \
1927#undef CRC_CASE_EXT_UNARYOP
1928#define CSR_CASE(ID) \
1929 case Intrinsic::loongarch_##ID: { \
1930 if (!Subtarget.is64Bit()) \
1931 emitErrorAndReplaceIntrinsicResults(N, Results, DAG, ErrorMsgReqLA64); \
1939 case Intrinsic::loongarch_csrrd_w: {
1940 unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
1941 if (!isUInt<14>(Imm)) {
1953 case Intrinsic::loongarch_csrwr_w: {
1954 unsigned Imm = cast<ConstantSDNode>(
N->getOperand(3))->getZExtValue();
1955 if (!isUInt<14>(Imm)) {
1968 case Intrinsic::loongarch_csrxchg_w: {
1969 unsigned Imm = cast<ConstantSDNode>(
N->getOperand(4))->getZExtValue();
1970 if (!isUInt<14>(Imm)) {
1984#define IOCSRRD_CASE(NAME, NODE) \
1985 case Intrinsic::loongarch_##NAME: { \
1986 SDValue IOCSRRDResults = \
1987 DAG.getNode(LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \
1988 {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2)}); \
1989 Results.push_back( \
1990 DAG.getNode(ISD::TRUNCATE, DL, VT, IOCSRRDResults.getValue(0))); \
1991 Results.push_back(IOCSRRDResults.getValue(1)); \
1998 case Intrinsic::loongarch_cpucfg: {
2007 case Intrinsic::loongarch_lddir_d: {
2020 "On LA64, only 64-bit registers can be read.");
2023 "On LA32, only 32-bit registers can be read.");
2025 Results.push_back(
N->getOperand(0));
2041 SDValue FirstOperand =
N->getOperand(0);
2042 SDValue SecondOperand =
N->getOperand(1);
2043 unsigned FirstOperandOpc = FirstOperand.
getOpcode();
2044 EVT ValTy =
N->getValueType(0);
2047 unsigned SMIdx, SMLen;
2053 if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand)) ||
2064 if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.
getOperand(1))))
2105 NewOperand = FirstOperand;
2108 msb = lsb + SMLen - 1;
2112 if (FirstOperandOpc ==
ISD::SRA || FirstOperandOpc ==
ISD::SRL || lsb == 0)
2133 SDValue FirstOperand =
N->getOperand(0);
2135 EVT ValTy =
N->getValueType(0);
2138 unsigned MaskIdx, MaskLen;
2144 !(CN = dyn_cast<ConstantSDNode>(FirstOperand.
getOperand(1))) ||
2149 if (!(CN = dyn_cast<ConstantSDNode>(
N->getOperand(1))))
2153 if (MaskIdx <= Shamt && Shamt <= MaskIdx + MaskLen - 1)
2166 EVT ValTy =
N->getValueType(0);
2167 SDValue N0 =
N->getOperand(0), N1 =
N->getOperand(1);
2171 unsigned MaskIdx0, MaskLen0, MaskIdx1, MaskLen1;
2173 bool SwapAndRetried =
false;
2178 if (ValBits != 32 && ValBits != 64)
2188 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2191 (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2193 MaskIdx0 == MaskIdx1 && MaskLen0 == MaskLen1 &&
2194 (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
2196 (MaskIdx0 + MaskLen0 <= ValBits)) {
2210 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2213 (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2215 (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
2217 MaskLen0 == MaskLen1 && MaskIdx1 == 0 &&
2218 (MaskIdx0 + MaskLen0 <= ValBits)) {
2233 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2235 (MaskIdx0 + MaskLen0 <= 64) &&
2236 (CN1 = dyn_cast<ConstantSDNode>(N1->getOperand(1))) &&
2243 ? (MaskIdx0 + (MaskLen0 & 31) - 1)
2244 : (MaskIdx0 + MaskLen0 - 1),
2256 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2258 MaskIdx0 == 0 && (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2260 (MaskIdx0 + MaskLen0 <= ValBits)) {
2275 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2277 (CN1 = dyn_cast<ConstantSDNode>(N1)) &&
2297 unsigned MaskIdx, MaskLen;
2298 if (N1.getOpcode() ==
ISD::SHL && N1.getOperand(0).getOpcode() ==
ISD::AND &&
2299 (CNMask = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
2301 MaskIdx == 0 && (CNShamt = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2323 (CNMask = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2325 N1.getOperand(0).getOpcode() ==
ISD::SHL &&
2326 (CNShamt = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
2339 if (!SwapAndRetried) {
2341 SwapAndRetried =
true;
2345 SwapAndRetried =
false;
2357 (CNMask = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2371 if (!SwapAndRetried) {
2373 SwapAndRetried =
true;
2395template <
unsigned N>
2399 bool IsSigned =
false) {
2401 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(ImmOp));
2403 if ((IsSigned && !isInt<N>(CImm->getSExtValue())) ||
2404 (!IsSigned && !isUInt<N>(CImm->getZExtValue()))) {
2406 ": argument out of range.");
2412template <
unsigned N>
2416 EVT ResTy =
Node->getValueType(0);
2417 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(ImmOp));
2420 if ((IsSigned && !isInt<N>(CImm->getSExtValue())) ||
2421 (!IsSigned && !isUInt<N>(CImm->getZExtValue()))) {
2423 ": argument out of range.");
2428 IsSigned ? CImm->getSExtValue() : CImm->getZExtValue(), IsSigned),
2434 EVT ResTy =
Node->getValueType(0);
2442 EVT ResTy =
Node->getValueType(0);
2451template <
unsigned N>
2454 EVT ResTy =
Node->getValueType(0);
2455 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(2));
2457 if (!isUInt<N>(CImm->getZExtValue())) {
2459 ": argument out of range.");
2469template <
unsigned N>
2472 EVT ResTy =
Node->getValueType(0);
2473 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(2));
2475 if (!isUInt<N>(CImm->getZExtValue())) {
2477 ": argument out of range.");
2486template <
unsigned N>
2489 EVT ResTy =
Node->getValueType(0);
2490 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(2));
2492 if (!isUInt<N>(CImm->getZExtValue())) {
2494 ": argument out of range.");
2508 switch (
N->getConstantOperandVal(0)) {
2511 case Intrinsic::loongarch_lsx_vadd_b:
2512 case Intrinsic::loongarch_lsx_vadd_h:
2513 case Intrinsic::loongarch_lsx_vadd_w:
2514 case Intrinsic::loongarch_lsx_vadd_d:
2515 case Intrinsic::loongarch_lasx_xvadd_b:
2516 case Intrinsic::loongarch_lasx_xvadd_h:
2517 case Intrinsic::loongarch_lasx_xvadd_w:
2518 case Intrinsic::loongarch_lasx_xvadd_d:
2521 case Intrinsic::loongarch_lsx_vaddi_bu:
2522 case Intrinsic::loongarch_lsx_vaddi_hu:
2523 case Intrinsic::loongarch_lsx_vaddi_wu:
2524 case Intrinsic::loongarch_lsx_vaddi_du:
2525 case Intrinsic::loongarch_lasx_xvaddi_bu:
2526 case Intrinsic::loongarch_lasx_xvaddi_hu:
2527 case Intrinsic::loongarch_lasx_xvaddi_wu:
2528 case Intrinsic::loongarch_lasx_xvaddi_du:
2530 lowerVectorSplatImm<5>(
N, 2, DAG));
2531 case Intrinsic::loongarch_lsx_vsub_b:
2532 case Intrinsic::loongarch_lsx_vsub_h:
2533 case Intrinsic::loongarch_lsx_vsub_w:
2534 case Intrinsic::loongarch_lsx_vsub_d:
2535 case Intrinsic::loongarch_lasx_xvsub_b:
2536 case Intrinsic::loongarch_lasx_xvsub_h:
2537 case Intrinsic::loongarch_lasx_xvsub_w:
2538 case Intrinsic::loongarch_lasx_xvsub_d:
2541 case Intrinsic::loongarch_lsx_vsubi_bu:
2542 case Intrinsic::loongarch_lsx_vsubi_hu:
2543 case Intrinsic::loongarch_lsx_vsubi_wu:
2544 case Intrinsic::loongarch_lsx_vsubi_du:
2545 case Intrinsic::loongarch_lasx_xvsubi_bu:
2546 case Intrinsic::loongarch_lasx_xvsubi_hu:
2547 case Intrinsic::loongarch_lasx_xvsubi_wu:
2548 case Intrinsic::loongarch_lasx_xvsubi_du:
2550 lowerVectorSplatImm<5>(
N, 2, DAG));
2551 case Intrinsic::loongarch_lsx_vneg_b:
2552 case Intrinsic::loongarch_lsx_vneg_h:
2553 case Intrinsic::loongarch_lsx_vneg_w:
2554 case Intrinsic::loongarch_lsx_vneg_d:
2555 case Intrinsic::loongarch_lasx_xvneg_b:
2556 case Intrinsic::loongarch_lasx_xvneg_h:
2557 case Intrinsic::loongarch_lasx_xvneg_w:
2558 case Intrinsic::loongarch_lasx_xvneg_d:
2562 APInt(
N->getValueType(0).getScalarType().getSizeInBits(), 0,
2564 SDLoc(
N),
N->getValueType(0)),
2566 case Intrinsic::loongarch_lsx_vmax_b:
2567 case Intrinsic::loongarch_lsx_vmax_h:
2568 case Intrinsic::loongarch_lsx_vmax_w:
2569 case Intrinsic::loongarch_lsx_vmax_d:
2570 case Intrinsic::loongarch_lasx_xvmax_b:
2571 case Intrinsic::loongarch_lasx_xvmax_h:
2572 case Intrinsic::loongarch_lasx_xvmax_w:
2573 case Intrinsic::loongarch_lasx_xvmax_d:
2576 case Intrinsic::loongarch_lsx_vmax_bu:
2577 case Intrinsic::loongarch_lsx_vmax_hu:
2578 case Intrinsic::loongarch_lsx_vmax_wu:
2579 case Intrinsic::loongarch_lsx_vmax_du:
2580 case Intrinsic::loongarch_lasx_xvmax_bu:
2581 case Intrinsic::loongarch_lasx_xvmax_hu:
2582 case Intrinsic::loongarch_lasx_xvmax_wu:
2583 case Intrinsic::loongarch_lasx_xvmax_du:
2586 case Intrinsic::loongarch_lsx_vmaxi_b:
2587 case Intrinsic::loongarch_lsx_vmaxi_h:
2588 case Intrinsic::loongarch_lsx_vmaxi_w:
2589 case Intrinsic::loongarch_lsx_vmaxi_d:
2590 case Intrinsic::loongarch_lasx_xvmaxi_b:
2591 case Intrinsic::loongarch_lasx_xvmaxi_h:
2592 case Intrinsic::loongarch_lasx_xvmaxi_w:
2593 case Intrinsic::loongarch_lasx_xvmaxi_d:
2595 lowerVectorSplatImm<5>(
N, 2, DAG,
true));
2596 case Intrinsic::loongarch_lsx_vmaxi_bu:
2597 case Intrinsic::loongarch_lsx_vmaxi_hu:
2598 case Intrinsic::loongarch_lsx_vmaxi_wu:
2599 case Intrinsic::loongarch_lsx_vmaxi_du:
2600 case Intrinsic::loongarch_lasx_xvmaxi_bu:
2601 case Intrinsic::loongarch_lasx_xvmaxi_hu:
2602 case Intrinsic::loongarch_lasx_xvmaxi_wu:
2603 case Intrinsic::loongarch_lasx_xvmaxi_du:
2605 lowerVectorSplatImm<5>(
N, 2, DAG));
2606 case Intrinsic::loongarch_lsx_vmin_b:
2607 case Intrinsic::loongarch_lsx_vmin_h:
2608 case Intrinsic::loongarch_lsx_vmin_w:
2609 case Intrinsic::loongarch_lsx_vmin_d:
2610 case Intrinsic::loongarch_lasx_xvmin_b:
2611 case Intrinsic::loongarch_lasx_xvmin_h:
2612 case Intrinsic::loongarch_lasx_xvmin_w:
2613 case Intrinsic::loongarch_lasx_xvmin_d:
2616 case Intrinsic::loongarch_lsx_vmin_bu:
2617 case Intrinsic::loongarch_lsx_vmin_hu:
2618 case Intrinsic::loongarch_lsx_vmin_wu:
2619 case Intrinsic::loongarch_lsx_vmin_du:
2620 case Intrinsic::loongarch_lasx_xvmin_bu:
2621 case Intrinsic::loongarch_lasx_xvmin_hu:
2622 case Intrinsic::loongarch_lasx_xvmin_wu:
2623 case Intrinsic::loongarch_lasx_xvmin_du:
2626 case Intrinsic::loongarch_lsx_vmini_b:
2627 case Intrinsic::loongarch_lsx_vmini_h:
2628 case Intrinsic::loongarch_lsx_vmini_w:
2629 case Intrinsic::loongarch_lsx_vmini_d:
2630 case Intrinsic::loongarch_lasx_xvmini_b:
2631 case Intrinsic::loongarch_lasx_xvmini_h:
2632 case Intrinsic::loongarch_lasx_xvmini_w:
2633 case Intrinsic::loongarch_lasx_xvmini_d:
2635 lowerVectorSplatImm<5>(
N, 2, DAG,
true));
2636 case Intrinsic::loongarch_lsx_vmini_bu:
2637 case Intrinsic::loongarch_lsx_vmini_hu:
2638 case Intrinsic::loongarch_lsx_vmini_wu:
2639 case Intrinsic::loongarch_lsx_vmini_du:
2640 case Intrinsic::loongarch_lasx_xvmini_bu:
2641 case Intrinsic::loongarch_lasx_xvmini_hu:
2642 case Intrinsic::loongarch_lasx_xvmini_wu:
2643 case Intrinsic::loongarch_lasx_xvmini_du:
2645 lowerVectorSplatImm<5>(
N, 2, DAG));
2646 case Intrinsic::loongarch_lsx_vmul_b:
2647 case Intrinsic::loongarch_lsx_vmul_h:
2648 case Intrinsic::loongarch_lsx_vmul_w:
2649 case Intrinsic::loongarch_lsx_vmul_d:
2650 case Intrinsic::loongarch_lasx_xvmul_b:
2651 case Intrinsic::loongarch_lasx_xvmul_h:
2652 case Intrinsic::loongarch_lasx_xvmul_w:
2653 case Intrinsic::loongarch_lasx_xvmul_d:
2656 case Intrinsic::loongarch_lsx_vmadd_b:
2657 case Intrinsic::loongarch_lsx_vmadd_h:
2658 case Intrinsic::loongarch_lsx_vmadd_w:
2659 case Intrinsic::loongarch_lsx_vmadd_d:
2660 case Intrinsic::loongarch_lasx_xvmadd_b:
2661 case Intrinsic::loongarch_lasx_xvmadd_h:
2662 case Intrinsic::loongarch_lasx_xvmadd_w:
2663 case Intrinsic::loongarch_lasx_xvmadd_d: {
2664 EVT ResTy =
N->getValueType(0);
2669 case Intrinsic::loongarch_lsx_vmsub_b:
2670 case Intrinsic::loongarch_lsx_vmsub_h:
2671 case Intrinsic::loongarch_lsx_vmsub_w:
2672 case Intrinsic::loongarch_lsx_vmsub_d:
2673 case Intrinsic::loongarch_lasx_xvmsub_b:
2674 case Intrinsic::loongarch_lasx_xvmsub_h:
2675 case Intrinsic::loongarch_lasx_xvmsub_w:
2676 case Intrinsic::loongarch_lasx_xvmsub_d: {
2677 EVT ResTy =
N->getValueType(0);
2682 case Intrinsic::loongarch_lsx_vdiv_b:
2683 case Intrinsic::loongarch_lsx_vdiv_h:
2684 case Intrinsic::loongarch_lsx_vdiv_w:
2685 case Intrinsic::loongarch_lsx_vdiv_d:
2686 case Intrinsic::loongarch_lasx_xvdiv_b:
2687 case Intrinsic::loongarch_lasx_xvdiv_h:
2688 case Intrinsic::loongarch_lasx_xvdiv_w:
2689 case Intrinsic::loongarch_lasx_xvdiv_d:
2692 case Intrinsic::loongarch_lsx_vdiv_bu:
2693 case Intrinsic::loongarch_lsx_vdiv_hu:
2694 case Intrinsic::loongarch_lsx_vdiv_wu:
2695 case Intrinsic::loongarch_lsx_vdiv_du:
2696 case Intrinsic::loongarch_lasx_xvdiv_bu:
2697 case Intrinsic::loongarch_lasx_xvdiv_hu:
2698 case Intrinsic::loongarch_lasx_xvdiv_wu:
2699 case Intrinsic::loongarch_lasx_xvdiv_du:
2702 case Intrinsic::loongarch_lsx_vmod_b:
2703 case Intrinsic::loongarch_lsx_vmod_h:
2704 case Intrinsic::loongarch_lsx_vmod_w:
2705 case Intrinsic::loongarch_lsx_vmod_d:
2706 case Intrinsic::loongarch_lasx_xvmod_b:
2707 case Intrinsic::loongarch_lasx_xvmod_h:
2708 case Intrinsic::loongarch_lasx_xvmod_w:
2709 case Intrinsic::loongarch_lasx_xvmod_d:
2712 case Intrinsic::loongarch_lsx_vmod_bu:
2713 case Intrinsic::loongarch_lsx_vmod_hu:
2714 case Intrinsic::loongarch_lsx_vmod_wu:
2715 case Intrinsic::loongarch_lsx_vmod_du:
2716 case Intrinsic::loongarch_lasx_xvmod_bu:
2717 case Intrinsic::loongarch_lasx_xvmod_hu:
2718 case Intrinsic::loongarch_lasx_xvmod_wu:
2719 case Intrinsic::loongarch_lasx_xvmod_du:
2722 case Intrinsic::loongarch_lsx_vand_v:
2723 case Intrinsic::loongarch_lasx_xvand_v:
2726 case Intrinsic::loongarch_lsx_vor_v:
2727 case Intrinsic::loongarch_lasx_xvor_v:
2730 case Intrinsic::loongarch_lsx_vxor_v:
2731 case Intrinsic::loongarch_lasx_xvxor_v:
2734 case Intrinsic::loongarch_lsx_vnor_v:
2735 case Intrinsic::loongarch_lasx_xvnor_v: {
2740 case Intrinsic::loongarch_lsx_vandi_b:
2741 case Intrinsic::loongarch_lasx_xvandi_b:
2743 lowerVectorSplatImm<8>(
N, 2, DAG));
2744 case Intrinsic::loongarch_lsx_vori_b:
2745 case Intrinsic::loongarch_lasx_xvori_b:
2747 lowerVectorSplatImm<8>(
N, 2, DAG));
2748 case Intrinsic::loongarch_lsx_vxori_b:
2749 case Intrinsic::loongarch_lasx_xvxori_b:
2751 lowerVectorSplatImm<8>(
N, 2, DAG));
2752 case Intrinsic::loongarch_lsx_vsll_b:
2753 case Intrinsic::loongarch_lsx_vsll_h:
2754 case Intrinsic::loongarch_lsx_vsll_w:
2755 case Intrinsic::loongarch_lsx_vsll_d:
2756 case Intrinsic::loongarch_lasx_xvsll_b:
2757 case Intrinsic::loongarch_lasx_xvsll_h:
2758 case Intrinsic::loongarch_lasx_xvsll_w:
2759 case Intrinsic::loongarch_lasx_xvsll_d:
2762 case Intrinsic::loongarch_lsx_vslli_b:
2763 case Intrinsic::loongarch_lasx_xvslli_b:
2765 lowerVectorSplatImm<3>(
N, 2, DAG));
2766 case Intrinsic::loongarch_lsx_vslli_h:
2767 case Intrinsic::loongarch_lasx_xvslli_h:
2769 lowerVectorSplatImm<4>(
N, 2, DAG));
2770 case Intrinsic::loongarch_lsx_vslli_w:
2771 case Intrinsic::loongarch_lasx_xvslli_w:
2773 lowerVectorSplatImm<5>(
N, 2, DAG));
2774 case Intrinsic::loongarch_lsx_vslli_d:
2775 case Intrinsic::loongarch_lasx_xvslli_d:
2777 lowerVectorSplatImm<6>(
N, 2, DAG));
2778 case Intrinsic::loongarch_lsx_vsrl_b:
2779 case Intrinsic::loongarch_lsx_vsrl_h:
2780 case Intrinsic::loongarch_lsx_vsrl_w:
2781 case Intrinsic::loongarch_lsx_vsrl_d:
2782 case Intrinsic::loongarch_lasx_xvsrl_b:
2783 case Intrinsic::loongarch_lasx_xvsrl_h:
2784 case Intrinsic::loongarch_lasx_xvsrl_w:
2785 case Intrinsic::loongarch_lasx_xvsrl_d:
2788 case Intrinsic::loongarch_lsx_vsrli_b:
2789 case Intrinsic::loongarch_lasx_xvsrli_b:
2791 lowerVectorSplatImm<3>(
N, 2, DAG));
2792 case Intrinsic::loongarch_lsx_vsrli_h:
2793 case Intrinsic::loongarch_lasx_xvsrli_h:
2795 lowerVectorSplatImm<4>(
N, 2, DAG));
2796 case Intrinsic::loongarch_lsx_vsrli_w:
2797 case Intrinsic::loongarch_lasx_xvsrli_w:
2799 lowerVectorSplatImm<5>(
N, 2, DAG));
2800 case Intrinsic::loongarch_lsx_vsrli_d:
2801 case Intrinsic::loongarch_lasx_xvsrli_d:
2803 lowerVectorSplatImm<6>(
N, 2, DAG));
2804 case Intrinsic::loongarch_lsx_vsra_b:
2805 case Intrinsic::loongarch_lsx_vsra_h:
2806 case Intrinsic::loongarch_lsx_vsra_w:
2807 case Intrinsic::loongarch_lsx_vsra_d:
2808 case Intrinsic::loongarch_lasx_xvsra_b:
2809 case Intrinsic::loongarch_lasx_xvsra_h:
2810 case Intrinsic::loongarch_lasx_xvsra_w:
2811 case Intrinsic::loongarch_lasx_xvsra_d:
2814 case Intrinsic::loongarch_lsx_vsrai_b:
2815 case Intrinsic::loongarch_lasx_xvsrai_b:
2817 lowerVectorSplatImm<3>(
N, 2, DAG));
2818 case Intrinsic::loongarch_lsx_vsrai_h:
2819 case Intrinsic::loongarch_lasx_xvsrai_h:
2821 lowerVectorSplatImm<4>(
N, 2, DAG));
2822 case Intrinsic::loongarch_lsx_vsrai_w:
2823 case Intrinsic::loongarch_lasx_xvsrai_w:
2825 lowerVectorSplatImm<5>(
N, 2, DAG));
2826 case Intrinsic::loongarch_lsx_vsrai_d:
2827 case Intrinsic::loongarch_lasx_xvsrai_d:
2829 lowerVectorSplatImm<6>(
N, 2, DAG));
2830 case Intrinsic::loongarch_lsx_vclz_b:
2831 case Intrinsic::loongarch_lsx_vclz_h:
2832 case Intrinsic::loongarch_lsx_vclz_w:
2833 case Intrinsic::loongarch_lsx_vclz_d:
2834 case Intrinsic::loongarch_lasx_xvclz_b:
2835 case Intrinsic::loongarch_lasx_xvclz_h:
2836 case Intrinsic::loongarch_lasx_xvclz_w:
2837 case Intrinsic::loongarch_lasx_xvclz_d:
2839 case Intrinsic::loongarch_lsx_vpcnt_b:
2840 case Intrinsic::loongarch_lsx_vpcnt_h:
2841 case Intrinsic::loongarch_lsx_vpcnt_w:
2842 case Intrinsic::loongarch_lsx_vpcnt_d:
2843 case Intrinsic::loongarch_lasx_xvpcnt_b:
2844 case Intrinsic::loongarch_lasx_xvpcnt_h:
2845 case Intrinsic::loongarch_lasx_xvpcnt_w:
2846 case Intrinsic::loongarch_lasx_xvpcnt_d:
2848 case Intrinsic::loongarch_lsx_vbitclr_b:
2849 case Intrinsic::loongarch_lsx_vbitclr_h:
2850 case Intrinsic::loongarch_lsx_vbitclr_w:
2851 case Intrinsic::loongarch_lsx_vbitclr_d:
2852 case Intrinsic::loongarch_lasx_xvbitclr_b:
2853 case Intrinsic::loongarch_lasx_xvbitclr_h:
2854 case Intrinsic::loongarch_lasx_xvbitclr_w:
2855 case Intrinsic::loongarch_lasx_xvbitclr_d:
2857 case Intrinsic::loongarch_lsx_vbitclri_b:
2858 case Intrinsic::loongarch_lasx_xvbitclri_b:
2859 return lowerVectorBitClearImm<3>(
N, DAG);
2860 case Intrinsic::loongarch_lsx_vbitclri_h:
2861 case Intrinsic::loongarch_lasx_xvbitclri_h:
2862 return lowerVectorBitClearImm<4>(
N, DAG);
2863 case Intrinsic::loongarch_lsx_vbitclri_w:
2864 case Intrinsic::loongarch_lasx_xvbitclri_w:
2865 return lowerVectorBitClearImm<5>(
N, DAG);
2866 case Intrinsic::loongarch_lsx_vbitclri_d:
2867 case Intrinsic::loongarch_lasx_xvbitclri_d:
2868 return lowerVectorBitClearImm<6>(
N, DAG);
2869 case Intrinsic::loongarch_lsx_vbitset_b:
2870 case Intrinsic::loongarch_lsx_vbitset_h:
2871 case Intrinsic::loongarch_lsx_vbitset_w:
2872 case Intrinsic::loongarch_lsx_vbitset_d:
2873 case Intrinsic::loongarch_lasx_xvbitset_b:
2874 case Intrinsic::loongarch_lasx_xvbitset_h:
2875 case Intrinsic::loongarch_lasx_xvbitset_w:
2876 case Intrinsic::loongarch_lasx_xvbitset_d: {
2877 EVT VecTy =
N->getValueType(0);
2883 case Intrinsic::loongarch_lsx_vbitseti_b:
2884 case Intrinsic::loongarch_lasx_xvbitseti_b:
2885 return lowerVectorBitSetImm<3>(
N, DAG);
2886 case Intrinsic::loongarch_lsx_vbitseti_h:
2887 case Intrinsic::loongarch_lasx_xvbitseti_h:
2888 return lowerVectorBitSetImm<4>(
N, DAG);
2889 case Intrinsic::loongarch_lsx_vbitseti_w:
2890 case Intrinsic::loongarch_lasx_xvbitseti_w:
2891 return lowerVectorBitSetImm<5>(
N, DAG);
2892 case Intrinsic::loongarch_lsx_vbitseti_d:
2893 case Intrinsic::loongarch_lasx_xvbitseti_d:
2894 return lowerVectorBitSetImm<6>(
N, DAG);
2895 case Intrinsic::loongarch_lsx_vbitrev_b:
2896 case Intrinsic::loongarch_lsx_vbitrev_h:
2897 case Intrinsic::loongarch_lsx_vbitrev_w:
2898 case Intrinsic::loongarch_lsx_vbitrev_d:
2899 case Intrinsic::loongarch_lasx_xvbitrev_b:
2900 case Intrinsic::loongarch_lasx_xvbitrev_h:
2901 case Intrinsic::loongarch_lasx_xvbitrev_w:
2902 case Intrinsic::loongarch_lasx_xvbitrev_d: {
2903 EVT VecTy =
N->getValueType(0);
2909 case Intrinsic::loongarch_lsx_vbitrevi_b:
2910 case Intrinsic::loongarch_lasx_xvbitrevi_b:
2911 return lowerVectorBitRevImm<3>(
N, DAG);
2912 case Intrinsic::loongarch_lsx_vbitrevi_h:
2913 case Intrinsic::loongarch_lasx_xvbitrevi_h:
2914 return lowerVectorBitRevImm<4>(
N, DAG);
2915 case Intrinsic::loongarch_lsx_vbitrevi_w:
2916 case Intrinsic::loongarch_lasx_xvbitrevi_w:
2917 return lowerVectorBitRevImm<5>(
N, DAG);
2918 case Intrinsic::loongarch_lsx_vbitrevi_d:
2919 case Intrinsic::loongarch_lasx_xvbitrevi_d:
2920 return lowerVectorBitRevImm<6>(
N, DAG);
2921 case Intrinsic::loongarch_lsx_vfadd_s:
2922 case Intrinsic::loongarch_lsx_vfadd_d:
2923 case Intrinsic::loongarch_lasx_xvfadd_s:
2924 case Intrinsic::loongarch_lasx_xvfadd_d:
2927 case Intrinsic::loongarch_lsx_vfsub_s:
2928 case Intrinsic::loongarch_lsx_vfsub_d:
2929 case Intrinsic::loongarch_lasx_xvfsub_s:
2930 case Intrinsic::loongarch_lasx_xvfsub_d:
2933 case Intrinsic::loongarch_lsx_vfmul_s:
2934 case Intrinsic::loongarch_lsx_vfmul_d:
2935 case Intrinsic::loongarch_lasx_xvfmul_s:
2936 case Intrinsic::loongarch_lasx_xvfmul_d:
2939 case Intrinsic::loongarch_lsx_vfdiv_s:
2940 case Intrinsic::loongarch_lsx_vfdiv_d:
2941 case Intrinsic::loongarch_lasx_xvfdiv_s:
2942 case Intrinsic::loongarch_lasx_xvfdiv_d:
2945 case Intrinsic::loongarch_lsx_vfmadd_s:
2946 case Intrinsic::loongarch_lsx_vfmadd_d:
2947 case Intrinsic::loongarch_lasx_xvfmadd_s:
2948 case Intrinsic::loongarch_lasx_xvfmadd_d:
2950 N->getOperand(2),
N->getOperand(3));
2951 case Intrinsic::loongarch_lsx_vinsgr2vr_b:
2953 N->getOperand(1),
N->getOperand(2),
2954 legalizeIntrinsicImmArg<4>(
N, 3, DAG, Subtarget));
2955 case Intrinsic::loongarch_lsx_vinsgr2vr_h:
2956 case Intrinsic::loongarch_lasx_xvinsgr2vr_w:
2958 N->getOperand(1),
N->getOperand(2),
2959 legalizeIntrinsicImmArg<3>(
N, 3, DAG, Subtarget));
2960 case Intrinsic::loongarch_lsx_vinsgr2vr_w:
2961 case Intrinsic::loongarch_lasx_xvinsgr2vr_d:
2963 N->getOperand(1),
N->getOperand(2),
2964 legalizeIntrinsicImmArg<2>(
N, 3, DAG, Subtarget));
2965 case Intrinsic::loongarch_lsx_vinsgr2vr_d:
2967 N->getOperand(1),
N->getOperand(2),
2968 legalizeIntrinsicImmArg<1>(
N, 3, DAG, Subtarget));
2969 case Intrinsic::loongarch_lsx_vreplgr2vr_b:
2970 case Intrinsic::loongarch_lsx_vreplgr2vr_h:
2971 case Intrinsic::loongarch_lsx_vreplgr2vr_w:
2972 case Intrinsic::loongarch_lsx_vreplgr2vr_d:
2973 case Intrinsic::loongarch_lasx_xvreplgr2vr_b:
2974 case Intrinsic::loongarch_lasx_xvreplgr2vr_h:
2975 case Intrinsic::loongarch_lasx_xvreplgr2vr_w:
2976 case Intrinsic::loongarch_lasx_xvreplgr2vr_d: {
2977 EVT ResTy =
N->getValueType(0);
2981 case Intrinsic::loongarch_lsx_vreplve_b:
2982 case Intrinsic::loongarch_lsx_vreplve_h:
2983 case Intrinsic::loongarch_lsx_vreplve_w:
2984 case Intrinsic::loongarch_lsx_vreplve_d:
2985 case Intrinsic::loongarch_lasx_xvreplve_b:
2986 case Intrinsic::loongarch_lasx_xvreplve_h:
2987 case Intrinsic::loongarch_lasx_xvreplve_w:
2988 case Intrinsic::loongarch_lasx_xvreplve_d:
3000 switch (
N->getOpcode()) {
3035 MF->
insert(It, BreakMBB);
3039 SinkMBB->splice(SinkMBB->end(),
MBB, std::next(
MI.getIterator()),
MBB->
end());
3040 SinkMBB->transferSuccessorsAndUpdatePHIs(
MBB);
3058 BreakMBB->addSuccessor(SinkMBB);
3070 switch (
MI.getOpcode()) {
3073 case LoongArch::PseudoVBZ:
3074 CondOpc = LoongArch::VSETEQZ_V;
3076 case LoongArch::PseudoVBZ_B:
3077 CondOpc = LoongArch::VSETANYEQZ_B;
3079 case LoongArch::PseudoVBZ_H:
3080 CondOpc = LoongArch::VSETANYEQZ_H;
3082 case LoongArch::PseudoVBZ_W:
3083 CondOpc = LoongArch::VSETANYEQZ_W;
3085 case LoongArch::PseudoVBZ_D:
3086 CondOpc = LoongArch::VSETANYEQZ_D;
3088 case LoongArch::PseudoVBNZ:
3089 CondOpc = LoongArch::VSETNEZ_V;
3091 case LoongArch::PseudoVBNZ_B:
3092 CondOpc = LoongArch::VSETALLNEZ_B;
3094 case LoongArch::PseudoVBNZ_H:
3095 CondOpc = LoongArch::VSETALLNEZ_H;
3097 case LoongArch::PseudoVBNZ_W:
3098 CondOpc = LoongArch::VSETALLNEZ_W;
3100 case LoongArch::PseudoVBNZ_D:
3101 CondOpc = LoongArch::VSETALLNEZ_D;
3103 case LoongArch::PseudoXVBZ:
3104 CondOpc = LoongArch::XVSETEQZ_V;
3106 case LoongArch::PseudoXVBZ_B:
3107 CondOpc = LoongArch::XVSETANYEQZ_B;
3109 case LoongArch::PseudoXVBZ_H:
3110 CondOpc = LoongArch::XVSETANYEQZ_H;
3112 case LoongArch::PseudoXVBZ_W:
3113 CondOpc = LoongArch::XVSETANYEQZ_W;
3115 case LoongArch::PseudoXVBZ_D:
3116 CondOpc = LoongArch::XVSETANYEQZ_D;
3118 case LoongArch::PseudoXVBNZ:
3119 CondOpc = LoongArch::XVSETNEZ_V;
3121 case LoongArch::PseudoXVBNZ_B:
3122 CondOpc = LoongArch::XVSETALLNEZ_B;
3124 case LoongArch::PseudoXVBNZ_H:
3125 CondOpc = LoongArch::XVSETALLNEZ_H;
3127 case LoongArch::PseudoXVBNZ_W:
3128 CondOpc = LoongArch::XVSETALLNEZ_W;
3130 case LoongArch::PseudoXVBNZ_D:
3131 CondOpc = LoongArch::XVSETALLNEZ_D;
3146 F->insert(It, FalseBB);
3147 F->insert(It, TrueBB);
3148 F->insert(It, SinkBB);
3151 SinkBB->
splice(SinkBB->
end(), BB, std::next(
MI.getIterator()), BB->
end());
3155 Register FCC =
MRI.createVirtualRegister(&LoongArch::CFRRegClass);
3164 Register RD1 =
MRI.createVirtualRegister(&LoongArch::GPRRegClass);
3172 Register RD2 =
MRI.createVirtualRegister(&LoongArch::GPRRegClass);
3180 MI.getOperand(0).getReg())
3187 MI.eraseFromParent();
3196 switch (
MI.getOpcode()) {
3199 case LoongArch::PseudoXVINSGR2VR_B:
3201 InsOp = LoongArch::VINSGR2VR_B;
3203 case LoongArch::PseudoXVINSGR2VR_H:
3205 InsOp = LoongArch::VINSGR2VR_H;
3217 unsigned Idx =
MI.getOperand(3).getImm();
3220 if (
Idx >= HalfSize) {
3221 ScratchReg1 =
MRI.createVirtualRegister(RC);
3222 BuildMI(*BB,
MI,
DL,
TII->get(LoongArch::XVPERMI_Q), ScratchReg1)
3228 Register ScratchSubReg1 =
MRI.createVirtualRegister(SubRC);
3229 Register ScratchSubReg2 =
MRI.createVirtualRegister(SubRC);
3231 .
addReg(ScratchReg1, 0, LoongArch::sub_128);
3238 if (
Idx >= HalfSize)
3239 ScratchReg2 =
MRI.createVirtualRegister(RC);
3241 BuildMI(*BB,
MI,
DL,
TII->get(LoongArch::SUBREG_TO_REG), ScratchReg2)
3244 .
addImm(LoongArch::sub_128);
3246 if (
Idx >= HalfSize)
3252 MI.eraseFromParent();
3261 switch (
MI.getOpcode()) {
3264 case LoongArch::DIV_W:
3265 case LoongArch::DIV_WU:
3266 case LoongArch::MOD_W:
3267 case LoongArch::MOD_WU:
3268 case LoongArch::DIV_D:
3269 case LoongArch::DIV_DU:
3270 case LoongArch::MOD_D:
3271 case LoongArch::MOD_DU:
3274 case LoongArch::WRFCSR: {
3276 LoongArch::FCSR0 +
MI.getOperand(0).getImm())
3277 .
addReg(
MI.getOperand(1).getReg());
3278 MI.eraseFromParent();
3281 case LoongArch::RDFCSR: {
3284 MI.getOperand(0).getReg())
3285 .
addReg(LoongArch::FCSR0 +
MI.getOperand(1).getImm());
3287 MI.eraseFromParent();
3290 case LoongArch::PseudoVBZ:
3291 case LoongArch::PseudoVBZ_B:
3292 case LoongArch::PseudoVBZ_H:
3293 case LoongArch::PseudoVBZ_W:
3294 case LoongArch::PseudoVBZ_D:
3295 case LoongArch::PseudoVBNZ:
3296 case LoongArch::PseudoVBNZ_B:
3297 case LoongArch::PseudoVBNZ_H:
3298 case LoongArch::PseudoVBNZ_W:
3299 case LoongArch::PseudoVBNZ_D:
3300 case LoongArch::PseudoXVBZ:
3301 case LoongArch::PseudoXVBZ_B:
3302 case LoongArch::PseudoXVBZ_H:
3303 case LoongArch::PseudoXVBZ_W:
3304 case LoongArch::PseudoXVBZ_D:
3305 case LoongArch::PseudoXVBNZ:
3306 case LoongArch::PseudoXVBNZ_B:
3307 case LoongArch::PseudoXVBNZ_H:
3308 case LoongArch::PseudoXVBNZ_W:
3309 case LoongArch::PseudoXVBNZ_D:
3311 case LoongArch::PseudoXVINSGR2VR_B:
3312 case LoongArch::PseudoXVINSGR2VR_H:
3319 unsigned *
Fast)
const {
3334#define NODE_NAME_CASE(node) \
3335 case LoongArchISD::node: \
3336 return "LoongArchISD::" #node;
3394#undef NODE_NAME_CASE
3407 LoongArch::R7, LoongArch::R8, LoongArch::R9,
3408 LoongArch::R10, LoongArch::R11};
3412 LoongArch::F3, LoongArch::F4, LoongArch::F5,
3413 LoongArch::F6, LoongArch::F7};
3416 LoongArch::F0_64, LoongArch::F1_64, LoongArch::F2_64, LoongArch::F3_64,
3417 LoongArch::F4_64, LoongArch::F5_64, LoongArch::F6_64, LoongArch::F7_64};
3420 LoongArch::VR3, LoongArch::VR4, LoongArch::VR5,
3421 LoongArch::VR6, LoongArch::VR7};
3424 LoongArch::XR3, LoongArch::XR4, LoongArch::XR5,
3425 LoongArch::XR6, LoongArch::XR7};
3431 unsigned ValNo2,
MVT ValVT2,
MVT LocVT2,
3433 unsigned GRLenInBytes = GRLen / 8;
3466 unsigned ValNo,
MVT ValVT,
3468 CCState &State,
bool IsFixed,
bool IsRet,
3470 unsigned GRLen =
DL.getLargestLegalIntTypeSizeInBits();
3471 assert((GRLen == 32 || GRLen == 64) &&
"Unspport GRLen");
3472 MVT GRLenVT = GRLen == 32 ? MVT::i32 : MVT::i64;
3477 if (IsRet && ValNo > 1)
3481 bool UseGPRForFloat =
true;
3493 UseGPRForFloat = !IsFixed;
3501 UseGPRForFloat =
true;
3503 if (UseGPRForFloat && ValVT == MVT::f32) {
3506 }
else if (UseGPRForFloat && GRLen == 64 && ValVT == MVT::f64) {
3509 }
else if (UseGPRForFloat && GRLen == 32 && ValVT == MVT::f64) {
3520 unsigned TwoGRLenInBytes = (2 * GRLen) / 8;
3522 DL.getTypeAllocSize(OrigTy) == TwoGRLenInBytes) {
3525 if (RegIdx != std::size(
ArgGPRs) && RegIdx % 2 == 1)
3534 "PendingLocs and PendingArgFlags out of sync");
3552 PendingLocs.
size() <= 2) {
3553 assert(PendingLocs.
size() == 2 &&
"Unexpected PendingLocs.size()");
3558 PendingLocs.
clear();
3559 PendingArgFlags.
clear();
3566 unsigned StoreSizeBytes = GRLen / 8;
3569 if (ValVT == MVT::f32 && !UseGPRForFloat)
3571 else if (ValVT == MVT::f64 && !UseGPRForFloat)
3585 if (!PendingLocs.
empty()) {
3587 assert(PendingLocs.
size() > 2 &&
"Unexpected PendingLocs.size()");
3588 for (
auto &It : PendingLocs) {
3590 It.convertToReg(Reg);
3595 PendingLocs.clear();
3596 PendingArgFlags.
clear();
3599 assert((!UseGPRForFloat || LocVT == GRLenVT) &&
3600 "Expected an GRLenVT at this stage");
3617void LoongArchTargetLowering::analyzeInputArgs(
3620 LoongArchCCAssignFn Fn)
const {
3622 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
3624 Type *ArgTy =
nullptr;
3626 ArgTy = FType->getReturnType();
3627 else if (Ins[i].isOrigArg())
3628 ArgTy = FType->getParamType(Ins[i].getOrigArgIndex());
3632 CCInfo,
true, IsRet, ArgTy)) {
3633 LLVM_DEBUG(
dbgs() <<
"InputArg #" << i <<
" has unhandled type " << ArgVT
3640void LoongArchTargetLowering::analyzeOutputArgs(
3643 CallLoweringInfo *CLI, LoongArchCCAssignFn Fn)
const {
3644 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
3645 MVT ArgVT = Outs[i].VT;
3646 Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty :
nullptr;
3650 CCInfo, Outs[i].IsFixed, IsRet, OrigTy)) {
3651 LLVM_DEBUG(
dbgs() <<
"OutputArg #" << i <<
" has unhandled type " << ArgVT
3742 if (LocVT == MVT::i32 || LocVT == MVT::i64) {
3746 LoongArch::R23, LoongArch::R24, LoongArch::R25,
3747 LoongArch::R26, LoongArch::R27, LoongArch::R28,
3748 LoongArch::R29, LoongArch::R30, LoongArch::R31};
3755 if (LocVT == MVT::f32) {
3758 static const MCPhysReg FPR32List[] = {LoongArch::F24, LoongArch::F25,
3759 LoongArch::F26, LoongArch::F27};
3760 if (
unsigned Reg = State.
AllocateReg(FPR32List)) {
3766 if (LocVT == MVT::f64) {
3769 static const MCPhysReg FPR64List[] = {LoongArch::F28_64, LoongArch::F29_64,
3770 LoongArch::F30_64, LoongArch::F31_64};
3771 if (
unsigned Reg = State.
AllocateReg(FPR64List)) {
3799 "GHC calling convention requires the F and D extensions");
3804 unsigned GRLenInBytes = Subtarget.
getGRLen() / 8;
3806 std::vector<SDValue> OutChains;
3815 analyzeInputArgs(MF, CCInfo, Ins,
false,
CC_LoongArch);
3817 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
3829 unsigned ArgIndex = Ins[i].OrigArgIndex;
3830 unsigned ArgPartOffset = Ins[i].PartOffset;
3831 assert(ArgPartOffset == 0);
3832 while (i + 1 != e && Ins[i + 1].OrigArgIndex == ArgIndex) {
3834 unsigned PartOffset = Ins[i + 1].PartOffset - ArgPartOffset;
3857 int VaArgOffset, VarArgsSaveSize;
3863 VarArgsSaveSize = 0;
3865 VarArgsSaveSize = GRLenInBytes * (ArgRegs.
size() -
Idx);
3866 VaArgOffset = -VarArgsSaveSize;
3872 LoongArchFI->setVarArgsFrameIndex(FI);
3880 VarArgsSaveSize += GRLenInBytes;
3885 for (
unsigned I =
Idx;
I < ArgRegs.
size();
3886 ++
I, VaArgOffset += GRLenInBytes) {
3894 cast<StoreSDNode>(Store.getNode())
3896 ->setValue((
Value *)
nullptr);
3897 OutChains.push_back(Store);
3899 LoongArchFI->setVarArgsSaveSize(VarArgsSaveSize);
3904 if (!OutChains.empty()) {
3905 OutChains.push_back(Chain);
3920 if (
N->getNumValues() != 1)
3922 if (!
N->hasNUsesOfValue(1, 0))
3925 SDNode *Copy = *
N->use_begin();
3931 if (Copy->getGluedNode())
3935 bool HasRet =
false;
3936 for (
SDNode *Node : Copy->uses()) {
3945 Chain = Copy->getOperand(0);
3950bool LoongArchTargetLowering::isEligibleForTailCallOptimization(
3954 auto CalleeCC = CLI.CallConv;
3955 auto &Outs = CLI.Outs;
3957 auto CallerCC = Caller.getCallingConv();
3964 for (
auto &VA : ArgLocs)
3970 auto IsCallerStructRet = Caller.hasStructRetAttr();
3971 auto IsCalleeStructRet = Outs.
empty() ?
false : Outs[0].Flags.isSRet();
3972 if (IsCallerStructRet || IsCalleeStructRet)
3976 for (
auto &Arg : Outs)
3977 if (Arg.Flags.isByVal())
3982 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
3983 if (CalleeCC != CallerCC) {
3984 const uint32_t *CalleePreserved =
TRI->getCallPreservedMask(MF, CalleeCC);
3985 if (!
TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
4023 analyzeOutputArgs(MF, ArgCCInfo, Outs,
false, &CLI,
CC_LoongArch);
4027 IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs);
4033 "site marked musttail");
4040 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
4042 if (!Flags.isByVal())
4046 unsigned Size = Flags.getByValSize();
4047 Align Alignment = Flags.getNonZeroByValAlign();
4054 Chain = DAG.
getMemcpy(Chain,
DL, FIPtr, Arg, SizeNode, Alignment,
4068 for (
unsigned i = 0, j = 0, e = ArgLocs.
size(); i != e; ++i) {
4070 SDValue ArgValue = OutVals[i];
4083 unsigned ArgIndex = Outs[i].OrigArgIndex;
4084 unsigned ArgPartOffset = Outs[i].PartOffset;
4085 assert(ArgPartOffset == 0);
4090 while (i + 1 != e && Outs[i + 1].OrigArgIndex == ArgIndex) {
4091 SDValue PartValue = OutVals[i + 1];
4092 unsigned PartOffset = Outs[i + 1].PartOffset - ArgPartOffset;
4102 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
4106 for (
const auto &Part : Parts) {
4107 SDValue PartValue = Part.first;
4108 SDValue PartOffset = Part.second;
4115 ArgValue = SpillSlot;
4121 if (Flags.isByVal())
4122 ArgValue = ByValArgs[j++];
4129 assert(!IsTailCall &&
"Tail call not allowed if stack is used "
4130 "for passing parameters");
4133 if (!StackPtr.getNode())
4146 if (!MemOpChains.
empty())
4152 for (
auto &Reg : RegsToPass) {
4153 Chain = DAG.
getCopyToReg(Chain,
DL, Reg.first, Reg.second, Glue);
4182 for (
auto &Reg : RegsToPass)
4188 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
4189 assert(Mask &&
"Missing call preserved mask for calling convention");
4218 analyzeInputArgs(MF, RetCCInfo, Ins,
true,
CC_LoongArch);
4221 for (
auto &VA : RVLocs) {
4243 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
4247 Outs[i].Flags, CCInfo,
true,
true,
4274 for (
unsigned i = 0, e = RVLocs.
size(); i < e; ++i) {