xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Mips/MipsISelDAGToDAG.h (revision 71ac745d76c3ba442e753daff1870893f272b29d)
10b57cec5SDimitry Andric //===---- MipsISelDAGToDAG.h - A Dag to Dag Inst Selector for Mips --------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines an instruction selector for the MIPS target.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_MIPS_MIPSISELDAGTODAG_H
140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_MIPS_MIPSISELDAGTODAG_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "Mips.h"
170b57cec5SDimitry Andric #include "MipsSubtarget.h"
180b57cec5SDimitry Andric #include "MipsTargetMachine.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGISel.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
220b57cec5SDimitry Andric // Instruction Selector Implementation
230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
260b57cec5SDimitry Andric // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
270b57cec5SDimitry Andric // instructions for SelectionDAG operations.
280b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
290b57cec5SDimitry Andric namespace llvm {
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric class MipsDAGToDAGISel : public SelectionDAGISel {
320b57cec5SDimitry Andric public:
33bdd1243dSDimitry Andric   MipsDAGToDAGISel() = delete;
34bdd1243dSDimitry Andric 
355f757f3fSDimitry Andric   explicit MipsDAGToDAGISel(MipsTargetMachine &TM, CodeGenOptLevel OL)
360fca6ea1SDimitry Andric       : SelectionDAGISel(TM, OL), Subtarget(nullptr) {}
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric protected:
410b57cec5SDimitry Andric   SDNode *getGlobalBaseReg();
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   /// Keep a pointer to the MipsSubtarget around so that we can make the right
440b57cec5SDimitry Andric   /// decision when generating code for different targets.
450b57cec5SDimitry Andric   const MipsSubtarget *Subtarget;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric private:
480b57cec5SDimitry Andric   // Include the pieces autogenerated from the target description.
490b57cec5SDimitry Andric   #include "MipsGenDAGISel.inc"
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   // Complex Pattern.
520b57cec5SDimitry Andric   /// (reg + imm).
530b57cec5SDimitry Andric   virtual bool selectAddrRegImm(SDValue Addr, SDValue &Base,
540b57cec5SDimitry Andric                                 SDValue &Offset) const;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric   /// Fall back on this function if all else fails.
570b57cec5SDimitry Andric   virtual bool selectAddrDefault(SDValue Addr, SDValue &Base,
580b57cec5SDimitry Andric                                  SDValue &Offset) const;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   /// Match integer address pattern.
610b57cec5SDimitry Andric   virtual bool selectIntAddr(SDValue Addr, SDValue &Base,
620b57cec5SDimitry Andric                              SDValue &Offset) const;
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   virtual bool selectIntAddr11MM(SDValue Addr, SDValue &Base,
650b57cec5SDimitry Andric                                  SDValue &Offset) const;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   virtual bool selectIntAddr12MM(SDValue Addr, SDValue &Base,
680b57cec5SDimitry Andric                                SDValue &Offset) const;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   virtual bool selectIntAddr16MM(SDValue Addr, SDValue &Base,
710b57cec5SDimitry Andric                                  SDValue &Offset) const;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   virtual bool selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
740b57cec5SDimitry Andric                                    SDValue &Offset) const;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   /// Match addr+simm10 and addr
770b57cec5SDimitry Andric   virtual bool selectIntAddrSImm10(SDValue Addr, SDValue &Base,
780b57cec5SDimitry Andric                                    SDValue &Offset) const;
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   virtual bool selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base,
810b57cec5SDimitry Andric                                        SDValue &Offset) const;
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   virtual bool selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base,
840b57cec5SDimitry Andric                                        SDValue &Offset) const;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   virtual bool selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base,
870b57cec5SDimitry Andric                                        SDValue &Offset) const;
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   virtual bool selectAddr16(SDValue Addr, SDValue &Base, SDValue &Offset);
900b57cec5SDimitry Andric   virtual bool selectAddr16SP(SDValue Addr, SDValue &Base, SDValue &Offset);
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   /// Select constant vector splats.
930b57cec5SDimitry Andric   virtual bool selectVSplat(SDNode *N, APInt &Imm,
940b57cec5SDimitry Andric                             unsigned MinSizeInBits) const;
950b57cec5SDimitry Andric   /// Select constant vector splats whose value fits in a uimm1.
960b57cec5SDimitry Andric   virtual bool selectVSplatUimm1(SDValue N, SDValue &Imm) const;
970b57cec5SDimitry Andric   /// Select constant vector splats whose value fits in a uimm2.
980b57cec5SDimitry Andric   virtual bool selectVSplatUimm2(SDValue N, SDValue &Imm) const;
990b57cec5SDimitry Andric   /// Select constant vector splats whose value fits in a uimm3.
1000b57cec5SDimitry Andric   virtual bool selectVSplatUimm3(SDValue N, SDValue &Imm) const;
1010b57cec5SDimitry Andric   /// Select constant vector splats whose value fits in a uimm4.
1020b57cec5SDimitry Andric   virtual bool selectVSplatUimm4(SDValue N, SDValue &Imm) const;
1030b57cec5SDimitry Andric   /// Select constant vector splats whose value fits in a uimm5.
1040b57cec5SDimitry Andric   virtual bool selectVSplatUimm5(SDValue N, SDValue &Imm) const;
1050b57cec5SDimitry Andric   /// Select constant vector splats whose value fits in a uimm6.
1060b57cec5SDimitry Andric   virtual bool selectVSplatUimm6(SDValue N, SDValue &Imm) const;
1070b57cec5SDimitry Andric   /// Select constant vector splats whose value fits in a uimm8.
1080b57cec5SDimitry Andric   virtual bool selectVSplatUimm8(SDValue N, SDValue &Imm) const;
1090b57cec5SDimitry Andric   /// Select constant vector splats whose value fits in a simm5.
1100b57cec5SDimitry Andric   virtual bool selectVSplatSimm5(SDValue N, SDValue &Imm) const;
1110b57cec5SDimitry Andric   /// Select constant vector splats whose value is a power of 2.
1120b57cec5SDimitry Andric   virtual bool selectVSplatUimmPow2(SDValue N, SDValue &Imm) const;
1130b57cec5SDimitry Andric   /// Select constant vector splats whose value is the inverse of a
1140b57cec5SDimitry Andric   /// power of 2.
1150b57cec5SDimitry Andric   virtual bool selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const;
1160b57cec5SDimitry Andric   /// Select constant vector splats whose value is a run of set bits
1170b57cec5SDimitry Andric   /// ending at the most significant bit
1180b57cec5SDimitry Andric   virtual bool selectVSplatMaskL(SDValue N, SDValue &Imm) const;
1190b57cec5SDimitry Andric   /// Select constant vector splats whose value is a run of set bits
1200b57cec5SDimitry Andric   /// starting at bit zero.
1210b57cec5SDimitry Andric   virtual bool selectVSplatMaskR(SDValue N, SDValue &Imm) const;
1220b57cec5SDimitry Andric 
123*71ac745dSDimitry Andric   /// Select constant vector splats whose value is 1.
124*71ac745dSDimitry Andric   virtual bool selectVSplatImmEq1(SDValue N) const;
125*71ac745dSDimitry Andric 
1268bcb0991SDimitry Andric   /// Convert vector addition with vector subtraction if that allows to encode
1278bcb0991SDimitry Andric   /// constant as an immediate and thus avoid extra 'ldi' instruction.
1288bcb0991SDimitry Andric   /// add X, <-1, -1...> --> sub X, <1, 1...>
1298bcb0991SDimitry Andric   bool selectVecAddAsVecSubIfProfitable(SDNode *Node);
1308bcb0991SDimitry Andric 
1310b57cec5SDimitry Andric   void Select(SDNode *N) override;
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   virtual bool trySelect(SDNode *Node) = 0;
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric   // getImm - Return a target constant with the specified value.
1360b57cec5SDimitry Andric   inline SDValue getImm(const SDNode *Node, uint64_t Imm) {
1370b57cec5SDimitry Andric     return CurDAG->getTargetConstant(Imm, SDLoc(Node), Node->getValueType(0));
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   virtual void processFunctionAfterISel(MachineFunction &MF) = 0;
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   bool SelectInlineAsmMemoryOperand(const SDValue &Op,
1435f757f3fSDimitry Andric                                     InlineAsm::ConstraintCode ConstraintID,
1440b57cec5SDimitry Andric                                     std::vector<SDValue> &OutOps) override;
145647cbc5dSDimitry Andric   bool isUnneededShiftMask(SDNode *N, unsigned ShAmtBits) const;
1460b57cec5SDimitry Andric };
1470fca6ea1SDimitry Andric 
1480fca6ea1SDimitry Andric class MipsDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
1490fca6ea1SDimitry Andric public:
1500fca6ea1SDimitry Andric   static char ID;
1510fca6ea1SDimitry Andric   MipsDAGToDAGISelLegacy(std::unique_ptr<SelectionDAGISel> S);
1520fca6ea1SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
1530fca6ea1SDimitry Andric };
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric #endif
157