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. 400b57cec5SDimitry Andric unsigned 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. 480b57cec5SDimitry Andric unsigned 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 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. 109*bdd1243dSDimitry Andric std::optional<DestSourcePair> 110*bdd1243dSDimitry 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