1 //===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the VE implementation of the TargetInstrInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "VEInstrInfo.h" 14 #include "VE.h" 15 #include "VEMachineFunctionInfo.h" 16 #include "VESubtarget.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/CodeGen/MachineFrameInfo.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineMemOperand.h" 22 #include "llvm/CodeGen/MachineRegisterInfo.h" 23 #include "llvm/Support/CommandLine.h" 24 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/TargetRegistry.h" 27 28 #define DEBUG_TYPE "ve" 29 30 using namespace llvm; 31 32 #define GET_INSTRINFO_CTOR_DTOR 33 #include "VEGenInstrInfo.inc" 34 35 // Pin the vtable to this file. 36 void VEInstrInfo::anchor() {} 37 38 VEInstrInfo::VEInstrInfo(VESubtarget &ST) 39 : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI() {} 40 41 static bool IsIntegerCC(unsigned CC) { return (CC < VECC::CC_AF); } 42 43 static VECC::CondCode GetOppositeBranchCondition(VECC::CondCode CC) { 44 switch(CC) { 45 case VECC::CC_IG: return VECC::CC_ILE; 46 case VECC::CC_IL: return VECC::CC_IGE; 47 case VECC::CC_INE: return VECC::CC_IEQ; 48 case VECC::CC_IEQ: return VECC::CC_INE; 49 case VECC::CC_IGE: return VECC::CC_IL; 50 case VECC::CC_ILE: return VECC::CC_IG; 51 case VECC::CC_AF: return VECC::CC_AT; 52 case VECC::CC_G: return VECC::CC_LENAN; 53 case VECC::CC_L: return VECC::CC_GENAN; 54 case VECC::CC_NE: return VECC::CC_EQNAN; 55 case VECC::CC_EQ: return VECC::CC_NENAN; 56 case VECC::CC_GE: return VECC::CC_LNAN; 57 case VECC::CC_LE: return VECC::CC_GNAN; 58 case VECC::CC_NUM: return VECC::CC_NAN; 59 case VECC::CC_NAN: return VECC::CC_NUM; 60 case VECC::CC_GNAN: return VECC::CC_LE; 61 case VECC::CC_LNAN: return VECC::CC_GE; 62 case VECC::CC_NENAN: return VECC::CC_EQ; 63 case VECC::CC_EQNAN: return VECC::CC_NE; 64 case VECC::CC_GENAN: return VECC::CC_L; 65 case VECC::CC_LENAN: return VECC::CC_G; 66 case VECC::CC_AT: return VECC::CC_AF; 67 } 68 llvm_unreachable("Invalid cond code"); 69 } 70 71 // Treat br.l [BCR AT] as unconditional branch 72 static bool isUncondBranchOpcode(int Opc) { 73 return Opc == VE::BCRLa || Opc == VE::BCRWa || 74 Opc == VE::BCRDa || Opc == VE::BCRSa; 75 } 76 77 static bool isCondBranchOpcode(int Opc) { 78 return Opc == VE::BCRLrr || Opc == VE::BCRLir || 79 Opc == VE::BCRLrm0 || Opc == VE::BCRLrm1 || 80 Opc == VE::BCRLim0 || Opc == VE::BCRLim1 || 81 Opc == VE::BCRWrr || Opc == VE::BCRWir || 82 Opc == VE::BCRWrm0 || Opc == VE::BCRWrm1 || 83 Opc == VE::BCRWim0 || Opc == VE::BCRWim1 || 84 Opc == VE::BCRDrr || Opc == VE::BCRDir || 85 Opc == VE::BCRDrm0 || Opc == VE::BCRDrm1 || 86 Opc == VE::BCRDim0 || Opc == VE::BCRDim1 || 87 Opc == VE::BCRSrr || Opc == VE::BCRSir || 88 Opc == VE::BCRSrm0 || Opc == VE::BCRSrm1 || 89 Opc == VE::BCRSim0 || Opc == VE::BCRSim1; 90 } 91 92 static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, 93 SmallVectorImpl<MachineOperand> &Cond) { 94 Cond.push_back(MachineOperand::CreateImm(LastInst->getOperand(0).getImm())); 95 Cond.push_back(LastInst->getOperand(1)); 96 Cond.push_back(LastInst->getOperand(2)); 97 Target = LastInst->getOperand(3).getMBB(); 98 } 99 100 bool VEInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 101 MachineBasicBlock *&FBB, 102 SmallVectorImpl<MachineOperand> &Cond, 103 bool AllowModify) const { 104 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 105 if (I == MBB.end()) 106 return false; 107 108 if (!isUnpredicatedTerminator(*I)) 109 return false; 110 111 // Get the last instruction in the block. 112 MachineInstr *LastInst = &*I; 113 unsigned LastOpc = LastInst->getOpcode(); 114 115 // If there is only one terminator instruction, process it. 116 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 117 if (isUncondBranchOpcode(LastOpc)) { 118 TBB = LastInst->getOperand(0).getMBB(); 119 return false; 120 } 121 if (isCondBranchOpcode(LastOpc)) { 122 // Block ends with fall-through condbranch. 123 parseCondBranch(LastInst, TBB, Cond); 124 return false; 125 } 126 return true; // Can't handle indirect branch. 127 } 128 129 // Get the instruction before it if it is a terminator. 130 MachineInstr *SecondLastInst = &*I; 131 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 132 133 // If AllowModify is true and the block ends with two or more unconditional 134 // branches, delete all but the first unconditional branch. 135 if (AllowModify && isUncondBranchOpcode(LastOpc)) { 136 while (isUncondBranchOpcode(SecondLastOpc)) { 137 LastInst->eraseFromParent(); 138 LastInst = SecondLastInst; 139 LastOpc = LastInst->getOpcode(); 140 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 141 // Return now the only terminator is an unconditional branch. 142 TBB = LastInst->getOperand(0).getMBB(); 143 return false; 144 } 145 SecondLastInst = &*I; 146 SecondLastOpc = SecondLastInst->getOpcode(); 147 } 148 } 149 150 // If there are three terminators, we don't know what sort of block this is. 151 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) 152 return true; 153 154 // If the block ends with a B and a Bcc, handle it. 155 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 156 parseCondBranch(SecondLastInst, TBB, Cond); 157 FBB = LastInst->getOperand(0).getMBB(); 158 return false; 159 } 160 161 // If the block ends with two unconditional branches, handle it. The second 162 // one is not executed. 163 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 164 TBB = SecondLastInst->getOperand(0).getMBB(); 165 return false; 166 } 167 168 // TODO ...likewise if it ends with an indirect branch followed by an unconditional 169 // branch. 170 // if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 171 // I = LastInst; 172 // if (AllowModify) 173 // I->eraseFromParent(); 174 // return true; 175 // } 176 177 // Otherwise, can't handle this. 178 return true; 179 } 180 181 unsigned VEInstrInfo::insertBranch(MachineBasicBlock &MBB, 182 MachineBasicBlock *TBB, 183 MachineBasicBlock *FBB, 184 ArrayRef<MachineOperand> Cond, 185 const DebugLoc &DL, int *BytesAdded) const { 186 assert(TBB && "insertBranch must not be told to insert a fallthrough"); 187 assert((Cond.size() == 3 || Cond.size() == 0) && 188 "VE branch conditions should have three component!"); 189 assert(!BytesAdded && "code size not handled"); 190 if (Cond.empty()) { 191 // Uncondition branch 192 assert(!FBB && "Unconditional branch with multiple successors!"); 193 BuildMI(&MBB, DL, get(VE::BCRLa)) 194 .addMBB(TBB); 195 return 1; 196 } 197 198 // Conditional branch 199 // (BCRir CC sy sz addr) 200 assert(Cond[0].isImm() && Cond[2].isReg() && "not implemented"); 201 202 unsigned opc[2]; 203 const TargetRegisterInfo *TRI = &getRegisterInfo(); 204 MachineFunction *MF = MBB.getParent(); 205 const MachineRegisterInfo &MRI = MF->getRegInfo(); 206 unsigned Reg = Cond[2].getReg(); 207 if (IsIntegerCC(Cond[0].getImm())) { 208 if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 209 opc[0] = VE::BCRWir; 210 opc[1] = VE::BCRWrr; 211 } else { 212 opc[0] = VE::BCRLir; 213 opc[1] = VE::BCRLrr; 214 } 215 } else { 216 if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 217 opc[0] = VE::BCRSir; 218 opc[1] = VE::BCRSrr; 219 } else { 220 opc[0] = VE::BCRDir; 221 opc[1] = VE::BCRDrr; 222 } 223 } 224 if (Cond[1].isImm()) { 225 BuildMI(&MBB, DL, get(opc[0])) 226 .add(Cond[0]) // condition code 227 .add(Cond[1]) // lhs 228 .add(Cond[2]) // rhs 229 .addMBB(TBB); 230 } else { 231 BuildMI(&MBB, DL, get(opc[1])) 232 .add(Cond[0]) 233 .add(Cond[1]) 234 .add(Cond[2]) 235 .addMBB(TBB); 236 } 237 238 if (!FBB) 239 return 1; 240 241 BuildMI(&MBB, DL, get(VE::BCRLa)) 242 .addMBB(FBB); 243 return 2; 244 } 245 246 unsigned VEInstrInfo::removeBranch(MachineBasicBlock &MBB, 247 int *BytesRemoved) const { 248 assert(!BytesRemoved && "code size not handled"); 249 250 MachineBasicBlock::iterator I = MBB.end(); 251 unsigned Count = 0; 252 while (I != MBB.begin()) { 253 --I; 254 255 if (I->isDebugValue()) 256 continue; 257 258 if (!isUncondBranchOpcode(I->getOpcode()) && 259 !isCondBranchOpcode(I->getOpcode())) 260 break; // Not a branch 261 262 I->eraseFromParent(); 263 I = MBB.end(); 264 ++Count; 265 } 266 return Count; 267 } 268 269 bool VEInstrInfo::reverseBranchCondition( 270 SmallVectorImpl<MachineOperand> &Cond) const { 271 VECC::CondCode CC = static_cast<VECC::CondCode>(Cond[0].getImm()); 272 Cond[0].setImm(GetOppositeBranchCondition(CC)); 273 return false; 274 } 275 276 static bool IsAliasOfSX(Register Reg) { 277 return VE::I8RegClass.contains(Reg) || VE::I16RegClass.contains(Reg) || 278 VE::I32RegClass.contains(Reg) || VE::I64RegClass.contains(Reg) || 279 VE::F32RegClass.contains(Reg); 280 } 281 282 void VEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 283 MachineBasicBlock::iterator I, const DebugLoc &DL, 284 MCRegister DestReg, MCRegister SrcReg, 285 bool KillSrc) const { 286 287 if (IsAliasOfSX(SrcReg) && IsAliasOfSX(DestReg)) { 288 BuildMI(MBB, I, DL, get(VE::ORri), DestReg) 289 .addReg(SrcReg, getKillRegState(KillSrc)) 290 .addImm(0); 291 } else { 292 const TargetRegisterInfo *TRI = &getRegisterInfo(); 293 dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg, TRI) 294 << " to " << printReg(DestReg, TRI) << "\n"; 295 llvm_unreachable("Impossible reg-to-reg copy"); 296 } 297 } 298 299 /// isLoadFromStackSlot - If the specified machine instruction is a direct 300 /// load from a stack slot, return the virtual or physical register number of 301 /// the destination along with the FrameIndex of the loaded stack slot. If 302 /// not, return 0. This predicate must return 0 if the instruction has 303 /// any side effects other than loading from the stack slot. 304 unsigned VEInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 305 int &FrameIndex) const { 306 if (MI.getOpcode() == VE::LDrii || // I64 307 MI.getOpcode() == VE::LDLSXrii || // I32 308 MI.getOpcode() == VE::LDUrii // F32 309 ) { 310 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 311 MI.getOperand(2).getImm() == 0 && MI.getOperand(3).isImm() && 312 MI.getOperand(3).getImm() == 0) { 313 FrameIndex = MI.getOperand(1).getIndex(); 314 return MI.getOperand(0).getReg(); 315 } 316 } 317 return 0; 318 } 319 320 /// isStoreToStackSlot - If the specified machine instruction is a direct 321 /// store to a stack slot, return the virtual or physical register number of 322 /// the source reg along with the FrameIndex of the loaded stack slot. If 323 /// not, return 0. This predicate must return 0 if the instruction has 324 /// any side effects other than storing to the stack slot. 325 unsigned VEInstrInfo::isStoreToStackSlot(const MachineInstr &MI, 326 int &FrameIndex) const { 327 if (MI.getOpcode() == VE::STrii || // I64 328 MI.getOpcode() == VE::STLrii || // I32 329 MI.getOpcode() == VE::STUrii // F32 330 ) { 331 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() && 332 MI.getOperand(1).getImm() == 0 && MI.getOperand(2).isImm() && 333 MI.getOperand(2).getImm() == 0) { 334 FrameIndex = MI.getOperand(0).getIndex(); 335 return MI.getOperand(3).getReg(); 336 } 337 } 338 return 0; 339 } 340 341 void VEInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 342 MachineBasicBlock::iterator I, 343 Register SrcReg, bool isKill, int FI, 344 const TargetRegisterClass *RC, 345 const TargetRegisterInfo *TRI) const { 346 DebugLoc DL; 347 if (I != MBB.end()) 348 DL = I->getDebugLoc(); 349 350 MachineFunction *MF = MBB.getParent(); 351 const MachineFrameInfo &MFI = MF->getFrameInfo(); 352 MachineMemOperand *MMO = MF->getMachineMemOperand( 353 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, 354 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 355 356 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 357 if (RC == &VE::I64RegClass) { 358 BuildMI(MBB, I, DL, get(VE::STrii)) 359 .addFrameIndex(FI) 360 .addImm(0) 361 .addImm(0) 362 .addReg(SrcReg, getKillRegState(isKill)) 363 .addMemOperand(MMO); 364 } else if (RC == &VE::I32RegClass) { 365 BuildMI(MBB, I, DL, get(VE::STLrii)) 366 .addFrameIndex(FI) 367 .addImm(0) 368 .addImm(0) 369 .addReg(SrcReg, getKillRegState(isKill)) 370 .addMemOperand(MMO); 371 } else if (RC == &VE::F32RegClass) { 372 BuildMI(MBB, I, DL, get(VE::STUrii)) 373 .addFrameIndex(FI) 374 .addImm(0) 375 .addImm(0) 376 .addReg(SrcReg, getKillRegState(isKill)) 377 .addMemOperand(MMO); 378 } else 379 report_fatal_error("Can't store this register to stack slot"); 380 } 381 382 void VEInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 383 MachineBasicBlock::iterator I, 384 Register DestReg, int FI, 385 const TargetRegisterClass *RC, 386 const TargetRegisterInfo *TRI) const { 387 DebugLoc DL; 388 if (I != MBB.end()) 389 DL = I->getDebugLoc(); 390 391 MachineFunction *MF = MBB.getParent(); 392 const MachineFrameInfo &MFI = MF->getFrameInfo(); 393 MachineMemOperand *MMO = MF->getMachineMemOperand( 394 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, 395 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 396 397 if (RC == &VE::I64RegClass) { 398 BuildMI(MBB, I, DL, get(VE::LDrii), DestReg) 399 .addFrameIndex(FI) 400 .addImm(0) 401 .addImm(0) 402 .addMemOperand(MMO); 403 } else if (RC == &VE::I32RegClass) { 404 BuildMI(MBB, I, DL, get(VE::LDLSXrii), DestReg) 405 .addFrameIndex(FI) 406 .addImm(0) 407 .addImm(0) 408 .addMemOperand(MMO); 409 } else if (RC == &VE::F32RegClass) { 410 BuildMI(MBB, I, DL, get(VE::LDUrii), DestReg) 411 .addFrameIndex(FI) 412 .addImm(0) 413 .addImm(0) 414 .addMemOperand(MMO); 415 } else 416 report_fatal_error("Can't load this register from stack slot"); 417 } 418 419 Register VEInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 420 VEMachineFunctionInfo *VEFI = MF->getInfo<VEMachineFunctionInfo>(); 421 Register GlobalBaseReg = VEFI->getGlobalBaseReg(); 422 if (GlobalBaseReg != 0) 423 return GlobalBaseReg; 424 425 // We use %s15 (%got) as a global base register 426 GlobalBaseReg = VE::SX15; 427 428 // Insert a pseudo instruction to set the GlobalBaseReg into the first 429 // MBB of the function 430 MachineBasicBlock &FirstMBB = MF->front(); 431 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 432 DebugLoc dl; 433 BuildMI(FirstMBB, MBBI, dl, get(VE::GETGOT), GlobalBaseReg); 434 VEFI->setGlobalBaseReg(GlobalBaseReg); 435 return GlobalBaseReg; 436 } 437 438 bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 439 switch (MI.getOpcode()) { 440 case VE::EXTEND_STACK: { 441 return expandExtendStackPseudo(MI); 442 } 443 case VE::EXTEND_STACK_GUARD: { 444 MI.eraseFromParent(); // The pseudo instruction is gone now. 445 return true; 446 } 447 } 448 return false; 449 } 450 451 bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { 452 MachineBasicBlock &MBB = *MI.getParent(); 453 MachineFunction &MF = *MBB.getParent(); 454 const VEInstrInfo &TII = 455 *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 456 DebugLoc dl = MBB.findDebugLoc(MI); 457 458 // Create following instructions and multiple basic blocks. 459 // 460 // thisBB: 461 // brge.l.t %sp, %sl, sinkBB 462 // syscallBB: 463 // ld %s61, 0x18(, %tp) // load param area 464 // or %s62, 0, %s0 // spill the value of %s0 465 // lea %s63, 0x13b // syscall # of grow 466 // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 467 // shm.l %sl, 0x8(%s61) // store old limit at addr:8 468 // shm.l %sp, 0x10(%s61) // store new limit at addr:16 469 // monc // call monitor 470 // or %s0, 0, %s62 // restore the value of %s0 471 // sinkBB: 472 473 // Create new MBB 474 MachineBasicBlock *BB = &MBB; 475 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 476 MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); 477 MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); 478 MachineFunction::iterator It = ++(BB->getIterator()); 479 MF.insert(It, syscallMBB); 480 MF.insert(It, sinkMBB); 481 482 // Transfer the remainder of BB and its successor edges to sinkMBB. 483 sinkMBB->splice(sinkMBB->begin(), BB, 484 std::next(std::next(MachineBasicBlock::iterator(MI))), 485 BB->end()); 486 sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 487 488 // Next, add the true and fallthrough blocks as its successors. 489 BB->addSuccessor(syscallMBB); 490 BB->addSuccessor(sinkMBB); 491 BuildMI(BB, dl, TII.get(VE::BCRLrr)) 492 .addImm(VECC::CC_IGE) 493 .addReg(VE::SX11) // %sp 494 .addReg(VE::SX8) // %sl 495 .addMBB(sinkMBB); 496 497 BB = syscallMBB; 498 499 // Update machine-CFG edges 500 BB->addSuccessor(sinkMBB); 501 502 BuildMI(BB, dl, TII.get(VE::LDrii), VE::SX61) 503 .addReg(VE::SX14) 504 .addImm(0) 505 .addImm(0x18); 506 BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) 507 .addReg(VE::SX0) 508 .addImm(0); 509 BuildMI(BB, dl, TII.get(VE::LEAzii), VE::SX63) 510 .addImm(0) 511 .addImm(0) 512 .addImm(0x13b); 513 BuildMI(BB, dl, TII.get(VE::SHMri)) 514 .addReg(VE::SX61) 515 .addImm(0) 516 .addReg(VE::SX63); 517 BuildMI(BB, dl, TII.get(VE::SHMri)) 518 .addReg(VE::SX61) 519 .addImm(8) 520 .addReg(VE::SX8); 521 BuildMI(BB, dl, TII.get(VE::SHMri)) 522 .addReg(VE::SX61) 523 .addImm(16) 524 .addReg(VE::SX11); 525 BuildMI(BB, dl, TII.get(VE::MONC)); 526 527 BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) 528 .addReg(VE::SX62) 529 .addImm(0); 530 531 MI.eraseFromParent(); // The pseudo instruction is gone now. 532 return true; 533 } 534