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