HexagonInstrInfo.cpp revision ee498d3254b86bceb4f441741e9f442990647ce6
1//=- HexagonInstrInfo.cpp - Hexagon Instruction Information -------*- C++ -*-=// 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 Hexagon implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "HexagonRegisterInfo.h" 15#include "HexagonInstrInfo.h" 16#include "HexagonSubtarget.h" 17#include "Hexagon.h" 18#include "llvm/Support/MathExtras.h" 19#include "llvm/ADT/STLExtras.h" 20#include "llvm/ADT/SmallVector.h" 21#include "llvm/CodeGen/MachineInstrBuilder.h" 22#include "llvm/CodeGen/MachineRegisterInfo.h" 23#include "llvm/CodeGen/MachineFrameInfo.h" 24#include "llvm/CodeGen/MachineMemOperand.h" 25#include "llvm/CodeGen/PseudoSourceValue.h" 26#define GET_INSTRINFO_CTOR 27#include "llvm/CodeGen/DFAPacketizer.h" 28#include "HexagonGenInstrInfo.inc" 29#include "HexagonGenDFAPacketizer.inc" 30 31#include <iostream> 32 33 34using namespace llvm; 35 36/// 37/// Constants for Hexagon instructions. 38/// 39const int Hexagon_MEMW_OFFSET_MAX = 4095; 40const int Hexagon_MEMW_OFFSET_MIN = 4096; 41const int Hexagon_MEMD_OFFSET_MAX = 8191; 42const int Hexagon_MEMD_OFFSET_MIN = 8192; 43const int Hexagon_MEMH_OFFSET_MAX = 2047; 44const int Hexagon_MEMH_OFFSET_MIN = 2048; 45const int Hexagon_MEMB_OFFSET_MAX = 1023; 46const int Hexagon_MEMB_OFFSET_MIN = 1024; 47const int Hexagon_ADDI_OFFSET_MAX = 32767; 48const int Hexagon_ADDI_OFFSET_MIN = 32768; 49const int Hexagon_MEMD_AUTOINC_MAX = 56; 50const int Hexagon_MEMD_AUTOINC_MIN = 64; 51const int Hexagon_MEMW_AUTOINC_MAX = 28; 52const int Hexagon_MEMW_AUTOINC_MIN = 32; 53const int Hexagon_MEMH_AUTOINC_MAX = 14; 54const int Hexagon_MEMH_AUTOINC_MIN = 16; 55const int Hexagon_MEMB_AUTOINC_MAX = 7; 56const int Hexagon_MEMB_AUTOINC_MIN = 8; 57 58 59 60HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST) 61 : HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP), 62 RI(ST, *this), Subtarget(ST) { 63} 64 65 66/// isLoadFromStackSlot - If the specified machine instruction is a direct 67/// load from a stack slot, return the virtual or physical register number of 68/// the destination along with the FrameIndex of the loaded stack slot. If 69/// not, return 0. This predicate must return 0 if the instruction has 70/// any side effects other than loading from the stack slot. 71unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 72 int &FrameIndex) const { 73 74 75 switch (MI->getOpcode()) { 76 case Hexagon::LDriw: 77 case Hexagon::LDrid: 78 case Hexagon::LDrih: 79 case Hexagon::LDrib: 80 case Hexagon::LDriub: 81 if (MI->getOperand(2).isFI() && 82 MI->getOperand(1).isImm() && (MI->getOperand(1).getImm() == 0)) { 83 FrameIndex = MI->getOperand(2).getIndex(); 84 return MI->getOperand(0).getReg(); 85 } 86 break; 87 88 default: 89 break; 90 } 91 92 return 0; 93} 94 95 96/// isStoreToStackSlot - If the specified machine instruction is a direct 97/// store to a stack slot, return the virtual or physical register number of 98/// the source reg along with the FrameIndex of the loaded stack slot. If 99/// not, return 0. This predicate must return 0 if the instruction has 100/// any side effects other than storing to the stack slot. 101unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 102 int &FrameIndex) const { 103 switch (MI->getOpcode()) { 104 case Hexagon::STriw: 105 case Hexagon::STrid: 106 case Hexagon::STrih: 107 case Hexagon::STrib: 108 if (MI->getOperand(2).isFI() && 109 MI->getOperand(1).isImm() && (MI->getOperand(1).getImm() == 0)) { 110 FrameIndex = MI->getOperand(2).getIndex(); 111 return MI->getOperand(0).getReg(); 112 } 113 break; 114 115 default: 116 break; 117 } 118 119 return 0; 120} 121 122 123unsigned 124HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 125 MachineBasicBlock *FBB, 126 const SmallVectorImpl<MachineOperand> &Cond, 127 DebugLoc DL) const{ 128 129 int BOpc = Hexagon::JMP; 130 int BccOpc = Hexagon::JMP_Pred; 131 132 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 133 134 int regPos = 0; 135 // Check if ReverseBranchCondition has asked to reverse this branch 136 // If we want to reverse the branch an odd number of times, we want 137 // JMP_PredNot. 138 if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) { 139 BccOpc = Hexagon::JMP_PredNot; 140 regPos = 1; 141 } 142 143 if (FBB == 0) { 144 if (Cond.empty()) { 145 // Due to a bug in TailMerging/CFG Optimization, we need to add a 146 // special case handling of a predicated jump followed by an 147 // unconditional jump. If not, Tail Merging and CFG Optimization go 148 // into an infinite loop. 149 MachineBasicBlock *NewTBB, *NewFBB; 150 SmallVector<MachineOperand, 4> Cond; 151 MachineInstr *Term = MBB.getFirstTerminator(); 152 if (isPredicated(Term) && !AnalyzeBranch(MBB, NewTBB, NewFBB, Cond, 153 false)) { 154 MachineBasicBlock *NextBB = 155 llvm::next(MachineFunction::iterator(&MBB)); 156 if (NewTBB == NextBB) { 157 ReverseBranchCondition(Cond); 158 RemoveBranch(MBB); 159 return InsertBranch(MBB, TBB, 0, Cond, DL); 160 } 161 } 162 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB); 163 } else { 164 BuildMI(&MBB, DL, 165 get(BccOpc)).addReg(Cond[regPos].getReg()).addMBB(TBB); 166 } 167 return 1; 168 } 169 170 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[regPos].getReg()).addMBB(TBB); 171 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB); 172 173 return 2; 174} 175 176 177bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 178 MachineBasicBlock *&TBB, 179 MachineBasicBlock *&FBB, 180 SmallVectorImpl<MachineOperand> &Cond, 181 bool AllowModify) const { 182 FBB = NULL; 183 184 // If the block has no terminators, it just falls into the block after it. 185 MachineBasicBlock::iterator I = MBB.end(); 186 if (I == MBB.begin()) 187 return false; 188 189 // A basic block may looks like this: 190 // 191 // [ insn 192 // EH_LABEL 193 // insn 194 // insn 195 // insn 196 // EH_LABEL 197 // insn ] 198 // 199 // It has two succs but does not have a terminator 200 // Don't know how to handle it. 201 do { 202 --I; 203 if (I->isEHLabel()) 204 return true; 205 } while (I != MBB.begin()); 206 207 I = MBB.end(); 208 --I; 209 210 while (I->isDebugValue()) { 211 if (I == MBB.begin()) 212 return false; 213 --I; 214 } 215 if (!isUnpredicatedTerminator(I)) 216 return false; 217 218 // Get the last instruction in the block. 219 MachineInstr *LastInst = I; 220 221 // If there is only one terminator instruction, process it. 222 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 223 if (LastInst->getOpcode() == Hexagon::JMP) { 224 TBB = LastInst->getOperand(0).getMBB(); 225 return false; 226 } 227 if (LastInst->getOpcode() == Hexagon::JMP_Pred) { 228 // Block ends with fall-through true condbranch. 229 TBB = LastInst->getOperand(1).getMBB(); 230 Cond.push_back(LastInst->getOperand(0)); 231 return false; 232 } 233 if (LastInst->getOpcode() == Hexagon::JMP_PredNot) { 234 // Block ends with fall-through false condbranch. 235 TBB = LastInst->getOperand(1).getMBB(); 236 Cond.push_back(MachineOperand::CreateImm(0)); 237 Cond.push_back(LastInst->getOperand(0)); 238 return false; 239 } 240 // Otherwise, don't know what this is. 241 return true; 242 } 243 244 // Get the instruction before it if it's a terminator. 245 MachineInstr *SecondLastInst = I; 246 247 // If there are three terminators, we don't know what sort of block this is. 248 if (SecondLastInst && I != MBB.begin() && 249 isUnpredicatedTerminator(--I)) 250 return true; 251 252 // If the block ends with Hexagon::BRCOND and Hexagon:JMP, handle it. 253 if (((SecondLastInst->getOpcode() == Hexagon::BRCOND) || 254 (SecondLastInst->getOpcode() == Hexagon::JMP_Pred)) && 255 LastInst->getOpcode() == Hexagon::JMP) { 256 TBB = SecondLastInst->getOperand(1).getMBB(); 257 Cond.push_back(SecondLastInst->getOperand(0)); 258 FBB = LastInst->getOperand(0).getMBB(); 259 return false; 260 } 261 262 // If the block ends with Hexagon::JMP_PredNot and Hexagon:JMP, handle it. 263 if ((SecondLastInst->getOpcode() == Hexagon::JMP_PredNot) && 264 LastInst->getOpcode() == Hexagon::JMP) { 265 TBB = SecondLastInst->getOperand(1).getMBB(); 266 Cond.push_back(MachineOperand::CreateImm(0)); 267 Cond.push_back(SecondLastInst->getOperand(0)); 268 FBB = LastInst->getOperand(0).getMBB(); 269 return false; 270 } 271 272 // If the block ends with two Hexagon:JMPs, handle it. The second one is not 273 // executed, so remove it. 274 if (SecondLastInst->getOpcode() == Hexagon::JMP && 275 LastInst->getOpcode() == Hexagon::JMP) { 276 TBB = SecondLastInst->getOperand(0).getMBB(); 277 I = LastInst; 278 if (AllowModify) 279 I->eraseFromParent(); 280 return false; 281 } 282 283 // Otherwise, can't handle this. 284 return true; 285} 286 287 288unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 289 int BOpc = Hexagon::JMP; 290 int BccOpc = Hexagon::JMP_Pred; 291 int BccOpcNot = Hexagon::JMP_PredNot; 292 293 MachineBasicBlock::iterator I = MBB.end(); 294 if (I == MBB.begin()) return 0; 295 --I; 296 if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc && 297 I->getOpcode() != BccOpcNot) 298 return 0; 299 300 // Remove the branch. 301 I->eraseFromParent(); 302 303 I = MBB.end(); 304 305 if (I == MBB.begin()) return 1; 306 --I; 307 if (I->getOpcode() != BccOpc && I->getOpcode() != BccOpcNot) 308 return 1; 309 310 // Remove the branch. 311 I->eraseFromParent(); 312 return 2; 313} 314 315 316void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 317 MachineBasicBlock::iterator I, DebugLoc DL, 318 unsigned DestReg, unsigned SrcReg, 319 bool KillSrc) const { 320 if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) { 321 BuildMI(MBB, I, DL, get(Hexagon::TFR), DestReg).addReg(SrcReg); 322 return; 323 } 324 if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) { 325 BuildMI(MBB, I, DL, get(Hexagon::TFR_64), DestReg).addReg(SrcReg); 326 return; 327 } 328 if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) { 329 // Map Pd = Ps to Pd = or(Ps, Ps). 330 BuildMI(MBB, I, DL, get(Hexagon::OR_pp), 331 DestReg).addReg(SrcReg).addReg(SrcReg); 332 return; 333 } 334 if (Hexagon::DoubleRegsRegClass.contains(DestReg, SrcReg)) { 335 // We can have an overlap between single and double reg: r1:0 = r0. 336 if(SrcReg == RI.getSubReg(DestReg, Hexagon::subreg_loreg)) { 337 // r1:0 = r0 338 BuildMI(MBB, I, DL, get(Hexagon::TFRI), (RI.getSubReg(DestReg, 339 Hexagon::subreg_hireg))).addImm(0); 340 } else { 341 // r1:0 = r1 or no overlap. 342 BuildMI(MBB, I, DL, get(Hexagon::TFR), (RI.getSubReg(DestReg, 343 Hexagon::subreg_loreg))).addReg(SrcReg); 344 BuildMI(MBB, I, DL, get(Hexagon::TFRI), (RI.getSubReg(DestReg, 345 Hexagon::subreg_hireg))).addImm(0); 346 } 347 return; 348 } 349 if (Hexagon::CRRegsRegClass.contains(DestReg, SrcReg)) { 350 BuildMI(MBB, I, DL, get(Hexagon::TFCR), DestReg).addReg(SrcReg); 351 return; 352 } 353 354 assert (0 && "Unimplemented"); 355} 356 357 358void HexagonInstrInfo:: 359storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 360 unsigned SrcReg, bool isKill, int FI, 361 const TargetRegisterClass *RC, 362 const TargetRegisterInfo *TRI) const { 363 364 DebugLoc DL = MBB.findDebugLoc(I); 365 MachineFunction &MF = *MBB.getParent(); 366 MachineFrameInfo &MFI = *MF.getFrameInfo(); 367 unsigned Align = MFI.getObjectAlignment(FI); 368 369 MachineMemOperand *MMO = 370 MF.getMachineMemOperand( 371 MachinePointerInfo(PseudoSourceValue::getFixedStack(FI)), 372 MachineMemOperand::MOStore, 373 MFI.getObjectSize(FI), 374 Align); 375 376 if (Hexagon::IntRegsRegisterClass->hasSubClassEq(RC)) { 377 BuildMI(MBB, I, DL, get(Hexagon::STriw)) 378 .addFrameIndex(FI).addImm(0) 379 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); 380 } else if (Hexagon::DoubleRegsRegisterClass->hasSubClassEq(RC)) { 381 BuildMI(MBB, I, DL, get(Hexagon::STrid)) 382 .addFrameIndex(FI).addImm(0) 383 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); 384 } else if (Hexagon::PredRegsRegisterClass->hasSubClassEq(RC)) { 385 BuildMI(MBB, I, DL, get(Hexagon::STriw_pred)) 386 .addFrameIndex(FI).addImm(0) 387 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); 388 } else { 389 assert(0 && "Unimplemented"); 390 } 391} 392 393 394void HexagonInstrInfo::storeRegToAddr( 395 MachineFunction &MF, unsigned SrcReg, 396 bool isKill, 397 SmallVectorImpl<MachineOperand> &Addr, 398 const TargetRegisterClass *RC, 399 SmallVectorImpl<MachineInstr*> &NewMIs) const 400{ 401 assert(0 && "Unimplemented"); 402 return; 403} 404 405 406void HexagonInstrInfo:: 407loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 408 unsigned DestReg, int FI, 409 const TargetRegisterClass *RC, 410 const TargetRegisterInfo *TRI) const { 411 DebugLoc DL = MBB.findDebugLoc(I); 412 MachineFunction &MF = *MBB.getParent(); 413 MachineFrameInfo &MFI = *MF.getFrameInfo(); 414 unsigned Align = MFI.getObjectAlignment(FI); 415 416 MachineMemOperand *MMO = 417 MF.getMachineMemOperand( 418 MachinePointerInfo(PseudoSourceValue::getFixedStack(FI)), 419 MachineMemOperand::MOLoad, 420 MFI.getObjectSize(FI), 421 Align); 422 423 if (RC == Hexagon::IntRegsRegisterClass) { 424 BuildMI(MBB, I, DL, get(Hexagon::LDriw), DestReg) 425 .addFrameIndex(FI).addImm(0).addMemOperand(MMO); 426 } else if (RC == Hexagon::DoubleRegsRegisterClass) { 427 BuildMI(MBB, I, DL, get(Hexagon::LDrid), DestReg) 428 .addFrameIndex(FI).addImm(0).addMemOperand(MMO); 429 } else if (RC == Hexagon::PredRegsRegisterClass) { 430 BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg) 431 .addFrameIndex(FI).addImm(0).addMemOperand(MMO); 432 } else { 433 assert(0 && "Can't store this register to stack slot"); 434 } 435} 436 437 438void HexagonInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 439 SmallVectorImpl<MachineOperand> &Addr, 440 const TargetRegisterClass *RC, 441 SmallVectorImpl<MachineInstr*> &NewMIs) const { 442 assert(0 && "Unimplemented"); 443} 444 445 446MachineInstr *HexagonInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 447 MachineInstr* MI, 448 const SmallVectorImpl<unsigned> &Ops, 449 int FI) const { 450 // Hexagon_TODO: Implement. 451 return(0); 452} 453 454 455unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const { 456 457 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 458 const TargetRegisterClass *TRC; 459 if (VT == MVT::i1) { 460 TRC = Hexagon::PredRegsRegisterClass; 461 } else if (VT == MVT::i32) { 462 TRC = Hexagon::IntRegsRegisterClass; 463 } else if (VT == MVT::i64) { 464 TRC = Hexagon::DoubleRegsRegisterClass; 465 } else { 466 llvm_unreachable("Cannot handle this register class"); 467 } 468 469 unsigned NewReg = RegInfo.createVirtualRegister(TRC); 470 return NewReg; 471} 472 473 474 475bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const { 476 bool isPred = MI->getDesc().isPredicable(); 477 478 if (!isPred) 479 return false; 480 481 const int Opc = MI->getOpcode(); 482 483 switch(Opc) { 484 case Hexagon::TFRI: 485 return isInt<12>(MI->getOperand(1).getImm()); 486 487 case Hexagon::STrid: 488 case Hexagon::STrid_indexed: 489 return isShiftedUInt<6,3>(MI->getOperand(1).getImm()); 490 491 case Hexagon::STriw: 492 case Hexagon::STriw_indexed: 493 case Hexagon::STriw_nv_V4: 494 return isShiftedUInt<6,2>(MI->getOperand(1).getImm()); 495 496 case Hexagon::STrih: 497 case Hexagon::STrih_indexed: 498 case Hexagon::STrih_nv_V4: 499 return isShiftedUInt<6,1>(MI->getOperand(1).getImm()); 500 501 case Hexagon::STrib: 502 case Hexagon::STrib_indexed: 503 case Hexagon::STrib_nv_V4: 504 return isUInt<6>(MI->getOperand(1).getImm()); 505 506 case Hexagon::LDrid: 507 case Hexagon::LDrid_indexed: 508 return isShiftedUInt<6,3>(MI->getOperand(2).getImm()); 509 510 case Hexagon::LDriw: 511 case Hexagon::LDriw_indexed: 512 return isShiftedUInt<6,2>(MI->getOperand(2).getImm()); 513 514 case Hexagon::LDrih: 515 case Hexagon::LDriuh: 516 case Hexagon::LDrih_indexed: 517 case Hexagon::LDriuh_indexed: 518 return isShiftedUInt<6,1>(MI->getOperand(2).getImm()); 519 520 case Hexagon::LDrib: 521 case Hexagon::LDriub: 522 case Hexagon::LDrib_indexed: 523 case Hexagon::LDriub_indexed: 524 return isUInt<6>(MI->getOperand(2).getImm()); 525 526 case Hexagon::POST_LDrid: 527 return isShiftedInt<4,3>(MI->getOperand(3).getImm()); 528 529 case Hexagon::POST_LDriw: 530 return isShiftedInt<4,2>(MI->getOperand(3).getImm()); 531 532 case Hexagon::POST_LDrih: 533 case Hexagon::POST_LDriuh: 534 return isShiftedInt<4,1>(MI->getOperand(3).getImm()); 535 536 case Hexagon::POST_LDrib: 537 case Hexagon::POST_LDriub: 538 return isInt<4>(MI->getOperand(3).getImm()); 539 540 case Hexagon::STrib_imm_V4: 541 case Hexagon::STrih_imm_V4: 542 case Hexagon::STriw_imm_V4: 543 return (isUInt<6>(MI->getOperand(1).getImm()) && 544 isInt<6>(MI->getOperand(2).getImm())); 545 546 case Hexagon::ADD_ri: 547 return isInt<8>(MI->getOperand(2).getImm()); 548 549 case Hexagon::ASLH: 550 case Hexagon::ASRH: 551 case Hexagon::SXTB: 552 case Hexagon::SXTH: 553 case Hexagon::ZXTB: 554 case Hexagon::ZXTH: 555 return Subtarget.getHexagonArchVersion() == HexagonSubtarget::V4; 556 557 case Hexagon::JMPR: 558 return false; 559 } 560 561 return true; 562} 563 564 565 566int HexagonInstrInfo:: 567getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const { 568 switch(Opc) { 569 case Hexagon::TFR: 570 return !invertPredicate ? Hexagon::TFR_cPt : 571 Hexagon::TFR_cNotPt; 572 case Hexagon::TFRI: 573 return !invertPredicate ? Hexagon::TFRI_cPt : 574 Hexagon::TFRI_cNotPt; 575 case Hexagon::JMP: 576 return !invertPredicate ? Hexagon::JMP_Pred : 577 Hexagon::JMP_PredNot; 578 case Hexagon::ADD_ri: 579 return !invertPredicate ? Hexagon::ADD_ri_cPt : 580 Hexagon::ADD_ri_cNotPt; 581 case Hexagon::ADD_rr: 582 return !invertPredicate ? Hexagon::ADD_rr_cPt : 583 Hexagon::ADD_rr_cNotPt; 584 case Hexagon::XOR_rr: 585 return !invertPredicate ? Hexagon::XOR_rr_cPt : 586 Hexagon::XOR_rr_cNotPt; 587 case Hexagon::AND_rr: 588 return !invertPredicate ? Hexagon::AND_rr_cPt : 589 Hexagon::AND_rr_cNotPt; 590 case Hexagon::OR_rr: 591 return !invertPredicate ? Hexagon::OR_rr_cPt : 592 Hexagon::OR_rr_cNotPt; 593 case Hexagon::SUB_rr: 594 return !invertPredicate ? Hexagon::SUB_rr_cPt : 595 Hexagon::SUB_rr_cNotPt; 596 case Hexagon::COMBINE_rr: 597 return !invertPredicate ? Hexagon::COMBINE_rr_cPt : 598 Hexagon::COMBINE_rr_cNotPt; 599 case Hexagon::ASLH: 600 return !invertPredicate ? Hexagon::ASLH_cPt_V4 : 601 Hexagon::ASLH_cNotPt_V4; 602 case Hexagon::ASRH: 603 return !invertPredicate ? Hexagon::ASRH_cPt_V4 : 604 Hexagon::ASRH_cNotPt_V4; 605 case Hexagon::SXTB: 606 return !invertPredicate ? Hexagon::SXTB_cPt_V4 : 607 Hexagon::SXTB_cNotPt_V4; 608 case Hexagon::SXTH: 609 return !invertPredicate ? Hexagon::SXTH_cPt_V4 : 610 Hexagon::SXTH_cNotPt_V4; 611 case Hexagon::ZXTB: 612 return !invertPredicate ? Hexagon::ZXTB_cPt_V4 : 613 Hexagon::ZXTB_cNotPt_V4; 614 case Hexagon::ZXTH: 615 return !invertPredicate ? Hexagon::ZXTH_cPt_V4 : 616 Hexagon::ZXTH_cNotPt_V4; 617 618 case Hexagon::JMPR: 619 return !invertPredicate ? Hexagon::JMPR_cPt : 620 Hexagon::JMPR_cNotPt; 621 622 // V4 indexed+scaled load. 623 case Hexagon::LDrid_indexed_V4: 624 return !invertPredicate ? Hexagon::LDrid_indexed_cPt_V4 : 625 Hexagon::LDrid_indexed_cNotPt_V4; 626 case Hexagon::LDrid_indexed_shl_V4: 627 return !invertPredicate ? Hexagon::LDrid_indexed_shl_cPt_V4 : 628 Hexagon::LDrid_indexed_shl_cNotPt_V4; 629 case Hexagon::LDrib_indexed_V4: 630 return !invertPredicate ? Hexagon::LDrib_indexed_cPt_V4 : 631 Hexagon::LDrib_indexed_cNotPt_V4; 632 case Hexagon::LDriub_indexed_V4: 633 return !invertPredicate ? Hexagon::LDriub_indexed_cPt_V4 : 634 Hexagon::LDriub_indexed_cNotPt_V4; 635 case Hexagon::LDriub_ae_indexed_V4: 636 return !invertPredicate ? Hexagon::LDriub_indexed_cPt_V4 : 637 Hexagon::LDriub_indexed_cNotPt_V4; 638 case Hexagon::LDrib_indexed_shl_V4: 639 return !invertPredicate ? Hexagon::LDrib_indexed_shl_cPt_V4 : 640 Hexagon::LDrib_indexed_shl_cNotPt_V4; 641 case Hexagon::LDriub_indexed_shl_V4: 642 return !invertPredicate ? Hexagon::LDriub_indexed_shl_cPt_V4 : 643 Hexagon::LDriub_indexed_shl_cNotPt_V4; 644 case Hexagon::LDriub_ae_indexed_shl_V4: 645 return !invertPredicate ? Hexagon::LDriub_indexed_shl_cPt_V4 : 646 Hexagon::LDriub_indexed_shl_cNotPt_V4; 647 case Hexagon::LDrih_indexed_V4: 648 return !invertPredicate ? Hexagon::LDrih_indexed_cPt_V4 : 649 Hexagon::LDrih_indexed_cNotPt_V4; 650 case Hexagon::LDriuh_indexed_V4: 651 return !invertPredicate ? Hexagon::LDriuh_indexed_cPt_V4 : 652 Hexagon::LDriuh_indexed_cNotPt_V4; 653 case Hexagon::LDriuh_ae_indexed_V4: 654 return !invertPredicate ? Hexagon::LDriuh_indexed_cPt_V4 : 655 Hexagon::LDriuh_indexed_cNotPt_V4; 656 case Hexagon::LDrih_indexed_shl_V4: 657 return !invertPredicate ? Hexagon::LDrih_indexed_shl_cPt_V4 : 658 Hexagon::LDrih_indexed_shl_cNotPt_V4; 659 case Hexagon::LDriuh_indexed_shl_V4: 660 return !invertPredicate ? Hexagon::LDriuh_indexed_shl_cPt_V4 : 661 Hexagon::LDriuh_indexed_shl_cNotPt_V4; 662 case Hexagon::LDriuh_ae_indexed_shl_V4: 663 return !invertPredicate ? Hexagon::LDriuh_indexed_shl_cPt_V4 : 664 Hexagon::LDriuh_indexed_shl_cNotPt_V4; 665 case Hexagon::LDriw_indexed_V4: 666 return !invertPredicate ? Hexagon::LDriw_indexed_cPt_V4 : 667 Hexagon::LDriw_indexed_cNotPt_V4; 668 case Hexagon::LDriw_indexed_shl_V4: 669 return !invertPredicate ? Hexagon::LDriw_indexed_shl_cPt_V4 : 670 Hexagon::LDriw_indexed_shl_cNotPt_V4; 671 // Byte. 672 case Hexagon::POST_STbri: 673 return !invertPredicate ? Hexagon::POST_STbri_cPt : 674 Hexagon::POST_STbri_cNotPt; 675 case Hexagon::STrib: 676 return !invertPredicate ? Hexagon::STrib_cPt : 677 Hexagon::STrib_cNotPt; 678 case Hexagon::STrib_indexed: 679 return !invertPredicate ? Hexagon::STrib_indexed_cPt : 680 Hexagon::STrib_indexed_cNotPt; 681 case Hexagon::STrib_imm_V4: 682 return !invertPredicate ? Hexagon::STrib_imm_cPt_V4 : 683 Hexagon::STrib_imm_cNotPt_V4; 684 case Hexagon::STrib_indexed_shl_V4: 685 return !invertPredicate ? Hexagon::STrib_indexed_shl_cPt_V4 : 686 Hexagon::STrib_indexed_shl_cNotPt_V4; 687 // Halfword. 688 case Hexagon::POST_SThri: 689 return !invertPredicate ? Hexagon::POST_SThri_cPt : 690 Hexagon::POST_SThri_cNotPt; 691 case Hexagon::STrih: 692 return !invertPredicate ? Hexagon::STrih_cPt : 693 Hexagon::STrih_cNotPt; 694 case Hexagon::STrih_indexed: 695 return !invertPredicate ? Hexagon::STrih_indexed_cPt : 696 Hexagon::STrih_indexed_cNotPt; 697 case Hexagon::STrih_imm_V4: 698 return !invertPredicate ? Hexagon::STrih_imm_cPt_V4 : 699 Hexagon::STrih_imm_cNotPt_V4; 700 case Hexagon::STrih_indexed_shl_V4: 701 return !invertPredicate ? Hexagon::STrih_indexed_shl_cPt_V4 : 702 Hexagon::STrih_indexed_shl_cNotPt_V4; 703 // Word. 704 case Hexagon::POST_STwri: 705 return !invertPredicate ? Hexagon::POST_STwri_cPt : 706 Hexagon::POST_STwri_cNotPt; 707 case Hexagon::STriw: 708 return !invertPredicate ? Hexagon::STriw_cPt : 709 Hexagon::STriw_cNotPt; 710 case Hexagon::STriw_indexed: 711 return !invertPredicate ? Hexagon::STriw_indexed_cPt : 712 Hexagon::STriw_indexed_cNotPt; 713 case Hexagon::STriw_indexed_shl_V4: 714 return !invertPredicate ? Hexagon::STriw_indexed_shl_cPt_V4 : 715 Hexagon::STriw_indexed_shl_cNotPt_V4; 716 case Hexagon::STriw_imm_V4: 717 return !invertPredicate ? Hexagon::STriw_imm_cPt_V4 : 718 Hexagon::STriw_imm_cNotPt_V4; 719 // Double word. 720 case Hexagon::POST_STdri: 721 return !invertPredicate ? Hexagon::POST_STdri_cPt : 722 Hexagon::POST_STdri_cNotPt; 723 case Hexagon::STrid: 724 return !invertPredicate ? Hexagon::STrid_cPt : 725 Hexagon::STrid_cNotPt; 726 case Hexagon::STrid_indexed: 727 return !invertPredicate ? Hexagon::STrid_indexed_cPt : 728 Hexagon::STrid_indexed_cNotPt; 729 case Hexagon::STrid_indexed_shl_V4: 730 return !invertPredicate ? Hexagon::STrid_indexed_shl_cPt_V4 : 731 Hexagon::STrid_indexed_shl_cNotPt_V4; 732 // Load. 733 case Hexagon::LDrid: 734 return !invertPredicate ? Hexagon::LDrid_cPt : 735 Hexagon::LDrid_cNotPt; 736 case Hexagon::LDriw: 737 return !invertPredicate ? Hexagon::LDriw_cPt : 738 Hexagon::LDriw_cNotPt; 739 case Hexagon::LDrih: 740 return !invertPredicate ? Hexagon::LDrih_cPt : 741 Hexagon::LDrih_cNotPt; 742 case Hexagon::LDriuh: 743 return !invertPredicate ? Hexagon::LDriuh_cPt : 744 Hexagon::LDriuh_cNotPt; 745 case Hexagon::LDrib: 746 return !invertPredicate ? Hexagon::LDrib_cPt : 747 Hexagon::LDrib_cNotPt; 748 case Hexagon::LDriub: 749 return !invertPredicate ? Hexagon::LDriub_cPt : 750 Hexagon::LDriub_cNotPt; 751 case Hexagon::LDriubit: 752 return !invertPredicate ? Hexagon::LDriub_cPt : 753 Hexagon::LDriub_cNotPt; 754 // Load Indexed. 755 case Hexagon::LDrid_indexed: 756 return !invertPredicate ? Hexagon::LDrid_indexed_cPt : 757 Hexagon::LDrid_indexed_cNotPt; 758 case Hexagon::LDriw_indexed: 759 return !invertPredicate ? Hexagon::LDriw_indexed_cPt : 760 Hexagon::LDriw_indexed_cNotPt; 761 case Hexagon::LDrih_indexed: 762 return !invertPredicate ? Hexagon::LDrih_indexed_cPt : 763 Hexagon::LDrih_indexed_cNotPt; 764 case Hexagon::LDriuh_indexed: 765 return !invertPredicate ? Hexagon::LDriuh_indexed_cPt : 766 Hexagon::LDriuh_indexed_cNotPt; 767 case Hexagon::LDrib_indexed: 768 return !invertPredicate ? Hexagon::LDrib_indexed_cPt : 769 Hexagon::LDrib_indexed_cNotPt; 770 case Hexagon::LDriub_indexed: 771 return !invertPredicate ? Hexagon::LDriub_indexed_cPt : 772 Hexagon::LDriub_indexed_cNotPt; 773 // Post Increment Load. 774 case Hexagon::POST_LDrid: 775 return !invertPredicate ? Hexagon::POST_LDrid_cPt : 776 Hexagon::POST_LDrid_cNotPt; 777 case Hexagon::POST_LDriw: 778 return !invertPredicate ? Hexagon::POST_LDriw_cPt : 779 Hexagon::POST_LDriw_cNotPt; 780 case Hexagon::POST_LDrih: 781 return !invertPredicate ? Hexagon::POST_LDrih_cPt : 782 Hexagon::POST_LDrih_cNotPt; 783 case Hexagon::POST_LDriuh: 784 return !invertPredicate ? Hexagon::POST_LDriuh_cPt : 785 Hexagon::POST_LDriuh_cNotPt; 786 case Hexagon::POST_LDrib: 787 return !invertPredicate ? Hexagon::POST_LDrib_cPt : 788 Hexagon::POST_LDrib_cNotPt; 789 case Hexagon::POST_LDriub: 790 return !invertPredicate ? Hexagon::POST_LDriub_cPt : 791 Hexagon::POST_LDriub_cNotPt; 792 // DEALLOC_RETURN. 793 case Hexagon::DEALLOC_RET_V4: 794 return !invertPredicate ? Hexagon::DEALLOC_RET_cPt_V4 : 795 Hexagon::DEALLOC_RET_cNotPt_V4; 796 } 797 llvm_unreachable("Unexpected predicable instruction"); 798} 799 800 801bool HexagonInstrInfo:: 802PredicateInstruction(MachineInstr *MI, 803 const SmallVectorImpl<MachineOperand> &Cond) const { 804 int Opc = MI->getOpcode(); 805 assert (isPredicable(MI) && "Expected predicable instruction"); 806 bool invertJump = (!Cond.empty() && Cond[0].isImm() && 807 (Cond[0].getImm() == 0)); 808 MI->setDesc(get(getMatchingCondBranchOpcode(Opc, invertJump))); 809 // 810 // This assumes that the predicate is always the first operand 811 // in the set of inputs. 812 // 813 MI->addOperand(MI->getOperand(MI->getNumOperands()-1)); 814 int oper; 815 for (oper = MI->getNumOperands() - 3; oper >= 0; --oper) { 816 MachineOperand MO = MI->getOperand(oper); 817 if ((MO.isReg() && !MO.isUse() && !MO.isImplicit())) { 818 break; 819 } 820 821 if (MO.isReg()) { 822 MI->getOperand(oper+1).ChangeToRegister(MO.getReg(), MO.isDef(), 823 MO.isImplicit(), MO.isKill(), 824 MO.isDead(), MO.isUndef(), 825 MO.isDebug()); 826 } else if (MO.isImm()) { 827 MI->getOperand(oper+1).ChangeToImmediate(MO.getImm()); 828 } else { 829 assert(false && "Unexpected operand type"); 830 } 831 } 832 833 int regPos = invertJump ? 1 : 0; 834 MachineOperand PredMO = Cond[regPos]; 835 MI->getOperand(oper+1).ChangeToRegister(PredMO.getReg(), PredMO.isDef(), 836 PredMO.isImplicit(), PredMO.isKill(), 837 PredMO.isDead(), PredMO.isUndef(), 838 PredMO.isDebug()); 839 840 return true; 841} 842 843 844bool 845HexagonInstrInfo:: 846isProfitableToIfCvt(MachineBasicBlock &MBB, 847 unsigned NumCyles, 848 unsigned ExtraPredCycles, 849 const BranchProbability &Probability) const { 850 return true; 851} 852 853 854bool 855HexagonInstrInfo:: 856isProfitableToIfCvt(MachineBasicBlock &TMBB, 857 unsigned NumTCycles, 858 unsigned ExtraTCycles, 859 MachineBasicBlock &FMBB, 860 unsigned NumFCycles, 861 unsigned ExtraFCycles, 862 const BranchProbability &Probability) const { 863 return true; 864} 865 866 867bool HexagonInstrInfo::isPredicated(const MachineInstr *MI) const { 868 switch (MI->getOpcode()) { 869 case Hexagon::TFR_cPt: 870 case Hexagon::TFR_cNotPt: 871 case Hexagon::TFRI_cPt: 872 case Hexagon::TFRI_cNotPt: 873 case Hexagon::TFR_cdnPt: 874 case Hexagon::TFR_cdnNotPt: 875 case Hexagon::TFRI_cdnPt: 876 case Hexagon::TFRI_cdnNotPt: 877 return true; 878 879 case Hexagon::JMP_Pred: 880 case Hexagon::JMP_PredNot: 881 case Hexagon::BRCOND: 882 case Hexagon::JMP_PredPt: 883 case Hexagon::JMP_PredNotPt: 884 case Hexagon::JMP_PredPnt: 885 case Hexagon::JMP_PredNotPnt: 886 return true; 887 888 case Hexagon::LDrid_indexed_cPt_V4 : 889 case Hexagon::LDrid_indexed_cdnPt_V4 : 890 case Hexagon::LDrid_indexed_cNotPt_V4 : 891 case Hexagon::LDrid_indexed_cdnNotPt_V4 : 892 case Hexagon::LDrid_indexed_shl_cPt_V4 : 893 case Hexagon::LDrid_indexed_shl_cdnPt_V4 : 894 case Hexagon::LDrid_indexed_shl_cNotPt_V4 : 895 case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 : 896 case Hexagon::LDrib_indexed_cPt_V4 : 897 case Hexagon::LDrib_indexed_cdnPt_V4 : 898 case Hexagon::LDrib_indexed_cNotPt_V4 : 899 case Hexagon::LDrib_indexed_cdnNotPt_V4 : 900 case Hexagon::LDrib_indexed_shl_cPt_V4 : 901 case Hexagon::LDrib_indexed_shl_cdnPt_V4 : 902 case Hexagon::LDrib_indexed_shl_cNotPt_V4 : 903 case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 : 904 case Hexagon::LDriub_indexed_cPt_V4 : 905 case Hexagon::LDriub_indexed_cdnPt_V4 : 906 case Hexagon::LDriub_indexed_cNotPt_V4 : 907 case Hexagon::LDriub_indexed_cdnNotPt_V4 : 908 case Hexagon::LDriub_indexed_shl_cPt_V4 : 909 case Hexagon::LDriub_indexed_shl_cdnPt_V4 : 910 case Hexagon::LDriub_indexed_shl_cNotPt_V4 : 911 case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 : 912 case Hexagon::LDrih_indexed_cPt_V4 : 913 case Hexagon::LDrih_indexed_cdnPt_V4 : 914 case Hexagon::LDrih_indexed_cNotPt_V4 : 915 case Hexagon::LDrih_indexed_cdnNotPt_V4 : 916 case Hexagon::LDrih_indexed_shl_cPt_V4 : 917 case Hexagon::LDrih_indexed_shl_cdnPt_V4 : 918 case Hexagon::LDrih_indexed_shl_cNotPt_V4 : 919 case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 : 920 case Hexagon::LDriuh_indexed_cPt_V4 : 921 case Hexagon::LDriuh_indexed_cdnPt_V4 : 922 case Hexagon::LDriuh_indexed_cNotPt_V4 : 923 case Hexagon::LDriuh_indexed_cdnNotPt_V4 : 924 case Hexagon::LDriuh_indexed_shl_cPt_V4 : 925 case Hexagon::LDriuh_indexed_shl_cdnPt_V4 : 926 case Hexagon::LDriuh_indexed_shl_cNotPt_V4 : 927 case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 : 928 case Hexagon::LDriw_indexed_cPt_V4 : 929 case Hexagon::LDriw_indexed_cdnPt_V4 : 930 case Hexagon::LDriw_indexed_cNotPt_V4 : 931 case Hexagon::LDriw_indexed_cdnNotPt_V4 : 932 case Hexagon::LDriw_indexed_shl_cPt_V4 : 933 case Hexagon::LDriw_indexed_shl_cdnPt_V4 : 934 case Hexagon::LDriw_indexed_shl_cNotPt_V4 : 935 case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 : 936 return true; 937 938 case Hexagon::LDrid_cPt : 939 case Hexagon::LDrid_cNotPt : 940 case Hexagon::LDrid_indexed_cPt : 941 case Hexagon::LDrid_indexed_cNotPt : 942 case Hexagon::POST_LDrid_cPt : 943 case Hexagon::POST_LDrid_cNotPt : 944 case Hexagon::LDriw_cPt : 945 case Hexagon::LDriw_cNotPt : 946 case Hexagon::LDriw_indexed_cPt : 947 case Hexagon::LDriw_indexed_cNotPt : 948 case Hexagon::POST_LDriw_cPt : 949 case Hexagon::POST_LDriw_cNotPt : 950 case Hexagon::LDrih_cPt : 951 case Hexagon::LDrih_cNotPt : 952 case Hexagon::LDrih_indexed_cPt : 953 case Hexagon::LDrih_indexed_cNotPt : 954 case Hexagon::POST_LDrih_cPt : 955 case Hexagon::POST_LDrih_cNotPt : 956 case Hexagon::LDrib_cPt : 957 case Hexagon::LDrib_cNotPt : 958 case Hexagon::LDrib_indexed_cPt : 959 case Hexagon::LDrib_indexed_cNotPt : 960 case Hexagon::POST_LDrib_cPt : 961 case Hexagon::POST_LDrib_cNotPt : 962 case Hexagon::LDriuh_cPt : 963 case Hexagon::LDriuh_cNotPt : 964 case Hexagon::LDriuh_indexed_cPt : 965 case Hexagon::LDriuh_indexed_cNotPt : 966 case Hexagon::POST_LDriuh_cPt : 967 case Hexagon::POST_LDriuh_cNotPt : 968 case Hexagon::LDriub_cPt : 969 case Hexagon::LDriub_cNotPt : 970 case Hexagon::LDriub_indexed_cPt : 971 case Hexagon::LDriub_indexed_cNotPt : 972 case Hexagon::POST_LDriub_cPt : 973 case Hexagon::POST_LDriub_cNotPt : 974 return true; 975 976 case Hexagon::LDrid_cdnPt : 977 case Hexagon::LDrid_cdnNotPt : 978 case Hexagon::LDrid_indexed_cdnPt : 979 case Hexagon::LDrid_indexed_cdnNotPt : 980 case Hexagon::POST_LDrid_cdnPt_V4 : 981 case Hexagon::POST_LDrid_cdnNotPt_V4 : 982 case Hexagon::LDriw_cdnPt : 983 case Hexagon::LDriw_cdnNotPt : 984 case Hexagon::LDriw_indexed_cdnPt : 985 case Hexagon::LDriw_indexed_cdnNotPt : 986 case Hexagon::POST_LDriw_cdnPt_V4 : 987 case Hexagon::POST_LDriw_cdnNotPt_V4 : 988 case Hexagon::LDrih_cdnPt : 989 case Hexagon::LDrih_cdnNotPt : 990 case Hexagon::LDrih_indexed_cdnPt : 991 case Hexagon::LDrih_indexed_cdnNotPt : 992 case Hexagon::POST_LDrih_cdnPt_V4 : 993 case Hexagon::POST_LDrih_cdnNotPt_V4 : 994 case Hexagon::LDrib_cdnPt : 995 case Hexagon::LDrib_cdnNotPt : 996 case Hexagon::LDrib_indexed_cdnPt : 997 case Hexagon::LDrib_indexed_cdnNotPt : 998 case Hexagon::POST_LDrib_cdnPt_V4 : 999 case Hexagon::POST_LDrib_cdnNotPt_V4 : 1000 case Hexagon::LDriuh_cdnPt : 1001 case Hexagon::LDriuh_cdnNotPt : 1002 case Hexagon::LDriuh_indexed_cdnPt : 1003 case Hexagon::LDriuh_indexed_cdnNotPt : 1004 case Hexagon::POST_LDriuh_cdnPt_V4 : 1005 case Hexagon::POST_LDriuh_cdnNotPt_V4 : 1006 case Hexagon::LDriub_cdnPt : 1007 case Hexagon::LDriub_cdnNotPt : 1008 case Hexagon::LDriub_indexed_cdnPt : 1009 case Hexagon::LDriub_indexed_cdnNotPt : 1010 case Hexagon::POST_LDriub_cdnPt_V4 : 1011 case Hexagon::POST_LDriub_cdnNotPt_V4 : 1012 return true; 1013 1014 case Hexagon::ADD_ri_cPt: 1015 case Hexagon::ADD_ri_cNotPt: 1016 case Hexagon::ADD_ri_cdnPt: 1017 case Hexagon::ADD_ri_cdnNotPt: 1018 case Hexagon::ADD_rr_cPt: 1019 case Hexagon::ADD_rr_cNotPt: 1020 case Hexagon::ADD_rr_cdnPt: 1021 case Hexagon::ADD_rr_cdnNotPt: 1022 case Hexagon::XOR_rr_cPt: 1023 case Hexagon::XOR_rr_cNotPt: 1024 case Hexagon::XOR_rr_cdnPt: 1025 case Hexagon::XOR_rr_cdnNotPt: 1026 case Hexagon::AND_rr_cPt: 1027 case Hexagon::AND_rr_cNotPt: 1028 case Hexagon::AND_rr_cdnPt: 1029 case Hexagon::AND_rr_cdnNotPt: 1030 case Hexagon::OR_rr_cPt: 1031 case Hexagon::OR_rr_cNotPt: 1032 case Hexagon::OR_rr_cdnPt: 1033 case Hexagon::OR_rr_cdnNotPt: 1034 case Hexagon::SUB_rr_cPt: 1035 case Hexagon::SUB_rr_cNotPt: 1036 case Hexagon::SUB_rr_cdnPt: 1037 case Hexagon::SUB_rr_cdnNotPt: 1038 case Hexagon::COMBINE_rr_cPt: 1039 case Hexagon::COMBINE_rr_cNotPt: 1040 case Hexagon::COMBINE_rr_cdnPt: 1041 case Hexagon::COMBINE_rr_cdnNotPt: 1042 return true; 1043 1044 case Hexagon::ASLH_cPt_V4: 1045 case Hexagon::ASLH_cNotPt_V4: 1046 case Hexagon::ASRH_cPt_V4: 1047 case Hexagon::ASRH_cNotPt_V4: 1048 case Hexagon::SXTB_cPt_V4: 1049 case Hexagon::SXTB_cNotPt_V4: 1050 case Hexagon::SXTH_cPt_V4: 1051 case Hexagon::SXTH_cNotPt_V4: 1052 case Hexagon::ZXTB_cPt_V4: 1053 case Hexagon::ZXTB_cNotPt_V4: 1054 case Hexagon::ZXTH_cPt_V4: 1055 case Hexagon::ZXTH_cNotPt_V4: 1056 return true; 1057 1058 case Hexagon::ASLH_cdnPt_V4: 1059 case Hexagon::ASLH_cdnNotPt_V4: 1060 case Hexagon::ASRH_cdnPt_V4: 1061 case Hexagon::ASRH_cdnNotPt_V4: 1062 case Hexagon::SXTB_cdnPt_V4: 1063 case Hexagon::SXTB_cdnNotPt_V4: 1064 case Hexagon::SXTH_cdnPt_V4: 1065 case Hexagon::SXTH_cdnNotPt_V4: 1066 case Hexagon::ZXTB_cdnPt_V4: 1067 case Hexagon::ZXTB_cdnNotPt_V4: 1068 case Hexagon::ZXTH_cdnPt_V4: 1069 case Hexagon::ZXTH_cdnNotPt_V4: 1070 return true; 1071 1072 default: 1073 return false; 1074 } 1075} 1076 1077 1078bool 1079HexagonInstrInfo::DefinesPredicate(MachineInstr *MI, 1080 std::vector<MachineOperand> &Pred) const { 1081 for (unsigned oper = 0; oper < MI->getNumOperands(); ++oper) { 1082 MachineOperand MO = MI->getOperand(oper); 1083 if (MO.isReg() && MO.isDef()) { 1084 const TargetRegisterClass* RC = RI.getMinimalPhysRegClass(MO.getReg()); 1085 if (RC == Hexagon::PredRegsRegisterClass) { 1086 Pred.push_back(MO); 1087 return true; 1088 } 1089 } 1090 } 1091 return false; 1092} 1093 1094 1095bool 1096HexagonInstrInfo:: 1097SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 1098 const SmallVectorImpl<MachineOperand> &Pred2) const { 1099 // TODO: Fix this 1100 return false; 1101} 1102 1103 1104// 1105// We indicate that we want to reverse the branch by 1106// inserting a 0 at the beginning of the Cond vector. 1107// 1108bool HexagonInstrInfo:: 1109ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 1110 if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) { 1111 Cond.erase(Cond.begin()); 1112 } else { 1113 Cond.insert(Cond.begin(), MachineOperand::CreateImm(0)); 1114 } 1115 return false; 1116} 1117 1118 1119bool HexagonInstrInfo:: 1120isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumInstrs, 1121 const BranchProbability &Probability) const { 1122 return (NumInstrs <= 4); 1123} 1124 1125bool HexagonInstrInfo::isDeallocRet(const MachineInstr *MI) const { 1126 switch (MI->getOpcode()) { 1127 case Hexagon::DEALLOC_RET_V4 : 1128 case Hexagon::DEALLOC_RET_cPt_V4 : 1129 case Hexagon::DEALLOC_RET_cNotPt_V4 : 1130 case Hexagon::DEALLOC_RET_cdnPnt_V4 : 1131 case Hexagon::DEALLOC_RET_cNotdnPnt_V4 : 1132 case Hexagon::DEALLOC_RET_cdnPt_V4 : 1133 case Hexagon::DEALLOC_RET_cNotdnPt_V4 : 1134 return true; 1135 } 1136 return false; 1137} 1138 1139 1140bool HexagonInstrInfo:: 1141isValidOffset(const int Opcode, const int Offset) const { 1142 // This function is to check whether the "Offset" is in the correct range of 1143 // the given "Opcode". If "Offset" is not in the correct range, "ADD_ri" is 1144 // inserted to calculate the final address. Due to this reason, the function 1145 // assumes that the "Offset" has correct alignment. 1146 1147 switch(Opcode) { 1148 1149 case Hexagon::LDriw: 1150 case Hexagon::STriw: 1151 case Hexagon::STriwt: 1152 assert((Offset % 4 == 0) && "Offset has incorrect alignment"); 1153 return (Offset >= Hexagon_MEMW_OFFSET_MIN) && 1154 (Offset <= Hexagon_MEMW_OFFSET_MAX); 1155 1156 case Hexagon::LDrid: 1157 case Hexagon::STrid: 1158 assert((Offset % 8 == 0) && "Offset has incorrect alignment"); 1159 return (Offset >= Hexagon_MEMD_OFFSET_MIN) && 1160 (Offset <= Hexagon_MEMD_OFFSET_MAX); 1161 1162 case Hexagon::LDrih: 1163 case Hexagon::LDriuh: 1164 case Hexagon::STrih: 1165 case Hexagon::LDrih_ae: 1166 assert((Offset % 2 == 0) && "Offset has incorrect alignment"); 1167 return (Offset >= Hexagon_MEMH_OFFSET_MIN) && 1168 (Offset <= Hexagon_MEMH_OFFSET_MAX); 1169 1170 case Hexagon::LDrib: 1171 case Hexagon::STrib: 1172 case Hexagon::LDriub: 1173 case Hexagon::LDriubit: 1174 case Hexagon::LDrib_ae: 1175 case Hexagon::LDriub_ae: 1176 return (Offset >= Hexagon_MEMB_OFFSET_MIN) && 1177 (Offset <= Hexagon_MEMB_OFFSET_MAX); 1178 1179 case Hexagon::ADD_ri: 1180 case Hexagon::TFR_FI: 1181 return (Offset >= Hexagon_ADDI_OFFSET_MIN) && 1182 (Offset <= Hexagon_ADDI_OFFSET_MAX); 1183 1184 case Hexagon::MEMw_ADDSUBi_indexed_MEM_V4 : 1185 case Hexagon::MEMw_ADDi_indexed_MEM_V4 : 1186 case Hexagon::MEMw_SUBi_indexed_MEM_V4 : 1187 case Hexagon::MEMw_ADDr_indexed_MEM_V4 : 1188 case Hexagon::MEMw_SUBr_indexed_MEM_V4 : 1189 case Hexagon::MEMw_ANDr_indexed_MEM_V4 : 1190 case Hexagon::MEMw_ORr_indexed_MEM_V4 : 1191 case Hexagon::MEMw_ADDSUBi_MEM_V4 : 1192 case Hexagon::MEMw_ADDi_MEM_V4 : 1193 case Hexagon::MEMw_SUBi_MEM_V4 : 1194 case Hexagon::MEMw_ADDr_MEM_V4 : 1195 case Hexagon::MEMw_SUBr_MEM_V4 : 1196 case Hexagon::MEMw_ANDr_MEM_V4 : 1197 case Hexagon::MEMw_ORr_MEM_V4 : 1198 assert ((Offset % 4) == 0 && "MEMOPw offset is not aligned correctly." ); 1199 return (0 <= Offset && Offset <= 255); 1200 1201 case Hexagon::MEMh_ADDSUBi_indexed_MEM_V4 : 1202 case Hexagon::MEMh_ADDi_indexed_MEM_V4 : 1203 case Hexagon::MEMh_SUBi_indexed_MEM_V4 : 1204 case Hexagon::MEMh_ADDr_indexed_MEM_V4 : 1205 case Hexagon::MEMh_SUBr_indexed_MEM_V4 : 1206 case Hexagon::MEMh_ANDr_indexed_MEM_V4 : 1207 case Hexagon::MEMh_ORr_indexed_MEM_V4 : 1208 case Hexagon::MEMh_ADDSUBi_MEM_V4 : 1209 case Hexagon::MEMh_ADDi_MEM_V4 : 1210 case Hexagon::MEMh_SUBi_MEM_V4 : 1211 case Hexagon::MEMh_ADDr_MEM_V4 : 1212 case Hexagon::MEMh_SUBr_MEM_V4 : 1213 case Hexagon::MEMh_ANDr_MEM_V4 : 1214 case Hexagon::MEMh_ORr_MEM_V4 : 1215 assert ((Offset % 2) == 0 && "MEMOPh offset is not aligned correctly." ); 1216 return (0 <= Offset && Offset <= 127); 1217 1218 case Hexagon::MEMb_ADDSUBi_indexed_MEM_V4 : 1219 case Hexagon::MEMb_ADDi_indexed_MEM_V4 : 1220 case Hexagon::MEMb_SUBi_indexed_MEM_V4 : 1221 case Hexagon::MEMb_ADDr_indexed_MEM_V4 : 1222 case Hexagon::MEMb_SUBr_indexed_MEM_V4 : 1223 case Hexagon::MEMb_ANDr_indexed_MEM_V4 : 1224 case Hexagon::MEMb_ORr_indexed_MEM_V4 : 1225 case Hexagon::MEMb_ADDSUBi_MEM_V4 : 1226 case Hexagon::MEMb_ADDi_MEM_V4 : 1227 case Hexagon::MEMb_SUBi_MEM_V4 : 1228 case Hexagon::MEMb_ADDr_MEM_V4 : 1229 case Hexagon::MEMb_SUBr_MEM_V4 : 1230 case Hexagon::MEMb_ANDr_MEM_V4 : 1231 case Hexagon::MEMb_ORr_MEM_V4 : 1232 return (0 <= Offset && Offset <= 63); 1233 1234 // LDri_pred and STriw_pred are pseudo operations, so it has to take offset of 1235 // any size. Later pass knows how to handle it. 1236 case Hexagon::STriw_pred: 1237 case Hexagon::LDriw_pred: 1238 return true; 1239 1240 // INLINEASM is very special. 1241 case Hexagon::INLINEASM: 1242 return true; 1243 } 1244 1245 llvm_unreachable("No offset range is defined for this opcode. " 1246 "Please define it in the above switch statement!"); 1247} 1248 1249 1250// 1251// Check if the Offset is a valid auto-inc imm by Load/Store Type. 1252// 1253bool HexagonInstrInfo:: 1254isValidAutoIncImm(const EVT VT, const int Offset) const { 1255 1256 if (VT == MVT::i64) { 1257 return (Offset >= Hexagon_MEMD_AUTOINC_MIN && 1258 Offset <= Hexagon_MEMD_AUTOINC_MAX && 1259 (Offset & 0x7) == 0); 1260 } 1261 if (VT == MVT::i32) { 1262 return (Offset >= Hexagon_MEMW_AUTOINC_MIN && 1263 Offset <= Hexagon_MEMW_AUTOINC_MAX && 1264 (Offset & 0x3) == 0); 1265 } 1266 if (VT == MVT::i16) { 1267 return (Offset >= Hexagon_MEMH_AUTOINC_MIN && 1268 Offset <= Hexagon_MEMH_AUTOINC_MAX && 1269 (Offset & 0x1) == 0); 1270 } 1271 if (VT == MVT::i8) { 1272 return (Offset >= Hexagon_MEMB_AUTOINC_MIN && 1273 Offset <= Hexagon_MEMB_AUTOINC_MAX); 1274 } 1275 1276 assert(0 && "Not an auto-inc opc!"); 1277 1278 return false; 1279} 1280 1281 1282bool HexagonInstrInfo:: 1283isMemOp(const MachineInstr *MI) const { 1284 switch (MI->getOpcode()) 1285 { 1286 case Hexagon::MEMw_ADDSUBi_indexed_MEM_V4 : 1287 case Hexagon::MEMw_ADDi_indexed_MEM_V4 : 1288 case Hexagon::MEMw_SUBi_indexed_MEM_V4 : 1289 case Hexagon::MEMw_ADDr_indexed_MEM_V4 : 1290 case Hexagon::MEMw_SUBr_indexed_MEM_V4 : 1291 case Hexagon::MEMw_ANDr_indexed_MEM_V4 : 1292 case Hexagon::MEMw_ORr_indexed_MEM_V4 : 1293 case Hexagon::MEMw_ADDSUBi_MEM_V4 : 1294 case Hexagon::MEMw_ADDi_MEM_V4 : 1295 case Hexagon::MEMw_SUBi_MEM_V4 : 1296 case Hexagon::MEMw_ADDr_MEM_V4 : 1297 case Hexagon::MEMw_SUBr_MEM_V4 : 1298 case Hexagon::MEMw_ANDr_MEM_V4 : 1299 case Hexagon::MEMw_ORr_MEM_V4 : 1300 case Hexagon::MEMh_ADDSUBi_indexed_MEM_V4 : 1301 case Hexagon::MEMh_ADDi_indexed_MEM_V4 : 1302 case Hexagon::MEMh_SUBi_indexed_MEM_V4 : 1303 case Hexagon::MEMh_ADDr_indexed_MEM_V4 : 1304 case Hexagon::MEMh_SUBr_indexed_MEM_V4 : 1305 case Hexagon::MEMh_ANDr_indexed_MEM_V4 : 1306 case Hexagon::MEMh_ORr_indexed_MEM_V4 : 1307 case Hexagon::MEMh_ADDSUBi_MEM_V4 : 1308 case Hexagon::MEMh_ADDi_MEM_V4 : 1309 case Hexagon::MEMh_SUBi_MEM_V4 : 1310 case Hexagon::MEMh_ADDr_MEM_V4 : 1311 case Hexagon::MEMh_SUBr_MEM_V4 : 1312 case Hexagon::MEMh_ANDr_MEM_V4 : 1313 case Hexagon::MEMh_ORr_MEM_V4 : 1314 case Hexagon::MEMb_ADDSUBi_indexed_MEM_V4 : 1315 case Hexagon::MEMb_ADDi_indexed_MEM_V4 : 1316 case Hexagon::MEMb_SUBi_indexed_MEM_V4 : 1317 case Hexagon::MEMb_ADDr_indexed_MEM_V4 : 1318 case Hexagon::MEMb_SUBr_indexed_MEM_V4 : 1319 case Hexagon::MEMb_ANDr_indexed_MEM_V4 : 1320 case Hexagon::MEMb_ORr_indexed_MEM_V4 : 1321 case Hexagon::MEMb_ADDSUBi_MEM_V4 : 1322 case Hexagon::MEMb_ADDi_MEM_V4 : 1323 case Hexagon::MEMb_SUBi_MEM_V4 : 1324 case Hexagon::MEMb_ADDr_MEM_V4 : 1325 case Hexagon::MEMb_SUBr_MEM_V4 : 1326 case Hexagon::MEMb_ANDr_MEM_V4 : 1327 case Hexagon::MEMb_ORr_MEM_V4 : 1328 return true; 1329 } 1330 return false; 1331} 1332 1333 1334bool HexagonInstrInfo:: 1335isSpillPredRegOp(const MachineInstr *MI) const { 1336 switch (MI->getOpcode()) 1337 { 1338 case Hexagon::STriw_pred : 1339 case Hexagon::LDriw_pred : 1340 return true; 1341 } 1342 return false; 1343} 1344 1345 1346bool HexagonInstrInfo::isConditionalALU32 (const MachineInstr* MI) const { 1347 const HexagonRegisterInfo& QRI = getRegisterInfo(); 1348 switch (MI->getOpcode()) 1349 { 1350 case Hexagon::ADD_ri_cPt: 1351 case Hexagon::ADD_ri_cNotPt: 1352 case Hexagon::ADD_rr_cPt: 1353 case Hexagon::ADD_rr_cNotPt: 1354 case Hexagon::XOR_rr_cPt: 1355 case Hexagon::XOR_rr_cNotPt: 1356 case Hexagon::AND_rr_cPt: 1357 case Hexagon::AND_rr_cNotPt: 1358 case Hexagon::OR_rr_cPt: 1359 case Hexagon::OR_rr_cNotPt: 1360 case Hexagon::SUB_rr_cPt: 1361 case Hexagon::SUB_rr_cNotPt: 1362 case Hexagon::COMBINE_rr_cPt: 1363 case Hexagon::COMBINE_rr_cNotPt: 1364 return true; 1365 case Hexagon::ASLH_cPt_V4: 1366 case Hexagon::ASLH_cNotPt_V4: 1367 case Hexagon::ASRH_cPt_V4: 1368 case Hexagon::ASRH_cNotPt_V4: 1369 case Hexagon::SXTB_cPt_V4: 1370 case Hexagon::SXTB_cNotPt_V4: 1371 case Hexagon::SXTH_cPt_V4: 1372 case Hexagon::SXTH_cNotPt_V4: 1373 case Hexagon::ZXTB_cPt_V4: 1374 case Hexagon::ZXTB_cNotPt_V4: 1375 case Hexagon::ZXTH_cPt_V4: 1376 case Hexagon::ZXTH_cNotPt_V4: 1377 return QRI.Subtarget.getHexagonArchVersion() == HexagonSubtarget::V4; 1378 1379 default: 1380 return false; 1381 } 1382} 1383 1384 1385bool HexagonInstrInfo:: 1386isConditionalLoad (const MachineInstr* MI) const { 1387 const HexagonRegisterInfo& QRI = getRegisterInfo(); 1388 switch (MI->getOpcode()) 1389 { 1390 case Hexagon::LDrid_cPt : 1391 case Hexagon::LDrid_cNotPt : 1392 case Hexagon::LDrid_indexed_cPt : 1393 case Hexagon::LDrid_indexed_cNotPt : 1394 case Hexagon::LDriw_cPt : 1395 case Hexagon::LDriw_cNotPt : 1396 case Hexagon::LDriw_indexed_cPt : 1397 case Hexagon::LDriw_indexed_cNotPt : 1398 case Hexagon::LDrih_cPt : 1399 case Hexagon::LDrih_cNotPt : 1400 case Hexagon::LDrih_indexed_cPt : 1401 case Hexagon::LDrih_indexed_cNotPt : 1402 case Hexagon::LDrib_cPt : 1403 case Hexagon::LDrib_cNotPt : 1404 case Hexagon::LDrib_indexed_cPt : 1405 case Hexagon::LDrib_indexed_cNotPt : 1406 case Hexagon::LDriuh_cPt : 1407 case Hexagon::LDriuh_cNotPt : 1408 case Hexagon::LDriuh_indexed_cPt : 1409 case Hexagon::LDriuh_indexed_cNotPt : 1410 case Hexagon::LDriub_cPt : 1411 case Hexagon::LDriub_cNotPt : 1412 case Hexagon::LDriub_indexed_cPt : 1413 case Hexagon::LDriub_indexed_cNotPt : 1414 return true; 1415 case Hexagon::POST_LDrid_cPt : 1416 case Hexagon::POST_LDrid_cNotPt : 1417 case Hexagon::POST_LDriw_cPt : 1418 case Hexagon::POST_LDriw_cNotPt : 1419 case Hexagon::POST_LDrih_cPt : 1420 case Hexagon::POST_LDrih_cNotPt : 1421 case Hexagon::POST_LDrib_cPt : 1422 case Hexagon::POST_LDrib_cNotPt : 1423 case Hexagon::POST_LDriuh_cPt : 1424 case Hexagon::POST_LDriuh_cNotPt : 1425 case Hexagon::POST_LDriub_cPt : 1426 case Hexagon::POST_LDriub_cNotPt : 1427 return QRI.Subtarget.getHexagonArchVersion() == HexagonSubtarget::V4; 1428 case Hexagon::LDrid_indexed_cPt_V4 : 1429 case Hexagon::LDrid_indexed_cNotPt_V4 : 1430 case Hexagon::LDrid_indexed_shl_cPt_V4 : 1431 case Hexagon::LDrid_indexed_shl_cNotPt_V4 : 1432 case Hexagon::LDrib_indexed_cPt_V4 : 1433 case Hexagon::LDrib_indexed_cNotPt_V4 : 1434 case Hexagon::LDrib_indexed_shl_cPt_V4 : 1435 case Hexagon::LDrib_indexed_shl_cNotPt_V4 : 1436 case Hexagon::LDriub_indexed_cPt_V4 : 1437 case Hexagon::LDriub_indexed_cNotPt_V4 : 1438 case Hexagon::LDriub_indexed_shl_cPt_V4 : 1439 case Hexagon::LDriub_indexed_shl_cNotPt_V4 : 1440 case Hexagon::LDrih_indexed_cPt_V4 : 1441 case Hexagon::LDrih_indexed_cNotPt_V4 : 1442 case Hexagon::LDrih_indexed_shl_cPt_V4 : 1443 case Hexagon::LDrih_indexed_shl_cNotPt_V4 : 1444 case Hexagon::LDriuh_indexed_cPt_V4 : 1445 case Hexagon::LDriuh_indexed_cNotPt_V4 : 1446 case Hexagon::LDriuh_indexed_shl_cPt_V4 : 1447 case Hexagon::LDriuh_indexed_shl_cNotPt_V4 : 1448 case Hexagon::LDriw_indexed_cPt_V4 : 1449 case Hexagon::LDriw_indexed_cNotPt_V4 : 1450 case Hexagon::LDriw_indexed_shl_cPt_V4 : 1451 case Hexagon::LDriw_indexed_shl_cNotPt_V4 : 1452 return QRI.Subtarget.getHexagonArchVersion() == HexagonSubtarget::V4; 1453 default: 1454 return false; 1455 } 1456} 1457 1458DFAPacketizer *HexagonInstrInfo:: 1459CreateTargetScheduleState(const TargetMachine *TM, 1460 const ScheduleDAG *DAG) const { 1461 const InstrItineraryData *II = TM->getInstrItineraryData(); 1462 return TM->getSubtarget<HexagonGenSubtargetInfo>().createDFAPacketizer(II); 1463} 1464 1465bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr *MI, 1466 const MachineBasicBlock *MBB, 1467 const MachineFunction &MF) const { 1468 // Debug info is never a scheduling boundary. It's necessary to be explicit 1469 // due to the special treatment of IT instructions below, otherwise a 1470 // dbg_value followed by an IT will result in the IT instruction being 1471 // considered a scheduling hazard, which is wrong. It should be the actual 1472 // instruction preceding the dbg_value instruction(s), just like it is 1473 // when debug info is not present. 1474 if (MI->isDebugValue()) 1475 return false; 1476 1477 // Terminators and labels can't be scheduled around. 1478 if (MI->getDesc().isTerminator() || MI->isLabel() || MI->isInlineAsm()) 1479 return true; 1480 1481 return false; 1482} 1483