xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/Mips16InstrInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- Mips16InstrInfo.h - Mips16 Instruction Information -------*- C++ -*-===//
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 contains the Mips16 implementation of the TargetInstrInfo class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_MIPS_MIPS16INSTRINFO_H
140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_MIPS_MIPS16INSTRINFO_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "Mips16RegisterInfo.h"
170b57cec5SDimitry Andric #include "MipsInstrInfo.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
190b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
200b57cec5SDimitry Andric #include <cstdint>
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace llvm {
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric class MCInstrDesc;
250b57cec5SDimitry Andric class MipsSubtarget;
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric class Mips16InstrInfo : public MipsInstrInfo {
280b57cec5SDimitry Andric   const Mips16RegisterInfo RI;
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric public:
310b57cec5SDimitry Andric   explicit Mips16InstrInfo(const MipsSubtarget &STI);
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   const MipsRegisterInfo &getRegisterInfo() const override;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric   /// isLoadFromStackSlot - If the specified machine instruction is a direct
360b57cec5SDimitry Andric   /// load from a stack slot, return the virtual or physical register number of
370b57cec5SDimitry Andric   /// the destination along with the FrameIndex of the loaded stack slot.  If
380b57cec5SDimitry Andric   /// not, return 0.  This predicate must return 0 if the instruction has
390b57cec5SDimitry Andric   /// any side effects other than loading from the stack slot.
40*0fca6ea1SDimitry Andric   Register isLoadFromStackSlot(const MachineInstr &MI,
410b57cec5SDimitry Andric                                int &FrameIndex) const override;
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   /// isStoreToStackSlot - If the specified machine instruction is a direct
440b57cec5SDimitry Andric   /// store to a stack slot, return the virtual or physical register number of
450b57cec5SDimitry Andric   /// the source reg along with the FrameIndex of the loaded stack slot.  If
460b57cec5SDimitry Andric   /// not, return 0.  This predicate must return 0 if the instruction has
470b57cec5SDimitry Andric   /// any side effects other than storing to the stack slot.
48*0fca6ea1SDimitry Andric   Register isStoreToStackSlot(const MachineInstr &MI,
490b57cec5SDimitry Andric                               int &FrameIndex) const override;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
52480093f4SDimitry Andric                    const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
530b57cec5SDimitry Andric                    bool KillSrc) const override;
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   void storeRegToStack(MachineBasicBlock &MBB,
560b57cec5SDimitry Andric                        MachineBasicBlock::iterator MBBI,
575ffd83dbSDimitry Andric                        Register SrcReg, bool isKill, int FrameIndex,
580b57cec5SDimitry Andric                        const TargetRegisterClass *RC,
590b57cec5SDimitry Andric                        const TargetRegisterInfo *TRI,
600b57cec5SDimitry Andric                        int64_t Offset) const override;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   void loadRegFromStack(MachineBasicBlock &MBB,
630b57cec5SDimitry Andric                         MachineBasicBlock::iterator MBBI,
645ffd83dbSDimitry Andric                         Register DestReg, int FrameIndex,
650b57cec5SDimitry Andric                         const TargetRegisterClass *RC,
660b57cec5SDimitry Andric                         const TargetRegisterInfo *TRI,
670b57cec5SDimitry Andric                         int64_t Offset) const override;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   bool expandPostRAPseudo(MachineInstr &MI) const override;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   unsigned getOppositeBranchOpc(unsigned Opc) const override;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   // Adjust SP by FrameSize bytes. Save RA, S0, S1
740b57cec5SDimitry Andric   void makeFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB,
750b57cec5SDimitry Andric                  MachineBasicBlock::iterator I) const;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   // Adjust SP by FrameSize bytes. Restore RA, S0, S1
780b57cec5SDimitry Andric   void restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB,
790b57cec5SDimitry Andric                       MachineBasicBlock::iterator I) const;
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   /// Adjust SP by Amount bytes.
820b57cec5SDimitry Andric   void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB,
830b57cec5SDimitry Andric                       MachineBasicBlock::iterator I) const override;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   /// Emit a series of instructions to load an immediate.
860b57cec5SDimitry Andric   // This is to adjust some FrameReg. We return the new register to be used
870b57cec5SDimitry Andric   // in place of FrameReg and the adjusted immediate field (&NewImm)
880b57cec5SDimitry Andric   unsigned loadImmediate(unsigned FrameReg, int64_t Imm, MachineBasicBlock &MBB,
890b57cec5SDimitry Andric                          MachineBasicBlock::iterator II, const DebugLoc &DL,
900b57cec5SDimitry Andric                          unsigned &NewImm) const;
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   static bool validImmediate(unsigned Opcode, unsigned Reg, int64_t Amount);
930b57cec5SDimitry Andric 
validSpImm8(int offset)940b57cec5SDimitry Andric   static bool validSpImm8(int offset) {
950b57cec5SDimitry Andric     return ((offset & 7) == 0) && isInt<11>(offset);
960b57cec5SDimitry Andric   }
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   // build the proper one based on the Imm field
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   const MCInstrDesc& AddiuSpImm(int64_t Imm) const;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   void BuildAddiuSpImm
1030b57cec5SDimitry Andric     (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric protected:
1060b57cec5SDimitry Andric   /// If the specific machine instruction is a instruction that moves/copies
107480093f4SDimitry Andric   /// value from one register to another register return destination and source
108480093f4SDimitry Andric   /// registers as machine operands.
109bdd1243dSDimitry Andric   std::optional<DestSourcePair>
110bdd1243dSDimitry Andric   isCopyInstrImpl(const MachineInstr &MI) const override;
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric private:
1130b57cec5SDimitry Andric   unsigned getAnalyzableBrOpc(unsigned Opc) const override;
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   void ExpandRetRA16(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
1160b57cec5SDimitry Andric                    unsigned Opc) const;
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   // Adjust SP by Amount bytes where bytes can be up to 32bit number.
1190b57cec5SDimitry Andric   void adjustStackPtrBig(unsigned SP, int64_t Amount, MachineBasicBlock &MBB,
1200b57cec5SDimitry Andric                          MachineBasicBlock::iterator I,
1210b57cec5SDimitry Andric                          unsigned Reg1, unsigned Reg2) const;
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   // Adjust SP by Amount bytes where bytes can be up to 32bit number.
1240b57cec5SDimitry Andric   void adjustStackPtrBigUnrestricted(unsigned SP, int64_t Amount,
1250b57cec5SDimitry Andric                                      MachineBasicBlock &MBB,
1260b57cec5SDimitry Andric                                      MachineBasicBlock::iterator I) const;
1270b57cec5SDimitry Andric };
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric } // end namespace llvm
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_MIPS_MIPS16INSTRINFO_H
132