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