343 lines · c
1//===-- M68kInstrInfo.h - M68k Instruction Information ----------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains the M68k implementation of the TargetInstrInfo class.11///12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H15#define LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H16 17#include "M68k.h"18#include "M68kRegisterInfo.h"19 20#include "MCTargetDesc/M68kBaseInfo.h"21 22#include "llvm/CodeGen/MachineInstrBuilder.h"23#include "llvm/CodeGen/TargetInstrInfo.h"24 25#define GET_INSTRINFO_HEADER26#include "M68kGenInstrInfo.inc"27 28namespace llvm {29 30class M68kSubtarget;31 32namespace M68k {33// These MUST be kept in sync with codes definitions in M68kInstrInfo.td34enum CondCode {35 COND_T = 0, // True36 COND_F = 1, // False37 COND_HI = 2, // High38 COND_LS = 3, // Less or Same39 COND_CC = 4, // Carry Clear40 COND_CS = 5, // Carry Set41 COND_NE = 6, // Not Equal42 COND_EQ = 7, // Equal43 COND_VC = 8, // Overflow Clear44 COND_VS = 9, // Overflow Set45 COND_PL = 10, // Plus46 COND_MI = 11, // Minus47 COND_GE = 12, // Greater or Equal48 COND_LT = 13, // Less Than49 COND_GT = 14, // Greater Than50 COND_LE = 15, // Less or Equal51 LAST_VALID_COND = COND_LE,52 COND_INVALID53};54 55// FIXME would be nice tablegen to generate these predicates and converters56// mb tag based57 58static inline M68k::CondCode GetOppositeBranchCondition(M68k::CondCode CC) {59 switch (CC) {60 default:61 llvm_unreachable("Illegal condition code!");62 case M68k::COND_T:63 return M68k::COND_F;64 case M68k::COND_F:65 return M68k::COND_T;66 case M68k::COND_HI:67 return M68k::COND_LS;68 case M68k::COND_LS:69 return M68k::COND_HI;70 case M68k::COND_CC:71 return M68k::COND_CS;72 case M68k::COND_CS:73 return M68k::COND_CC;74 case M68k::COND_NE:75 return M68k::COND_EQ;76 case M68k::COND_EQ:77 return M68k::COND_NE;78 case M68k::COND_VC:79 return M68k::COND_VS;80 case M68k::COND_VS:81 return M68k::COND_VC;82 case M68k::COND_PL:83 return M68k::COND_MI;84 case M68k::COND_MI:85 return M68k::COND_PL;86 case M68k::COND_GE:87 return M68k::COND_LT;88 case M68k::COND_LT:89 return M68k::COND_GE;90 case M68k::COND_GT:91 return M68k::COND_LE;92 case M68k::COND_LE:93 return M68k::COND_GT;94 }95}96 97static inline unsigned GetCondBranchFromCond(M68k::CondCode CC) {98 switch (CC) {99 default:100 llvm_unreachable("Illegal condition code!");101 case M68k::COND_EQ:102 return M68k::Beq8;103 case M68k::COND_NE:104 return M68k::Bne8;105 case M68k::COND_LT:106 return M68k::Blt8;107 case M68k::COND_LE:108 return M68k::Ble8;109 case M68k::COND_GT:110 return M68k::Bgt8;111 case M68k::COND_GE:112 return M68k::Bge8;113 case M68k::COND_CS:114 return M68k::Bcs8;115 case M68k::COND_LS:116 return M68k::Bls8;117 case M68k::COND_HI:118 return M68k::Bhi8;119 case M68k::COND_CC:120 return M68k::Bcc8;121 case M68k::COND_MI:122 return M68k::Bmi8;123 case M68k::COND_PL:124 return M68k::Bpl8;125 case M68k::COND_VS:126 return M68k::Bvs8;127 case M68k::COND_VC:128 return M68k::Bvc8;129 }130}131 132static inline M68k::CondCode GetCondFromBranchOpc(unsigned Opcode) {133 switch (Opcode) {134 default:135 return M68k::COND_INVALID;136 case M68k::Beq8:137 return M68k::COND_EQ;138 case M68k::Bne8:139 return M68k::COND_NE;140 case M68k::Blt8:141 return M68k::COND_LT;142 case M68k::Ble8:143 return M68k::COND_LE;144 case M68k::Bgt8:145 return M68k::COND_GT;146 case M68k::Bge8:147 return M68k::COND_GE;148 case M68k::Bcs8:149 return M68k::COND_CS;150 case M68k::Bls8:151 return M68k::COND_LS;152 case M68k::Bhi8:153 return M68k::COND_HI;154 case M68k::Bcc8:155 return M68k::COND_CC;156 case M68k::Bmi8:157 return M68k::COND_MI;158 case M68k::Bpl8:159 return M68k::COND_PL;160 case M68k::Bvs8:161 return M68k::COND_VS;162 case M68k::Bvc8:163 return M68k::COND_VC;164 }165}166 167static inline unsigned IsCMP(unsigned Op) {168 switch (Op) {169 default:170 return false;171 case M68k::CMP8dd:172 case M68k::CMP8df:173 case M68k::CMP8di:174 case M68k::CMP8dj:175 case M68k::CMP8dp:176 case M68k::CMP16dr:177 case M68k::CMP16df:178 case M68k::CMP16di:179 case M68k::CMP16dj:180 case M68k::CMP16dp:181 return true;182 }183}184 185static inline bool IsSETCC(unsigned SETCC) {186 switch (SETCC) {187 default:188 return false;189 case M68k::SETd8eq:190 case M68k::SETd8ne:191 case M68k::SETd8lt:192 case M68k::SETd8ge:193 case M68k::SETd8le:194 case M68k::SETd8gt:195 case M68k::SETd8cs:196 case M68k::SETd8cc:197 case M68k::SETd8ls:198 case M68k::SETd8hi:199 case M68k::SETd8pl:200 case M68k::SETd8mi:201 case M68k::SETd8vc:202 case M68k::SETd8vs:203 case M68k::SETj8eq:204 case M68k::SETj8ne:205 case M68k::SETj8lt:206 case M68k::SETj8ge:207 case M68k::SETj8le:208 case M68k::SETj8gt:209 case M68k::SETj8cs:210 case M68k::SETj8cc:211 case M68k::SETj8ls:212 case M68k::SETj8hi:213 case M68k::SETj8pl:214 case M68k::SETj8mi:215 case M68k::SETj8vc:216 case M68k::SETj8vs:217 case M68k::SETp8eq:218 case M68k::SETp8ne:219 case M68k::SETp8lt:220 case M68k::SETp8ge:221 case M68k::SETp8le:222 case M68k::SETp8gt:223 case M68k::SETp8cs:224 case M68k::SETp8cc:225 case M68k::SETp8ls:226 case M68k::SETp8hi:227 case M68k::SETp8pl:228 case M68k::SETp8mi:229 case M68k::SETp8vc:230 case M68k::SETp8vs:231 return true;232 }233}234 235} // namespace M68k236 237class M68kInstrInfo : public M68kGenInstrInfo {238 virtual void anchor();239 240protected:241 const M68kSubtarget &Subtarget;242 const M68kRegisterInfo RI;243 244public:245 explicit M68kInstrInfo(const M68kSubtarget &STI);246 247 static const M68kInstrInfo *create(M68kSubtarget &STI);248 249 /// TargetInstrInfo is a superset of MRegister info. As such, whenever a250 /// client has an instance of instruction info, it should always be able to251 /// get register info as well (through this method).252 const M68kRegisterInfo &getRegisterInfo() const { return RI; };253 254 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,255 MachineBasicBlock *&FBB,256 SmallVectorImpl<MachineOperand> &Cond,257 bool AllowModify) const override;258 259 bool AnalyzeBranchImpl(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,260 MachineBasicBlock *&FBB,261 SmallVectorImpl<MachineOperand> &Cond,262 bool AllowModify) const;263 264 unsigned removeBranch(MachineBasicBlock &MBB,265 int *BytesRemoved = nullptr) const override;266 267 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,268 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,269 const DebugLoc &DL,270 int *BytesAdded = nullptr) const override;271 272 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,273 const DebugLoc &DL, Register DestReg, Register SrcReg,274 bool KillSrc, bool RenamableDest = false,275 bool RenamableSrc = false) const override;276 277 bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx,278 unsigned &Size, unsigned &Offset,279 const MachineFunction &MF) const override;280 281 void storeRegToStackSlot(282 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,283 bool IsKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg,284 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;285 286 void loadRegFromStackSlot(287 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg,288 int FrameIndex, const TargetRegisterClass *RC, Register VReg,289 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;290 291 bool expandPostRAPseudo(MachineInstr &MI) const override;292 293 bool isPCRelRegisterOperandLegal(const MachineOperand &MO) const override;294 295 /// Add appropriate SExt nodes296 void AddSExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,297 DebugLoc DL, unsigned Reg, MVT From, MVT To) const;298 299 /// Add appropriate ZExt nodes300 void AddZExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,301 DebugLoc DL, unsigned Reg, MVT From, MVT To) const;302 303 /// Move immediate to register304 bool ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const;305 306 /// Move across register classes without extension307 bool ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst, MVT MVTSrc) const;308 309 /// Move from register and extend310 bool ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned, MVT MVTDst,311 MVT MVTSrc) const;312 313 /// Move from memory and extend314 bool ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,315 const MCInstrDesc &Desc, MVT MVTDst, MVT MVTSrc) const;316 317 /// Push/Pop to/from stack318 bool ExpandPUSH_POP(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,319 bool IsPush) const;320 321 /// Moves to/from CCR322 bool ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const;323 324 /// Expand all MOVEM pseudos into real MOVEMs325 bool ExpandMOVEM(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,326 bool IsRM) const;327 328 /// Return a virtual register initialized with the global base register329 /// value. Output instructions required to initialize the register in the330 /// function entry block, if necessary.331 unsigned getGlobalBaseReg(MachineFunction *MF) const;332 333 std::pair<unsigned, unsigned>334 decomposeMachineOperandsTargetFlags(unsigned TF) const override;335 336 ArrayRef<std::pair<unsigned, const char *>>337 getSerializableDirectMachineOperandTargetFlags() const override;338};339 340} // namespace llvm341 342#endif // LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H343