LLVM: lib/Target/Mips/MipsSEISelDAGToDAG.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
27#include "llvm/IR/IntrinsicsMips.h"
31using namespace llvm;
32
33#define DEBUG_TYPE "mips-isel"
34
35bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
38 return false;
40}
41
46
47void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI,
50 unsigned Mask = MI.getOperand(1).getImm();
51 unsigned Flag =
53
54 if (Mask & 1)
55 MIB.addReg(Mips::DSPPos, Flag);
56
57 if (Mask & 2)
58 MIB.addReg(Mips::DSPSCount, Flag);
59
60 if (Mask & 4)
61 MIB.addReg(Mips::DSPCarry, Flag);
62
63 if (Mask & 8)
64 MIB.addReg(Mips::DSPOutFlag, Flag);
65
66 if (Mask & 16)
67 MIB.addReg(Mips::DSPCCond, Flag);
68
69 if (Mask & 32)
70 MIB.addReg(Mips::DSPEFI, Flag);
71}
72
73MCRegister MipsSEDAGToDAGISel::getMSACtrlReg(const SDValue RegIdx) const {
75 return Mips::MSACtrlRegClass.getRegister(RegNum);
76}
77
80 unsigned DstReg = 0, ZeroReg = 0;
81
82
83 if ((MI.getOpcode() == Mips::ADDiu) &&
84 (MI.getOperand(1).getReg() == Mips::ZERO) &&
85 (MI.getOperand(2).isImm()) &&
86 (MI.getOperand(2).getImm() == 0)) {
87 DstReg = MI.getOperand(0).getReg();
88 ZeroReg = Mips::ZERO;
89 } else if ((MI.getOpcode() == Mips::DADDiu) &&
90 (MI.getOperand(1).getReg() == Mips::ZERO_64) &&
91 (MI.getOperand(2).isImm()) &&
92 (MI.getOperand(2).getImm() == 0)) {
93 DstReg = MI.getOperand(0).getReg();
94 ZeroReg = Mips::ZERO_64;
95 }
96
97 if (!DstReg)
98 return false;
99
100
102 E = MRI->use_end(); U != E;) {
103 MachineOperand &MO = *U;
104 unsigned OpNo = U.getOperandNo();
106 ++U;
107
108
109 if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) || MI->isPseudo())
110 continue;
111
112
113
114 if (->getRegClass(MO.getReg())->contains(ZeroReg))
115 continue;
116
118 }
119
120 return true;
121}
122
125 MachineInstrBuilder MIB(MF, &MI);
126 if (->isABI_O32()) {
127
131 .addUse(Mips::ZERO_64);
132
134 } else {
135
140
145
147 }
148}
149
150void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
151 MF.getInfo()->initGlobalBaseReg(MF);
152
153 MachineRegisterInfo *MRI = &MF.getRegInfo();
154
157 switch (MI.getOpcode()) {
158 case Mips::RDDSP:
159 addDSPCtrlRegOperands(false, MI, MF);
160 break;
161 case Mips::WRDSP:
162 addDSPCtrlRegOperands(true, MI, MF);
163 break;
164 case Mips::BuildPairF64_64:
165 case Mips::ExtractElementF64_64:
168 break;
169 }
170 [[fallthrough]];
171 case Mips::BuildPairF64:
172 case Mips::ExtractElementF64:
175 break;
176 case Mips::JAL:
177 case Mips::JAL_MM:
178 if (MI.getOperand(0).isGlobal() &&
179 MI.getOperand(0).getGlobal()->hasExternalLinkage() &&
180 MI.getOperand(0).getGlobal()->getName() == "_mcount")
181 emitMCountABI(MI, MBB, MF);
182 break;
183 case Mips::JALRPseudo:
184 case Mips::JALR64Pseudo:
185 case Mips::JALR16_MM:
186 if (MI.getOperand(2).isMCSymbol() &&
187 MI.getOperand(2).getMCSymbol()->getName() == "_mcount")
188 emitMCountABI(MI, MBB, MF);
189 break;
190 case Mips::JALR:
191 if (MI.getOperand(3).isMCSymbol() &&
192 MI.getOperand(3).getMCSymbol()->getName() == "_mcount")
193 emitMCountABI(MI, MBB, MF);
194 break;
195 default:
196 replaceUsesWithZeroReg(MRI, MI);
197 }
198 }
199 }
200}
201
202void MipsSEDAGToDAGISel::selectAddE(SDNode *Node, const SDLoc &DL) const {
206 EVT VT = LHS.getValueType();
207
208
209
212 CurDAG->SelectNodeTo(Node, Mips::ADDWC, VT, MVT::Glue, Ops);
213 return;
214 }
215
216 assert(Opc == ISD::ADDE && "ISD::ADDE not in a chain of ADDE nodes!");
217
218
219
220
221
222
223
224
225
226
227
228
229
230 SDValue CstOne = CurDAG->getTargetConstant(1, DL, MVT::i32);
231
232 SDValue OuFlag = CurDAG->getTargetConstant(20, DL, MVT::i32);
233
234 SDNode *DSPCtrlField = CurDAG->getMachineNode(Mips::RDDSP, DL, MVT::i32,
235 MVT::Glue, CstOne, InGlue);
236
237 SDNode *Carry = CurDAG->getMachineNode(
238 Mips::EXT, DL, MVT::i32, SDValue(DSPCtrlField, 0), OuFlag, CstOne);
239
241 CurDAG->getTargetConstant(6, DL, MVT::i32), CstOne,
243 SDNode *DSPCFWithCarry = CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, Ops);
244
245
246
247
248
249
251
252 SDValue InsOps[4] = {Zero, OuFlag, CstOne, SDValue(DSPCFWithCarry, 0)};
253 SDNode *DSPCtrlFinal =
254 CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, InsOps);
255
256 SDNode *WrDSP = CurDAG->getMachineNode(Mips::WRDSP, DL, MVT::Glue,
257 SDValue(DSPCtrlFinal, 0), CstOne);
258
260 CurDAG->SelectNodeTo(Node, Mips::ADDWC, VT, MVT::Glue, Operands);
261}
262
263
264bool MipsSEDAGToDAGISel::selectAddrFrameIndex(SDValue Addr, SDValue &Base,
268
269 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
270 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy);
271 return true;
272 }
273 return false;
274}
275
276
277bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(
279 unsigned ShiftAmount = 0) const {
280 if (CurDAG->isBaseWithConstantOffset(Addr)) {
282 if (isIntN(OffsetBits + ShiftAmount, CN->getSExtValue())) {
284
285
286 if (FrameIndexSDNode *FIN =
288 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
289 else {
291
292
293 const Align Alignment(1ULL << ShiftAmount);
294 if ((Alignment, CN->getZExtValue()))
295 return false;
296 }
297
298 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr),
299 ValTy);
300 return true;
301 }
302 }
303 return false;
304}
305
306
307
308bool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
310
311 if (selectAddrFrameIndex(Addr, Base, Offset))
312 return true;
313
314
315 if (Addr.getOpcode() == MipsISD::Wrapper) {
318 return true;
319 }
320
321 if (.isPositionIndependent()) {
324 return false;
325 }
326
327
328 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16))
329 return true;
330
331
333
334
335
336
337
338
339
340
348 return true;
349 }
350 }
351 }
352
353 return false;
354}
355
356
357
358bool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
362 return true;
363}
364
367 return selectAddrRegImm(Addr, Base, Offset) ||
368 selectAddrDefault(Addr, Base, Offset);
369}
370
371bool MipsSEDAGToDAGISel::selectAddrRegImm9(SDValue Addr, SDValue &Base,
373 if (selectAddrFrameIndex(Addr, Base, Offset))
374 return true;
375
376 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 9))
377 return true;
378
379 return false;
380}
381
382
383bool MipsSEDAGToDAGISel::selectAddrRegImm11(SDValue Addr, SDValue &Base,
385 if (selectAddrFrameIndex(Addr, Base, Offset))
386 return true;
387
388 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 11))
389 return true;
390
391 return false;
392}
393
394
395bool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base,
397 if (selectAddrFrameIndex(Addr, Base, Offset))
398 return true;
399
400 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12))
401 return true;
402
403 return false;
404}
405
406bool MipsSEDAGToDAGISel::selectAddrRegImm16(SDValue Addr, SDValue &Base,
408 if (selectAddrFrameIndex(Addr, Base, Offset))
409 return true;
410
411 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16))
412 return true;
413
414 return false;
415}
416
417bool MipsSEDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base,
419 return selectAddrRegImm11(Addr, Base, Offset) ||
420 selectAddrDefault(Addr, Base, Offset);
421}
422
423bool MipsSEDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base,
425 return selectAddrRegImm12(Addr, Base, Offset) ||
426 selectAddrDefault(Addr, Base, Offset);
427}
428
429bool MipsSEDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base,
431 return selectAddrRegImm16(Addr, Base, Offset) ||
432 selectAddrDefault(Addr, Base, Offset);
433}
434
435bool MipsSEDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
437 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 7)) {
439 return false;
440
442 unsigned CnstOff = CN->getZExtValue();
443 return (CnstOff == (CnstOff & 0x3c));
444 }
445
446 return false;
447 }
448
449
450
451 if (selectAddrRegImm(Addr, Base, Offset))
452 return false;
453
454 return selectAddrDefault(Addr, Base, Offset);
455}
456
457bool MipsSEDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base,
459
460 if (selectAddrFrameIndex(Addr, Base, Offset))
461 return true;
462
463 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10))
464 return true;
465
466 return selectAddrDefault(Addr, Base, Offset);
467}
468
469bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base,
471 if (selectAddrFrameIndex(Addr, Base, Offset))
472 return true;
473
474 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 1))
475 return true;
476
477 return selectAddrDefault(Addr, Base, Offset);
478}
479
480bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base,
482 if (selectAddrFrameIndex(Addr, Base, Offset))
483 return true;
484
485 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 2))
486 return true;
487
488 return selectAddrDefault(Addr, Base, Offset);
489}
490
491bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base,
493 if (selectAddrFrameIndex(Addr, Base, Offset))
494 return true;
495
496 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 3))
497 return true;
498
499 return selectAddrDefault(Addr, Base, Offset);
500}
501
502
503
504
505
506
507bool MipsSEDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm,
508 unsigned MinSizeInBits) const {
510 return false;
511
513
514 if (!Node)
515 return false;
516
517 APInt SplatValue, SplatUndef;
518 unsigned SplatBitSize;
519 bool HasAnyUndefs;
520
521 if (->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
522 MinSizeInBits, ->isLittle()))
523 return false;
524
525 Imm = SplatValue;
526
527 return true;
528}
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546bool MipsSEDAGToDAGISel::
548 unsigned ImmBitSize) const {
549 APInt ImmValue;
550 EVT EltTy = N->getValueType(0).getVectorElementType();
551
552 if (N->getOpcode() == ISD::BITCAST)
554
555 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
557
560 Imm = CurDAG->getTargetConstant(ImmValue, SDLoc(N), EltTy);
561 return true;
562 }
563 }
564
565 return false;
566}
567
568
569
570
571
572
573
574
575
576
577
578bool MipsSEDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
579 APInt ImmValue;
581
582 if (N->getOpcode() == ISD::BITCAST)
584
585 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
588
589 if (Log2 != -1) {
590 Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy);
591 return true;
592 }
593 }
594
595 return false;
596}
597
598
599
600
601
602
603
604
605
606
607
608
609bool MipsSEDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
610 APInt ImmValue;
612
613 if (N->getOpcode() == ISD::BITCAST)
615
616 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
618
619
621 Imm = CurDAG->getTargetConstant(ImmValue.popcount() - 1, SDLoc(N), EltTy);
622 return true;
623 }
624 }
625
626 return false;
627}
628
629
630
631
632
633
634
635
636
637
638
639
640bool MipsSEDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
641 APInt ImmValue;
643
644 if (N->getOpcode() == ISD::BITCAST)
646
647 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
649 if (ImmValue.isMask()) {
650 Imm = CurDAG->getTargetConstant(ImmValue.popcount() - 1, SDLoc(N), EltTy);
651 return true;
652 }
653 }
654
655 return false;
656}
657
658bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N,
660 APInt ImmValue;
662
663 if (N->getOpcode() == ISD::BITCAST)
665
666 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
668 int32_t Log2 = (~ImmValue).exactLogBase2();
669
670 if (Log2 != -1) {
671 Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy);
672 return true;
673 }
674 }
675
676 return false;
677}
678
679
680bool MipsSEDAGToDAGISel::selectVSplatImmEq1(SDValue N) const {
681 APInt ImmValue;
683
684 if (N->getOpcode() == ISD::BITCAST)
686
687 return selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
689}
690
691bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
692 unsigned Opcode = Node->getOpcode();
693 SDLoc DL(Node);
694
695
696
697
698
699 switch(Opcode) {
700 default: break;
701
704 MVT VT = Subtarget->isGP64bit() ? MVT::i64 : MVT::i32;
710
711 SDValue ops[] = {cond, Hi1, Lo1, Hi2, Lo2};
712 EVT NodeTys[] = {VT, VT};
714 ? Mips::PseudoD_SELECT_I64
715 : Mips::PseudoD_SELECT_I,
717 return true;
718 }
719
721 selectAddE(Node, DL);
722 return true;
723 }
724
727 if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
730 Mips::ZERO_64, MVT::i64);
732 CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero));
733 } else if (Subtarget->isFP64bit()) {
735 Mips::ZERO, MVT::i32);
737 MVT::f64, Zero, Zero));
738 } else {
740 Mips::ZERO, MVT::i32);
742 MVT::f64, Zero, Zero));
743 }
744 return true;
745 }
746 break;
747 }
748
751 int64_t Imm = CN->getSExtValue();
752 unsigned Size = CN->getValueSizeInBits(0);
753
755 break;
756
757 MipsAnalyzeImmediate AnalyzeImm;
758
761
763 SDLoc DL(CN);
764 SDNode *RegOpnd;
766 DL, MVT::i64);
767
768
769
770
771 if (Inst->Opc == Mips::LUi64)
772 RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd);
773 else
774 RegOpnd =
775 CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
776 CurDAG->getRegister(Mips::ZERO_64, MVT::i64),
777 ImmOpnd);
778
779
780 for (++Inst; Inst != Seq.end(); ++Inst) {
782 MVT::i64);
783 RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
784 SDValue(RegOpnd, 0), ImmOpnd);
785 }
786
788 return true;
789 }
790
792 const unsigned IntrinsicOpcode = Node->getConstantOperandVal(1);
793 switch (IntrinsicOpcode) {
794 default:
795 break;
796
797 case Intrinsic::mips_cfcmsa: {
801 getMSACtrlReg(RegIdx), MVT::i32);
803 return true;
804 }
805 case Intrinsic::mips_ldr_d:
806 case Intrinsic::mips_ldr_w: {
807 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_ldr_d) ? Mips::LDR_D
808 : Mips::LDR_W;
809
810 SDLoc DL(Node);
811 assert(Node->getNumOperands() == 4 && "Unexpected number of operands.");
812 const SDValue &Chain = Node->getOperand(0);
816
818 (void)Intrinsic;
821 "Invalid instruction operand.");
822
823
824 const ConstantInt *Val =
827 CurDAG->getTargetConstant(*Val, DL, Constant.getValueType());
828
830
832 assert(Node->getValueType(0).is128BitVector());
833 assert(Node->getValueType(1) == MVT::Other);
835
837
838 return true;
839 }
840 }
841 break;
842 }
843
845 switch (Node->getConstantOperandVal(0)) {
846 default:
847 break;
848
849 case Intrinsic::mips_move_v:
850
851
853 Node->getValueType(0),
854 Node->getOperand(1)));
855 return true;
856 }
857 break;
858 }
859
861 const unsigned IntrinsicOpcode = Node->getConstantOperandVal(1);
862 switch (IntrinsicOpcode) {
863 default:
864 break;
865
866 case Intrinsic::mips_ctcmsa: {
871 getMSACtrlReg(RegIdx), Value);
873 return true;
874 }
875 case Intrinsic::mips_str_d:
876 case Intrinsic::mips_str_w: {
877 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_str_d) ? Mips::STR_D
878 : Mips::STR_W;
879
880 SDLoc DL(Node);
881 assert(Node->getNumOperands() == 5 && "Unexpected number of operands.");
882 const SDValue &Chain = Node->getOperand(0);
884 const SDValue &Vec = Node->getOperand(2);
887
889 (void)Intrinsic;
892 "Invalid instruction operand.");
893
894
895 const ConstantInt *Val =
898 CurDAG->getTargetConstant(*Val, DL, Constant.getValueType());
899
901
903 assert(Node->getValueType(0) == MVT::Other);
905
907 return true;
908 }
909 }
910 break;
911 }
912
914 MVT ResTy = Node->getSimpleValueType(0);
915 assert((ResTy == MVT::f64 || ResTy == MVT::f32) &&
916 "Unsupported float type!");
917 unsigned Opc = 0;
918 if (ResTy == MVT::f64)
919 Opc = (Subtarget->isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32);
920 else
921 Opc = Mips::FABS_S;
922
923 if (Subtarget->inMicroMipsMode()) {
924 switch (Opc) {
925 case Mips::FABS_D64:
926 Opc = Mips::FABS_D64_MM;
927 break;
928 case Mips::FABS_D32:
929 Opc = Mips::FABS_D32_MM;
930 break;
931 case Mips::FABS_S:
932 Opc = Mips::FABS_S_MM;
933 break;
934 default:
935 llvm_unreachable("Unknown opcode for MIPS floating point abs!");
936 }
937 }
938
940 CurDAG->getMachineNode(Opc, DL, ResTy, Node->getOperand(0)));
941
942 return true;
943 }
944
945
946
947
948
949
950
951 case MipsISD::Ins: {
952
953
954 if (Node->getValueType(0) != MVT::i32 && Node->getValueType(0) != MVT::i64)
955 return false;
956
957 if (Node->getNumOperands() != 4)
958 return false;
959
962 return false;
963
964 MVT ResTy = Node->getSimpleValueType(0);
965 uint64_t Pos = Node->getConstantOperandVal(1);
966 uint64_t Size = Node->getConstantOperandVal(2);
967
968
970 return false;
971
972 if (Pos + Size > 64)
973 return false;
974
975 if (ResTy != MVT::i32 && ResTy != MVT::i64)
976 return false;
977
978 unsigned Opcode = 0;
979 if (ResTy == MVT::i32) {
980 if (Pos + Size <= 32)
981 Opcode = Mips::INS;
982 } else {
983 if (Pos + Size <= 32)
984 Opcode = Mips::DINS;
985 else if (Pos < 32 && 1 < Size)
986 Opcode = Mips::DINSM;
987 else
988 Opcode = Mips::DINSU;
989 }
990
991 if (Opcode) {
993 Node->getOperand(0), CurDAG->getTargetConstant(Pos, DL, MVT::i32),
994 CurDAG->getTargetConstant(Size, DL, MVT::i32), Node->getOperand(3)};
995
997 return true;
998 }
999
1000 return false;
1001 }
1002
1003 case MipsISD::ThreadPointer: {
1005 unsigned RdhwrOpc, DestReg;
1006
1007 if (PtrVT == MVT::i32) {
1008 RdhwrOpc = Mips::RDHWR;
1009 DestReg = Mips::V1;
1010 } else {
1011 RdhwrOpc = Mips::RDHWR64;
1012 DestReg = Mips::V1_64;
1013 }
1014
1015 SDNode *Rdhwr =
1016 CurDAG->getMachineNode(RdhwrOpc, DL, Node->getValueType(0), MVT::Glue,
1017 CurDAG->getRegister(Mips::HWR29, MVT::i32),
1018 CurDAG->getTargetConstant(0, DL, MVT::i32));
1021 SDValue ResNode = CurDAG->getCopyFromReg(Chain, DL, DestReg, PtrVT,
1024 return true;
1025 }
1026
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040 const MipsABIInfo &ABI =
1041 static_cast<const MipsTargetMachine &>(TM).getABI();
1042
1044 APInt SplatValue, SplatUndef;
1045 unsigned SplatBitSize;
1046 bool HasAnyUndefs;
1047 unsigned LdiOp;
1049 EVT ViaVecTy;
1050
1052 return false;
1053
1054 if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
1055 HasAnyUndefs, 8,
1057 return false;
1058
1059 switch (SplatBitSize) {
1060 default:
1061 return false;
1062 case 8:
1063 LdiOp = Mips::LDI_B;
1064 ViaVecTy = MVT::v16i8;
1065 break;
1066 case 16:
1067 LdiOp = Mips::LDI_H;
1068 ViaVecTy = MVT::v8i16;
1069 break;
1070 case 32:
1071 LdiOp = Mips::LDI_W;
1072 ViaVecTy = MVT::v4i32;
1073 break;
1074 case 64:
1075 LdiOp = Mips::LDI_D;
1076 ViaVecTy = MVT::v2i64;
1077 break;
1078 }
1079
1080 SDNode *Res = nullptr;
1081
1082
1083
1084
1085
1089
1090 Res = CurDAG->getMachineNode(LdiOp, DL, ViaVecTy, Imm);
1092 ((ABI.IsO32() && SplatBitSize < 64) ||
1093 (ABI.IsN32() || ABI.IsN64()))) {
1094
1095
1096
1097
1098
1099 bool Is32BitSplat = ABI.IsO32() || SplatBitSize < 64;
1100 const unsigned ADDiuOp = Is32BitSplat ? Mips::ADDiu : Mips::DADDiu;
1101 const MVT SplatMVT = Is32BitSplat ? MVT::i32 : MVT::i64;
1103 Is32BitSplat ? Mips::ZERO : Mips::ZERO_64, SplatMVT);
1104
1105 const unsigned FILLOp =
1106 SplatBitSize == 16
1107 ? Mips::FILL_H
1108 : (SplatBitSize == 32 ? Mips::FILL_W
1109 : (SplatBitSize == 64 ? Mips::FILL_D : 0));
1110
1111 assert(FILLOp != 0 && "Unknown FILL Op for splat synthesis!");
1112 assert((.IsO32() || (FILLOp != Mips::FILL_D)) &&
1113 "Attempting to use fill.d on MIPS32!");
1114
1117
1118 Res = CurDAG->getMachineNode(ADDiuOp, DL, SplatMVT, ZeroVal, LoVal);
1119 Res = CurDAG->getMachineNode(FILLOp, DL, ViaVecTy, SDValue(Res, 0));
1120
1121 } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 32) {
1122
1123
1126 SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32);
1127
1130
1131 if (Hi)
1132 Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal);
1133
1134 if (Lo)
1135 Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,
1136 Hi ? SDValue(Res, 0) : ZeroVal, LoVal);
1137
1138 assert((Hi || Lo) && "Zero case reached 32 bit case splat synthesis!");
1139 Res =
1140 CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32, SDValue(Res, 0));
1141
1142 } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 64 &&
1143 (ABI.IsN32() || ABI.IsN64())) {
1144
1145
1146
1149 SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32);
1150
1153
1154 if (Hi)
1155 Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal);
1156
1157 if (Lo)
1158 Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,
1159 Hi ? SDValue(Res, 0) : ZeroVal, LoVal);
1160
1161 Res = CurDAG->getMachineNode(
1162 Mips::SUBREG_TO_REG, DL, MVT::i64,
1163 CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64),
1165 CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64));
1166
1167 Res =
1168 CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64, SDValue(Res, 0));
1169
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1200
1203 SDValue HigherVal = CurDAG->getTargetConstant(Higher, DL, MVT::i32);
1204 SDValue HighestVal = CurDAG->getTargetConstant(Highest, DL, MVT::i32);
1205 SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32);
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223 if (Hi)
1224 Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal);
1225
1226 if (Lo)
1227 Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,
1228 Hi ? SDValue(Res, 0) : ZeroVal, LoVal);
1229
1230 SDNode *HiRes;
1231 if (Highest)
1232 HiRes = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HighestVal);
1233
1234 if (Higher)
1235 HiRes = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,
1236 Highest ? SDValue(HiRes, 0) : ZeroVal,
1237 HigherVal);
1238
1239
1240 if (ABI.IsO32()) {
1241 Res = CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32,
1242 (Hi || Lo) ? SDValue(Res, 0) : ZeroVal);
1243
1244 Res = CurDAG->getMachineNode(
1245 Mips::INSERT_W, DL, MVT::v4i32, SDValue(Res, 0),
1246 (Highest || Higher) ? SDValue(HiRes, 0) : ZeroVal,
1247 CurDAG->getTargetConstant(1, DL, MVT::i32));
1248
1250 const TargetRegisterClass *RC =
1252
1253 Res = CurDAG->getMachineNode(
1254 Mips::COPY_TO_REGCLASS, DL, ViaVecTy, SDValue(Res, 0),
1255 CurDAG->getTargetConstant(RC->getID(), DL, MVT::i32));
1256
1257 Res = CurDAG->getMachineNode(
1258 Mips::SPLATI_D, DL, MVT::v2i64, SDValue(Res, 0),
1259 CurDAG->getTargetConstant(0, DL, MVT::i32));
1260 } else if (ABI.IsN64() || ABI.IsN32()) {
1261
1262 SDValue Zero64Val = CurDAG->getRegister(Mips::ZERO_64, MVT::i64);
1263 const bool HiResNonZero = Highest || Higher;
1264 const bool ResNonZero = Hi || Lo;
1265
1266 if (HiResNonZero)
1267 HiRes = CurDAG->getMachineNode(
1268 Mips::SUBREG_TO_REG, DL, MVT::i64,
1269 CurDAG->getTargetConstant(((Highest >> 15) & 0x1), DL, MVT::i64),
1271 CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64));
1272
1273 if (ResNonZero)
1274 Res = CurDAG->getMachineNode(
1275 Mips::SUBREG_TO_REG, DL, MVT::i64,
1276 CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64),
1278 CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64));
1279
1280
1281
1282
1283
1284
1285
1286
1287 if (ResNonZero) {
1290 const ConstantInt *Const32 = ConstantInt::get(Int32Ty, 32);
1295
1296 Res = CurDAG->getMachineNode(Mips::DINSU, DL, MVT::i64, Ops);
1297 } else if (HiResNonZero) {
1298 Res = CurDAG->getMachineNode(
1299 Mips::DSLL32, DL, MVT::i64, SDValue(HiRes, 0),
1300 CurDAG->getTargetConstant(0, DL, MVT::i32));
1301 } else
1303 "Zero splat value handled by non-zero 64bit splat synthesis!");
1304
1305 Res = CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64,
1307 } else
1309
1310 } else
1311 return false;
1312
1313 if (ResVecTy != ViaVecTy) {
1314
1315
1316
1317
1319 MVT ResVecTySimple = ResVecTy.getSimpleVT();
1320 const TargetRegisterClass *RC = TLI->getRegClassFor(ResVecTySimple);
1321 Res = CurDAG->getMachineNode(Mips::COPY_TO_REGCLASS, DL,
1322 ResVecTy, SDValue(Res, 0),
1324 MVT::i32));
1325 }
1326
1328 return true;
1329 }
1330
1331 }
1332
1333 return false;
1334}
1335
1336bool MipsSEDAGToDAGISel::SelectInlineAsmMemoryOperand(
1338 std::vector &OutOps) {
1340
1341 switch(ConstraintID) {
1342 default:
1344
1348 OutOps.push_back(Base);
1349 OutOps.push_back(Offset);
1350 return false;
1351 }
1352 OutOps.push_back(Op);
1353 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
1354 return false;
1356
1357
1358
1359
1360
1362 OutOps.push_back(Base);
1363 OutOps.push_back(Offset);
1364 return false;
1365 }
1366 OutOps.push_back(Op);
1367 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
1368 return false;
1370
1371
1372 if (Subtarget->inMicroMipsMode()) {
1373
1375 OutOps.push_back(Base);
1376 OutOps.push_back(Offset);
1377 return false;
1378 }
1379 } else if (Subtarget->hasMips32r6()) {
1380
1382 OutOps.push_back(Base);
1383 OutOps.push_back(Offset);
1384 return false;
1385 }
1386 } else if (selectAddrRegImm16(Op, Base, Offset)) {
1387
1388 OutOps.push_back(Base);
1389 OutOps.push_back(Offset);
1390 return false;
1391 }
1392
1393 OutOps.push_back(Op);
1394 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
1395 return false;
1396 }
1397 return true;
1398}
1399
1403
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static uint64_t getConstant(const Value *IndexValue)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Class for arbitrary precision integers.
LLVM_ABI APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isNegative() const
Determine sign of this APInt.
int32_t exactLogBase2() const
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
bool isMask(unsigned numBits) const
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
Legacy analysis pass which computes a DominatorTree.
FunctionPass class - This class is used to implement most global optimizations.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Wrapper class representing physical registers. Should be passed by value.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_iterator< true, false, false, true, false > use_iterator
use_iterator/use_begin/use_end - Walk all uses of the specified register.
MipsDAGToDAGISelLegacy(std::unique_ptr< SelectionDAGISel > S)
bool runOnMachineFunction(MachineFunction &MF) override
const MipsSubtarget * Subtarget
Keep a pointer to the MipsSubtarget around so that we can make the right decision when generating cod...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition MipsSEISelDAGToDAG.cpp:42
MipsSEDAGToDAGISelLegacy(MipsTargetMachine &TM, CodeGenOptLevel OL)
Definition MipsSEISelDAGToDAG.cpp:1400
bool inMips16Mode() const
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
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
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetLowering * TLI
const TargetInstrInfo * TII
void ReplaceNode(SDNode *F, SDNode *T)
Replace all uses of F with T, then remove F from the DAG.
const TargetLowering * getTargetLowering() const
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...
unsigned getID() const
Return the register class ID number.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
NodeAddr< NodeBase * > Node
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
FunctionPass * createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel)
Definition MipsSEISelDAGToDAG.cpp:1404
CodeGenOptLevel
Code generation optimization level.
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...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
unsigned Log2(Align A)
Returns the log2 of the alignment.
Implement std::hash so that hash_code can be used in STL containers.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
EVT getVectorElementType() const
Given a vector type, return the type of each element.