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