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