LLVM: lib/Target/Mips/MipsISelLowering.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
69#include
70#include
71#include
72#include
73#include
74#include
75#include
76#include
77
78using namespace llvm;
79
80#define DEBUG_TYPE "mips-lower"
81
82STATISTIC(NumTailCalls, "Number of tail calls");
83
86 cl::desc("MIPS: Don't trap on integer division by zero."),
88
90
92 Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,
93 Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64
94};
95
96
97
100 EVT VT) const {
103
106 : MVT::i64;
108}
109
112 EVT VT) const {
118 }
120}
121
124 unsigned &NumIntermediates, MVT &RegisterVT) const {
127 RegisterVT = IntermediateVT.getSimpleVT();
129 return NumIntermediates;
130 }
134 return NumIntermediates * getNumRegisters(Context, IntermediateVT);
135}
136
142
145 unsigned Flag) const {
147}
148
151 unsigned Flag) const {
153}
154
157 unsigned Flag) const {
159}
160
163 unsigned Flag) const {
165}
166
169 unsigned Flag) const {
171 N->getOffset(), Flag);
172}
173
177
178
181
182
186
187
192 }
193
194
195
199 }
200
201
206 }
207
210
212
213
214
215
216
218
219
239
244
248
249
263 } else {
266 }
267
278 } else {
281 }
288 }
289
294 }
295
299
308
309
323
327 } else {
330 }
337
340
343
360
361
366
368
373
374
377
381 }
382
386 }
387
388
393
398
404 } else if (Subtarget.isGP64bit()) {
409 }
410
412
416
419 else
421
423
424
425
428
430
432
433 isMicroMips = Subtarget.inMicroMipsMode();
434}
435
444
445
451
452
456
457
458
459 if (!TM.isPositionIndependent() || !TM.getABI().IsO32() ||
461 UseFastISel = false;
462
464}
465
467 EVT VT) const {
469 return MVT::i32;
471}
472
478
479 EVT Ty = N->getValueType(0);
480 unsigned LO = (Ty == MVT::i32) ? Mips::LO0 : Mips::LO0_64;
481 unsigned HI = (Ty == MVT::i32) ? Mips::HI0 : Mips::HI0_64;
482 unsigned Opc = N->getOpcode() == ISD::SDIVREM ? MipsISD::DivRem16 :
483 MipsISD::DivRemU16;
485
487 N->getOperand(0), N->getOperand(1));
490
491
492 if (N->hasAnyUseOfValue(0)) {
494 InGlue);
496 InChain = CopyFromLo.getValue(1);
497 InGlue = CopyFromLo.getValue(2);
498 }
499
500
501 if (N->hasAnyUseOfValue(1)) {
503 HI, Ty, InGlue);
505 }
506
508}
509
511 switch (CC) {
533 }
534}
535
536
537
540 return false;
541
543 "Illegal Condition Code");
544
545 return true;
546}
547
548
549
551
554 return Op;
555
557
558 if (.getValueType().isFloatingPoint())
559 return Op;
560
563
564
565
567
568 return DAG.getNode(MipsISD::FPCmp, DL, MVT::Glue, LHS, RHS,
570}
571
572
578
579 return DAG.getNode((invert ? MipsISD::CMovFP_F : MipsISD::CMovFP_T), DL,
581}
582
588
589 SDValue SetCC = N->getOperand(0);
590
594
595 SDValue False = N->getOperand(2);
597
600
602
603
604
605
606
607
608
609
610 if (!FalseC)
612
614
617 SDValue True = N->getOperand(1);
618
622
624 }
625
626
627
628 SDValue True = N->getOperand(1);
630
633
634
635
636
639
641
642
643
644
645 if (Diff == 1)
647
648
649
650
651
652 if (Diff == -1) {
658 }
659
660
662}
663
669
670 SDValue ValueIfTrue = N->getOperand(0), ValueIfFalse = N->getOperand(2);
671
675
676
677
678
679
680
681
682
683 unsigned Opc = (N->getOpcode() == MipsISD::CMovFP_T) ? MipsISD::CMovFP_F :
684 MipsISD::CMovFP_T;
685
686 SDValue FCC = N->getOperand(1), Glue = N->getOperand(3);
687 return DAG.getNode(Opc, SDLoc(N), ValueIfFalse.getValueType(),
688 ValueIfFalse, FCC, ValueIfTrue, Glue);
689}
690
696
697 SDValue FirstOperand = N->getOperand(0);
698 unsigned FirstOperandOpc = FirstOperand.getOpcode();
699 SDValue Mask = N->getOperand(1);
700 EVT ValTy = N->getValueType(0);
702
704 unsigned SMPos, SMSize;
707 unsigned Opc;
708
709
713
714 if (FirstOperandOpc == ISD::SRA || FirstOperandOpc == ISD::SRL) {
715
716
717
718
719
722
724
725
726
727 if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits())
729
730 Opc = MipsISD::Ext;
731 NewOperand = FirstOperand.getOperand(0);
732 } else if (FirstOperandOpc == ISD::SHL && Subtarget.hasCnMips()) {
733
734
735
736
737
738
739
742
744
745 if (SMPos != Pos || Pos >= ValTy.getSizeInBits() || SMSize >= 32 ||
746 Pos + SMSize > ValTy.getSizeInBits())
748
749 NewOperand = FirstOperand.getOperand(0);
750
751 SMSize--;
752 Opc = MipsISD::CIns;
753 } else {
754
755
756
757
758
761
762
763 if (SMPos)
765
766 Opc = MipsISD::Ext;
767 NewOperand = FirstOperand;
768 }
769 return DAG.getNode(Opc, DL, ValTy, NewOperand,
772}
773
779
780 SDValue FirstOperand = N->getOperand(0), SecondOperand = N->getOperand(1);
781 unsigned SMPos0, SMSize0, SMPos1, SMSize1;
783
785 SecondOperand.getOpcode() == ISD::SHL) ||
787 SecondOperand.getOpcode() == ISD::AND)) {
788
789
790
791
792
793
798 ? SecondOperand.getOperand(0)
806
808 ? SecondOperand.getOperand(1)
813
814 if (SMPos0 != 0 || SMSize0 != ShlShiftValue)
816
818 EVT ValTy = N->getValueType(0);
819 SMPos1 = ShlShiftValue;
820 assert(SMPos1 < ValTy.getSizeInBits());
821 SMSize1 = (ValTy == MVT::i64 ? 64 : 32) - SMPos1;
822 return DAG.getNode(MipsISD::Ins, DL, ValTy, ShlOperand0,
824 DAG.getConstant(SMSize1, DL, MVT::i32), AndOperand0);
825 }
826
827
830
831
832
833
834
838
839
840 if (SecondOperand.getOpcode() == ISD::AND &&
841 SecondOperand.getOperand(0).getOpcode() == ISD::SHL) {
842
846
847
848 if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
850
852
855
857
858
859
860 EVT ValTy = N->getValueType(0);
861 if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits()))
863
869 } else {
870
871
872
873
874 if (~CN->getSExtValue() == ((((int64_t)1 << SMSize0) - 1) << SMPos0) &&
875 ((SMSize0 + SMPos0 <= 64 && Subtarget.hasMips64r2()) ||
876 (SMSize0 + SMPos0 <= 32))) {
877
878 bool isConstCase = SecondOperand.getOpcode() != ISD::AND;
879 if (SecondOperand.getOpcode() == ISD::AND) {
882 } else {
885 }
886
887
890
892 EVT ValTy = N->getOperand(0)->getValueType(0);
895 if (!isConstCase) {
898 SecondOperand, Const1);
899 }
901 MipsISD::Ins, DL, N->getValueType(0),
902 isConstCase
904 : SrlX,
906 DAG.getConstant(ValTy.getSizeInBits() / 8 < 8 ? SMSize0 & 31
907 : SMSize0,
908 DL, MVT::i32),
910 }
912 }
913}
914
917
918
922
923
924
925
926
930
931
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
956
960
964
965
966
969
970
971
972
973
974
977
982
983 if (!IsSigned && !IsUnsigned)
985
986
988 SDValue BottomHalf, TopHalf;
989 std::tie(BottomHalf, TopHalf) =
990 CurDAG.SplitScalar(AddOperand, DL, MVT::i32, MVT::i32);
992 CurDAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, BottomHalf, TopHalf);
993
994
996 unsigned Opcode = IsAdd ? (IsUnsigned ? MipsISD::MAddu : MipsISD::MAdd)
997 : (IsUnsigned ? MipsISD::MSubu : MipsISD::MSub);
1001 SDValue MAdd = CurDAG.getNode(Opcode, DL, MVT::Untyped, MAddOps);
1002
1003 SDValue ResLo = CurDAG.getNode(MipsISD::MFLO, DL, MVT::i32, MAdd);
1004 SDValue ResHi = CurDAG.getNode(MipsISD::MFHI, DL, MVT::i32, MAdd);
1007 return Combined;
1008}
1009
1013
1016 !Subtarget.inMips16Mode() && N->getValueType(0) == MVT::i64)
1018
1020 }
1021
1023}
1024
1028
1031 !Subtarget.inMips16Mode() && N->getValueType(0) == MVT::i64)
1033
1035 }
1036
1037
1038
1039
1040
1041 SDValue InnerAdd = N->getOperand(1);
1042 SDValue Index = N->getOperand(0);
1047
1050 if (Lo.getOpcode() != MipsISD::Lo)
1052
1053 if ((Lo.getOpcode() != MipsISD::Lo) ||
1056
1057 EVT ValTy = N->getValueType(0);
1059
1062}
1063
1067
1068
1069
1070
1073
1074 SDValue FirstOperand = N->getOperand(0);
1075 unsigned FirstOperandOpc = FirstOperand.getOpcode();
1076 SDValue SecondOperand = N->getOperand(1);
1077 EVT ValTy = N->getValueType(0);
1079
1081 unsigned SMPos, SMSize;
1084
1085
1088
1090
1091 if (Pos >= ValTy.getSizeInBits())
1093
1094 if (FirstOperandOpc != ISD::AND)
1096
1097
1101
1102
1103
1104 if (SMPos != 0 || SMSize > 32 || Pos + SMSize > ValTy.getSizeInBits())
1106
1107 NewOperand = FirstOperand.getOperand(0);
1108
1109 SMSize--;
1110
1111 return DAG.getNode(MipsISD::CIns, DL, ValTy, NewOperand,
1114}
1115
1121 }
1122
1123 SDValue N0 = N->getOperand(0);
1124 EVT VT = N->getValueType(0);
1125
1126
1127
1128
1134
1138
1139 int64_t ConstImm = ConstantOperand->getSExtValue();
1142 }
1143
1145}
1146
1148 const {
1150 unsigned Opc = N->getOpcode();
1151
1152 switch (Opc) {
1153 default: break;
1159 case MipsISD::CMovFP_F:
1160 case MipsISD::CMovFP_T:
1174 }
1175
1177}
1178
1182
1186
1188
1189
1190
1192 return C->getAPIntValue().ule(15);
1193
1194 return false;
1195}
1196
1200 N->getOperand(0).getOpcode() == ISD::SRL) ||
1202 N->getOperand(0).getOpcode() == ISD::SHL)) &&
1203 "Expected shift-shift mask");
1204
1205 if (N->getOperand(0).getValueType().isVector())
1206 return false;
1207 return true;
1208}
1209
1210void
1216
1219{
1220 switch (Op.getOpcode())
1221 {
1222 case ISD::BRCOND: return lowerBRCOND(Op, DAG);
1229 case ISD::SETCC: return lowerSETCC(Op, DAG);
1232 return lowerFSETCC(Op, DAG);
1233 case ISD::VASTART: return lowerVASTART(Op, DAG);
1234 case ISD::VAARG: return lowerVAARG(Op, DAG);
1236 case ISD::FABS: return lowerFABS(Op, DAG);
1238 return lowerFCANONICALIZE(Op, DAG);
1242 case ISD::ATOMIC_FENCE: return lowerATOMIC_FENCE(Op, DAG);
1244 case ISD::SRA_PARTS: return lowerShiftRightParts(Op, DAG, true);
1245 case ISD::SRL_PARTS: return lowerShiftRightParts(Op, DAG, false);
1246 case ISD::LOAD: return lowerLOAD(Op, DAG);
1247 case ISD::STORE: return lowerSTORE(Op, DAG);
1251 return lowerSTRICT_FP_TO_INT(Op, DAG);
1253 case ISD::READCYCLECOUNTER:
1254 return lowerREADCYCLECOUNTER(Op, DAG);
1255 }
1257}
1258
1259
1260
1261
1262
1263
1264
1265
1266static unsigned
1268{
1271 return VReg;
1272}
1273
1277 bool Is64Bit, bool IsMicroMips) {
1279 return &MBB;
1280
1281
1285 MIB = BuildMI(MBB, std::next(I), MI.getDebugLoc(),
1286 TII.get(IsMicroMips ? Mips::TEQ_MM : Mips::TEQ))
1290
1291
1292 if (Is64Bit)
1294
1295
1297
1298
1299
1300
1301 return &MBB;
1302}
1303
1307 switch (MI.getOpcode()) {
1308 default:
1310 case Mips::ATOMIC_LOAD_ADD_I8:
1311 return emitAtomicBinaryPartword(MI, BB, 1);
1312 case Mips::ATOMIC_LOAD_ADD_I16:
1313 return emitAtomicBinaryPartword(MI, BB, 2);
1314 case Mips::ATOMIC_LOAD_ADD_I32:
1315 return emitAtomicBinary(MI, BB);
1316 case Mips::ATOMIC_LOAD_ADD_I64:
1317 return emitAtomicBinary(MI, BB);
1318
1319 case Mips::ATOMIC_LOAD_AND_I8:
1320 return emitAtomicBinaryPartword(MI, BB, 1);
1321 case Mips::ATOMIC_LOAD_AND_I16:
1322 return emitAtomicBinaryPartword(MI, BB, 2);
1323 case Mips::ATOMIC_LOAD_AND_I32:
1324 return emitAtomicBinary(MI, BB);
1325 case Mips::ATOMIC_LOAD_AND_I64:
1326 return emitAtomicBinary(MI, BB);
1327
1328 case Mips::ATOMIC_LOAD_OR_I8:
1329 return emitAtomicBinaryPartword(MI, BB, 1);
1330 case Mips::ATOMIC_LOAD_OR_I16:
1331 return emitAtomicBinaryPartword(MI, BB, 2);
1332 case Mips::ATOMIC_LOAD_OR_I32:
1333 return emitAtomicBinary(MI, BB);
1334 case Mips::ATOMIC_LOAD_OR_I64:
1335 return emitAtomicBinary(MI, BB);
1336
1337 case Mips::ATOMIC_LOAD_XOR_I8:
1338 return emitAtomicBinaryPartword(MI, BB, 1);
1339 case Mips::ATOMIC_LOAD_XOR_I16:
1340 return emitAtomicBinaryPartword(MI, BB, 2);
1341 case Mips::ATOMIC_LOAD_XOR_I32:
1342 return emitAtomicBinary(MI, BB);
1343 case Mips::ATOMIC_LOAD_XOR_I64:
1344 return emitAtomicBinary(MI, BB);
1345
1346 case Mips::ATOMIC_LOAD_NAND_I8:
1347 return emitAtomicBinaryPartword(MI, BB, 1);
1348 case Mips::ATOMIC_LOAD_NAND_I16:
1349 return emitAtomicBinaryPartword(MI, BB, 2);
1350 case Mips::ATOMIC_LOAD_NAND_I32:
1351 return emitAtomicBinary(MI, BB);
1352 case Mips::ATOMIC_LOAD_NAND_I64:
1353 return emitAtomicBinary(MI, BB);
1354
1355 case Mips::ATOMIC_LOAD_SUB_I8:
1356 return emitAtomicBinaryPartword(MI, BB, 1);
1357 case Mips::ATOMIC_LOAD_SUB_I16:
1358 return emitAtomicBinaryPartword(MI, BB, 2);
1359 case Mips::ATOMIC_LOAD_SUB_I32:
1360 return emitAtomicBinary(MI, BB);
1361 case Mips::ATOMIC_LOAD_SUB_I64:
1362 return emitAtomicBinary(MI, BB);
1363
1364 case Mips::ATOMIC_SWAP_I8:
1365 return emitAtomicBinaryPartword(MI, BB, 1);
1366 case Mips::ATOMIC_SWAP_I16:
1367 return emitAtomicBinaryPartword(MI, BB, 2);
1368 case Mips::ATOMIC_SWAP_I32:
1369 return emitAtomicBinary(MI, BB);
1370 case Mips::ATOMIC_SWAP_I64:
1371 return emitAtomicBinary(MI, BB);
1372
1373 case Mips::ATOMIC_CMP_SWAP_I8:
1374 return emitAtomicCmpSwapPartword(MI, BB, 1);
1375 case Mips::ATOMIC_CMP_SWAP_I16:
1376 return emitAtomicCmpSwapPartword(MI, BB, 2);
1377 case Mips::ATOMIC_CMP_SWAP_I32:
1378 return emitAtomicCmpSwap(MI, BB);
1379 case Mips::ATOMIC_CMP_SWAP_I64:
1380 return emitAtomicCmpSwap(MI, BB);
1381
1382 case Mips::ATOMIC_LOAD_MIN_I8:
1383 return emitAtomicBinaryPartword(MI, BB, 1);
1384 case Mips::ATOMIC_LOAD_MIN_I16:
1385 return emitAtomicBinaryPartword(MI, BB, 2);
1386 case Mips::ATOMIC_LOAD_MIN_I32:
1387 return emitAtomicBinary(MI, BB);
1388 case Mips::ATOMIC_LOAD_MIN_I64:
1389 return emitAtomicBinary(MI, BB);
1390
1391 case Mips::ATOMIC_LOAD_MAX_I8:
1392 return emitAtomicBinaryPartword(MI, BB, 1);
1393 case Mips::ATOMIC_LOAD_MAX_I16:
1394 return emitAtomicBinaryPartword(MI, BB, 2);
1395 case Mips::ATOMIC_LOAD_MAX_I32:
1396 return emitAtomicBinary(MI, BB);
1397 case Mips::ATOMIC_LOAD_MAX_I64:
1398 return emitAtomicBinary(MI, BB);
1399
1400 case Mips::ATOMIC_LOAD_UMIN_I8:
1401 return emitAtomicBinaryPartword(MI, BB, 1);
1402 case Mips::ATOMIC_LOAD_UMIN_I16:
1403 return emitAtomicBinaryPartword(MI, BB, 2);
1404 case Mips::ATOMIC_LOAD_UMIN_I32:
1405 return emitAtomicBinary(MI, BB);
1406 case Mips::ATOMIC_LOAD_UMIN_I64:
1407 return emitAtomicBinary(MI, BB);
1408
1409 case Mips::ATOMIC_LOAD_UMAX_I8:
1410 return emitAtomicBinaryPartword(MI, BB, 1);
1411 case Mips::ATOMIC_LOAD_UMAX_I16:
1412 return emitAtomicBinaryPartword(MI, BB, 2);
1413 case Mips::ATOMIC_LOAD_UMAX_I32:
1414 return emitAtomicBinary(MI, BB);
1415 case Mips::ATOMIC_LOAD_UMAX_I64:
1416 return emitAtomicBinary(MI, BB);
1417
1418 case Mips::PseudoSDIV:
1419 case Mips::PseudoUDIV:
1420 case Mips::DIV:
1421 case Mips::DIVU:
1422 case Mips::MOD:
1423 case Mips::MODU:
1425 false);
1426 case Mips::SDIV_MM_Pseudo:
1427 case Mips::UDIV_MM_Pseudo:
1428 case Mips::SDIV_MM:
1429 case Mips::UDIV_MM:
1430 case Mips::DIV_MMR6:
1431 case Mips::DIVU_MMR6:
1432 case Mips::MOD_MMR6:
1433 case Mips::MODU_MMR6:
1435 case Mips::PseudoDSDIV:
1436 case Mips::PseudoDUDIV:
1437 case Mips::DDIV:
1438 case Mips::DDIVU:
1439 case Mips::DMOD:
1440 case Mips::DMODU:
1442
1443 case Mips::PseudoSELECT_I:
1444 case Mips::PseudoSELECT_I64:
1445 case Mips::PseudoSELECT_S:
1446 case Mips::PseudoSELECT_D32:
1447 case Mips::PseudoSELECT_D64:
1448 return emitPseudoSELECT(MI, BB, false, Mips::BNE);
1449 case Mips::PseudoSELECTFP_F_I:
1450 case Mips::PseudoSELECTFP_F_I64:
1451 case Mips::PseudoSELECTFP_F_S:
1452 case Mips::PseudoSELECTFP_F_D32:
1453 case Mips::PseudoSELECTFP_F_D64:
1454 return emitPseudoSELECT(MI, BB, true, Mips::BC1F);
1455 case Mips::PseudoSELECTFP_T_I:
1456 case Mips::PseudoSELECTFP_T_I64:
1457 case Mips::PseudoSELECTFP_T_S:
1458 case Mips::PseudoSELECTFP_T_D32:
1459 case Mips::PseudoSELECTFP_T_D64:
1460 return emitPseudoSELECT(MI, BB, true, Mips::BC1T);
1461 case Mips::PseudoD_SELECT_I:
1462 case Mips::PseudoD_SELECT_I64:
1463 return emitPseudoD_SELECT(MI, BB);
1464 case Mips::LDR_W:
1465 return emitLDR_W(MI, BB);
1466 case Mips::LDR_D:
1467 return emitLDR_D(MI, BB);
1468 case Mips::STR_W:
1469 return emitSTR_W(MI, BB);
1470 case Mips::STR_D:
1471 return emitSTR_D(MI, BB);
1472 }
1473}
1474
1475
1476
1478MipsTargetLowering::emitAtomicBinary(MachineInstr &MI,
1480
1485
1486 unsigned AtomicOp;
1487 bool NeedsAdditionalReg = false;
1488 switch (MI.getOpcode()) {
1489 case Mips::ATOMIC_LOAD_ADD_I32:
1490 AtomicOp = Mips::ATOMIC_LOAD_ADD_I32_POSTRA;
1491 break;
1492 case Mips::ATOMIC_LOAD_SUB_I32:
1493 AtomicOp = Mips::ATOMIC_LOAD_SUB_I32_POSTRA;
1494 break;
1495 case Mips::ATOMIC_LOAD_AND_I32:
1496 AtomicOp = Mips::ATOMIC_LOAD_AND_I32_POSTRA;
1497 break;
1498 case Mips::ATOMIC_LOAD_OR_I32:
1499 AtomicOp = Mips::ATOMIC_LOAD_OR_I32_POSTRA;
1500 break;
1501 case Mips::ATOMIC_LOAD_XOR_I32:
1502 AtomicOp = Mips::ATOMIC_LOAD_XOR_I32_POSTRA;
1503 break;
1504 case Mips::ATOMIC_LOAD_NAND_I32:
1505 AtomicOp = Mips::ATOMIC_LOAD_NAND_I32_POSTRA;
1506 break;
1507 case Mips::ATOMIC_SWAP_I32:
1508 AtomicOp = Mips::ATOMIC_SWAP_I32_POSTRA;
1509 break;
1510 case Mips::ATOMIC_LOAD_ADD_I64:
1511 AtomicOp = Mips::ATOMIC_LOAD_ADD_I64_POSTRA;
1512 break;
1513 case Mips::ATOMIC_LOAD_SUB_I64:
1514 AtomicOp = Mips::ATOMIC_LOAD_SUB_I64_POSTRA;
1515 break;
1516 case Mips::ATOMIC_LOAD_AND_I64:
1517 AtomicOp = Mips::ATOMIC_LOAD_AND_I64_POSTRA;
1518 break;
1519 case Mips::ATOMIC_LOAD_OR_I64:
1520 AtomicOp = Mips::ATOMIC_LOAD_OR_I64_POSTRA;
1521 break;
1522 case Mips::ATOMIC_LOAD_XOR_I64:
1523 AtomicOp = Mips::ATOMIC_LOAD_XOR_I64_POSTRA;
1524 break;
1525 case Mips::ATOMIC_LOAD_NAND_I64:
1526 AtomicOp = Mips::ATOMIC_LOAD_NAND_I64_POSTRA;
1527 break;
1528 case Mips::ATOMIC_SWAP_I64:
1529 AtomicOp = Mips::ATOMIC_SWAP_I64_POSTRA;
1530 break;
1531 case Mips::ATOMIC_LOAD_MIN_I32:
1532 AtomicOp = Mips::ATOMIC_LOAD_MIN_I32_POSTRA;
1533 NeedsAdditionalReg = true;
1534 break;
1535 case Mips::ATOMIC_LOAD_MAX_I32:
1536 AtomicOp = Mips::ATOMIC_LOAD_MAX_I32_POSTRA;
1537 NeedsAdditionalReg = true;
1538 break;
1539 case Mips::ATOMIC_LOAD_UMIN_I32:
1540 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I32_POSTRA;
1541 NeedsAdditionalReg = true;
1542 break;
1543 case Mips::ATOMIC_LOAD_UMAX_I32:
1544 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I32_POSTRA;
1545 NeedsAdditionalReg = true;
1546 break;
1547 case Mips::ATOMIC_LOAD_MIN_I64:
1548 AtomicOp = Mips::ATOMIC_LOAD_MIN_I64_POSTRA;
1549 NeedsAdditionalReg = true;
1550 break;
1551 case Mips::ATOMIC_LOAD_MAX_I64:
1552 AtomicOp = Mips::ATOMIC_LOAD_MAX_I64_POSTRA;
1553 NeedsAdditionalReg = true;
1554 break;
1555 case Mips::ATOMIC_LOAD_UMIN_I64:
1556 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I64_POSTRA;
1557 NeedsAdditionalReg = true;
1558 break;
1559 case Mips::ATOMIC_LOAD_UMAX_I64:
1560 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I64_POSTRA;
1561 NeedsAdditionalReg = true;
1562 break;
1563 default:
1565 }
1566
1567 Register OldVal = MI.getOperand(0).getReg();
1568 Register Ptr = MI.getOperand(1).getReg();
1569 Register Incr = MI.getOperand(2).getReg();
1571
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1611
1614
1622 if (NeedsAdditionalReg) {
1624 RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal));
1627 }
1628
1629 MI.eraseFromParent();
1630
1631 return BB;
1632}
1633
1636 unsigned SrcReg) const {
1637 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1639
1642 return BB;
1643 }
1644
1647 return BB;
1648 }
1649
1650 MachineFunction *MF = BB->getParent();
1651 MachineRegisterInfo &RegInfo = MF->getRegInfo();
1652 const TargetRegisterClass *RC = getRegClassFor(MVT::i32);
1654
1656 int64_t ShiftImm = 32 - (Size * 8);
1657
1660
1661 return BB;
1662}
1663
1667 "Unsupported size for EmitAtomicBinaryPartial.");
1668
1669 MachineFunction *MF = BB->getParent();
1670 MachineRegisterInfo &RegInfo = MF->getRegInfo();
1671 const TargetRegisterClass *RC = getRegClassFor(MVT::i32);
1672 const bool ArePtrs64bit = ABI.ArePtrs64bit();
1673 const TargetRegisterClass *RCp =
1675 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1677
1678 Register Dest = MI.getOperand(0).getReg();
1679 Register Ptr = MI.getOperand(1).getReg();
1680 Register Incr = MI.getOperand(2).getReg();
1681
1693
1694 unsigned AtomicOp = 0;
1695 bool NeedsAdditionalReg = false;
1696 switch (MI.getOpcode()) {
1697 case Mips::ATOMIC_LOAD_NAND_I8:
1698 AtomicOp = Mips::ATOMIC_LOAD_NAND_I8_POSTRA;
1699 break;
1700 case Mips::ATOMIC_LOAD_NAND_I16:
1701 AtomicOp = Mips::ATOMIC_LOAD_NAND_I16_POSTRA;
1702 break;
1703 case Mips::ATOMIC_SWAP_I8:
1704 AtomicOp = Mips::ATOMIC_SWAP_I8_POSTRA;
1705 break;
1706 case Mips::ATOMIC_SWAP_I16:
1707 AtomicOp = Mips::ATOMIC_SWAP_I16_POSTRA;
1708 break;
1709 case Mips::ATOMIC_LOAD_ADD_I8:
1710 AtomicOp = Mips::ATOMIC_LOAD_ADD_I8_POSTRA;
1711 break;
1712 case Mips::ATOMIC_LOAD_ADD_I16:
1713 AtomicOp = Mips::ATOMIC_LOAD_ADD_I16_POSTRA;
1714 break;
1715 case Mips::ATOMIC_LOAD_SUB_I8:
1716 AtomicOp = Mips::ATOMIC_LOAD_SUB_I8_POSTRA;
1717 break;
1718 case Mips::ATOMIC_LOAD_SUB_I16:
1719 AtomicOp = Mips::ATOMIC_LOAD_SUB_I16_POSTRA;
1720 break;
1721 case Mips::ATOMIC_LOAD_AND_I8:
1722 AtomicOp = Mips::ATOMIC_LOAD_AND_I8_POSTRA;
1723 break;
1724 case Mips::ATOMIC_LOAD_AND_I16:
1725 AtomicOp = Mips::ATOMIC_LOAD_AND_I16_POSTRA;
1726 break;
1727 case Mips::ATOMIC_LOAD_OR_I8:
1728 AtomicOp = Mips::ATOMIC_LOAD_OR_I8_POSTRA;
1729 break;
1730 case Mips::ATOMIC_LOAD_OR_I16:
1731 AtomicOp = Mips::ATOMIC_LOAD_OR_I16_POSTRA;
1732 break;
1733 case Mips::ATOMIC_LOAD_XOR_I8:
1734 AtomicOp = Mips::ATOMIC_LOAD_XOR_I8_POSTRA;
1735 break;
1736 case Mips::ATOMIC_LOAD_XOR_I16:
1737 AtomicOp = Mips::ATOMIC_LOAD_XOR_I16_POSTRA;
1738 break;
1739 case Mips::ATOMIC_LOAD_MIN_I8:
1740 AtomicOp = Mips::ATOMIC_LOAD_MIN_I8_POSTRA;
1741 NeedsAdditionalReg = true;
1742 break;
1743 case Mips::ATOMIC_LOAD_MIN_I16:
1744 AtomicOp = Mips::ATOMIC_LOAD_MIN_I16_POSTRA;
1745 NeedsAdditionalReg = true;
1746 break;
1747 case Mips::ATOMIC_LOAD_MAX_I8:
1748 AtomicOp = Mips::ATOMIC_LOAD_MAX_I8_POSTRA;
1749 NeedsAdditionalReg = true;
1750 break;
1751 case Mips::ATOMIC_LOAD_MAX_I16:
1752 AtomicOp = Mips::ATOMIC_LOAD_MAX_I16_POSTRA;
1753 NeedsAdditionalReg = true;
1754 break;
1755 case Mips::ATOMIC_LOAD_UMIN_I8:
1756 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I8_POSTRA;
1757 NeedsAdditionalReg = true;
1758 break;
1759 case Mips::ATOMIC_LOAD_UMIN_I16:
1760 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I16_POSTRA;
1761 NeedsAdditionalReg = true;
1762 break;
1763 case Mips::ATOMIC_LOAD_UMAX_I8:
1764 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I8_POSTRA;
1765 NeedsAdditionalReg = true;
1766 break;
1767 case Mips::ATOMIC_LOAD_UMAX_I16:
1768 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I16_POSTRA;
1769 NeedsAdditionalReg = true;
1770 break;
1771 default:
1772 llvm_unreachable("Unknown subword atomic pseudo for expansion!");
1773 }
1774
1775
1779 MF->insert(It, exitMBB);
1780
1781
1785
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798 int64_t MaskImm = (Size == 1) ? 255 : 65535;
1804 .addReg(Ptr, 0, ArePtrs64bit ? Mips::sub_32 : 0).addImm(3);
1807 } else {
1812 }
1819
1820
1821
1822
1823
1824
1825 MachineInstrBuilder MIB =
1828 .addReg(AlignedAddr)
1839 if (NeedsAdditionalReg) {
1843 }
1844
1845 MI.eraseFromParent();
1846
1847 return exitMBB;
1848}
1849
1850
1851
1852
1853
1854
1856MipsTargetLowering::emitAtomicCmpSwap(MachineInstr &MI,
1858
1859 assert((MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ||
1860 MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I64) &&
1861 "Unsupported atomic pseudo for EmitAtomicCmpSwap.");
1862
1863 const unsigned Size = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ? 4 : 8;
1864
1865 MachineFunction *MF = BB->getParent();
1868 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1870
1871 unsigned AtomicOp = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32
1872 ? Mips::ATOMIC_CMP_SWAP_I32_POSTRA
1873 : Mips::ATOMIC_CMP_SWAP_I64_POSTRA;
1874 Register Dest = MI.getOperand(0).getReg();
1875 Register Ptr = MI.getOperand(1).getReg();
1876 Register OldVal = MI.getOperand(2).getReg();
1877 Register NewVal = MI.getOperand(3).getReg();
1878
1879 Register Scratch = MRI.createVirtualRegister(RC);
1881
1882
1883
1884
1885
1886
1887 Register PtrCopy = MRI.createVirtualRegister(MRI.getRegClass(Ptr));
1888 Register OldValCopy = MRI.createVirtualRegister(MRI.getRegClass(OldVal));
1889 Register NewValCopy = MRI.createVirtualRegister(MRI.getRegClass(NewVal));
1890
1894
1895
1896
1897
1898
1906
1907 MI.eraseFromParent();
1908
1909 return BB;
1910}
1911
1912MachineBasicBlock *MipsTargetLowering::emitAtomicCmpSwapPartword(
1915 "Unsupported size for EmitAtomicCmpSwapPartial.");
1916
1917 MachineFunction *MF = BB->getParent();
1918 MachineRegisterInfo &RegInfo = MF->getRegInfo();
1919 const TargetRegisterClass *RC = getRegClassFor(MVT::i32);
1920 const bool ArePtrs64bit = ABI.ArePtrs64bit();
1921 const TargetRegisterClass *RCp =
1923 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1925
1926 Register Dest = MI.getOperand(0).getReg();
1927 Register Ptr = MI.getOperand(1).getReg();
1928 Register CmpVal = MI.getOperand(2).getReg();
1929 Register NewVal = MI.getOperand(3).getReg();
1930
1942 unsigned AtomicOp = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I8
1943 ? Mips::ATOMIC_CMP_SWAP_I8_POSTRA
1944 : Mips::ATOMIC_CMP_SWAP_I16_POSTRA;
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1958
1959
1963 MF->insert(It, exitMBB);
1964
1965
1969
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985 int64_t MaskImm = (Size == 1) ? 255 : 65535;
1986 BuildMI(BB, DL, TII->get(ArePtrs64bit ? Mips::DADDiu : Mips::ADDiu), MaskLSB2)
1988 BuildMI(BB, DL, TII->get(ArePtrs64bit ? Mips::AND64 : Mips::AND), AlignedAddr)
1991 .addReg(Ptr, 0, ArePtrs64bit ? Mips::sub_32 : 0).addImm(3);
1994 } else {
1999 }
2013
2014
2015
2016
2017
2020 .addReg(AlignedAddr)
2022 .addReg(ShiftedCmpVal)
2024 .addReg(ShiftedNewVal)
2030
2031 MI.eraseFromParent();
2032
2033 return exitMBB;
2034}
2035
2036SDValue MipsTargetLowering::lowerREADCYCLECOUNTER(SDValue Op,
2041 unsigned RdhwrOpc, DestReg;
2043
2044 if (PtrVT == MVT::i64) {
2045 RdhwrOpc = Mips::RDHWR64;
2047 SDNode *Rdhwr = DAG.getMachineNode(RdhwrOpc, DL, MVT::i64, MVT::Glue,
2054 Results.push_back(ResNode);
2056 } else {
2057 RdhwrOpc = Mips::RDHWR;
2059 SDNode *Rdhwr = DAG.getMachineNode(RdhwrOpc, DL, MVT::i32, MVT::Glue,
2069 }
2070
2072}
2073
2075
2076
2077 SDValue Chain = Op.getOperand(0);
2078 SDValue Dest = Op.getOperand(2);
2080
2083
2084
2085 if (CondRes.getOpcode() != MipsISD::FPCmp)
2086 return Op;
2087
2093 return DAG.getNode(MipsISD::FPBrcond, DL, Op.getValueType(), Chain, BrCode,
2094 FCC0, Dest, CondRes);
2095}
2096
2097SDValue MipsTargetLowering::
2099{
2102
2103
2104 if (Cond.getOpcode() != MipsISD::FPCmp)
2105 return Op;
2106
2108 SDLoc(Op));
2109}
2110
2114
2115 assert(Cond.getOpcode() == MipsISD::FPCmp &&
2116 "Floating point operand expected.");
2117
2121
2123}
2124
2127
2129 SDValue Chain = Op.getOperand(0);
2133
2139
2141}
2142
2145 EVT Ty = Op.getValueType();
2147 const GlobalValue *GV = N->getGlobal();
2148
2151 "Windows is the only supported COFF target");
2155 }
2156
2158 const MipsTargetObjectFile *TLOF =
2159 static_cast<const MipsTargetObjectFile *>(
2162 if (GO && TLOF->IsGlobalInSmallSection(GO, getTargetMachine()))
2163
2165
2166
2168
2170 }
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2185
2191
2196}
2197
2201 EVT Ty = Op.getValueType();
2202
2206
2208}
2209
2210SDValue MipsTargetLowering::
2212{
2213
2214
2215
2216
2220
2221 SDLoc DL(GA);
2222 const GlobalValue *GV = GA->getGlobal();
2224
2226
2228
2231
2237
2239
2241 Args.emplace_back(Argument, PtrTy);
2242
2243 TargetLowering::CallLoweringInfo CLI(DAG);
2244 CLI.setDebugLoc(DL)
2246 .setLibCallee(CallingConv::C, PtrTy, TlsGetAddr, std::move(Args));
2247 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
2248
2249 SDValue Ret = CallResult.first;
2250
2252 return Ret;
2253
2262 }
2263
2266
2270 TGA);
2273 } else {
2274
2283 }
2284
2285 SDValue ThreadPointer = DAG.getNode(MipsISD::ThreadPointer, DL, PtrVT);
2287}
2288
2289SDValue MipsTargetLowering::
2291{
2293 EVT Ty = Op.getValueType();
2294
2298
2300}
2301
2302SDValue MipsTargetLowering::
2304{
2306 EVT Ty = Op.getValueType();
2307
2309 const MipsTargetObjectFile *TLOF =
2310 static_cast<const MipsTargetObjectFile *>(
2312
2315
2317
2320 }
2321
2323}
2324
2327 MipsFunctionInfo *FuncInfo = MF.getInfo();
2328
2332
2333
2334
2336 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
2337 MachinePointerInfo(SV));
2338}
2339
2341 SDNode *Node = Op.getNode();
2342 EVT VT = Node->getValueType(0);
2344 SDValue VAListPtr = Node->getOperand(1);
2346 llvm::MaybeAlign(Node->getConstantOperandVal(3)).valueOrOne();
2348 SDLoc DL(Node);
2349 unsigned ArgSlotSizeInBytes = (ABI.IsN32() || ABI.IsN64()) ? 8 : 4;
2350
2352 VAListPtr, MachinePointerInfo(SV));
2353 SDValue VAList = VAListLoad;
2354
2355
2356
2357
2358
2359
2360
2361
2366
2370 }
2371
2372
2374 unsigned ArgSizeInBytes =
2380
2382 MachinePointerInfo(SV));
2383
2384
2385
2386
2387
2388
2389 if (.isLittle() && ArgSizeInBytes < ArgSlotSizeInBytes) {
2390 unsigned Adjustment = ArgSlotSizeInBytes - ArgSizeInBytes;
2393 }
2394
2395 return DAG.getLoad(VT, DL, Chain, VAList, MachinePointerInfo());
2396}
2397
2399 bool HasExtractInsert) {
2400 EVT TyX = Op.getOperand(0).getValueType();
2401 EVT TyY = Op.getOperand(1).getValueType();
2406
2407
2408
2409 SDValue X = (TyX == MVT::f32) ?
2410 DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(0)) :
2411 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
2412 Const1);
2413 SDValue Y = (TyY == MVT::f32) ?
2414 DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(1)) :
2415 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(1),
2416 Const1);
2417
2418 if (HasExtractInsert) {
2419
2420
2421 SDValue E = DAG.getNode(MipsISD::Ext, DL, MVT::i32, Y, Const31, Const1);
2422 Res = DAG.getNode(MipsISD::Ins, DL, MVT::i32, E, Const31, Const1, X);
2423 } else {
2424
2425
2426
2427
2428
2434 }
2435
2436 if (TyX == MVT::f32)
2437 return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), Res);
2438
2439 SDValue LowX = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
2440 Op.getOperand(0),
2442 return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, LowX, Res);
2443}
2444
2446 bool HasExtractInsert) {
2447 unsigned WidthX = Op.getOperand(0).getValueSizeInBits();
2448 unsigned WidthY = Op.getOperand(1).getValueSizeInBits();
2452
2453
2456
2457 if (HasExtractInsert) {
2458
2459
2461 DAG.getConstant(WidthY - 1, DL, MVT::i32), Const1);
2462
2463 if (WidthX > WidthY)
2465 else if (WidthY > WidthX)
2467
2469 DAG.getConstant(WidthX - 1, DL, MVT::i32), Const1,
2470 X);
2471 return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), I);
2472 }
2473
2474
2475
2476
2477
2478
2483
2484 if (WidthX > WidthY)
2486 else if (WidthY > WidthX)
2488
2492 return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), Or);
2493}
2494
2499
2501}
2502
2504 bool HasExtractInsert) const {
2507
2510
2511
2512
2513 SDValue X = (Op.getValueType() == MVT::f32)
2514 ? DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(0))
2515 : DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
2516 Op.getOperand(0), Const1);
2517
2518
2519 if (HasExtractInsert)
2520 Res = DAG.getNode(MipsISD::Ins, DL, MVT::i32,
2523 else {
2524
2525
2528 }
2529
2530 if (Op.getValueType() == MVT::f32)
2531 return DAG.getNode(ISD::BITCAST, DL, MVT::f32, Res);
2532
2533
2534
2535
2536
2538 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
2540 return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, LowX, Res);
2541}
2542
2544 bool HasExtractInsert) const {
2547
2550
2551
2553
2554
2555 if (HasExtractInsert)
2556 Res = DAG.getNode(MipsISD::Ins, DL, MVT::i64,
2557 DAG.getRegister(Mips::ZERO_64, MVT::i64),
2559 else {
2562 }
2563
2564 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, Res);
2565}
2566
2568 if ((ABI.IsN32() || ABI.IsN64()) && (Op.getValueType() == MVT::f64))
2569 return lowerFABS64(Op, DAG, Subtarget.hasExtractInsert());
2570
2571 return lowerFABS32(Op, DAG, Subtarget.hasExtractInsert());
2572}
2573
2577 EVT VT = Op.getValueType();
2578 SDValue Operand = Op.getOperand(0);
2579 SDNodeFlags Flags = Op->getFlags();
2580
2582 return Operand;
2583
2586}
2587
2588SDValue MipsTargetLowering::
2590
2591 if (Op.getConstantOperandVal(0) != 0) {
2593 "return address can be determined only for current frame");
2595 }
2596
2599 EVT VT = Op.getValueType();
2602 DAG.getEntryNode(), DL, ABI.IsN64() ? Mips::FP_64 : Mips::FP, VT);
2603 return FrameAddr;
2604}
2605
2608
2609 if (Op.getConstantOperandVal(0) != 0) {
2611 "return address can be determined only for current frame");
2613 }
2614
2617 MVT VT = Op.getSimpleValueType();
2618 unsigned RA = ABI.IsN64() ? Mips::RA_64 : Mips::RA;
2620
2621
2624}
2625
2626
2627
2628
2629
2631 const {
2633 MipsFunctionInfo *MipsFI = MF.getInfo();
2634
2636 SDValue Chain = Op.getOperand(0);
2638 SDValue Handler = Op.getOperand(2);
2640 EVT Ty = ABI.IsN64() ? MVT::i64 : MVT::i32;
2641
2642
2643
2644 unsigned OffsetReg = ABI.IsN64() ? Mips::V1_64 : Mips::V1;
2645 unsigned AddrReg = ABI.IsN64() ? Mips::V0_64 : Mips::V0;
2648 return DAG.getNode(MipsISD::EH_RETURN, DL, MVT::Other, Chain,
2652}
2653
2656
2657
2658 unsigned SType = 0;
2660 return DAG.getNode(MipsISD::Sync, DL, MVT::Other, Op.getOperand(0),
2662}
2663
2667 MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;
2668
2670 SDValue Shamt = Op.getOperand(2);
2671
2672
2673
2674
2675
2676
2691
2694}
2695
2697 bool IsSRA) const {
2700 SDValue Shamt = Op.getOperand(2);
2701 MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2730
2732 SDVTList VTList = DAG.getVTList(VT, VT);
2735 DL, VTList, Cond, ShiftRightHi,
2737 ShiftRightHi);
2738 }
2739
2742 IsSRA ? Ext : DAG.getConstant(0, DL, VT), ShiftRightHi);
2743
2746}
2747
2750 SDValue Ptr = LD->getBasePtr();
2751 EVT VT = LD->getValueType(0), MemVT = LD->getMemoryVT();
2755
2759
2760 SDValue Ops[] = { Chain, Ptr, Src };
2762 LD->getMemOperand());
2763}
2764
2765
2768 EVT MemVT = LD->getMemoryVT();
2769
2770 if (Subtarget.systemSupportsUnalignedAccess())
2771 return Op;
2772
2773
2774 if ((LD->getAlign().value() >= (MemVT.getSizeInBits() / 8)) ||
2775 ((MemVT != MVT::i32) && (MemVT != MVT::i64)))
2777
2778 bool IsLittle = Subtarget.isLittle();
2779 EVT VT = Op.getValueType();
2781 SDValue Chain = LD->getChain(), Undef = DAG.getUNDEF(VT);
2782
2783 assert((VT == MVT::i32) || (VT == MVT::i64));
2784
2785
2786
2787
2788
2789
2792 IsLittle ? 7 : 0);
2794 IsLittle ? 0 : 7);
2795 }
2796
2798 IsLittle ? 3 : 0);
2800 IsLittle ? 0 : 3);
2801
2802
2803
2804
2805
2806
2807
2808
2809 if ((VT == MVT::i32) || (ExtType == ISD::SEXTLOAD) ||
2811 return LWR;
2812
2814
2815
2816
2817
2818
2819
2820
2821
2828}
2829
2845
2846
2848 bool IsLittle) {
2850 EVT VT = Value.getValueType();
2851
2852
2853
2854
2855
2856
2857
2860 IsLittle ? 3 : 0);
2861 return createStoreLR(MipsISD::SWR, DAG, SD, SWL, IsLittle ? 0 : 3);
2862 }
2863
2864 assert(VT == MVT::i64);
2865
2866
2867
2868
2869
2870
2871 SDValue SDL = createStoreLR(MipsISD::SDL, DAG, SD, Chain, IsLittle ? 7 : 0);
2872 return createStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7);
2873}
2874
2875
2877 bool SingleFloat) {
2879
2883
2890}
2891
2895
2896
2897 if (.systemSupportsUnalignedAccess() &&
2899 ((MemVT == MVT::i32) || (MemVT == MVT::i64)))
2901
2903}
2904
2907
2908
2909
2911 EVT ValTy = Op->getValueType(0);
2914}
2915
2920
2923 Op.getOperand(0));
2924 return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc);
2925}
2926
2927SDValue MipsTargetLowering::lowerSTRICT_FP_TO_INT(SDValue Op,
2929 assert(Op->isStrictFPOpcode());
2930 SDValue SrcVal = Op.getOperand(1);
2931 SDLoc Loc(Op);
2932
2936 Loc, Op.getValueType(), SrcVal);
2937
2939}
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2970 State.getMachineFunction().getSubtarget());
2971
2972 static const MCPhysReg IntRegs[] = { Mips::A0, Mips::A1, Mips::A2, Mips::A3 };
2973
2974 static const MCPhysReg F32Regs[] = { Mips::F12, Mips::F14 };
2975
2976 static const MCPhysReg FloatVectorIntRegs[] = { Mips::A0, Mips::A2 };
2977
2978
2980 return true;
2981
2982
2984 if (LocVT == MVT::i8 || LocVT == MVT::i16 || LocVT == MVT::i32) {
2985 LocVT = MVT::i32;
2986 if (ArgFlags.isSExt())
2988 else if (ArgFlags.isZExt())
2990 else
2992 }
2993 }
2994
2995
2996 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
2997 LocVT = MVT::i32;
2998 if (ArgFlags.isSExt())
3000 else if (ArgFlags.isZExt())
3002 else
3004 }
3005
3006 unsigned Reg;
3007
3008
3009
3010
3011 bool AllocateFloatsInIntReg = State.isVarArg() || ValNo > 1 ||
3012 State.getFirstUnallocated(F32Regs) != ValNo;
3014 bool isI64 = (ValVT == MVT::i32 && OrigAlign == Align(8));
3016
3017
3018 if (ValVT == MVT::i32 && isVectorFloat) {
3019
3020
3021
3022
3023 if (ArgFlags.isSplit()) {
3024 Reg = State.AllocateReg(FloatVectorIntRegs);
3025 if (Reg == Mips::A2)
3026 State.AllocateReg(Mips::A1);
3027 else if (Reg == 0)
3028 State.AllocateReg(Mips::A3);
3029 } else {
3030
3031
3033 }
3034 } else if (ValVT == MVT::i32 ||
3035 (ValVT == MVT::f32 && AllocateFloatsInIntReg)) {
3037
3038
3039 if (isI64 && (Reg == Mips::A1 || Reg == Mips::A3))
3041 LocVT = MVT::i32;
3042 } else if (ValVT == MVT::f64 && AllocateFloatsInIntReg) {
3043
3044
3046 if (Reg == Mips::A1 || Reg == Mips::A3)
3048
3049 if (Reg) {
3050 LocVT = MVT::i32;
3051
3052 State.addLoc(
3056 State.addLoc(
3058 return false;
3059 }
3060 } else if (ValVT.isFloatingPoint() && !AllocateFloatsInIntReg) {
3061
3062 if (ValVT == MVT::f32) {
3064
3065 State.AllocateReg(IntRegs);
3066 } else {
3067 Reg = State.AllocateReg(F64Regs);
3068
3070 if (Reg2 == Mips::A1 || Reg2 == Mips::A3)
3071 State.AllocateReg(IntRegs);
3072 State.AllocateReg(IntRegs);
3073 }
3074 } else
3076
3077 if () {
3078 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);
3080 } else
3082
3083 return false;
3084}
3085
3090 static const MCPhysReg F64Regs[] = { Mips::D6, Mips::D7 };
3091
3092 return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State,
3093 F64Regs);
3094}
3095
3100 static const MCPhysReg F64Regs[] = { Mips::D12_64, Mips::D14_64 };
3101
3102 return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State,
3103 F64Regs);
3104}
3105
3106[[maybe_unused]] static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,
3110
3111#include "MipsGenCallingConv.inc"
3112
3114 return CC_Mips_FixedArg;
3115 }
3116
3118 return RetCC_Mips;
3119 }
3120
3121
3122
3123
3124SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset,
3126 const SDLoc &DL, bool IsTailCall,
3128 if (!IsTailCall) {
3133 }
3134
3140}
3141
3144 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
3145 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158 if (IsPICCall && !InternalLinkage && IsCallReloc) {
3159 unsigned GPReg = ABI.IsN64() ? Mips::GP_64 : Mips::GP;
3160 EVT Ty = ABI.IsN64() ? MVT::i64 : MVT::i32;
3161 RegsToPass.push_back(std::make_pair(GPReg, getGlobalReg(CLI.DAG, Ty)));
3162 }
3163
3164
3165
3166
3167
3169
3170 for (auto &R : RegsToPass) {
3171 Chain = CLI.DAG.getCopyToReg(Chain, CLI.DL, R.first, R.second, InGlue);
3173 }
3174
3175
3176
3177 for (auto &R : RegsToPass)
3178 Ops.push_back(CLI.DAG.getRegister(R.first, R.second.getValueType()));
3179
3180
3184 assert(Mask && "Missing call preserved mask for calling convention");
3185 if (Subtarget.inMips16HardFloat()) {
3187 StringRef Sym = G->getGlobal()->getName();
3188 Function *F = G->getGlobal()->getParent()->getFunction(Sym);
3189 if (F && F->hasFnAttribute("__Mips16RetHelper")) {
3191 }
3192 }
3193 }
3195
3197 Ops.push_back(InGlue);
3198}
3199
3202 switch (MI.getOpcode()) {
3203 default:
3204 return;
3205 case Mips::JALR:
3206 case Mips::JALRPseudo:
3207 case Mips::JALR64:
3208 case Mips::JALR64Pseudo:
3209 case Mips::JALR16_MM:
3210 case Mips::JALRC16_MMR6:
3211 case Mips::TAILCALLREG:
3212 case Mips::TAILCALLREG64:
3213 case Mips::TAILCALLR6REG:
3214 case Mips::TAILCALL64R6REG:
3215 case Mips::TAILCALLREG_MM:
3216 case Mips::TAILCALLREG_MMR6: {
3220 Node->getNumOperands() < 1 ||
3221 Node->getOperand(0).getNumOperands() < 2) {
3222 return;
3223 }
3224
3225
3226
3227 const SDValue TargetAddr = Node->getOperand(0).getOperand(1);
3231
3232
3233
3235 LLVM_DEBUG(dbgs() << "Not adding R_MIPS_JALR against data symbol "
3236 << G->getGlobal()->getName() << "\n");
3237 return;
3238 }
3239 Sym = G->getGlobal()->getName();
3240 }
3243 Sym = ES->getSymbol();
3244 }
3245
3246 if (Sym.empty())
3247 return;
3248
3251 LLVM_DEBUG(dbgs() << "Adding R_MIPS_JALR against " << Sym << "\n");
3253 }
3254 }
3255}
3256
3257
3258
3271 bool IsVarArg = CLI.IsVarArg;
3273
3279
3280
3285
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313 bool MemcpyInByVal = ES && StringRef(ES->getSymbol()) == "memcpy" &&
3315 Chain.getOpcode() == ISD::CALLSEQ_START;
3316
3317
3318
3319 unsigned ReservedArgArea =
3320 MemcpyInByVal ? 0 : ABI.GetCalleeAllocdArgSizeInBytes(CallConv);
3321 CCInfo.AllocateStack(ReservedArgArea, Align(1));
3322
3323 CCInfo.AnalyzeCallOperands(Outs, CC_Mips);
3324
3325
3326 unsigned StackSize = CCInfo.getStackSize();
3327
3328
3330
3333
3334
3335
3336 bool InternalLinkage = false;
3337 if (IsTailCall) {
3338 IsTailCall = isEligibleForTailCallOptimization(
3341 InternalLinkage = G->getGlobal()->hasInternalLinkage();
3342 IsTailCall &= (InternalLinkage || G->getGlobal()->hasLocalLinkage() ||
3343 G->getGlobal()->hasPrivateLinkage() ||
3344 G->getGlobal()->hasHiddenVisibility() ||
3345 G->getGlobal()->hasProtectedVisibility());
3346 }
3347 }
3349 report_fatal_error("failed to perform tail call elimination on a call "
3350 "site marked musttail");
3351
3352 if (IsTailCall)
3353 ++NumTailCalls;
3354
3355
3356
3357
3359 StackSize = alignTo(StackSize, StackAlignment);
3360
3361 if (!(IsTailCall || MemcpyInByVal))
3363
3367 std::deque<std::pair<unsigned, SDValue>> RegsToPass;
3369
3370 CCInfo.rewindByValRegsInfo();
3371
3372
3373 for (unsigned i = 0, e = ArgLocs.size(), OutIdx = 0; i != e; ++i, ++OutIdx) {
3374 SDValue Arg = OutVals[OutIdx];
3375 CCValAssign &VA = ArgLocs[i];
3377 ISD::ArgFlagsTy Flags = Outs[OutIdx].Flags;
3378 bool UseUpperBits = false;
3379
3380
3381 if (Flags.isByVal()) {
3382 unsigned FirstByValReg, LastByValReg;
3383 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();
3384 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);
3385
3387 "ByVal args of size 0 should have been ignored by front-end.");
3388 assert(ByValIdx < CCInfo.getInRegsParamsCount());
3389 assert(!IsTailCall &&
3390 "Do not tail-call optimize if there is a byval argument.");
3391 passByValArg(Chain, DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg,
3392 FirstByValReg, LastByValReg, Flags, Subtarget.isLittle(),
3393 VA);
3394 CCInfo.nextInRegsParam();
3395 continue;
3396 }
3397
3398
3400 default:
3404 if ((ValVT == MVT::f32 && LocVT == MVT::i32) ||
3405 (ValVT == MVT::f64 && LocVT == MVT::i64) ||
3406 (ValVT == MVT::i64 && LocVT == MVT::f64))
3407 Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg);
3408 else if (ValVT == MVT::f64 && LocVT == MVT::i32) {
3415
3417
3419 Register LocRegHigh = ArgLocs[++i].getLocReg();
3420 RegsToPass.push_back(std::make_pair(LocRegLo, Lo));
3421 RegsToPass.push_back(std::make_pair(LocRegHigh, Hi));
3422 continue;
3423 }
3424 }
3425 break;
3427 Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg);
3428 break;
3430 UseUpperBits = true;
3431 [[fallthrough]];
3434 break;
3436 UseUpperBits = true;
3437 [[fallthrough]];
3440 break;
3442 UseUpperBits = true;
3443 [[fallthrough]];
3446 break;
3447 }
3448
3449 if (UseUpperBits) {
3450 unsigned ValSizeInBits = Outs[OutIdx].ArgVT.getSizeInBits();
3455 }
3456
3457
3458
3460 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
3461
3462
3463
3465 continue;
3466
3467
3469 if (Options.EmitCallSiteInfo)
3471
3472 continue;
3473 }
3474
3475
3477
3478
3479
3481 Chain, Arg, DL, IsTailCall, DAG));
3482 }
3483
3484
3485
3486 if (!MemOpChains.empty())
3488
3489
3490
3491
3492
3493 EVT Ty = Callee.getValueType();
3494 bool GlobalOrExternal = false, IsCallReloc = false;
3495
3496
3497
3498
3499 if (.isABICalls() && !IsPIC) {
3500
3501
3502
3509 bool UseLongCalls = Subtarget.useLongCalls();
3510
3511
3513 if (F->hasFnAttribute("long-call"))
3514 UseLongCalls = true;
3515 else if (F->hasFnAttribute("short-call"))
3516 UseLongCalls = false;
3517 }
3518 if (UseLongCalls)
3522 }
3523 }
3524
3527 G->getGlobal()->hasDLLImportStorageClass()) {
3529 "Windows is the only supported COFF target");
3530 auto PtrInfo = MachinePointerInfo();
3533 } else if (IsPIC) {
3534 const GlobalValue *Val = G->getGlobal();
3536
3537 if (InternalLinkage)
3543 IsCallReloc = true;
3544 } else {
3547 IsCallReloc = true;
3548 }
3549 } else
3553 GlobalOrExternal = true;
3554 }
3556 const char *Sym = S->getSymbol();
3557
3558 if (!IsPIC)
3565 IsCallReloc = true;
3566 } else {
3569 IsCallReloc = true;
3570 }
3571
3572 GlobalOrExternal = true;
3573 }
3574
3576 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
3577
3578 getOpndList(Ops, RegsToPass, IsPIC, GlobalOrExternal, InternalLinkage,
3579 IsCallReloc, CLI, Callee, Chain);
3580
3581 if (IsTailCall) {
3585 return Ret;
3586 }
3587
3588 Chain = DAG.getNode(MipsISD::JmpLink, DL, NodeTys, Ops);
3590
3592
3593
3594
3595 if (!(MemcpyInByVal)) {
3596 Chain = DAG.getCALLSEQ_END(Chain, StackSize, 0, InGlue, DL);
3598 }
3599
3600
3601
3602 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, DL, DAG,
3603 InVals, CLI);
3604}
3605
3606
3607
3608SDValue MipsTargetLowering::LowerCallResult(
3613
3615 MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
3617
3618 CCInfo.AnalyzeCallResult(Ins, RetCC_Mips);
3619
3620
3621 for (unsigned i = 0; i != RVLocs.size(); ++i) {
3622 CCValAssign &VA = RVLocs[i];
3623 assert(VA.isRegLoc() && "Can only return in registers!");
3624
3626 RVLocs[i].getLocVT(), InGlue);
3629
3631 unsigned ValSizeInBits = Ins[i].ArgVT.getSizeInBits();
3633 unsigned Shift =
3638 }
3639
3641 default:
3644 break;
3647 break;
3651 break;
3657 break;
3663 break;
3664 }
3665
3667 }
3668
3669 return Chain;
3670}
3671
3677
3678
3680 default:
3681 break;
3687 unsigned Opcode =
3692 break;
3693 }
3694 }
3695
3696
3697
3698
3699
3701 default:
3704 break;
3708 break;
3713 break;
3718 break;
3720 Val = DAG.getNode(ISD::BITCAST, DL, ValVT, Val);
3721 break;
3722 }
3723
3724 return Val;
3725}
3726
3727
3728
3729
3730
3731
3732SDValue MipsTargetLowering::LowerFormalArguments(
3738 MipsFunctionInfo *MipsFI = MF.getInfo();
3739
3741
3742
3743 std::vector OutChains;
3744
3745
3747 MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
3749 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), Align(1));
3752
3753 if (Func.hasFnAttribute("interrupt") && .arg_empty())
3755 "Functions with the interrupt attribute cannot have arguments!");
3756
3757 CCInfo.AnalyzeFormalArguments(Ins, CC_Mips_FixedArg);
3759 CCInfo.getInRegsParamsCount() > 0);
3760
3761 unsigned CurArgIdx = 0;
3762 CCInfo.rewindByValRegsInfo();
3763
3764 for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) {
3765 CCValAssign &VA = ArgLocs[i];
3766 if (Ins[InsIdx].isOrigArg()) {
3767 std::advance(FuncArg, Ins[InsIdx].getOrigArgIndex() - CurArgIdx);
3768 CurArgIdx = Ins[InsIdx].getOrigArgIndex();
3769 }
3771 ISD::ArgFlagsTy Flags = Ins[InsIdx].Flags;
3772 bool IsRegLoc = VA.isRegLoc();
3773
3774 if (Flags.isByVal()) {
3775 assert(Ins[InsIdx].isOrigArg() && "Byval arguments cannot be implicit");
3776 unsigned FirstByValReg, LastByValReg;
3777 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();
3778 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);
3779
3781 "ByVal args of size 0 should have been ignored by front-end.");
3782 assert(ByValIdx < CCInfo.getInRegsParamsCount());
3783 copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg,
3784 FirstByValReg, LastByValReg, VA, CCInfo);
3785 CCInfo.nextInRegsParam();
3786 continue;
3787 }
3788
3789
3790 if (IsRegLoc) {
3793 const TargetRegisterClass *RC = getRegClassFor(RegVT);
3794
3795
3796
3799
3800 ArgValue =
3802
3803
3804
3805 if ((RegVT == MVT::i32 && ValVT == MVT::f32) ||
3806 (RegVT == MVT::i64 && ValVT == MVT::f64) ||
3807 (RegVT == MVT::f64 && ValVT == MVT::i64))
3808 ArgValue = DAG.getNode(ISD::BITCAST, DL, ValVT, ArgValue);
3809 else if (ABI.IsO32() && RegVT == MVT::i32 &&
3810 ValVT == MVT::f64) {
3811 assert(VA.needsCustom() && "Expected custom argument for f64 split");
3812 CCValAssign &NextVA = ArgLocs[++i];
3813 unsigned Reg2 =
3818 ArgValue = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64,
3819 ArgValue, ArgValue2);
3820 }
3821
3823 } else {
3825
3826 assert(!VA.needsCustom() && "unexpected custom memory argument");
3827
3828
3830
3831
3834
3835
3838 LocVT, DL, Chain, FIN,
3840 OutChains.push_back(ArgValue.getValue(1));
3841
3842 ArgValue =
3844
3846 }
3847 }
3848
3849 for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) {
3850
3851 if (ArgLocs[i].needsCustom()) {
3852 ++i;
3853 continue;
3854 }
3855
3856
3857
3858
3859 if (Ins[InsIdx].Flags.isSRet()) {
3861 if () {
3865 }
3868 break;
3869 }
3870 }
3871
3872 if (IsVarArg)
3873 writeVarArgRegs(OutChains, Chain, DL, DAG, CCInfo);
3874
3875
3876
3877 if (!OutChains.empty()) {
3878 OutChains.push_back(Chain);
3880 }
3881
3882 return Chain;
3883}
3884
3885
3886
3887
3888
3889bool
3890MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
3895 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
3896 return CCInfo.CheckReturn(Outs, RetCC_Mips);
3897}
3898
3899bool MipsTargetLowering::shouldSignExtendTypeInLibCall(Type *Ty,
3900 bool IsSigned) const {
3902 return true;
3903
3904 return IsSigned;
3905}
3906
3912 MipsFunctionInfo *MipsFI = MF.getInfo();
3913
3915
3916 return DAG.getNode(MipsISD::ERet, DL, MVT::Other, RetOps);
3917}
3918
3921 bool IsVarArg,
3925
3926
3929
3930
3931 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
3932
3933
3934 CCInfo.AnalyzeReturn(Outs, RetCC_Mips);
3935
3938
3939
3940 for (unsigned i = 0; i != RVLocs.size(); ++i) {
3941 SDValue Val = OutVals[i];
3942 CCValAssign &VA = RVLocs[i];
3943 assert(VA.isRegLoc() && "Can only return in registers!");
3944 bool UseUpperBits = false;
3945
3947 default:
3950 break;
3953 break;
3955 UseUpperBits = true;
3956 [[fallthrough]];
3959 break;
3961 UseUpperBits = true;
3962 [[fallthrough]];
3965 break;
3967 UseUpperBits = true;
3968 [[fallthrough]];
3971 break;
3972 }
3973
3974 if (UseUpperBits) {
3975 unsigned ValSizeInBits = Outs[i].ArgVT.getSizeInBits();
3980 }
3981
3983
3984
3987 }
3988
3989
3990
3991
3992
3994 MipsFunctionInfo *MipsFI = MF.getInfo();
3996
3997 if ()
3998 llvm_unreachable("sret virtual register not created in the entry block");
4001 unsigned V0 = ABI.IsN64() ? Mips::V0_64 : Mips::V0;
4002
4006 }
4007
4008 RetOps[0] = Chain;
4009
4010
4013
4014
4016 return LowerInterruptReturn(RetOps, DL, DAG);
4017
4018
4019 return DAG.getNode(MipsISD::Ret, DL, MVT::Other, RetOps);
4020}
4021
4022
4023
4024
4025
4026
4027
4029MipsTargetLowering::getConstraintType(StringRef Constraint) const {
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041 if (Constraint.size() == 1) {
4042 switch (Constraint[0]) {
4043 default : break;
4044 case 'd':
4045 case 'y':
4046 case 'f':
4047 case 'c':
4048 case 'l':
4049 case 'x':
4051 case 'R':
4053 }
4054 }
4055
4056 if (Constraint == "ZC")
4058
4060}
4061
4062
4063
4064
4066MipsTargetLowering::getSingleConstraintMatchWeight(
4067 AsmOperandInfo &info, const char *constraint) const {
4069 Value *CallOperandVal = info.CallOperandVal;
4070
4071
4072 if (!CallOperandVal)
4075
4076 switch (*constraint) {
4077 default:
4079 break;
4080 case 'd':
4081 case 'y':
4084 break;
4085 case 'f':
4091 break;
4092 case 'c':
4093 case 'l':
4094 case 'x':
4097 break;
4098 case 'I':
4099 case 'J':
4100 case 'K':
4101 case 'L':
4102 case 'N':
4103 case 'O':
4104 case 'P':
4107 break;
4108 case 'R':
4110 break;
4111 }
4112 return weight;
4113}
4114
4115
4116
4117
4118
4120 unsigned long long &Reg) {
4121 if (C.front() != '{' || C.back() != '}')
4122 return std::make_pair(false, false);
4123
4124
4126 I = std::find_if(B, E, isdigit);
4127
4129
4130
4132 return std::make_pair(true, false);
4133
4134
4136 true);
4137}
4138
4143 return VT.bitsLT(MinVT) ? MinVT : VT;
4144}
4145
4146std::pair<unsigned, const TargetRegisterClass *> MipsTargetLowering::
4147parseRegForInlineAsmConstraint(StringRef C, MVT VT) const {
4152 unsigned long long Reg;
4153
4155
4156 if (!R.first)
4157 return std::make_pair(0U, nullptr);
4158
4159 if ((Prefix == "hi" || Prefix == "lo")) {
4160
4161 if (R.second)
4162 return std::make_pair(0U, nullptr);
4163
4164 RC = TRI->getRegClass(Prefix == "hi" ?
4165 Mips::HI32RegClassID : Mips::LO32RegClassID);
4166 return std::make_pair(*(RC->begin()), RC);
4167 } else if (Prefix.starts_with("$msa")) {
4168
4169
4170
4171 if (R.second)
4172 return std::make_pair(0U, nullptr);
4173
4175 .Case("$msair", Mips::MSAIR)
4176 .Case("$msacsr", Mips::MSACSR)
4177 .Case("$msaaccess", Mips::MSAAccess)
4178 .Case("$msasave", Mips::MSASave)
4179 .Case("$msamodify", Mips::MSAModify)
4180 .Case("$msarequest", Mips::MSARequest)
4181 .Case("$msamap", Mips::MSAMap)
4182 .Case("$msaunmap", Mips::MSAUnmap)
4184
4185 if ()
4186 return std::make_pair(0U, nullptr);
4187
4188 RC = TRI->getRegClass(Mips::MSACtrlRegClassID);
4189 return std::make_pair(Reg, RC);
4190 }
4191
4192 if (.second)
4193 return std::make_pair(0U, nullptr);
4194
4195 if (Prefix == "$f") {
4196
4197
4198
4199
4200 if (VT == MVT::Other) {
4202 VT = MVT::f32;
4203 else
4204 VT = (Subtarget.isFP64bit() || !(Reg % 2)) ? MVT::f64 : MVT::f32;
4205 }
4206
4208
4209 if (RC == &Mips::AFGR64RegClass) {
4211 Reg >>= 1;
4212 }
4213 } else if (Prefix == "$fcc")
4214 RC = TRI->getRegClass(Mips::FCCRegClassID);
4215 else if (Prefix == "$w") {
4216 RC = getRegClassFor((VT == MVT::Other) ? MVT::v16i8 : VT);
4217 } else {
4218 assert(Prefix == "$");
4219 RC = getRegClassFor((VT == MVT::Other) ? MVT::i32 : VT);
4220 }
4221
4223 return std::make_pair(*(RC->begin() + Reg), RC);
4224}
4225
4226
4227
4228
4229std::pair<unsigned, const TargetRegisterClass *>
4232 MVT VT) const {
4233 if (Constraint.size() == 1) {
4234 switch (Constraint[0]) {
4235 case 'd':
4236 case 'y':
4237 case 'r':
4238 if ((VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 ||
4239 VT == MVT::i1) ||
4240 (VT == MVT::f32 && Subtarget.useSoftFloat())) {
4242 return std::make_pair(0U, &Mips::CPU16RegsRegClass);
4243 return std::make_pair(0U, &Mips::GPR32RegClass);
4244 }
4245 if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat()) ||
4246 (VT == MVT::f64 && Subtarget.isSingleFloat())) &&
4248 return std::make_pair(0U, &Mips::GPR32RegClass);
4249 if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat()) ||
4250 (VT == MVT::f64 && Subtarget.isSingleFloat())) &&
4252 return std::make_pair(0U, &Mips::GPR64RegClass);
4253
4254 return std::make_pair(0U, nullptr);
4255 case 'f':
4256 if (VT == MVT::v16i8)
4257 return std::make_pair(0U, &Mips::MSA128BRegClass);
4258 else if (VT == MVT::v8i16 || VT == MVT::v8f16)
4259 return std::make_pair(0U, &Mips::MSA128HRegClass);
4260 else if (VT == MVT::v4i32 || VT == MVT::v4f32)
4261 return std::make_pair(0U, &Mips::MSA128WRegClass);
4262 else if (VT == MVT::v2i64 || VT == MVT::v2f64)
4263 return std::make_pair(0U, &Mips::MSA128DRegClass);
4264 else if (VT == MVT::f32)
4265 return std::make_pair(0U, &Mips::FGR32RegClass);
4266 else if ((VT == MVT::f64) && (.isSingleFloat())) {
4268 return std::make_pair(0U, &Mips::FGR64RegClass);
4269 return std::make_pair(0U, &Mips::AFGR64RegClass);
4270 }
4271 break;
4272 case 'c':
4273 if (VT == MVT::i32)
4274 return std::make_pair((unsigned)Mips::T9, &Mips::GPR32RegClass);
4275 if (VT == MVT::i64)
4276 return std::make_pair((unsigned)Mips::T9_64, &Mips::GPR64RegClass);
4277
4278 return std::make_pair(0U, nullptr);
4279 case 'l':
4280
4281 if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8)
4282 return std::make_pair((unsigned)Mips::LO0, &Mips::LO32RegClass);
4283 return std::make_pair((unsigned)Mips::LO0_64, &Mips::LO64RegClass);
4284 case 'x':
4285
4286
4287
4288 return std::make_pair(0U, nullptr);
4289 }
4290 }
4291
4292 if (!Constraint.empty()) {
4293 std::pair<unsigned, const TargetRegisterClass *> R;
4294 R = parseRegForInlineAsmConstraint(Constraint, VT);
4295
4296 if (R.second)
4297 return R;
4298 }
4299
4301}
4302
4303
4304
4305void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
4307 std::vector &Ops,
4311
4312
4313 if (Constraint.size() > 1)
4314 return;
4315
4316 char ConstraintLetter = Constraint[0];
4317 switch (ConstraintLetter) {
4318 default: break;
4319 case 'I':
4320
4322 EVT Type = Op.getValueType();
4323 int64_t Val = C->getSExtValue();
4326 break;
4327 }
4328 }
4329 return;
4330 case 'J':
4332 EVT Type = Op.getValueType();
4333 int64_t Val = C->getZExtValue();
4334 if (Val == 0) {
4336 break;
4337 }
4338 }
4339 return;
4340 case 'K':
4342 EVT Type = Op.getValueType();
4343 uint64_t Val = C->getZExtValue();
4346 break;
4347 }
4348 }
4349 return;
4350 case 'L':
4352 EVT Type = Op.getValueType();
4353 int64_t Val = C->getSExtValue();
4354 if ((isInt<32>(Val)) && ((Val & 0xffff) == 0)){
4356 break;
4357 }
4358 }
4359 return;
4360 case 'N':
4362 EVT Type = Op.getValueType();
4363 int64_t Val = C->getSExtValue();
4364 if ((Val >= -65535) && (Val <= -1)) {
4366 break;
4367 }
4368 }
4369 return;
4370 case 'O':
4372 EVT Type = Op.getValueType();
4373 int64_t Val = C->getSExtValue();
4376 break;
4377 }
4378 }
4379 return;
4380 case 'P':
4382 EVT Type = Op.getValueType();
4383 int64_t Val = C->getSExtValue();
4384 if ((Val <= 65535) && (Val >= 1)) {
4386 break;
4387 }
4388 }
4389 return;
4390 }
4391
4392 if (Result.getNode()) {
4393 Ops.push_back(Result);
4394 return;
4395 }
4396
4398}
4399
4400bool MipsTargetLowering::isLegalAddressingMode(const DataLayout &DL,
4402 unsigned AS,
4404
4405 if (AM.BaseGV)
4406 return false;
4407
4408 switch (AM.Scale) {
4409 case 0:
4410 break;
4411 case 1:
4412 if (!AM.HasBaseReg)
4413 break;
4414 return false;
4415 default:
4416 return false;
4417 }
4418
4419 return true;
4420}
4421
4422bool
4423MipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
4424
4425 return false;
4426}
4427
4428EVT MipsTargetLowering::getOptimalMemOpType(
4430 const AttributeList &FuncAttributes) const {
4432 return MVT::i64;
4433
4434 return MVT::i32;
4435}
4436
4437bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
4438 bool ForCodeSize) const {
4439 if (VT != MVT::f32 && VT != MVT::f64)
4440 return false;
4441 if (Imm.isNegZero())
4442 return false;
4443 return Imm.isZero();
4444}
4445
4446bool MipsTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
4448}
4449
4450bool MipsTargetLowering::isLegalAddImmediate(int64_t Imm) const {
4452}
4453
4457 if (ABI.IsN64())
4460}
4461
4462SDValue MipsTargetLowering::getPICJumpTableRelocBase(SDValue Table,
4465 return Table;
4467}
4468
4470 return Subtarget.useSoftFloat();
4471}
4472
4473void MipsTargetLowering::copyByValRegs(
4474 SDValue Chain, const SDLoc &DL, std::vector &OutChains,
4477 unsigned FirstReg, unsigned LastReg, const CCValAssign &VA,
4481 unsigned GPRSizeInBytes = Subtarget.getGPRSizeInBytes();
4482 unsigned NumRegs = LastReg - FirstReg;
4483 unsigned RegAreaSize = NumRegs * GPRSizeInBytes;
4484 unsigned FrameObjSize = std::max(Flags.getByValSize(), RegAreaSize);
4485 int FrameObjOffset;
4487
4488 if (RegAreaSize)
4489 FrameObjOffset =
4490 (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) -
4491 (int)((ByValArgRegs.size() - FirstReg) * GPRSizeInBytes);
4492 else
4494
4495
4497
4498
4499
4500
4501
4502 int FI = MFI.CreateFixedObject(FrameObjSize, FrameObjOffset, false, true);
4505
4506 if (!NumRegs)
4507 return;
4508
4509
4511 const TargetRegisterClass *RC = getRegClassFor(RegTy);
4512
4513 for (unsigned I = 0; I < NumRegs; ++I) {
4514 unsigned ArgReg = ByValArgRegs[FirstReg + I];
4515 unsigned VReg = addLiveIn(MF, ArgReg, RC);
4516 unsigned Offset = I * GPRSizeInBytes;
4520 StorePtr, MachinePointerInfo(FuncArg, Offset));
4521 OutChains.push_back(Store);
4522 }
4523}
4524
4525
4526void MipsTargetLowering::passByValArg(
4528 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
4531 unsigned LastReg, const ISD::ArgFlagsTy &Flags, bool isLittle,
4533 unsigned ByValSizeInBytes = Flags.getByValSize();
4534 unsigned OffsetInBytes = 0;
4535 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
4536 Align Alignment =
4537 std::min(Flags.getNonZeroByValAlign(), Align(RegSizeInBytes));
4540 unsigned NumRegs = LastReg - FirstReg;
4541
4542 if (NumRegs) {
4544 bool LeftoverBytes = (NumRegs * RegSizeInBytes > ByValSizeInBytes);
4545 unsigned I = 0;
4546
4547
4548 for (; I < NumRegs - LeftoverBytes; ++I, OffsetInBytes += RegSizeInBytes) {
4552 MachinePointerInfo(), Alignment);
4554 unsigned ArgReg = ArgRegs[FirstReg + I];
4555 RegsToPass.push_back(std::make_pair(ArgReg, LoadVal));
4556 }
4557
4558
4559 if (ByValSizeInBytes == OffsetInBytes)
4560 return;
4561
4562
4563 if (LeftoverBytes) {
4565
4566 for (unsigned LoadSizeInBytes = RegSizeInBytes / 2, TotalBytesLoaded = 0;
4567 OffsetInBytes < ByValSizeInBytes; LoadSizeInBytes /= 2) {
4568 unsigned RemainingSizeInBytes = ByValSizeInBytes - OffsetInBytes;
4569
4570 if (RemainingSizeInBytes < LoadSizeInBytes)
4571 continue;
4572
4573
4576 PtrTy));
4578 ISD::ZEXTLOAD, DL, RegTy, Chain, LoadPtr, MachinePointerInfo(),
4581
4582
4583 unsigned Shamt;
4584
4585 if (isLittle)
4586 Shamt = TotalBytesLoaded * 8;
4587 else
4588 Shamt = (RegSizeInBytes - (TotalBytesLoaded + LoadSizeInBytes)) * 8;
4589
4592
4595 else
4596 Val = Shift;
4597
4598 OffsetInBytes += LoadSizeInBytes;
4599 TotalBytesLoaded += LoadSizeInBytes;
4600 Alignment = std::min(Alignment, Align(LoadSizeInBytes));
4601 }
4602
4603 unsigned ArgReg = ArgRegs[FirstReg + I];
4604 RegsToPass.push_back(std::make_pair(ArgReg, Val));
4605 return;
4606 }
4607 }
4608
4609
4610 unsigned MemCpySize = ByValSizeInBytes - OffsetInBytes;
4616 Chain, DL, Dst, Src, DAG.getConstant(MemCpySize, DL, PtrTy),
4617 Align(Alignment), false, false,
4618 nullptr, std::nullopt, MachinePointerInfo(), MachinePointerInfo());
4620}
4621
4622void MipsTargetLowering::writeVarArgRegs(std::vector &OutChains,
4628 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
4630 const TargetRegisterClass *RC = getRegClassFor(RegTy);
4633 MipsFunctionInfo *MipsFI = MF.getInfo();
4634
4635
4636 int VaArgOffset;
4637
4638 if (ArgRegs.size() == Idx)
4640 else {
4641 VaArgOffset =
4642 (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) -
4643 (int)(RegSizeInBytes * (ArgRegs.size() - Idx));
4644 }
4645
4646
4647
4648 int FI = MFI.CreateFixedObject(RegSizeInBytes, VaArgOffset, true);
4650
4651
4652
4653
4654
4655 for (unsigned I = Idx; I < ArgRegs.size();
4656 ++I, VaArgOffset += RegSizeInBytes) {
4662 DAG.getStore(Chain, DL, ArgValue, PtrOff, MachinePointerInfo());
4664 (Value *)nullptr);
4665 OutChains.push_back(Store);
4666 }
4667}
4668
4670 Align Alignment) const {
4672
4673 assert(Size && "Byval argument's size shouldn't be 0.");
4674
4675 Alignment = std::min(Alignment, TFL->getStackAlign());
4676
4677 unsigned FirstReg = 0;
4678 unsigned NumRegs = 0;
4679
4681 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
4683
4686
4687
4688
4690 Alignment >= Align(RegSizeInBytes) &&
4691 "Byval argument's alignment should be a multiple of RegSizeInBytes.");
4692
4693 FirstReg = State->getFirstUnallocated(IntArgRegs);
4694
4695
4696
4697
4698
4699 if ((Alignment > RegSizeInBytes) && (FirstReg % 2)) {
4700 State->AllocateReg(IntArgRegs[FirstReg], ShadowRegs[FirstReg]);
4701 ++FirstReg;
4702 }
4703
4704
4706 for (unsigned I = FirstReg; Size > 0 && (I < IntArgRegs.size());
4707 Size -= RegSizeInBytes, ++I, ++NumRegs)
4708 State->AllocateReg(IntArgRegs[I], ShadowRegs[I]);
4709 }
4710
4711 State->addInRegsParamInfo(FirstReg, FirstReg + NumRegs);
4712}
4713
4716 bool isFPCmp,
4717 unsigned Opc) const {
4719 "Subtarget already supports SELECT nodes with the use of"
4720 "conditional-move instructions.");
4721
4725
4726
4727
4728
4729
4732
4733
4734
4735
4736
4737
4738
4743 F->insert(It, copy0MBB);
4744 F->insert(It, sinkMBB);
4745
4746
4750
4751
4754
4755 if (isFPCmp) {
4756
4758 .addReg(MI.getOperand(1).getReg())
4760 } else {
4761
4763 .addReg(MI.getOperand(1).getReg())
4766 }
4767
4768
4769
4770
4771 BB = copy0MBB;
4772
4773
4775
4776
4777
4778
4779 BB = sinkMBB;
4780
4782 .addReg(MI.getOperand(2).getReg())
4784 .addReg(MI.getOperand(3).getReg())
4786
4787 MI.eraseFromParent();
4788
4789 return BB;
4790}
4791
4793MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,
4796 "Subtarget already supports SELECT nodes with the use of"
4797 "conditional-move instructions.");
4798
4799 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
4801
4802
4803
4804
4805
4806
4809
4810
4811
4812
4813
4814
4815
4816 MachineBasicBlock *thisMBB = BB;
4817 MachineFunction *F = BB->getParent();
4818 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
4819 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
4821 F->insert(It, sinkMBB);
4822
4823
4827
4828
4831
4832
4834 .addReg(MI.getOperand(2).getReg())
4837
4838
4839
4840
4841 BB = copy0MBB;
4842
4843
4845
4846
4847
4848
4849 BB = sinkMBB;
4850
4851
4853 .addReg(MI.getOperand(3).getReg())
4855 .addReg(MI.getOperand(5).getReg())
4858 .addReg(MI.getOperand(4).getReg())
4860 .addReg(MI.getOperand(6).getReg())
4862
4863 MI.eraseFromParent();
4864
4865 return BB;
4866}
4867
4868
4869
4873
4876 .Case("$28", Mips::GP_64)
4877 .Case("sp", Mips::SP_64)
4879 return Reg;
4880 }
4881
4883 .Case("$28", Mips::GP)
4884 .Case("sp", Mips::SP)
4886 return Reg;
4887}
4888
4896
4897 Register Dest = MI.getOperand(0).getReg();
4899 unsigned Imm = MI.getOperand(2).getImm();
4900
4902
4904
4905 Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4911 } else {
4912
4913
4914 Register LoadHalf = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4915 Register LoadFull = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4916 Register Undef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4921 .addImm(Imm + (IsLittle ? 0 : 3))
4926 .addImm(Imm + (IsLittle ? 3 : 0))
4929 }
4930
4931 MI.eraseFromParent();
4932 return BB;
4933}
4934
4937 MachineFunction *MF = BB->getParent();
4939 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
4940 const bool IsLittle = Subtarget.isLittle();
4942
4943 Register Dest = MI.getOperand(0).getReg();
4945 unsigned Imm = MI.getOperand(2).getImm();
4946
4948
4950
4952 Register Temp = MRI.createVirtualRegister(&Mips::GPR64RegClass);
4958 } else {
4959 Register Wtemp = MRI.createVirtualRegister(&Mips::MSA128WRegClass);
4960 Register Lo = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4961 Register Hi = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4965 .addImm(Imm + (IsLittle ? 0 : 4));
4969 .addImm(Imm + (IsLittle ? 4 : 0));
4975 }
4976 } else {
4977
4978
4979 Register LoHalf = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4980 Register LoFull = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4981 Register LoUndef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4982 Register HiHalf = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4983 Register HiFull = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4984 Register HiUndef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4985 Register Wtemp = MRI.createVirtualRegister(&Mips::MSA128WRegClass);
4990 .addImm(Imm + (IsLittle ? 0 : 7))
4995 .addImm(Imm + (IsLittle ? 3 : 4))
5001 .addImm(Imm + (IsLittle ? 4 : 3))
5006 .addImm(Imm + (IsLittle ? 7 : 0))
5013 }
5014
5015 MI.eraseFromParent();
5016 return BB;
5017}
5018
5021 MachineFunction *MF = BB->getParent();
5023 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
5024 const bool IsLittle = Subtarget.isLittle();
5026
5027 Register StoreVal = MI.getOperand(0).getReg();
5029 unsigned Imm = MI.getOperand(2).getImm();
5030
5032
5034
5035 Register BitcastW = MRI.createVirtualRegister(&Mips::MSA128WRegClass);
5036 Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
5046 } else {
5047
5048
5049 Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
5057 .addImm(Imm + (IsLittle ? 0 : 3));
5061 .addImm(Imm + (IsLittle ? 3 : 0));
5062 }
5063
5064 MI.eraseFromParent();
5065
5066 return BB;
5067}
5068
5071 MachineFunction *MF = BB->getParent();
5073 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
5074 const bool IsLittle = Subtarget.isLittle();
5076
5077 Register StoreVal = MI.getOperand(0).getReg();
5079 unsigned Imm = MI.getOperand(2).getImm();
5080
5082
5084
5086 Register BitcastD = MRI.createVirtualRegister(&Mips::MSA128DRegClass);
5087 Register Lo = MRI.createVirtualRegister(&Mips::GPR64RegClass);
5099 } else {
5100 Register BitcastW = MRI.createVirtualRegister(&Mips::MSA128WRegClass);
5101 Register Lo = MRI.createVirtualRegister(&Mips::GPR32RegClass);
5102 Register Hi = MRI.createVirtualRegister(&Mips::GPR32RegClass);
5117 .addImm(Imm + (IsLittle ? 0 : 4));
5121 .addImm(Imm + (IsLittle ? 4 : 0));
5122 }
5123 } else {
5124
5125
5126 Register Bitcast = MRI.createVirtualRegister(&Mips::MSA128WRegClass);
5127 Register Lo = MRI.createVirtualRegister(&Mips::GPR32RegClass);
5128 Register Hi = MRI.createVirtualRegister(&Mips::GPR32RegClass);
5141 .addImm(Imm + (IsLittle ? 0 : 3));
5145 .addImm(Imm + (IsLittle ? 3 : 0));
5149 .addImm(Imm + (IsLittle ? 4 : 7));
5153 .addImm(Imm + (IsLittle ? 7 : 4));
5154 }
5155
5156 MI.eraseFromParent();
5157 return BB;
5158}
unsigned const MachineRegisterInfo * MRI
static SDValue performSHLCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG)
If the operand is a bitwise AND with a constant RHS, and the shift has a constant RHS and is the only...
static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget, const AArch64TargetLowering &TLI)
static SDValue performANDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
This file declares a class to represent arbitrary precision floating point values and provide a varie...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static MachineBasicBlock * insertDivByZeroTrap(MachineInstr &MI, MachineBasicBlock *MBB)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
cl::opt< bool > EmitJalrReloc
static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static SDValue performMADD_MSUBCombine(SDNode *ROOTNode, SelectionDAG &CurDAG, const MipsSubtarget &Subtarget)
Definition MipsISelLowering.cpp:915
static bool invertFPCondCodeUser(Mips::CondCode CC)
This function returns true if the floating point conditional branches and conditional moves which use...
Definition MipsISelLowering.cpp:538
static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State, ArrayRef< MCPhysReg > F64Regs)
Definition MipsISelLowering.cpp:2965
static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG, bool SingleFloat)
Definition MipsISelLowering.cpp:2876
static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition MipsISelLowering.cpp:473
static const MCPhysReg Mips64DPRegs[8]
Definition MipsISelLowering.cpp:91
static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG, bool IsLittle)
Definition MipsISelLowering.cpp:2847
static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD, SDValue Chain, unsigned Offset)
Definition MipsISelLowering.cpp:2830
static unsigned addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC)
Definition MipsISelLowering.cpp:1267
static std::pair< bool, bool > parsePhysicalReg(StringRef C, StringRef &Prefix, unsigned long long &Reg)
This is a helper function to parse a physical register string and split it into non-numeric and numer...
Definition MipsISelLowering.cpp:4119
static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD, SDValue Chain, SDValue Src, unsigned Offset)
Definition MipsISelLowering.cpp:2748
static SDValue lowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)
Definition MipsISelLowering.cpp:2445
static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition MipsISelLowering.cpp:1025
static SDValue performSUBCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition MipsISelLowering.cpp:1010
static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op)
Definition MipsISelLowering.cpp:550
static SDValue lowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)
Definition MipsISelLowering.cpp:2398
static cl::opt< bool > NoZeroDivCheck("mno-check-zero-division", cl::Hidden, cl::desc("MIPS: Don't trap on integer division by zero."), cl::init(false))
static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition MipsISelLowering.cpp:583
static SDValue performSignExtendCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition MipsISelLowering.cpp:1116
static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition MipsISelLowering.cpp:664
static SDValue UnpackFromArgumentSlot(SDValue Val, const CCValAssign &VA, EVT ArgVT, const SDLoc &DL, SelectionDAG &DAG)
Definition MipsISelLowering.cpp:3672
static Mips::CondCode condCodeToFCC(ISD::CondCode CC)
Definition MipsISelLowering.cpp:510
static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True, SDValue False, const SDLoc &DL)
Definition MipsISelLowering.cpp:573
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
SI optimize exec mask operations pre RA
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
static const MCPhysReg IntRegs[32]
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static const MCPhysReg F32Regs[64]
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
LLVM Basic Block Representation.
static BranchProbability getOne()
CCState - This class holds information needed while lowering arguments and return values.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
CallingConv::ID getCallingConv() const
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
bool isUpperBitsInLoc() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
uint64_t getZExtValue() const
int64_t getSExtValue() const
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
const char * getSymbol() const
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
const Argument * const_arg_iterator
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
const GlobalValue * getGlobal() const
bool hasLocalLinkage() const
bool hasDLLImportStorageClass() const
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool hasInternalLinkage() const
This is an important class for using LLVM in a threaded context.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
This class is used to represent ISD::LOAD nodes.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Wrapper class representing physical registers. Should be passed by value.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
bool isValid() const
Return true if this is a valid simple valuetype.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
static auto fp_fixedlen_vector_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
const MachineOperand & getOperand(unsigned i) const
@ EK_GPRel32BlockAddress
EK_GPRel32BlockAddress - Each entry is an address of block, encoded with a relocation as gp-relative,...
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
@ EK_GPRel64BlockAddress
EK_GPRel64BlockAddress - Each entry is an address of block, encoded with a relocation as gp-relative,...
@ MOVolatile
The memory access is volatile.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
static SpecialCallingConvType getSpecialCallingConvForCallee(const SDNode *Callee, const MipsSubtarget &Subtarget)
Determine the SpecialCallingConvType for the given callee.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
void setVarArgsFrameIndex(int Index)
unsigned getSRetReturnReg() const
int getVarArgsFrameIndex() const
MachinePointerInfo callPtrInfo(MachineFunction &MF, const char *ES)
Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue object representing a GOT ent...
Register getGlobalBaseReg(MachineFunction &MF)
void setSRetReturnReg(unsigned Reg)
void setFormalArgInfo(unsigned Size, bool HasByval)
static const uint32_t * getMips16RetHelperMask()
const MipsInstrInfo * getInstrInfo() const override
bool inMips16Mode() const
const MipsRegisterInfo * getRegisterInfo() const override
bool hasExtractInsert() const
Features related to the presence of specific instructions.
bool isSingleFloat() const
const TargetFrameLowering * getFrameLowering() const override
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Return the register type for a given MVT, ensuring vectors are treated as a series of gpr sized integ...
Definition MipsISelLowering.cpp:98
bool hasBitTest(SDValue X, SDValue Y) const override
Return true if the target has a bit-test instruction: (X & (1 << Y)) ==/!= 0 This knowledge can be us...
Definition MipsISelLowering.cpp:1187
static const MipsTargetLowering * create(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Definition MipsISelLowering.cpp:437
SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, bool IsN64) const
unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override
Break down vectors to the correct number of gpr sized integers.
Definition MipsISelLowering.cpp:122
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
Definition MipsISelLowering.cpp:4871
SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - get the ISD::SETCC result ValueType
Definition MipsISelLowering.cpp:466
SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo) const override
createFastISel - This method returns a target specific FastISel object, or null if the target does no...
Definition MipsISelLowering.cpp:447
MipsTargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Definition MipsISelLowering.cpp:174
SDValue getAddrGlobalLargeGOT(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned HiFlag, unsigned LoFlag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
SDValue getDllimportVariable(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, SDValue Chain, const MachinePointerInfo &PtrInfo) const
bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override
Return true if it is profitable to fold a pair of shifts into a mask.
Definition MipsISelLowering.cpp:1197
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
Definition MipsISelLowering.cpp:1147
CCAssignFn * CCAssignFnForReturn() const
Definition MipsISelLowering.cpp:3117
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
Definition MipsISelLowering.cpp:1211
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
Definition MipsISelLowering.cpp:1305
SDValue getDllimportSymbol(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const
CCAssignFn * CCAssignFnForCall() const
Definition MipsISelLowering.cpp:3113
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Return the number of registers for a given MVT, ensuring vectors are treated as a series of gpr sized...
Definition MipsISelLowering.cpp:110
SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const
Definition MipsISelLowering.cpp:2892
void AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const override
This method should be implemented by targets that mark instructions with the 'hasPostISelHook' flag.
Definition MipsISelLowering.cpp:3200
virtual void getOpndList(SmallVectorImpl< SDValue > &Ops, std::deque< std::pair< unsigned, SDValue > > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const
This function fills Ops, which is the list of operands that will later be used when a function call n...
Definition MipsISelLowering.cpp:3143
EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, ISD::NodeType) const override
Return the type that should be used to zero or sign extend a zeroext/signext integer return value.
Definition MipsISelLowering.cpp:4139
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
Definition MipsISelLowering.cpp:1183
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
Definition MipsISelLowering.cpp:1218
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
Definition MipsISelLowering.cpp:1179
SDValue getAddrLocal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, bool IsN32OrN64) const
SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const
Definition MipsISelLowering.cpp:137
const MipsSubtarget & Subtarget
void HandleByVal(CCState *, unsigned &, Align) const override
Target-specific cleanup for formal ByVal parameters.
Definition MipsISelLowering.cpp:4669
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const
Definition MipsISelLowering.cpp:2766
bool IsConstantInSmallSection(const DataLayout &DL, const Constant *CN, const TargetMachine &TM) const
Return true if this constant should be placed into small data section.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI bool isKnownNeverNaN(SDValue Op, const APInt &DemandedElts, bool SNaN=false, unsigned Depth=0) const
Test whether the given SDValue (or all elements of it, if it is a vector) is known to never be NaN in...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
void addCallSiteInfo(const SDNode *Node, CallSiteInfo &&CallInfo)
Set CallSiteInfo to be associated with Node.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
const char * const_iterator
constexpr size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const
Return the number of registers that this ValueType will eventually require.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual bool useSoftFloat() const
Align getMinStackArgumentAlignment() const
Return the minimum stack alignment of an argument.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
MVT getRegisterType(MVT VT) const
Return the type of registers that this ValueType will eventually require.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
virtual void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
virtual TargetLoweringObjectFile * getObjFileLowering() const
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
unsigned EmitCallGraphSection
Emit section containing call graph metadata.
iterator begin() const
begin/end - Return all of the registers in this class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
constexpr ScalarTy getFixedValue() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ BSWAP
Byte Swap and Counting operators.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ FADD
Simple binary floating point operators.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ EH_RETURN
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin,...
@ SIGN_EXTEND
Conversion operators.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ BasicBlock
Various leaf nodes.
@ SHL
Shift and rotation operations.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSGD
On a symbol operand, this indicates that the immediate is the offset to the slot in GOT which stores ...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
@ EarlyClobber
Register definition happens before uses.
Not(const Pred &P) -> Not< Pred >
initializer< Ty > init(const Ty &Val)
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
const MipsTargetLowering * createMips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Create MipsTargetLowering objects.
@ Or
Bitwise or logical OR of integers.
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
const MipsTargetLowering * createMipsSETargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
LLVM_ABI bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
bool isVector() const
Return true if this is a vector value type.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
Align getNonZeroOrigAlign() const
SmallVector< ArgRegPair, 1 > ArgRegPairs
Vector of call argument and its forwarding register.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isBeforeLegalizeOps() const