1 //===-- Mips16InstrInfo.cpp - Mips16 Instruction Information --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the Mips16 implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "Mips16InstrInfo.h" 15 #include "InstPrinter/MipsInstPrinter.h" 16 #include "MipsMachineFunction.h" 17 #include "MipsTargetMachine.h" 18 #include "llvm/ADT/STLExtras.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/TargetRegistry.h" 25 26 using namespace llvm; 27 28 static cl::opt<bool> NeverUseSaveRestore( 29 "mips16-never-use-save-restore", 30 cl::init(false), 31 cl::desc("For testing ability to adjust stack pointer without save/restore instruction"), 32 cl::Hidden); 33 34 35 Mips16InstrInfo::Mips16InstrInfo(MipsTargetMachine &tm) 36 : MipsInstrInfo(tm, Mips::BimmX16), 37 RI(*tm.getSubtargetImpl(), *this) {} 38 39 const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { 40 return RI; 41 } 42 43 /// isLoadFromStackSlot - If the specified machine instruction is a direct 44 /// load from a stack slot, return the virtual or physical register number of 45 /// the destination along with the FrameIndex of the loaded stack slot. If 46 /// not, return 0. This predicate must return 0 if the instruction has 47 /// any side effects other than loading from the stack slot. 48 unsigned Mips16InstrInfo:: 49 isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const 50 { 51 return 0; 52 } 53 54 /// isStoreToStackSlot - If the specified machine instruction is a direct 55 /// store to a stack slot, return the virtual or physical register number of 56 /// the source reg along with the FrameIndex of the loaded stack slot. If 57 /// not, return 0. This predicate must return 0 if the instruction has 58 /// any side effects other than storing to the stack slot. 59 unsigned Mips16InstrInfo:: 60 isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const 61 { 62 return 0; 63 } 64 65 void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 66 MachineBasicBlock::iterator I, DebugLoc DL, 67 unsigned DestReg, unsigned SrcReg, 68 bool KillSrc) const { 69 unsigned Opc = 0; 70 71 if (Mips::CPU16RegsRegClass.contains(DestReg) && 72 Mips::CPURegsRegClass.contains(SrcReg)) 73 Opc = Mips::MoveR3216; 74 else if (Mips::CPURegsRegClass.contains(DestReg) && 75 Mips::CPU16RegsRegClass.contains(SrcReg)) 76 Opc = Mips::Move32R16; 77 else if ((SrcReg == Mips::HI) && 78 (Mips::CPU16RegsRegClass.contains(DestReg))) 79 Opc = Mips::Mfhi16, SrcReg = 0; 80 81 else if ((SrcReg == Mips::LO) && 82 (Mips::CPU16RegsRegClass.contains(DestReg))) 83 Opc = Mips::Mflo16, SrcReg = 0; 84 85 86 assert(Opc && "Cannot copy registers"); 87 88 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); 89 90 if (DestReg) 91 MIB.addReg(DestReg, RegState::Define); 92 93 if (SrcReg) 94 MIB.addReg(SrcReg, getKillRegState(KillSrc)); 95 } 96 97 void Mips16InstrInfo:: 98 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 99 unsigned SrcReg, bool isKill, int FI, 100 const TargetRegisterClass *RC, 101 const TargetRegisterInfo *TRI) const { 102 DebugLoc DL; 103 if (I != MBB.end()) DL = I->getDebugLoc(); 104 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); 105 unsigned Opc = 0; 106 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 107 Opc = Mips::SwRxSpImmX16; 108 assert(Opc && "Register class not handled!"); 109 BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)) 110 .addFrameIndex(FI).addImm(0).addMemOperand(MMO); 111 } 112 113 void Mips16InstrInfo:: 114 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 115 unsigned DestReg, int FI, 116 const TargetRegisterClass *RC, 117 const TargetRegisterInfo *TRI) const { 118 DebugLoc DL; 119 if (I != MBB.end()) DL = I->getDebugLoc(); 120 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); 121 unsigned Opc = 0; 122 123 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 124 Opc = Mips::LwRxSpImmX16; 125 assert(Opc && "Register class not handled!"); 126 BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(0) 127 .addMemOperand(MMO); 128 } 129 130 bool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 131 MachineBasicBlock &MBB = *MI->getParent(); 132 133 switch(MI->getDesc().getOpcode()) { 134 default: 135 return false; 136 case Mips::RetRA16: 137 ExpandRetRA16(MBB, MI, Mips::JrcRa16); 138 break; 139 } 140 141 MBB.erase(MI); 142 return true; 143 } 144 145 /// GetOppositeBranchOpc - Return the inverse of the specified 146 /// opcode, e.g. turning BEQ to BNE. 147 unsigned Mips16InstrInfo::GetOppositeBranchOpc(unsigned Opc) const { 148 switch (Opc) { 149 default: llvm_unreachable("Illegal opcode!"); 150 case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16; 151 case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16; 152 case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16; 153 case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16; 154 case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16; 155 case Mips::BtnezX16: return Mips::BteqzX16; 156 case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16; 157 case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16; 158 case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16; 159 case Mips::BteqzX16: return Mips::BtnezX16; 160 case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16; 161 case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16; 162 case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16; 163 case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16; 164 case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16; 165 case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16; 166 } 167 assert(false && "Implement this function."); 168 return 0; 169 } 170 171 // Adjust SP by FrameSize bytes. Save RA, S0, S1 172 void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, 173 MachineBasicBlock::iterator I) const { 174 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 175 if (!NeverUseSaveRestore) { 176 if (isUInt<11>(FrameSize)) 177 BuildMI(MBB, I, DL, get(Mips::SaveRaF16)).addImm(FrameSize); 178 else { 179 int Base = 2040; // should create template function like isUInt that returns largest 180 // possible n bit unsigned integer 181 int64_t Remainder = FrameSize - Base; 182 BuildMI(MBB, I, DL, get(Mips::SaveRaF16)). addImm(Base); 183 if (isInt<16>(-Remainder)) 184 BuildMI(MBB, I, DL, get(Mips::AddiuSpImmX16)). addImm(-Remainder); 185 else 186 adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1); 187 } 188 189 } 190 else { 191 // 192 // sw ra, -4[sp] 193 // sw s1, -8[sp] 194 // sw s0, -12[sp] 195 196 MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), Mips::RA); 197 MIB1.addReg(Mips::SP); 198 MIB1.addImm(-4); 199 MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), Mips::S1); 200 MIB2.addReg(Mips::SP); 201 MIB2.addImm(-8); 202 MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), Mips::S0); 203 MIB3.addReg(Mips::SP); 204 MIB3.addImm(-12); 205 adjustStackPtrBig(SP, -FrameSize, MBB, I, Mips::V0, Mips::V1); 206 } 207 } 208 209 // Adjust SP by FrameSize bytes. Restore RA, S0, S1 210 void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, 211 MachineBasicBlock::iterator I) const { 212 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 213 if (!NeverUseSaveRestore) { 214 if (isUInt<11>(FrameSize)) 215 BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)).addImm(FrameSize); 216 else { 217 int Base = 2040; // should create template function like isUInt that returns largest 218 // possible n bit unsigned integer 219 int64_t Remainder = FrameSize - Base; 220 if (isInt<16>(Remainder)) 221 BuildMI(MBB, I, DL, get(Mips::AddiuSpImmX16)). addImm(Remainder); 222 else 223 adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1); 224 BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)). addImm(Base); 225 } 226 } 227 else { 228 adjustStackPtrBig(SP, FrameSize, MBB, I, Mips::A0, Mips::A1); 229 // lw ra, -4[sp] 230 // lw s1, -8[sp] 231 // lw s0, -12[sp] 232 MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), Mips::A0); 233 MIB1.addReg(Mips::SP); 234 MIB1.addImm(-4); 235 MachineInstrBuilder MIB0 = BuildMI(MBB, I, DL, get(Mips::Move32R16), Mips::RA); 236 MIB0.addReg(Mips::A0); 237 MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), Mips::S1); 238 MIB2.addReg(Mips::SP); 239 MIB2.addImm(-8); 240 MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), Mips::S0); 241 MIB3.addReg(Mips::SP); 242 MIB3.addImm(-12); 243 } 244 245 } 246 247 // Adjust SP by Amount bytes where bytes can be up to 32bit number. 248 // This can only be called at times that we know that there is at least one free register. 249 // This is clearly safe at prologue and epilogue. 250 // 251 void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, 252 MachineBasicBlock::iterator I, 253 unsigned Reg1, unsigned Reg2) const { 254 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 255 // MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); 256 // unsigned Reg1 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass); 257 // unsigned Reg2 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass); 258 // 259 // li reg1, constant 260 // move reg2, sp 261 // add reg1, reg1, reg2 262 // move sp, reg1 263 // 264 // 265 MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1); 266 MIB1.addImm(Amount); 267 MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2); 268 MIB2.addReg(Mips::SP, RegState::Kill); 269 MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1); 270 MIB3.addReg(Reg1); 271 MIB3.addReg(Reg2, RegState::Kill); 272 MachineInstrBuilder MIB4 = BuildMI(MBB, I, DL, get(Mips::Move32R16), Mips::SP); 273 MIB4.addReg(Reg1, RegState::Kill); 274 } 275 276 void Mips16InstrInfo::adjustStackPtrBigUnrestricted(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, 277 MachineBasicBlock::iterator I) const { 278 assert(false && "adjust stack pointer amount exceeded"); 279 } 280 281 /// Adjust SP by Amount bytes. 282 void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, 283 MachineBasicBlock &MBB, 284 MachineBasicBlock::iterator I) const { 285 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 286 if (isInt<16>(Amount)) // need to change to addiu sp, ....and isInt<16> 287 BuildMI(MBB, I, DL, get(Mips::AddiuSpImmX16)). addImm(Amount); 288 else 289 adjustStackPtrBigUnrestricted(SP, Amount, MBB, I); 290 } 291 292 /// This function generates the sequence of instructions needed to get the 293 /// result of adding register REG and immediate IMM. 294 unsigned 295 Mips16InstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB, 296 MachineBasicBlock::iterator II, DebugLoc DL, 297 unsigned *NewImm) const { 298 299 return 0; 300 } 301 302 unsigned Mips16InstrInfo::GetAnalyzableBrOpc(unsigned Opc) const { 303 return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || 304 Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 || 305 Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 || 306 Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 || 307 Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 || 308 Opc == Mips::BtnezX16 || Opc == Mips::BtnezT8CmpX16 || 309 Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 || 310 Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 || 311 Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0; 312 } 313 314 void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB, 315 MachineBasicBlock::iterator I, 316 unsigned Opc) const { 317 BuildMI(MBB, I, I->getDebugLoc(), get(Opc)); 318 } 319 320 const MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) { 321 return new Mips16InstrInfo(TM); 322 } 323