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-instr-info" 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: 46 return VECC::CC_ILE; 47 case VECC::CC_IL: 48 return VECC::CC_IGE; 49 case VECC::CC_INE: 50 return VECC::CC_IEQ; 51 case VECC::CC_IEQ: 52 return VECC::CC_INE; 53 case VECC::CC_IGE: 54 return VECC::CC_IL; 55 case VECC::CC_ILE: 56 return VECC::CC_IG; 57 case VECC::CC_AF: 58 return VECC::CC_AT; 59 case VECC::CC_G: 60 return VECC::CC_LENAN; 61 case VECC::CC_L: 62 return VECC::CC_GENAN; 63 case VECC::CC_NE: 64 return VECC::CC_EQNAN; 65 case VECC::CC_EQ: 66 return VECC::CC_NENAN; 67 case VECC::CC_GE: 68 return VECC::CC_LNAN; 69 case VECC::CC_LE: 70 return VECC::CC_GNAN; 71 case VECC::CC_NUM: 72 return VECC::CC_NAN; 73 case VECC::CC_NAN: 74 return VECC::CC_NUM; 75 case VECC::CC_GNAN: 76 return VECC::CC_LE; 77 case VECC::CC_LNAN: 78 return VECC::CC_GE; 79 case VECC::CC_NENAN: 80 return VECC::CC_EQ; 81 case VECC::CC_EQNAN: 82 return VECC::CC_NE; 83 case VECC::CC_GENAN: 84 return VECC::CC_L; 85 case VECC::CC_LENAN: 86 return VECC::CC_G; 87 case VECC::CC_AT: 88 return VECC::CC_AF; 89 case VECC::UNKNOWN: 90 return VECC::UNKNOWN; 91 } 92 llvm_unreachable("Invalid cond code"); 93 } 94 95 // Treat br.l [BRCF AT] as unconditional branch 96 static bool isUncondBranchOpcode(int Opc) { 97 return Opc == VE::BRCFLa || Opc == VE::BRCFWa || 98 Opc == VE::BRCFLa_nt || Opc == VE::BRCFWa_nt || 99 Opc == VE::BRCFLa_t || Opc == VE::BRCFWa_t || 100 Opc == VE::BRCFDa || Opc == VE::BRCFSa || 101 Opc == VE::BRCFDa_nt || Opc == VE::BRCFSa_nt || 102 Opc == VE::BRCFDa_t || Opc == VE::BRCFSa_t; 103 } 104 105 static bool isCondBranchOpcode(int Opc) { 106 return Opc == VE::BRCFLrr || Opc == VE::BRCFLir || 107 Opc == VE::BRCFLrr_nt || Opc == VE::BRCFLir_nt || 108 Opc == VE::BRCFLrr_t || Opc == VE::BRCFLir_t || 109 Opc == VE::BRCFWrr || Opc == VE::BRCFWir || 110 Opc == VE::BRCFWrr_nt || Opc == VE::BRCFWir_nt || 111 Opc == VE::BRCFWrr_t || Opc == VE::BRCFWir_t || 112 Opc == VE::BRCFDrr || Opc == VE::BRCFDir || 113 Opc == VE::BRCFDrr_nt || Opc == VE::BRCFDir_nt || 114 Opc == VE::BRCFDrr_t || Opc == VE::BRCFDir_t || 115 Opc == VE::BRCFSrr || Opc == VE::BRCFSir || 116 Opc == VE::BRCFSrr_nt || Opc == VE::BRCFSir_nt || 117 Opc == VE::BRCFSrr_t || Opc == VE::BRCFSir_t; 118 } 119 120 static bool isIndirectBranchOpcode(int Opc) { 121 return Opc == VE::BCFLari || Opc == VE::BCFLari || 122 Opc == VE::BCFLari_nt || Opc == VE::BCFLari_nt || 123 Opc == VE::BCFLari_t || Opc == VE::BCFLari_t || 124 Opc == VE::BCFLari || Opc == VE::BCFLari || 125 Opc == VE::BCFLari_nt || Opc == VE::BCFLari_nt || 126 Opc == VE::BCFLari_t || Opc == VE::BCFLari_t; 127 } 128 129 static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, 130 SmallVectorImpl<MachineOperand> &Cond) { 131 Cond.push_back(MachineOperand::CreateImm(LastInst->getOperand(0).getImm())); 132 Cond.push_back(LastInst->getOperand(1)); 133 Cond.push_back(LastInst->getOperand(2)); 134 Target = LastInst->getOperand(3).getMBB(); 135 } 136 137 bool VEInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 138 MachineBasicBlock *&FBB, 139 SmallVectorImpl<MachineOperand> &Cond, 140 bool AllowModify) const { 141 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 142 if (I == MBB.end()) 143 return false; 144 145 if (!isUnpredicatedTerminator(*I)) 146 return false; 147 148 // Get the last instruction in the block. 149 MachineInstr *LastInst = &*I; 150 unsigned LastOpc = LastInst->getOpcode(); 151 152 // If there is only one terminator instruction, process it. 153 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 154 if (isUncondBranchOpcode(LastOpc)) { 155 TBB = LastInst->getOperand(0).getMBB(); 156 return false; 157 } 158 if (isCondBranchOpcode(LastOpc)) { 159 // Block ends with fall-through condbranch. 160 parseCondBranch(LastInst, TBB, Cond); 161 return false; 162 } 163 return true; // Can't handle indirect branch. 164 } 165 166 // Get the instruction before it if it is a terminator. 167 MachineInstr *SecondLastInst = &*I; 168 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 169 170 // If AllowModify is true and the block ends with two or more unconditional 171 // branches, delete all but the first unconditional branch. 172 if (AllowModify && isUncondBranchOpcode(LastOpc)) { 173 while (isUncondBranchOpcode(SecondLastOpc)) { 174 LastInst->eraseFromParent(); 175 LastInst = SecondLastInst; 176 LastOpc = LastInst->getOpcode(); 177 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 178 // Return now the only terminator is an unconditional branch. 179 TBB = LastInst->getOperand(0).getMBB(); 180 return false; 181 } 182 SecondLastInst = &*I; 183 SecondLastOpc = SecondLastInst->getOpcode(); 184 } 185 } 186 187 // If there are three terminators, we don't know what sort of block this is. 188 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) 189 return true; 190 191 // If the block ends with a B and a Bcc, handle it. 192 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 193 parseCondBranch(SecondLastInst, TBB, Cond); 194 FBB = LastInst->getOperand(0).getMBB(); 195 return false; 196 } 197 198 // If the block ends with two unconditional branches, handle it. The second 199 // one is not executed. 200 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 201 TBB = SecondLastInst->getOperand(0).getMBB(); 202 return false; 203 } 204 205 // ...likewise if it ends with an indirect branch followed by an unconditional 206 // branch. 207 if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 208 I = LastInst; 209 if (AllowModify) 210 I->eraseFromParent(); 211 return true; 212 } 213 214 // Otherwise, can't handle this. 215 return true; 216 } 217 218 unsigned VEInstrInfo::insertBranch(MachineBasicBlock &MBB, 219 MachineBasicBlock *TBB, 220 MachineBasicBlock *FBB, 221 ArrayRef<MachineOperand> Cond, 222 const DebugLoc &DL, int *BytesAdded) const { 223 assert(TBB && "insertBranch must not be told to insert a fallthrough"); 224 assert((Cond.size() == 3 || Cond.size() == 0) && 225 "VE branch conditions should have three component!"); 226 assert(!BytesAdded && "code size not handled"); 227 if (Cond.empty()) { 228 // Uncondition branch 229 assert(!FBB && "Unconditional branch with multiple successors!"); 230 BuildMI(&MBB, DL, get(VE::BRCFLa_t)) 231 .addMBB(TBB); 232 return 1; 233 } 234 235 // Conditional branch 236 // (BRCFir CC sy sz addr) 237 assert(Cond[0].isImm() && Cond[2].isReg() && "not implemented"); 238 239 unsigned opc[2]; 240 const TargetRegisterInfo *TRI = &getRegisterInfo(); 241 MachineFunction *MF = MBB.getParent(); 242 const MachineRegisterInfo &MRI = MF->getRegInfo(); 243 unsigned Reg = Cond[2].getReg(); 244 if (IsIntegerCC(Cond[0].getImm())) { 245 if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 246 opc[0] = VE::BRCFWir; 247 opc[1] = VE::BRCFWrr; 248 } else { 249 opc[0] = VE::BRCFLir; 250 opc[1] = VE::BRCFLrr; 251 } 252 } else { 253 if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 254 opc[0] = VE::BRCFSir; 255 opc[1] = VE::BRCFSrr; 256 } else { 257 opc[0] = VE::BRCFDir; 258 opc[1] = VE::BRCFDrr; 259 } 260 } 261 if (Cond[1].isImm()) { 262 BuildMI(&MBB, DL, get(opc[0])) 263 .add(Cond[0]) // condition code 264 .add(Cond[1]) // lhs 265 .add(Cond[2]) // rhs 266 .addMBB(TBB); 267 } else { 268 BuildMI(&MBB, DL, get(opc[1])) 269 .add(Cond[0]) 270 .add(Cond[1]) 271 .add(Cond[2]) 272 .addMBB(TBB); 273 } 274 275 if (!FBB) 276 return 1; 277 278 BuildMI(&MBB, DL, get(VE::BRCFLa_t)) 279 .addMBB(FBB); 280 return 2; 281 } 282 283 unsigned VEInstrInfo::removeBranch(MachineBasicBlock &MBB, 284 int *BytesRemoved) const { 285 assert(!BytesRemoved && "code size not handled"); 286 287 MachineBasicBlock::iterator I = MBB.end(); 288 unsigned Count = 0; 289 while (I != MBB.begin()) { 290 --I; 291 292 if (I->isDebugValue()) 293 continue; 294 295 if (!isUncondBranchOpcode(I->getOpcode()) && 296 !isCondBranchOpcode(I->getOpcode())) 297 break; // Not a branch 298 299 I->eraseFromParent(); 300 I = MBB.end(); 301 ++Count; 302 } 303 return Count; 304 } 305 306 bool VEInstrInfo::reverseBranchCondition( 307 SmallVectorImpl<MachineOperand> &Cond) const { 308 VECC::CondCode CC = static_cast<VECC::CondCode>(Cond[0].getImm()); 309 Cond[0].setImm(GetOppositeBranchCondition(CC)); 310 return false; 311 } 312 313 static bool IsAliasOfSX(Register Reg) { 314 return VE::I32RegClass.contains(Reg) || VE::I64RegClass.contains(Reg) || 315 VE::F32RegClass.contains(Reg); 316 } 317 318 static void copyPhysSubRegs(MachineBasicBlock &MBB, 319 MachineBasicBlock::iterator I, const DebugLoc &DL, 320 MCRegister DestReg, MCRegister SrcReg, bool KillSrc, 321 const MCInstrDesc &MCID, unsigned int NumSubRegs, 322 const unsigned *SubRegIdx, 323 const TargetRegisterInfo *TRI) { 324 MachineInstr *MovMI = nullptr; 325 326 for (unsigned Idx = 0; Idx != NumSubRegs; ++Idx) { 327 Register SubDest = TRI->getSubReg(DestReg, SubRegIdx[Idx]); 328 Register SubSrc = TRI->getSubReg(SrcReg, SubRegIdx[Idx]); 329 assert(SubDest && SubSrc && "Bad sub-register"); 330 331 if (MCID.getOpcode() == VE::ORri) { 332 // generate "ORri, dest, src, 0" instruction. 333 MachineInstrBuilder MIB = 334 BuildMI(MBB, I, DL, MCID, SubDest).addReg(SubSrc).addImm(0); 335 MovMI = MIB.getInstr(); 336 } else { 337 llvm_unreachable("Unexpected reg-to-reg copy instruction"); 338 } 339 } 340 // Add implicit super-register defs and kills to the last MovMI. 341 MovMI->addRegisterDefined(DestReg, TRI); 342 if (KillSrc) 343 MovMI->addRegisterKilled(SrcReg, TRI, true); 344 } 345 346 void VEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 347 MachineBasicBlock::iterator I, const DebugLoc &DL, 348 MCRegister DestReg, MCRegister SrcReg, 349 bool KillSrc) const { 350 351 if (IsAliasOfSX(SrcReg) && IsAliasOfSX(DestReg)) { 352 BuildMI(MBB, I, DL, get(VE::ORri), DestReg) 353 .addReg(SrcReg, getKillRegState(KillSrc)) 354 .addImm(0); 355 } else if (VE::V64RegClass.contains(DestReg, SrcReg)) { 356 // Generate following instructions 357 // %sw16 = LEA32zii 256 358 // VORmvl %dest, (0)1, %src, %sw16 359 // TODO: reuse a register if vl is already assigned to a register 360 // FIXME: it would be better to scavenge a register here instead of 361 // reserving SX16 all of the time. 362 const TargetRegisterInfo *TRI = &getRegisterInfo(); 363 Register TmpReg = VE::SX16; 364 Register SubTmp = TRI->getSubReg(TmpReg, VE::sub_i32); 365 BuildMI(MBB, I, DL, get(VE::LEAzii), TmpReg) 366 .addImm(0) 367 .addImm(0) 368 .addImm(256); 369 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(VE::VORmvl), DestReg) 370 .addImm(M1(0)) // Represent (0)1. 371 .addReg(SrcReg, getKillRegState(KillSrc)) 372 .addReg(SubTmp, getKillRegState(true)); 373 MIB.getInstr()->addRegisterKilled(TmpReg, TRI, true); 374 } else if (VE::F128RegClass.contains(DestReg, SrcReg)) { 375 // Use two instructions. 376 const unsigned SubRegIdx[] = {VE::sub_even, VE::sub_odd}; 377 unsigned int NumSubRegs = 2; 378 copyPhysSubRegs(MBB, I, DL, DestReg, SrcReg, KillSrc, get(VE::ORri), 379 NumSubRegs, SubRegIdx, &getRegisterInfo()); 380 } else { 381 const TargetRegisterInfo *TRI = &getRegisterInfo(); 382 dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg, TRI) 383 << " to " << printReg(DestReg, TRI) << "\n"; 384 llvm_unreachable("Impossible reg-to-reg copy"); 385 } 386 } 387 388 /// isLoadFromStackSlot - If the specified machine instruction is a direct 389 /// load from a stack slot, return the virtual or physical register number of 390 /// the destination along with the FrameIndex of the loaded stack slot. If 391 /// not, return 0. This predicate must return 0 if the instruction has 392 /// any side effects other than loading from the stack slot. 393 unsigned VEInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 394 int &FrameIndex) const { 395 if (MI.getOpcode() == VE::LDrii || // I64 396 MI.getOpcode() == VE::LDLSXrii || // I32 397 MI.getOpcode() == VE::LDUrii || // F32 398 MI.getOpcode() == VE::LDQrii // F128 (pseudo) 399 ) { 400 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 401 MI.getOperand(2).getImm() == 0 && MI.getOperand(3).isImm() && 402 MI.getOperand(3).getImm() == 0) { 403 FrameIndex = MI.getOperand(1).getIndex(); 404 return MI.getOperand(0).getReg(); 405 } 406 } 407 return 0; 408 } 409 410 /// isStoreToStackSlot - If the specified machine instruction is a direct 411 /// store to a stack slot, return the virtual or physical register number of 412 /// the source reg along with the FrameIndex of the loaded stack slot. If 413 /// not, return 0. This predicate must return 0 if the instruction has 414 /// any side effects other than storing to the stack slot. 415 unsigned VEInstrInfo::isStoreToStackSlot(const MachineInstr &MI, 416 int &FrameIndex) const { 417 if (MI.getOpcode() == VE::STrii || // I64 418 MI.getOpcode() == VE::STLrii || // I32 419 MI.getOpcode() == VE::STUrii || // F32 420 MI.getOpcode() == VE::STQrii // F128 (pseudo) 421 ) { 422 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() && 423 MI.getOperand(1).getImm() == 0 && MI.getOperand(2).isImm() && 424 MI.getOperand(2).getImm() == 0) { 425 FrameIndex = MI.getOperand(0).getIndex(); 426 return MI.getOperand(3).getReg(); 427 } 428 } 429 return 0; 430 } 431 432 void VEInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 433 MachineBasicBlock::iterator I, 434 Register SrcReg, bool isKill, int FI, 435 const TargetRegisterClass *RC, 436 const TargetRegisterInfo *TRI) const { 437 DebugLoc DL; 438 if (I != MBB.end()) 439 DL = I->getDebugLoc(); 440 441 MachineFunction *MF = MBB.getParent(); 442 const MachineFrameInfo &MFI = MF->getFrameInfo(); 443 MachineMemOperand *MMO = MF->getMachineMemOperand( 444 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, 445 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 446 447 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 448 if (RC == &VE::I64RegClass) { 449 BuildMI(MBB, I, DL, get(VE::STrii)) 450 .addFrameIndex(FI) 451 .addImm(0) 452 .addImm(0) 453 .addReg(SrcReg, getKillRegState(isKill)) 454 .addMemOperand(MMO); 455 } else if (RC == &VE::I32RegClass) { 456 BuildMI(MBB, I, DL, get(VE::STLrii)) 457 .addFrameIndex(FI) 458 .addImm(0) 459 .addImm(0) 460 .addReg(SrcReg, getKillRegState(isKill)) 461 .addMemOperand(MMO); 462 } else if (RC == &VE::F32RegClass) { 463 BuildMI(MBB, I, DL, get(VE::STUrii)) 464 .addFrameIndex(FI) 465 .addImm(0) 466 .addImm(0) 467 .addReg(SrcReg, getKillRegState(isKill)) 468 .addMemOperand(MMO); 469 } else if (VE::F128RegClass.hasSubClassEq(RC)) { 470 BuildMI(MBB, I, DL, get(VE::STQrii)) 471 .addFrameIndex(FI) 472 .addImm(0) 473 .addImm(0) 474 .addReg(SrcReg, getKillRegState(isKill)) 475 .addMemOperand(MMO); 476 } else 477 report_fatal_error("Can't store this register to stack slot"); 478 } 479 480 void VEInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 481 MachineBasicBlock::iterator I, 482 Register DestReg, int FI, 483 const TargetRegisterClass *RC, 484 const TargetRegisterInfo *TRI) const { 485 DebugLoc DL; 486 if (I != MBB.end()) 487 DL = I->getDebugLoc(); 488 489 MachineFunction *MF = MBB.getParent(); 490 const MachineFrameInfo &MFI = MF->getFrameInfo(); 491 MachineMemOperand *MMO = MF->getMachineMemOperand( 492 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, 493 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 494 495 if (RC == &VE::I64RegClass) { 496 BuildMI(MBB, I, DL, get(VE::LDrii), DestReg) 497 .addFrameIndex(FI) 498 .addImm(0) 499 .addImm(0) 500 .addMemOperand(MMO); 501 } else if (RC == &VE::I32RegClass) { 502 BuildMI(MBB, I, DL, get(VE::LDLSXrii), DestReg) 503 .addFrameIndex(FI) 504 .addImm(0) 505 .addImm(0) 506 .addMemOperand(MMO); 507 } else if (RC == &VE::F32RegClass) { 508 BuildMI(MBB, I, DL, get(VE::LDUrii), DestReg) 509 .addFrameIndex(FI) 510 .addImm(0) 511 .addImm(0) 512 .addMemOperand(MMO); 513 } else if (VE::F128RegClass.hasSubClassEq(RC)) { 514 BuildMI(MBB, I, DL, get(VE::LDQrii), DestReg) 515 .addFrameIndex(FI) 516 .addImm(0) 517 .addImm(0) 518 .addMemOperand(MMO); 519 } else 520 report_fatal_error("Can't load this register from stack slot"); 521 } 522 523 bool VEInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, 524 Register Reg, MachineRegisterInfo *MRI) const { 525 LLVM_DEBUG(dbgs() << "FoldImmediate\n"); 526 527 LLVM_DEBUG(dbgs() << "checking DefMI\n"); 528 int64_t ImmVal; 529 switch (DefMI.getOpcode()) { 530 default: 531 return false; 532 case VE::ORim: 533 // General move small immediate instruction on VE. 534 LLVM_DEBUG(dbgs() << "checking ORim\n"); 535 LLVM_DEBUG(DefMI.dump()); 536 // FIXME: We may need to support FPImm too. 537 assert(DefMI.getOperand(1).isImm()); 538 assert(DefMI.getOperand(2).isImm()); 539 ImmVal = 540 DefMI.getOperand(1).getImm() + mimm2Val(DefMI.getOperand(2).getImm()); 541 LLVM_DEBUG(dbgs() << "ImmVal is " << ImmVal << "\n"); 542 break; 543 case VE::LEAzii: 544 // General move immediate instruction on VE. 545 LLVM_DEBUG(dbgs() << "checking LEAzii\n"); 546 LLVM_DEBUG(DefMI.dump()); 547 // FIXME: We may need to support FPImm too. 548 assert(DefMI.getOperand(2).isImm()); 549 if (!DefMI.getOperand(3).isImm()) 550 // LEAzii may refer label 551 return false; 552 ImmVal = DefMI.getOperand(2).getImm() + DefMI.getOperand(3).getImm(); 553 LLVM_DEBUG(dbgs() << "ImmVal is " << ImmVal << "\n"); 554 break; 555 } 556 557 // Try to fold like below: 558 // %1:i64 = ORim 0, 0(1) 559 // %2:i64 = CMPSLrr %0, %1 560 // To 561 // %2:i64 = CMPSLrm %0, 0(1) 562 // 563 // Another example: 564 // %1:i64 = ORim 6, 0(1) 565 // %2:i64 = CMPSLrr %1, %0 566 // To 567 // %2:i64 = CMPSLir 6, %0 568 // 569 // Support commutable instructions like below: 570 // %1:i64 = ORim 6, 0(1) 571 // %2:i64 = ADDSLrr %1, %0 572 // To 573 // %2:i64 = ADDSLri %0, 6 574 // 575 // FIXME: Need to support i32. Current implementtation requires 576 // EXTRACT_SUBREG, so input has following COPY and it avoids folding: 577 // %1:i64 = ORim 6, 0(1) 578 // %2:i32 = COPY %1.sub_i32 579 // %3:i32 = ADDSWSXrr %0, %2 580 // FIXME: Need to support shift, cmov, and more instructions. 581 // FIXME: Need to support lvl too, but LVLGen runs after peephole-opt. 582 583 LLVM_DEBUG(dbgs() << "checking UseMI\n"); 584 LLVM_DEBUG(UseMI.dump()); 585 unsigned NewUseOpcSImm7; 586 unsigned NewUseOpcMImm; 587 enum InstType { 588 rr2ri_rm, // rr -> ri or rm, commutable 589 rr2ir_rm, // rr -> ir or rm 590 } InstType; 591 592 using namespace llvm::VE; 593 #define INSTRKIND(NAME) \ 594 case NAME##rr: \ 595 NewUseOpcSImm7 = NAME##ri; \ 596 NewUseOpcMImm = NAME##rm; \ 597 InstType = rr2ri_rm; \ 598 break 599 #define NCINSTRKIND(NAME) \ 600 case NAME##rr: \ 601 NewUseOpcSImm7 = NAME##ir; \ 602 NewUseOpcMImm = NAME##rm; \ 603 InstType = rr2ir_rm; \ 604 break 605 606 switch (UseMI.getOpcode()) { 607 default: 608 return false; 609 610 INSTRKIND(ADDUL); 611 INSTRKIND(ADDSWSX); 612 INSTRKIND(ADDSWZX); 613 INSTRKIND(ADDSL); 614 NCINSTRKIND(SUBUL); 615 NCINSTRKIND(SUBSWSX); 616 NCINSTRKIND(SUBSWZX); 617 NCINSTRKIND(SUBSL); 618 INSTRKIND(MULUL); 619 INSTRKIND(MULSWSX); 620 INSTRKIND(MULSWZX); 621 INSTRKIND(MULSL); 622 NCINSTRKIND(DIVUL); 623 NCINSTRKIND(DIVSWSX); 624 NCINSTRKIND(DIVSWZX); 625 NCINSTRKIND(DIVSL); 626 NCINSTRKIND(CMPUL); 627 NCINSTRKIND(CMPSWSX); 628 NCINSTRKIND(CMPSWZX); 629 NCINSTRKIND(CMPSL); 630 INSTRKIND(MAXSWSX); 631 INSTRKIND(MAXSWZX); 632 INSTRKIND(MAXSL); 633 INSTRKIND(MINSWSX); 634 INSTRKIND(MINSWZX); 635 INSTRKIND(MINSL); 636 INSTRKIND(AND); 637 INSTRKIND(OR); 638 INSTRKIND(XOR); 639 INSTRKIND(EQV); 640 NCINSTRKIND(NND); 641 NCINSTRKIND(MRG); 642 } 643 644 #undef INSTRKIND 645 646 unsigned NewUseOpc; 647 unsigned UseIdx; 648 bool Commute = false; 649 LLVM_DEBUG(dbgs() << "checking UseMI operands\n"); 650 switch (InstType) { 651 case rr2ri_rm: 652 UseIdx = 2; 653 if (UseMI.getOperand(1).getReg() == Reg) { 654 Commute = true; 655 } else { 656 assert(UseMI.getOperand(2).getReg() == Reg); 657 } 658 if (isInt<7>(ImmVal)) { 659 // This ImmVal matches to SImm7 slot, so change UseOpc to an instruction 660 // holds a simm7 slot. 661 NewUseOpc = NewUseOpcSImm7; 662 } else if (isMImmVal(ImmVal)) { 663 // Similarly, change UseOpc to an instruction holds a mimm slot. 664 NewUseOpc = NewUseOpcMImm; 665 ImmVal = val2MImm(ImmVal); 666 } else 667 return false; 668 break; 669 case rr2ir_rm: 670 if (UseMI.getOperand(1).getReg() == Reg) { 671 // Check immediate value whether it matchs to the UseMI instruction. 672 if (!isInt<7>(ImmVal)) 673 return false; 674 NewUseOpc = NewUseOpcSImm7; 675 UseIdx = 1; 676 } else { 677 assert(UseMI.getOperand(2).getReg() == Reg); 678 // Check immediate value whether it matchs to the UseMI instruction. 679 if (!isMImmVal(ImmVal)) 680 return false; 681 NewUseOpc = NewUseOpcMImm; 682 ImmVal = val2MImm(ImmVal); 683 UseIdx = 2; 684 } 685 break; 686 } 687 688 LLVM_DEBUG(dbgs() << "modifying UseMI\n"); 689 bool DeleteDef = MRI->hasOneNonDBGUse(Reg); 690 UseMI.setDesc(get(NewUseOpc)); 691 if (Commute) { 692 UseMI.getOperand(1).setReg(UseMI.getOperand(UseIdx).getReg()); 693 } 694 UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal); 695 if (DeleteDef) 696 DefMI.eraseFromParent(); 697 698 return true; 699 } 700 701 Register VEInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 702 VEMachineFunctionInfo *VEFI = MF->getInfo<VEMachineFunctionInfo>(); 703 Register GlobalBaseReg = VEFI->getGlobalBaseReg(); 704 if (GlobalBaseReg != 0) 705 return GlobalBaseReg; 706 707 // We use %s15 (%got) as a global base register 708 GlobalBaseReg = VE::SX15; 709 710 // Insert a pseudo instruction to set the GlobalBaseReg into the first 711 // MBB of the function 712 MachineBasicBlock &FirstMBB = MF->front(); 713 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 714 DebugLoc dl; 715 BuildMI(FirstMBB, MBBI, dl, get(VE::GETGOT), GlobalBaseReg); 716 VEFI->setGlobalBaseReg(GlobalBaseReg); 717 return GlobalBaseReg; 718 } 719 720 static Register getVM512Upper(Register reg) { 721 return (reg - VE::VMP0) * 2 + VE::VM0; 722 } 723 724 static Register getVM512Lower(Register reg) { return getVM512Upper(reg) + 1; } 725 726 bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 727 switch (MI.getOpcode()) { 728 case VE::EXTEND_STACK: { 729 return expandExtendStackPseudo(MI); 730 } 731 case VE::EXTEND_STACK_GUARD: { 732 MI.eraseFromParent(); // The pseudo instruction is gone now. 733 return true; 734 } 735 case VE::GETSTACKTOP: { 736 return expandGetStackTopPseudo(MI); 737 } 738 739 case VE::LVMyir: 740 case VE::LVMyim: 741 case VE::LVMyir_y: 742 case VE::LVMyim_y: { 743 Register VMXu = getVM512Upper(MI.getOperand(0).getReg()); 744 Register VMXl = getVM512Lower(MI.getOperand(0).getReg()); 745 int64_t Imm = MI.getOperand(1).getImm(); 746 bool IsSrcReg = 747 MI.getOpcode() == VE::LVMyir || MI.getOpcode() == VE::LVMyir_y; 748 Register Src = IsSrcReg ? MI.getOperand(2).getReg() : VE::NoRegister; 749 int64_t MImm = IsSrcReg ? 0 : MI.getOperand(2).getImm(); 750 bool KillSrc = IsSrcReg ? MI.getOperand(2).isKill() : false; 751 Register VMX = VMXl; 752 if (Imm >= 4) { 753 VMX = VMXu; 754 Imm -= 4; 755 } 756 MachineBasicBlock *MBB = MI.getParent(); 757 DebugLoc DL = MI.getDebugLoc(); 758 switch (MI.getOpcode()) { 759 case VE::LVMyir: 760 BuildMI(*MBB, MI, DL, get(VE::LVMir)) 761 .addDef(VMX) 762 .addImm(Imm) 763 .addReg(Src, getKillRegState(KillSrc)); 764 break; 765 case VE::LVMyim: 766 BuildMI(*MBB, MI, DL, get(VE::LVMim)) 767 .addDef(VMX) 768 .addImm(Imm) 769 .addImm(MImm); 770 break; 771 case VE::LVMyir_y: 772 assert(MI.getOperand(0).getReg() == MI.getOperand(3).getReg() && 773 "LVMyir_y has different register in 3rd operand"); 774 BuildMI(*MBB, MI, DL, get(VE::LVMir_m)) 775 .addDef(VMX) 776 .addImm(Imm) 777 .addReg(Src, getKillRegState(KillSrc)) 778 .addReg(VMX); 779 break; 780 case VE::LVMyim_y: 781 assert(MI.getOperand(0).getReg() == MI.getOperand(3).getReg() && 782 "LVMyim_y has different register in 3rd operand"); 783 BuildMI(*MBB, MI, DL, get(VE::LVMim_m)) 784 .addDef(VMX) 785 .addImm(Imm) 786 .addImm(MImm) 787 .addReg(VMX); 788 break; 789 } 790 MI.eraseFromParent(); 791 return true; 792 } 793 case VE::SVMyi: { 794 Register Dest = MI.getOperand(0).getReg(); 795 Register VMZu = getVM512Upper(MI.getOperand(1).getReg()); 796 Register VMZl = getVM512Lower(MI.getOperand(1).getReg()); 797 bool KillSrc = MI.getOperand(1).isKill(); 798 int64_t Imm = MI.getOperand(2).getImm(); 799 Register VMZ = VMZl; 800 if (Imm >= 4) { 801 VMZ = VMZu; 802 Imm -= 4; 803 } 804 MachineBasicBlock *MBB = MI.getParent(); 805 DebugLoc DL = MI.getDebugLoc(); 806 MachineInstrBuilder MIB = 807 BuildMI(*MBB, MI, DL, get(VE::SVMmi), Dest).addReg(VMZ).addImm(Imm); 808 MachineInstr *Inst = MIB.getInstr(); 809 MI.eraseFromParent(); 810 if (KillSrc) { 811 const TargetRegisterInfo *TRI = &getRegisterInfo(); 812 Inst->addRegisterKilled(MI.getOperand(1).getReg(), TRI, true); 813 } 814 return true; 815 } 816 } 817 return false; 818 } 819 820 bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { 821 MachineBasicBlock &MBB = *MI.getParent(); 822 MachineFunction &MF = *MBB.getParent(); 823 const VESubtarget &STI = MF.getSubtarget<VESubtarget>(); 824 const VEInstrInfo &TII = *STI.getInstrInfo(); 825 DebugLoc dl = MBB.findDebugLoc(MI); 826 827 // Create following instructions and multiple basic blocks. 828 // 829 // thisBB: 830 // brge.l.t %sp, %sl, sinkBB 831 // syscallBB: 832 // ld %s61, 0x18(, %tp) // load param area 833 // or %s62, 0, %s0 // spill the value of %s0 834 // lea %s63, 0x13b // syscall # of grow 835 // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 836 // shm.l %sl, 0x8(%s61) // store old limit at addr:8 837 // shm.l %sp, 0x10(%s61) // store new limit at addr:16 838 // monc // call monitor 839 // or %s0, 0, %s62 // restore the value of %s0 840 // sinkBB: 841 842 // Create new MBB 843 MachineBasicBlock *BB = &MBB; 844 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 845 MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); 846 MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); 847 MachineFunction::iterator It = ++(BB->getIterator()); 848 MF.insert(It, syscallMBB); 849 MF.insert(It, sinkMBB); 850 851 // Transfer the remainder of BB and its successor edges to sinkMBB. 852 sinkMBB->splice(sinkMBB->begin(), BB, 853 std::next(std::next(MachineBasicBlock::iterator(MI))), 854 BB->end()); 855 sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 856 857 // Next, add the true and fallthrough blocks as its successors. 858 BB->addSuccessor(syscallMBB); 859 BB->addSuccessor(sinkMBB); 860 BuildMI(BB, dl, TII.get(VE::BRCFLrr_t)) 861 .addImm(VECC::CC_IGE) 862 .addReg(VE::SX11) // %sp 863 .addReg(VE::SX8) // %sl 864 .addMBB(sinkMBB); 865 866 BB = syscallMBB; 867 868 // Update machine-CFG edges 869 BB->addSuccessor(sinkMBB); 870 871 BuildMI(BB, dl, TII.get(VE::LDrii), VE::SX61) 872 .addReg(VE::SX14) 873 .addImm(0) 874 .addImm(0x18); 875 BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) 876 .addReg(VE::SX0) 877 .addImm(0); 878 BuildMI(BB, dl, TII.get(VE::LEAzii), VE::SX63) 879 .addImm(0) 880 .addImm(0) 881 .addImm(0x13b); 882 BuildMI(BB, dl, TII.get(VE::SHMLri)) 883 .addReg(VE::SX61) 884 .addImm(0) 885 .addReg(VE::SX63); 886 BuildMI(BB, dl, TII.get(VE::SHMLri)) 887 .addReg(VE::SX61) 888 .addImm(8) 889 .addReg(VE::SX8); 890 BuildMI(BB, dl, TII.get(VE::SHMLri)) 891 .addReg(VE::SX61) 892 .addImm(16) 893 .addReg(VE::SX11); 894 BuildMI(BB, dl, TII.get(VE::MONC)); 895 896 BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) 897 .addReg(VE::SX62) 898 .addImm(0); 899 900 MI.eraseFromParent(); // The pseudo instruction is gone now. 901 return true; 902 } 903 904 bool VEInstrInfo::expandGetStackTopPseudo(MachineInstr &MI) const { 905 MachineBasicBlock *MBB = MI.getParent(); 906 MachineFunction &MF = *MBB->getParent(); 907 const VESubtarget &STI = MF.getSubtarget<VESubtarget>(); 908 const VEInstrInfo &TII = *STI.getInstrInfo(); 909 DebugLoc DL = MBB->findDebugLoc(MI); 910 911 // Create following instruction 912 // 913 // dst = %sp + target specific frame + the size of parameter area 914 915 const MachineFrameInfo &MFI = MF.getFrameInfo(); 916 const VEFrameLowering &TFL = *STI.getFrameLowering(); 917 918 // The VE ABI requires a reserved area at the top of stack as described 919 // in VEFrameLowering.cpp. So, we adjust it here. 920 unsigned NumBytes = STI.getAdjustedFrameSize(0); 921 922 // Also adds the size of parameter area. 923 if (MFI.adjustsStack() && TFL.hasReservedCallFrame(MF)) 924 NumBytes += MFI.getMaxCallFrameSize(); 925 926 BuildMI(*MBB, MI, DL, TII.get(VE::LEArii)) 927 .addDef(MI.getOperand(0).getReg()) 928 .addReg(VE::SX11) 929 .addImm(0) 930 .addImm(NumBytes); 931 932 MI.eraseFromParent(); // The pseudo instruction is gone now. 933 return true; 934 } 935