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 "llvm/ADT/BitVector.h" 16 #include "llvm/CodeGen/MachineBasicBlock.h" 17 #include "llvm/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/MachineFunction.h" 19 #include "llvm/CodeGen/MachineInstr.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineMemOperand.h" 22 #include "llvm/CodeGen/MachineOperand.h" 23 #include "llvm/CodeGen/RegisterScavenging.h" 24 #include "llvm/CodeGen/TargetRegisterInfo.h" 25 #include "llvm/IR/DebugLoc.h" 26 #include "llvm/MC/MCAsmInfo.h" 27 #include "llvm/Support/Debug.h" 28 #include "llvm/Support/ErrorHandling.h" 29 #include "llvm/Support/MathExtras.h" 30 #include "llvm/Support/raw_ostream.h" 31 #include <cassert> 32 #include <cctype> 33 #include <cstdint> 34 #include <cstdlib> 35 #include <cstring> 36 #include <iterator> 37 #include <vector> 38 39 using namespace llvm; 40 41 #define DEBUG_TYPE "mips16-instrinfo" 42 43 Mips16InstrInfo::Mips16InstrInfo(const MipsSubtarget &STI) 44 : MipsInstrInfo(STI, Mips::Bimm16) {} 45 46 const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { 47 return RI; 48 } 49 50 /// isLoadFromStackSlot - If the specified machine instruction is a direct 51 /// load from a stack slot, return the virtual or physical register number of 52 /// the destination along with the FrameIndex of the loaded stack slot. If 53 /// not, return 0. This predicate must return 0 if the instruction has 54 /// any side effects other than loading from the stack slot. 55 unsigned Mips16InstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 56 int &FrameIndex) const { 57 return 0; 58 } 59 60 /// isStoreToStackSlot - If the specified machine instruction is a direct 61 /// store to a stack slot, return the virtual or physical register number of 62 /// the source reg along with the FrameIndex of the loaded stack slot. If 63 /// not, return 0. This predicate must return 0 if the instruction has 64 /// any side effects other than storing to the stack slot. 65 unsigned Mips16InstrInfo::isStoreToStackSlot(const MachineInstr &MI, 66 int &FrameIndex) const { 67 return 0; 68 } 69 70 void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 71 MachineBasicBlock::iterator I, 72 const DebugLoc &DL, unsigned DestReg, 73 unsigned SrcReg, bool KillSrc) const { 74 unsigned Opc = 0; 75 76 if (Mips::CPU16RegsRegClass.contains(DestReg) && 77 Mips::GPR32RegClass.contains(SrcReg)) 78 Opc = Mips::MoveR3216; 79 else if (Mips::GPR32RegClass.contains(DestReg) && 80 Mips::CPU16RegsRegClass.contains(SrcReg)) 81 Opc = Mips::Move32R16; 82 else if ((SrcReg == Mips::HI0) && 83 (Mips::CPU16RegsRegClass.contains(DestReg))) 84 Opc = Mips::Mfhi16, SrcReg = 0; 85 else if ((SrcReg == Mips::LO0) && 86 (Mips::CPU16RegsRegClass.contains(DestReg))) 87 Opc = Mips::Mflo16, SrcReg = 0; 88 89 assert(Opc && "Cannot copy registers"); 90 91 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); 92 93 if (DestReg) 94 MIB.addReg(DestReg, RegState::Define); 95 96 if (SrcReg) 97 MIB.addReg(SrcReg, getKillRegState(KillSrc)); 98 } 99 100 void Mips16InstrInfo::storeRegToStack(MachineBasicBlock &MBB, 101 MachineBasicBlock::iterator I, 102 unsigned SrcReg, bool isKill, int FI, 103 const TargetRegisterClass *RC, 104 const TargetRegisterInfo *TRI, 105 int64_t Offset) const { 106 DebugLoc DL; 107 if (I != MBB.end()) DL = I->getDebugLoc(); 108 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); 109 unsigned Opc = 0; 110 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 111 Opc = Mips::SwRxSpImmX16; 112 assert(Opc && "Register class not handled!"); 113 BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)). 114 addFrameIndex(FI).addImm(Offset) 115 .addMemOperand(MMO); 116 } 117 118 void Mips16InstrInfo::loadRegFromStack(MachineBasicBlock &MBB, 119 MachineBasicBlock::iterator I, 120 unsigned DestReg, int FI, 121 const TargetRegisterClass *RC, 122 const TargetRegisterInfo *TRI, 123 int64_t Offset) const { 124 DebugLoc DL; 125 if (I != MBB.end()) DL = I->getDebugLoc(); 126 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); 127 unsigned Opc = 0; 128 129 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 130 Opc = Mips::LwRxSpImmX16; 131 assert(Opc && "Register class not handled!"); 132 BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset) 133 .addMemOperand(MMO); 134 } 135 136 bool Mips16InstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 137 MachineBasicBlock &MBB = *MI.getParent(); 138 switch (MI.getDesc().getOpcode()) { 139 default: 140 return false; 141 case Mips::RetRA16: 142 ExpandRetRA16(MBB, MI, Mips::JrcRa16); 143 break; 144 } 145 146 MBB.erase(MI.getIterator()); 147 return true; 148 } 149 150 /// GetOppositeBranchOpc - Return the inverse of the specified 151 /// opcode, e.g. turning BEQ to BNE. 152 unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc) const { 153 switch (Opc) { 154 case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16; 155 case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16; 156 case Mips::BeqzRxImm16: return Mips::BnezRxImm16; 157 case Mips::BnezRxImm16: return Mips::BeqzRxImm16; 158 case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16; 159 case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16; 160 case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16; 161 case Mips::Btnez16: return Mips::Bteqz16; 162 case Mips::BtnezX16: return Mips::BteqzX16; 163 case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16; 164 case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16; 165 case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16; 166 case Mips::Bteqz16: return Mips::Btnez16; 167 case Mips::BteqzX16: return Mips::BtnezX16; 168 case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16; 169 case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16; 170 case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16; 171 case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16; 172 case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16; 173 case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16; 174 } 175 llvm_unreachable("Illegal opcode!"); 176 } 177 178 static void addSaveRestoreRegs(MachineInstrBuilder &MIB, 179 const std::vector<CalleeSavedInfo> &CSI, 180 unsigned Flags = 0) { 181 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 182 // Add the callee-saved register as live-in. Do not add if the register is 183 // RA and return address is taken, because it has already been added in 184 // method MipsTargetLowering::lowerRETURNADDR. 185 // It's killed at the spill, unless the register is RA and return address 186 // is taken. 187 unsigned Reg = CSI[e-i-1].getReg(); 188 switch (Reg) { 189 case Mips::RA: 190 case Mips::S0: 191 case Mips::S1: 192 MIB.addReg(Reg, Flags); 193 break; 194 case Mips::S2: 195 break; 196 default: 197 llvm_unreachable("unexpected mips16 callee saved register"); 198 199 } 200 } 201 } 202 203 // Adjust SP by FrameSize bytes. Save RA, S0, S1 204 void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize, 205 MachineBasicBlock &MBB, 206 MachineBasicBlock::iterator I) const { 207 DebugLoc DL; 208 MachineFunction &MF = *MBB.getParent(); 209 MachineFrameInfo &MFI = MF.getFrameInfo(); 210 const BitVector Reserved = RI.getReservedRegs(MF); 211 bool SaveS2 = Reserved[Mips::S2]; 212 MachineInstrBuilder MIB; 213 unsigned Opc = ((FrameSize <= 128) && !SaveS2)? Mips::Save16:Mips::SaveX16; 214 MIB = BuildMI(MBB, I, DL, get(Opc)); 215 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 216 addSaveRestoreRegs(MIB, CSI); 217 if (SaveS2) 218 MIB.addReg(Mips::S2); 219 if (isUInt<11>(FrameSize)) 220 MIB.addImm(FrameSize); 221 else { 222 int Base = 2040; // should create template function like isUInt that 223 // returns largest possible n bit unsigned integer 224 int64_t Remainder = FrameSize - Base; 225 MIB.addImm(Base); 226 if (isInt<16>(-Remainder)) 227 BuildAddiuSpImm(MBB, I, -Remainder); 228 else 229 adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1); 230 } 231 } 232 233 // Adjust SP by FrameSize bytes. Restore RA, S0, S1 234 void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize, 235 MachineBasicBlock &MBB, 236 MachineBasicBlock::iterator I) const { 237 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 238 MachineFunction *MF = MBB.getParent(); 239 MachineFrameInfo &MFI = MF->getFrameInfo(); 240 const BitVector Reserved = RI.getReservedRegs(*MF); 241 bool SaveS2 = Reserved[Mips::S2]; 242 MachineInstrBuilder MIB; 243 unsigned Opc = ((FrameSize <= 128) && !SaveS2)? 244 Mips::Restore16:Mips::RestoreX16; 245 246 if (!isUInt<11>(FrameSize)) { 247 unsigned Base = 2040; 248 int64_t Remainder = FrameSize - Base; 249 FrameSize = Base; // should create template function like isUInt that 250 // returns largest possible n bit unsigned integer 251 252 if (isInt<16>(Remainder)) 253 BuildAddiuSpImm(MBB, I, Remainder); 254 else 255 adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1); 256 } 257 MIB = BuildMI(MBB, I, DL, get(Opc)); 258 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 259 addSaveRestoreRegs(MIB, CSI, RegState::Define); 260 if (SaveS2) 261 MIB.addReg(Mips::S2, RegState::Define); 262 MIB.addImm(FrameSize); 263 } 264 265 // Adjust SP by Amount bytes where bytes can be up to 32bit number. 266 // This can only be called at times that we know that there is at least one free 267 // register. 268 // This is clearly safe at prologue and epilogue. 269 void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount, 270 MachineBasicBlock &MBB, 271 MachineBasicBlock::iterator I, 272 unsigned Reg1, unsigned Reg2) const { 273 DebugLoc DL; 274 // 275 // li reg1, constant 276 // move reg2, sp 277 // add reg1, reg1, reg2 278 // move sp, reg1 279 // 280 // 281 MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1); 282 MIB1.addImm(Amount).addImm(-1); 283 MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2); 284 MIB2.addReg(Mips::SP, RegState::Kill); 285 MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1); 286 MIB3.addReg(Reg1); 287 MIB3.addReg(Reg2, RegState::Kill); 288 MachineInstrBuilder MIB4 = BuildMI(MBB, I, DL, get(Mips::Move32R16), 289 Mips::SP); 290 MIB4.addReg(Reg1, RegState::Kill); 291 } 292 293 void Mips16InstrInfo::adjustStackPtrBigUnrestricted( 294 unsigned SP, int64_t Amount, MachineBasicBlock &MBB, 295 MachineBasicBlock::iterator I) const { 296 llvm_unreachable("adjust stack pointer amount exceeded"); 297 } 298 299 /// Adjust SP by Amount bytes. 300 void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, 301 MachineBasicBlock &MBB, 302 MachineBasicBlock::iterator I) const { 303 if (Amount == 0) 304 return; 305 306 if (isInt<16>(Amount)) // need to change to addiu sp, ....and isInt<16> 307 BuildAddiuSpImm(MBB, I, Amount); 308 else 309 adjustStackPtrBigUnrestricted(SP, Amount, MBB, I); 310 } 311 312 /// This function generates the sequence of instructions needed to get the 313 /// result of adding register REG and immediate IMM. 314 unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg, int64_t Imm, 315 MachineBasicBlock &MBB, 316 MachineBasicBlock::iterator II, 317 const DebugLoc &DL, 318 unsigned &NewImm) const { 319 // 320 // given original instruction is: 321 // Instr rx, T[offset] where offset is too big. 322 // 323 // lo = offset & 0xFFFF 324 // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF; 325 // 326 // let T = temporary register 327 // li T, hi 328 // shl T, 16 329 // add T, Rx, T 330 // 331 RegScavenger rs; 332 int32_t lo = Imm & 0xFFFF; 333 NewImm = lo; 334 int Reg =0; 335 int SpReg = 0; 336 337 rs.enterBasicBlock(MBB); 338 rs.forward(II); 339 // 340 // We need to know which registers can be used, in the case where there 341 // are not enough free registers. We exclude all registers that 342 // are used in the instruction that we are helping. 343 // // Consider all allocatable registers in the register class initially 344 BitVector Candidates = 345 RI.getAllocatableSet 346 (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass); 347 // Exclude all the registers being used by the instruction. 348 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 349 MachineOperand &MO = II->getOperand(i); 350 if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() && 351 !TargetRegisterInfo::isVirtualRegister(MO.getReg())) 352 Candidates.reset(MO.getReg()); 353 } 354 355 // If the same register was used and defined in an instruction, then 356 // it will not be in the list of candidates. 357 // 358 // we need to analyze the instruction that we are helping. 359 // we need to know if it defines register x but register x is not 360 // present as an operand of the instruction. this tells 361 // whether the register is live before the instruction. if it's not 362 // then we don't need to save it in case there are no free registers. 363 int DefReg = 0; 364 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 365 MachineOperand &MO = II->getOperand(i); 366 if (MO.isReg() && MO.isDef()) { 367 DefReg = MO.getReg(); 368 break; 369 } 370 } 371 372 BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass); 373 Available &= Candidates; 374 // 375 // we use T0 for the first register, if we need to save something away. 376 // we use T1 for the second register, if we need to save something away. 377 // 378 unsigned FirstRegSaved =0, SecondRegSaved=0; 379 unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0; 380 381 Reg = Available.find_first(); 382 383 if (Reg == -1) { 384 Reg = Candidates.find_first(); 385 Candidates.reset(Reg); 386 if (DefReg != Reg) { 387 FirstRegSaved = Reg; 388 FirstRegSavedTo = Mips::T0; 389 copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); 390 } 391 } 392 else 393 Available.reset(Reg); 394 BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm).addImm(-1); 395 NewImm = 0; 396 if (FrameReg == Mips::SP) { 397 SpReg = Available.find_first(); 398 if (SpReg == -1) { 399 SpReg = Candidates.find_first(); 400 // Candidates.reset(SpReg); // not really needed 401 if (DefReg!= SpReg) { 402 SecondRegSaved = SpReg; 403 SecondRegSavedTo = Mips::T1; 404 } 405 if (SecondRegSaved) 406 copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); 407 } 408 else 409 Available.reset(SpReg); 410 copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false); 411 BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill) 412 .addReg(Reg); 413 } 414 else 415 BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(FrameReg) 416 .addReg(Reg, RegState::Kill); 417 if (FirstRegSaved || SecondRegSaved) { 418 II = std::next(II); 419 if (FirstRegSaved) 420 copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true); 421 if (SecondRegSaved) 422 copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo, true); 423 } 424 return Reg; 425 } 426 427 unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const { 428 return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || 429 Opc == Mips::Bimm16 || 430 Opc == Mips::Bteqz16 || Opc == Mips::Btnez16 || 431 Opc == Mips::BeqzRxImm16 || Opc == Mips::BnezRxImm16 || 432 Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 || 433 Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 || 434 Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 || 435 Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 || 436 Opc == Mips::BtnezX16 || Opc == Mips::BtnezT8CmpX16 || 437 Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 || 438 Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 || 439 Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0; 440 } 441 442 void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB, 443 MachineBasicBlock::iterator I, 444 unsigned Opc) const { 445 BuildMI(MBB, I, I->getDebugLoc(), get(Opc)); 446 } 447 448 const MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const { 449 if (validSpImm8(Imm)) 450 return get(Mips::AddiuSpImm16); 451 else 452 return get(Mips::AddiuSpImmX16); 453 } 454 455 void Mips16InstrInfo::BuildAddiuSpImm 456 (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const { 457 DebugLoc DL; 458 BuildMI(MBB, I, DL, AddiuSpImm(Imm)).addImm(Imm); 459 } 460 461 const MipsInstrInfo *llvm::createMips16InstrInfo(const MipsSubtarget &STI) { 462 return new Mips16InstrInfo(STI); 463 } 464 465 bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg, 466 int64_t Amount) { 467 switch (Opcode) { 468 case Mips::LbRxRyOffMemX16: 469 case Mips::LbuRxRyOffMemX16: 470 case Mips::LhRxRyOffMemX16: 471 case Mips::LhuRxRyOffMemX16: 472 case Mips::SbRxRyOffMemX16: 473 case Mips::ShRxRyOffMemX16: 474 case Mips::LwRxRyOffMemX16: 475 case Mips::SwRxRyOffMemX16: 476 case Mips::SwRxSpImmX16: 477 case Mips::LwRxSpImmX16: 478 return isInt<16>(Amount); 479 case Mips::AddiuRxRyOffMemX16: 480 if ((Reg == Mips::PC) || (Reg == Mips::SP)) 481 return isInt<16>(Amount); 482 return isInt<15>(Amount); 483 } 484 llvm_unreachable("unexpected Opcode in validImmediate"); 485 } 486