1 2 //=== HexagonMCCompound.cpp - Hexagon Compound checker -------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is distributed under the University of Illinois Open Source 7 // License. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 // 11 // This file is looks at a packet and tries to form compound insns 12 // 13 //===----------------------------------------------------------------------===// 14 #include "Hexagon.h" 15 #include "MCTargetDesc/HexagonBaseInfo.h" 16 #include "MCTargetDesc/HexagonMCShuffler.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/MC/MCAssembler.h" 19 #include "llvm/MC/MCContext.h" 20 #include "llvm/MC/MCInst.h" 21 #include "llvm/MC/MCSectionELF.h" 22 #include "llvm/MC/MCStreamer.h" 23 #include "llvm/MC/MCSymbol.h" 24 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/raw_ostream.h" 26 27 using namespace llvm; 28 using namespace Hexagon; 29 30 #define DEBUG_TYPE "hexagon-mccompound" 31 32 enum OpcodeIndex { 33 fp0_jump_nt = 0, 34 fp0_jump_t, 35 fp1_jump_nt, 36 fp1_jump_t, 37 tp0_jump_nt, 38 tp0_jump_t, 39 tp1_jump_nt, 40 tp1_jump_t 41 }; 42 43 static const unsigned tstBitOpcode[8] = { 44 J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t, J4_tstbit0_fp1_jump_nt, 45 J4_tstbit0_fp1_jump_t, J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t, 46 J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t}; 47 static const unsigned cmpeqBitOpcode[8] = { 48 J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t, J4_cmpeq_fp1_jump_nt, 49 J4_cmpeq_fp1_jump_t, J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t, 50 J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t}; 51 static const unsigned cmpgtBitOpcode[8] = { 52 J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t, J4_cmpgt_fp1_jump_nt, 53 J4_cmpgt_fp1_jump_t, J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t, 54 J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t}; 55 static const unsigned cmpgtuBitOpcode[8] = { 56 J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t, J4_cmpgtu_fp1_jump_nt, 57 J4_cmpgtu_fp1_jump_t, J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t, 58 J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t}; 59 static const unsigned cmpeqiBitOpcode[8] = { 60 J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t, J4_cmpeqi_fp1_jump_nt, 61 J4_cmpeqi_fp1_jump_t, J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t, 62 J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t}; 63 static const unsigned cmpgtiBitOpcode[8] = { 64 J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t, J4_cmpgti_fp1_jump_nt, 65 J4_cmpgti_fp1_jump_t, J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t, 66 J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t}; 67 static const unsigned cmpgtuiBitOpcode[8] = { 68 J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t, J4_cmpgtui_fp1_jump_nt, 69 J4_cmpgtui_fp1_jump_t, J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t, 70 J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t}; 71 static const unsigned cmpeqn1BitOpcode[8] = { 72 J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t, J4_cmpeqn1_fp1_jump_nt, 73 J4_cmpeqn1_fp1_jump_t, J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t, 74 J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t}; 75 static const unsigned cmpgtn1BitOpcode[8] = { 76 J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t, J4_cmpgtn1_fp1_jump_nt, 77 J4_cmpgtn1_fp1_jump_t, J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t, 78 J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t, 79 }; 80 81 // enum HexagonII::CompoundGroup 82 namespace { 83 unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) { 84 unsigned DstReg, SrcReg, Src1Reg, Src2Reg; 85 86 switch (MI.getOpcode()) { 87 default: 88 return HexagonII::HCG_None; 89 // 90 // Compound pairs. 91 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2" 92 // "Rd16=#U6 ; jump #r9:2" 93 // "Rd16=Rs16 ; jump #r9:2" 94 // 95 case Hexagon::C2_cmpeq: 96 case Hexagon::C2_cmpgt: 97 case Hexagon::C2_cmpgtu: 98 if (IsExtended) 99 return false; 100 DstReg = MI.getOperand(0).getReg(); 101 Src1Reg = MI.getOperand(1).getReg(); 102 Src2Reg = MI.getOperand(2).getReg(); 103 if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) && 104 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) && 105 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) 106 return HexagonII::HCG_A; 107 break; 108 case Hexagon::C2_cmpeqi: 109 case Hexagon::C2_cmpgti: 110 case Hexagon::C2_cmpgtui: 111 if (IsExtended) 112 return false; 113 // P0 = cmp.eq(Rs,#u2) 114 DstReg = MI.getOperand(0).getReg(); 115 SrcReg = MI.getOperand(1).getReg(); 116 if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) && 117 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) && 118 (HexagonMCInstrInfo::inRange<5>(MI, 2) || 119 HexagonMCInstrInfo::minConstant(MI, 2) == -1)) 120 return HexagonII::HCG_A; 121 break; 122 case Hexagon::A2_tfr: 123 if (IsExtended) 124 return false; 125 // Rd = Rs 126 DstReg = MI.getOperand(0).getReg(); 127 SrcReg = MI.getOperand(1).getReg(); 128 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) && 129 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) 130 return HexagonII::HCG_A; 131 break; 132 case Hexagon::A2_tfrsi: 133 if (IsExtended) 134 return false; 135 // Rd = #u6 136 DstReg = MI.getOperand(0).getReg(); 137 if (HexagonMCInstrInfo::minConstant(MI, 1) <= 63 && 138 HexagonMCInstrInfo::minConstant(MI, 1) >= 0 && 139 HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) 140 return HexagonII::HCG_A; 141 break; 142 case Hexagon::S2_tstbit_i: 143 if (IsExtended) 144 return false; 145 DstReg = MI.getOperand(0).getReg(); 146 Src1Reg = MI.getOperand(1).getReg(); 147 if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) && 148 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) && 149 HexagonMCInstrInfo::minConstant(MI, 2) == 0) 150 return HexagonII::HCG_A; 151 break; 152 // The fact that .new form is used pretty much guarantees 153 // that predicate register will match. Nevertheless, 154 // there could be some false positives without additional 155 // checking. 156 case Hexagon::J2_jumptnew: 157 case Hexagon::J2_jumpfnew: 158 case Hexagon::J2_jumptnewpt: 159 case Hexagon::J2_jumpfnewpt: 160 Src1Reg = MI.getOperand(0).getReg(); 161 if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg) 162 return HexagonII::HCG_B; 163 break; 164 // Transfer and jump: 165 // Rd=#U6 ; jump #r9:2 166 // Rd=Rs ; jump #r9:2 167 // Do not test for jump range here. 168 case Hexagon::J2_jump: 169 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4: 170 return HexagonII::HCG_C; 171 break; 172 } 173 174 return HexagonII::HCG_None; 175 } 176 } 177 178 /// getCompoundOp - Return the index from 0-7 into the above opcode lists. 179 namespace { 180 unsigned getCompoundOp(MCInst const &HMCI) { 181 const MCOperand &Predicate = HMCI.getOperand(0); 182 unsigned PredReg = Predicate.getReg(); 183 184 assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) || 185 (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3)); 186 187 switch (HMCI.getOpcode()) { 188 default: 189 llvm_unreachable("Expected match not found.\n"); 190 break; 191 case Hexagon::J2_jumpfnew: 192 return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt; 193 case Hexagon::J2_jumpfnewpt: 194 return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t; 195 case Hexagon::J2_jumptnew: 196 return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt; 197 case Hexagon::J2_jumptnewpt: 198 return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t; 199 } 200 } 201 } 202 203 namespace { 204 MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) { 205 MCInst *CompoundInsn = 0; 206 unsigned compoundOpcode; 207 MCOperand Rs, Rt; 208 int64_t Value; 209 bool Success; 210 211 switch (L.getOpcode()) { 212 default: 213 DEBUG(dbgs() << "Possible compound ignored\n"); 214 return CompoundInsn; 215 216 case Hexagon::A2_tfrsi: 217 Rt = L.getOperand(0); 218 compoundOpcode = J4_jumpseti; 219 CompoundInsn = new (Context) MCInst; 220 CompoundInsn->setOpcode(compoundOpcode); 221 222 CompoundInsn->addOperand(Rt); 223 CompoundInsn->addOperand(L.getOperand(1)); // Immediate 224 CompoundInsn->addOperand(R.getOperand(0)); // Jump target 225 break; 226 227 case Hexagon::A2_tfr: 228 Rt = L.getOperand(0); 229 Rs = L.getOperand(1); 230 231 compoundOpcode = J4_jumpsetr; 232 CompoundInsn = new (Context) MCInst; 233 CompoundInsn->setOpcode(compoundOpcode); 234 CompoundInsn->addOperand(Rt); 235 CompoundInsn->addOperand(Rs); 236 CompoundInsn->addOperand(R.getOperand(0)); // Jump target. 237 238 break; 239 240 case Hexagon::C2_cmpeq: 241 DEBUG(dbgs() << "CX: C2_cmpeq\n"); 242 Rs = L.getOperand(1); 243 Rt = L.getOperand(2); 244 245 compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)]; 246 CompoundInsn = new (Context) MCInst; 247 CompoundInsn->setOpcode(compoundOpcode); 248 CompoundInsn->addOperand(Rs); 249 CompoundInsn->addOperand(Rt); 250 CompoundInsn->addOperand(R.getOperand(1)); 251 break; 252 253 case Hexagon::C2_cmpgt: 254 DEBUG(dbgs() << "CX: C2_cmpgt\n"); 255 Rs = L.getOperand(1); 256 Rt = L.getOperand(2); 257 258 compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)]; 259 CompoundInsn = new (Context) MCInst; 260 CompoundInsn->setOpcode(compoundOpcode); 261 CompoundInsn->addOperand(Rs); 262 CompoundInsn->addOperand(Rt); 263 CompoundInsn->addOperand(R.getOperand(1)); 264 break; 265 266 case Hexagon::C2_cmpgtu: 267 DEBUG(dbgs() << "CX: C2_cmpgtu\n"); 268 Rs = L.getOperand(1); 269 Rt = L.getOperand(2); 270 271 compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)]; 272 CompoundInsn = new (Context) MCInst; 273 CompoundInsn->setOpcode(compoundOpcode); 274 CompoundInsn->addOperand(Rs); 275 CompoundInsn->addOperand(Rt); 276 CompoundInsn->addOperand(R.getOperand(1)); 277 break; 278 279 case Hexagon::C2_cmpeqi: 280 DEBUG(dbgs() << "CX: C2_cmpeqi\n"); 281 Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value); 282 (void)Success; 283 assert(Success); 284 if (Value == -1) 285 compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)]; 286 else 287 compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)]; 288 289 Rs = L.getOperand(1); 290 CompoundInsn = new (Context) MCInst; 291 CompoundInsn->setOpcode(compoundOpcode); 292 CompoundInsn->addOperand(Rs); 293 if (Value != -1) 294 CompoundInsn->addOperand(L.getOperand(2)); 295 CompoundInsn->addOperand(R.getOperand(1)); 296 break; 297 298 case Hexagon::C2_cmpgti: 299 DEBUG(dbgs() << "CX: C2_cmpgti\n"); 300 Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value); 301 (void)Success; 302 assert(Success); 303 if (Value == -1) 304 compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)]; 305 else 306 compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)]; 307 308 Rs = L.getOperand(1); 309 CompoundInsn = new (Context) MCInst; 310 CompoundInsn->setOpcode(compoundOpcode); 311 CompoundInsn->addOperand(Rs); 312 if (Value != -1) 313 CompoundInsn->addOperand(L.getOperand(2)); 314 CompoundInsn->addOperand(R.getOperand(1)); 315 break; 316 317 case Hexagon::C2_cmpgtui: 318 DEBUG(dbgs() << "CX: C2_cmpgtui\n"); 319 Rs = L.getOperand(1); 320 compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)]; 321 CompoundInsn = new (Context) MCInst; 322 CompoundInsn->setOpcode(compoundOpcode); 323 CompoundInsn->addOperand(Rs); 324 CompoundInsn->addOperand(L.getOperand(2)); 325 CompoundInsn->addOperand(R.getOperand(1)); 326 break; 327 328 case Hexagon::S2_tstbit_i: 329 DEBUG(dbgs() << "CX: S2_tstbit_i\n"); 330 Rs = L.getOperand(1); 331 compoundOpcode = tstBitOpcode[getCompoundOp(R)]; 332 CompoundInsn = new (Context) MCInst; 333 CompoundInsn->setOpcode(compoundOpcode); 334 CompoundInsn->addOperand(Rs); 335 CompoundInsn->addOperand(R.getOperand(1)); 336 break; 337 } 338 339 return CompoundInsn; 340 } 341 } 342 343 /// Non-Symmetrical. See if these two instructions are fit for compound pair. 344 namespace { 345 bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA, 346 MCInst const &MIb, bool IsExtendedB) { 347 unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA); 348 unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB); 349 // We have two candidates - check that this is the same register 350 // we are talking about. 351 unsigned Opca = MIa.getOpcode(); 352 if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C && 353 (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi)) 354 return true; 355 return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) && 356 (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg())); 357 } 358 } 359 360 namespace { 361 bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) { 362 assert(HexagonMCInstrInfo::isBundle(MCI)); 363 bool JExtended = false; 364 for (MCInst::iterator J = 365 MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset; 366 J != MCI.end(); ++J) { 367 MCInst const *JumpInst = J->getInst(); 368 if (HexagonMCInstrInfo::isImmext(*JumpInst)) { 369 JExtended = true; 370 continue; 371 } 372 if (llvm::HexagonMCInstrInfo::getType(MCII, *JumpInst) == 373 HexagonII::TypeJ) { 374 // Try to pair with another insn (B)undled with jump. 375 bool BExtended = false; 376 for (MCInst::iterator B = 377 MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset; 378 B != MCI.end(); ++B) { 379 MCInst const *Inst = B->getInst(); 380 if (JumpInst == Inst) 381 continue; 382 if (HexagonMCInstrInfo::isImmext(*Inst)) { 383 BExtended = true; 384 continue; 385 } 386 DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << "," 387 << Inst->getOpcode() << "\n"); 388 if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) { 389 MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst); 390 if (CompoundInsn) { 391 DEBUG(dbgs() << "B: " << Inst->getOpcode() << "," 392 << JumpInst->getOpcode() << " Compounds to " 393 << CompoundInsn->getOpcode() << "\n"); 394 J->setInst(CompoundInsn); 395 MCI.erase(B); 396 return true; 397 } 398 } 399 BExtended = false; 400 } 401 } 402 JExtended = false; 403 } 404 return false; 405 } 406 } 407 408 /// tryCompound - Given a bundle check for compound insns when one 409 /// is found update the contents fo the bundle with the compound insn. 410 /// If a compound instruction is found then the bundle will have one 411 /// additional slot. 412 void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII, 413 MCContext &Context, MCInst &MCI) { 414 assert(HexagonMCInstrInfo::isBundle(MCI) && 415 "Non-Bundle where Bundle expected"); 416 417 // By definition a compound must have 2 insn. 418 if (MCI.size() < 2) 419 return; 420 421 // Look for compounds until none are found, only update the bundle when 422 // a compound is found. 423 while (lookForCompound(MCII, Context, MCI)) 424 ; 425 426 return; 427 } 428