1 //===- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions -------------===// 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 #include "MCTargetDesc/HexagonMCCodeEmitter.h" 10 #include "MCTargetDesc/HexagonBaseInfo.h" 11 #include "MCTargetDesc/HexagonFixupKinds.h" 12 #include "MCTargetDesc/HexagonMCExpr.h" 13 #include "MCTargetDesc/HexagonMCInstrInfo.h" 14 #include "MCTargetDesc/HexagonMCTargetDesc.h" 15 #include "llvm/ADT/Statistic.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCFixup.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCInstrDesc.h" 21 #include "llvm/MC/MCInstrInfo.h" 22 #include "llvm/MC/MCRegisterInfo.h" 23 #include "llvm/MC/MCSubtargetInfo.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/Compiler.h" 26 #include "llvm/Support/Debug.h" 27 #include "llvm/Support/EndianStream.h" 28 #include "llvm/Support/ErrorHandling.h" 29 #include "llvm/Support/raw_ostream.h" 30 #include <cassert> 31 #include <cstddef> 32 #include <cstdint> 33 #include <map> 34 #include <string> 35 #include <vector> 36 37 #define DEBUG_TYPE "mccodeemitter" 38 39 using namespace llvm; 40 using namespace Hexagon; 41 42 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 43 44 static const unsigned fixup_Invalid = ~0u; 45 46 #define _ fixup_Invalid 47 #define P(x) Hexagon::fixup_Hexagon##x 48 static const std::map<unsigned, std::vector<unsigned>> ExtFixups = { 49 { MCSymbolRefExpr::VK_DTPREL, 50 { _, _, _, _, 51 _, _, P(_DTPREL_16_X), P(_DTPREL_11_X), 52 P(_DTPREL_11_X), P(_9_X), _, P(_DTPREL_11_X), 53 P(_DTPREL_16_X), _, _, _, 54 P(_DTPREL_16_X), _, _, _, 55 _, _, _, _, 56 _, _, _, _, 57 _, _, _, _, 58 P(_DTPREL_32_6_X) }}, 59 { MCSymbolRefExpr::VK_GOT, 60 { _, _, _, _, 61 _, _, P(_GOT_11_X), _ /* [1] */, 62 _ /* [1] */, P(_9_X), _, P(_GOT_11_X), 63 P(_GOT_16_X), _, _, _, 64 P(_GOT_16_X), _, _, _, 65 _, _, _, _, 66 _, _, _, _, 67 _, _, _, _, 68 P(_GOT_32_6_X) }}, 69 { MCSymbolRefExpr::VK_GOTREL, 70 { _, _, _, _, 71 _, _, P(_GOTREL_11_X), P(_GOTREL_11_X), 72 P(_GOTREL_11_X), P(_9_X), _, P(_GOTREL_11_X), 73 P(_GOTREL_16_X), _, _, _, 74 P(_GOTREL_16_X), _, _, _, 75 _, _, _, _, 76 _, _, _, _, 77 _, _, _, _, 78 P(_GOTREL_32_6_X) }}, 79 { MCSymbolRefExpr::VK_TPREL, 80 { _, _, _, _, 81 _, _, P(_TPREL_16_X), P(_TPREL_11_X), 82 P(_TPREL_11_X), P(_9_X), _, P(_TPREL_11_X), 83 P(_TPREL_16_X), _, _, _, 84 P(_TPREL_16_X), _, _, _, 85 _, _, _, _, 86 _, _, _, _, 87 _, _, _, _, 88 P(_TPREL_32_6_X) }}, 89 { MCSymbolRefExpr::VK_Hexagon_GD_GOT, 90 { _, _, _, _, 91 _, _, P(_GD_GOT_16_X), P(_GD_GOT_11_X), 92 P(_GD_GOT_11_X), P(_9_X), _, P(_GD_GOT_11_X), 93 P(_GD_GOT_16_X), _, _, _, 94 P(_GD_GOT_16_X), _, _, _, 95 _, _, _, _, 96 _, _, _, _, 97 _, _, _, _, 98 P(_GD_GOT_32_6_X) }}, 99 { MCSymbolRefExpr::VK_Hexagon_GD_PLT, 100 { _, _, _, _, 101 _, _, _, _, 102 _, P(_9_X), _, P(_GD_PLT_B22_PCREL_X), 103 _, _, _, _, 104 _, _, _, _, 105 _, _, P(_GD_PLT_B22_PCREL_X), _, 106 _, _, _, _, 107 _, _, _, _, 108 _ }}, 109 { MCSymbolRefExpr::VK_Hexagon_IE, 110 { _, _, _, _, 111 _, _, P(_IE_16_X), _, 112 _, P(_9_X), _, _, 113 P(_IE_16_X), _, _, _, 114 P(_IE_16_X), _, _, _, 115 _, _, _, _, 116 _, _, _, _, 117 _, _, _, _, 118 P(_IE_32_6_X) }}, 119 { MCSymbolRefExpr::VK_Hexagon_IE_GOT, 120 { _, _, _, _, 121 _, _, P(_IE_GOT_11_X), P(_IE_GOT_11_X), 122 P(_IE_GOT_11_X), P(_9_X), _, P(_IE_GOT_11_X), 123 P(_IE_GOT_16_X), _, _, _, 124 P(_IE_GOT_16_X), _, _, _, 125 _, _, _, _, 126 _, _, _, _, 127 _, _, _, _, 128 P(_IE_GOT_32_6_X) }}, 129 { MCSymbolRefExpr::VK_Hexagon_LD_GOT, 130 { _, _, _, _, 131 _, _, P(_LD_GOT_11_X), P(_LD_GOT_11_X), 132 P(_LD_GOT_11_X), P(_9_X), _, P(_LD_GOT_11_X), 133 P(_LD_GOT_16_X), _, _, _, 134 P(_LD_GOT_16_X), _, _, _, 135 _, _, _, _, 136 _, _, _, _, 137 _, _, _, _, 138 P(_LD_GOT_32_6_X) }}, 139 { MCSymbolRefExpr::VK_Hexagon_LD_PLT, 140 { _, _, _, _, 141 _, _, _, _, 142 _, P(_9_X), _, P(_LD_PLT_B22_PCREL_X), 143 _, _, _, _, 144 _, _, _, _, 145 _, _, P(_LD_PLT_B22_PCREL_X), _, 146 _, _, _, _, 147 _, _, _, _, 148 _ }}, 149 { MCSymbolRefExpr::VK_PCREL, 150 { _, _, _, _, 151 _, _, P(_6_PCREL_X), _, 152 _, P(_9_X), _, _, 153 _, _, _, _, 154 _, _, _, _, 155 _, _, _, _, 156 _, _, _, _, 157 _, _, _, _, 158 P(_32_PCREL) }}, 159 { MCSymbolRefExpr::VK_None, 160 { _, _, _, _, 161 _, _, P(_6_X), P(_8_X), 162 P(_8_X), P(_9_X), P(_10_X), P(_11_X), 163 P(_12_X), P(_B13_PCREL), _, P(_B15_PCREL_X), 164 P(_16_X), _, _, _, 165 _, _, P(_B22_PCREL_X), _, 166 _, _, _, _, 167 _, _, _, _, 168 P(_32_6_X) }}, 169 }; 170 // [1] The fixup is GOT_16_X for signed values and GOT_11_X for unsigned. 171 172 static const std::map<unsigned, std::vector<unsigned>> StdFixups = { 173 { MCSymbolRefExpr::VK_DTPREL, 174 { _, _, _, _, 175 _, _, _, _, 176 _, _, _, _, 177 _, _, _, _, 178 P(_DTPREL_16), _, _, _, 179 _, _, _, _, 180 _, _, _, _, 181 _, _, _, _, 182 P(_DTPREL_32) }}, 183 { MCSymbolRefExpr::VK_GOT, 184 { _, _, _, _, 185 _, _, _, _, 186 _, _, _, _, 187 _, _, _, _, 188 _, _, _, _, 189 _, _, _, _, 190 _, _, _, _, 191 _, _, _, _, 192 P(_GOT_32) }}, 193 { MCSymbolRefExpr::VK_GOTREL, 194 { _, _, _, _, 195 _, _, _, _, 196 _, _, _, _, 197 _, _, _, _, 198 _ /* [2] */, _, _, _, 199 _, _, _, _, 200 _, _, _, _, 201 _, _, _, _, 202 P(_GOTREL_32) }}, 203 { MCSymbolRefExpr::VK_PLT, 204 { _, _, _, _, 205 _, _, _, _, 206 _, _, _, _, 207 _, _, _, _, 208 _, _, _, _, 209 _, _, P(_PLT_B22_PCREL), _, 210 _, _, _, _, 211 _, _, _, _, 212 _ }}, 213 { MCSymbolRefExpr::VK_TPREL, 214 { _, _, _, _, 215 _, _, _, _, 216 _, _, _, P(_TPREL_11_X), 217 _, _, _, _, 218 P(_TPREL_16), _, _, _, 219 _, _, _, _, 220 _, _, _, _, 221 _, _, _, _, 222 P(_TPREL_32) }}, 223 { MCSymbolRefExpr::VK_Hexagon_GD_GOT, 224 { _, _, _, _, 225 _, _, _, _, 226 _, _, _, _, 227 _, _, _, _, 228 P(_GD_GOT_16), _, _, _, 229 _, _, _, _, 230 _, _, _, _, 231 _, _, _, _, 232 P(_GD_GOT_32) }}, 233 { MCSymbolRefExpr::VK_Hexagon_GD_PLT, 234 { _, _, _, _, 235 _, _, _, _, 236 _, _, _, _, 237 _, _, _, _, 238 _, _, _, _, 239 _, _, P(_GD_PLT_B22_PCREL), _, 240 _, _, _, _, 241 _, _, _, _, 242 _ }}, 243 { MCSymbolRefExpr::VK_Hexagon_GPREL, 244 { _, _, _, _, 245 _, _, _, _, 246 _, _, _, _, 247 _, _, _, _, 248 P(_GPREL16_0), _, _, _, 249 _, _, _, _, 250 _, _, _, _, 251 _, _, _, _, 252 _ }}, 253 { MCSymbolRefExpr::VK_Hexagon_HI16, 254 { _, _, _, _, 255 _, _, _, _, 256 _, _, _, _, 257 _, _, _, _, 258 P(_HI16), _, _, _, 259 _, _, _, _, 260 _, _, _, _, 261 _, _, _, _, 262 _ }}, 263 { MCSymbolRefExpr::VK_Hexagon_IE, 264 { _, _, _, _, 265 _, _, _, _, 266 _, _, _, _, 267 _, _, _, _, 268 _, _, _, _, 269 _, _, _, _, 270 _, _, _, _, 271 _, _, _, _, 272 P(_IE_32) }}, 273 { MCSymbolRefExpr::VK_Hexagon_IE_GOT, 274 { _, _, _, _, 275 _, _, _, _, 276 _, _, _, _, 277 _, _, _, _, 278 P(_IE_GOT_16), _, _, _, 279 _, _, _, _, 280 _, _, _, _, 281 _, _, _, _, 282 P(_IE_GOT_32) }}, 283 { MCSymbolRefExpr::VK_Hexagon_LD_GOT, 284 { _, _, _, _, 285 _, _, _, _, 286 _, _, _, _, 287 _, _, _, _, 288 P(_LD_GOT_16), _, _, _, 289 _, _, _, _, 290 _, _, _, _, 291 _, _, _, _, 292 P(_LD_GOT_32) }}, 293 { MCSymbolRefExpr::VK_Hexagon_LD_PLT, 294 { _, _, _, _, 295 _, _, _, _, 296 _, _, _, _, 297 _, _, _, _, 298 _, _, _, _, 299 _, _, P(_LD_PLT_B22_PCREL), _, 300 _, _, _, _, 301 _, _, _, _, 302 _ }}, 303 { MCSymbolRefExpr::VK_Hexagon_LO16, 304 { _, _, _, _, 305 _, _, _, _, 306 _, _, _, _, 307 _, _, _, _, 308 P(_LO16), _, _, _, 309 _, _, _, _, 310 _, _, _, _, 311 _, _, _, _, 312 _ }}, 313 { MCSymbolRefExpr::VK_PCREL, 314 { _, _, _, _, 315 _, _, _, _, 316 _, _, _, _, 317 _, _, _, _, 318 _, _, _, _, 319 _, _, _, _, 320 _, _, _, _, 321 _, _, _, _, 322 P(_32_PCREL) }}, 323 { MCSymbolRefExpr::VK_None, 324 { _, _, _, _, 325 _, _, _, _, 326 _, _, _, _, 327 _, P(_B13_PCREL), _, P(_B15_PCREL), 328 _, _, _, _, 329 _, _, P(_B22_PCREL), _, 330 _, _, _, _, 331 _, _, _, _, 332 P(_32) }}, 333 }; 334 // 335 // [2] The actual fixup is LO16 or HI16, depending on the instruction. 336 #undef P 337 #undef _ 338 339 uint32_t HexagonMCCodeEmitter::parseBits(size_t Last, MCInst const &MCB, 340 MCInst const &MCI) const { 341 bool Duplex = HexagonMCInstrInfo::isDuplex(MCII, MCI); 342 if (State.Index == 0) { 343 if (HexagonMCInstrInfo::isInnerLoop(MCB)) { 344 assert(!Duplex); 345 assert(State.Index != Last); 346 return HexagonII::INST_PARSE_LOOP_END; 347 } 348 } 349 if (State.Index == 1) { 350 if (HexagonMCInstrInfo::isOuterLoop(MCB)) { 351 assert(!Duplex); 352 assert(State.Index != Last); 353 return HexagonII::INST_PARSE_LOOP_END; 354 } 355 } 356 if (Duplex) { 357 assert(State.Index == Last); 358 return HexagonII::INST_PARSE_DUPLEX; 359 } 360 if (State.Index == Last) 361 return HexagonII::INST_PARSE_PACKET_END; 362 return HexagonII::INST_PARSE_NOT_END; 363 } 364 365 /// Emit the bundle. 366 void HexagonMCCodeEmitter::encodeInstruction(const MCInst &MI, 367 SmallVectorImpl<char> &CB, 368 SmallVectorImpl<MCFixup> &Fixups, 369 const MCSubtargetInfo &STI) const { 370 MCInst &HMB = const_cast<MCInst &>(MI); 371 372 assert(HexagonMCInstrInfo::isBundle(HMB)); 373 LLVM_DEBUG(dbgs() << "Encoding bundle\n";); 374 State.Addend = 0; 375 State.Extended = false; 376 State.Bundle = &MI; 377 State.Index = 0; 378 size_t Last = HexagonMCInstrInfo::bundleSize(HMB) - 1; 379 380 for (auto &I : HexagonMCInstrInfo::bundleInstructions(HMB)) { 381 MCInst &HMI = const_cast<MCInst &>(*I.getInst()); 382 383 encodeSingleInstruction(HMI, CB, Fixups, STI, parseBits(Last, HMB, HMI)); 384 State.Extended = HexagonMCInstrInfo::isImmext(HMI); 385 State.Addend += HEXAGON_INSTR_SIZE; 386 ++State.Index; 387 } 388 } 389 390 static bool RegisterMatches(MCRegister Consumer, MCRegister Producer, 391 MCRegister Producer2) { 392 return (Consumer == Producer) || (Consumer == Producer2) || 393 HexagonMCInstrInfo::IsSingleConsumerRefPairProducer(Producer, 394 Consumer); 395 } 396 397 void HexagonMCCodeEmitter::encodeSingleInstruction( 398 const MCInst &MI, SmallVectorImpl<char> &CB, 399 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI, 400 uint32_t Parse) const { 401 assert(!HexagonMCInstrInfo::isBundle(MI)); 402 uint64_t Binary; 403 404 // Pseudo instructions don't get encoded and shouldn't be here 405 // in the first place! 406 assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo() && 407 "pseudo-instruction found"); 408 LLVM_DEBUG(dbgs() << "Encoding insn `" 409 << HexagonMCInstrInfo::getName(MCII, MI) << "'\n"); 410 411 Binary = getBinaryCodeForInstr(MI, Fixups, STI); 412 unsigned Opc = MI.getOpcode(); 413 414 // Check for unimplemented instructions. Immediate extenders 415 // are encoded as zero, so they need to be accounted for. 416 if (!Binary && Opc != DuplexIClass0 && Opc != A4_ext) { 417 LLVM_DEBUG(dbgs() << "Unimplemented inst `" 418 << HexagonMCInstrInfo::getName(MCII, MI) << "'\n"); 419 llvm_unreachable("Unimplemented Instruction"); 420 } 421 Binary |= Parse; 422 423 // if we need to emit a duplexed instruction 424 if (Opc >= Hexagon::DuplexIClass0 && Opc <= Hexagon::DuplexIClassF) { 425 assert(Parse == HexagonII::INST_PARSE_DUPLEX && 426 "Emitting duplex without duplex parse bits"); 427 unsigned DupIClass = MI.getOpcode() - Hexagon::DuplexIClass0; 428 // 29 is the bit position. 429 // 0b1110 =0xE bits are masked off and down shifted by 1 bit. 430 // Last bit is moved to bit position 13 431 Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13); 432 433 const MCInst *Sub0 = MI.getOperand(0).getInst(); 434 const MCInst *Sub1 = MI.getOperand(1).getInst(); 435 436 // Get subinstruction slot 0. 437 unsigned SubBits0 = getBinaryCodeForInstr(*Sub0, Fixups, STI); 438 // Get subinstruction slot 1. 439 State.SubInst1 = true; 440 unsigned SubBits1 = getBinaryCodeForInstr(*Sub1, Fixups, STI); 441 State.SubInst1 = false; 442 443 Binary |= SubBits0 | (SubBits1 << 16); 444 } 445 support::endian::write<uint32_t>(CB, Binary, llvm::endianness::little); 446 ++MCNumEmitted; 447 } 448 449 [[noreturn]] static void raise_relocation_error(unsigned Width, unsigned Kind) { 450 std::string Text; 451 raw_string_ostream Stream(Text); 452 Stream << "Unrecognized relocation combination: width=" << Width 453 << " kind=" << Kind; 454 report_fatal_error(Twine(Stream.str())); 455 } 456 457 /// Some insns are not extended and thus have no bits. These cases require 458 /// a more brute force method for determining the correct relocation. 459 Hexagon::Fixups HexagonMCCodeEmitter::getFixupNoBits( 460 MCInstrInfo const &MCII, const MCInst &MI, const MCOperand &MO, 461 const MCSymbolRefExpr::VariantKind VarKind) const { 462 const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI); 463 unsigned InsnType = HexagonMCInstrInfo::getType(MCII, MI); 464 using namespace Hexagon; 465 466 if (InsnType == HexagonII::TypeEXTENDER) { 467 if (VarKind == MCSymbolRefExpr::VK_None) { 468 auto Instrs = HexagonMCInstrInfo::bundleInstructions(*State.Bundle); 469 for (auto I = Instrs.begin(), N = Instrs.end(); I != N; ++I) { 470 if (I->getInst() != &MI) 471 continue; 472 assert(I+1 != N && "Extender cannot be last in packet"); 473 const MCInst &NextI = *(I+1)->getInst(); 474 const MCInstrDesc &NextD = HexagonMCInstrInfo::getDesc(MCII, NextI); 475 if (NextD.isBranch() || NextD.isCall() || 476 HexagonMCInstrInfo::getType(MCII, NextI) == HexagonII::TypeCR) 477 return fixup_Hexagon_B32_PCREL_X; 478 return fixup_Hexagon_32_6_X; 479 } 480 } 481 482 static const std::map<unsigned,unsigned> Relocs = { 483 { MCSymbolRefExpr::VK_GOTREL, fixup_Hexagon_GOTREL_32_6_X }, 484 { MCSymbolRefExpr::VK_GOT, fixup_Hexagon_GOT_32_6_X }, 485 { MCSymbolRefExpr::VK_TPREL, fixup_Hexagon_TPREL_32_6_X }, 486 { MCSymbolRefExpr::VK_DTPREL, fixup_Hexagon_DTPREL_32_6_X }, 487 { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_32_6_X }, 488 { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_32_6_X }, 489 { MCSymbolRefExpr::VK_Hexagon_IE, fixup_Hexagon_IE_32_6_X }, 490 { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_32_6_X }, 491 { MCSymbolRefExpr::VK_PCREL, fixup_Hexagon_B32_PCREL_X }, 492 { MCSymbolRefExpr::VK_Hexagon_GD_PLT, fixup_Hexagon_GD_PLT_B32_PCREL_X }, 493 { MCSymbolRefExpr::VK_Hexagon_LD_PLT, fixup_Hexagon_LD_PLT_B32_PCREL_X }, 494 }; 495 496 auto F = Relocs.find(VarKind); 497 if (F != Relocs.end()) 498 return Hexagon::Fixups(F->second); 499 raise_relocation_error(0, VarKind); 500 } 501 502 if (MCID.isBranch()) 503 return fixup_Hexagon_B13_PCREL; 504 505 static const std::map<unsigned,unsigned> RelocsLo = { 506 { MCSymbolRefExpr::VK_GOT, fixup_Hexagon_GOT_LO16 }, 507 { MCSymbolRefExpr::VK_GOTREL, fixup_Hexagon_GOTREL_LO16 }, 508 { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_LO16 }, 509 { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_LO16 }, 510 { MCSymbolRefExpr::VK_Hexagon_IE, fixup_Hexagon_IE_LO16 }, 511 { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_LO16 }, 512 { MCSymbolRefExpr::VK_TPREL, fixup_Hexagon_TPREL_LO16 }, 513 { MCSymbolRefExpr::VK_DTPREL, fixup_Hexagon_DTPREL_LO16 }, 514 { MCSymbolRefExpr::VK_None, fixup_Hexagon_LO16 }, 515 }; 516 517 static const std::map<unsigned,unsigned> RelocsHi = { 518 { MCSymbolRefExpr::VK_GOT, fixup_Hexagon_GOT_HI16 }, 519 { MCSymbolRefExpr::VK_GOTREL, fixup_Hexagon_GOTREL_HI16 }, 520 { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_HI16 }, 521 { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_HI16 }, 522 { MCSymbolRefExpr::VK_Hexagon_IE, fixup_Hexagon_IE_HI16 }, 523 { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_HI16 }, 524 { MCSymbolRefExpr::VK_TPREL, fixup_Hexagon_TPREL_HI16 }, 525 { MCSymbolRefExpr::VK_DTPREL, fixup_Hexagon_DTPREL_HI16 }, 526 { MCSymbolRefExpr::VK_None, fixup_Hexagon_HI16 }, 527 }; 528 529 switch (MCID.getOpcode()) { 530 case Hexagon::LO: 531 case Hexagon::A2_tfril: { 532 auto F = RelocsLo.find(VarKind); 533 if (F != RelocsLo.end()) 534 return Hexagon::Fixups(F->second); 535 break; 536 } 537 case Hexagon::HI: 538 case Hexagon::A2_tfrih: { 539 auto F = RelocsHi.find(VarKind); 540 if (F != RelocsHi.end()) 541 return Hexagon::Fixups(F->second); 542 break; 543 } 544 } 545 546 raise_relocation_error(0, VarKind); 547 } 548 549 static bool isPCRel(unsigned Kind) { 550 switch (Kind){ 551 case fixup_Hexagon_B22_PCREL: 552 case fixup_Hexagon_B15_PCREL: 553 case fixup_Hexagon_B7_PCREL: 554 case fixup_Hexagon_B13_PCREL: 555 case fixup_Hexagon_B9_PCREL: 556 case fixup_Hexagon_B32_PCREL_X: 557 case fixup_Hexagon_B22_PCREL_X: 558 case fixup_Hexagon_B15_PCREL_X: 559 case fixup_Hexagon_B13_PCREL_X: 560 case fixup_Hexagon_B9_PCREL_X: 561 case fixup_Hexagon_B7_PCREL_X: 562 case fixup_Hexagon_32_PCREL: 563 case fixup_Hexagon_PLT_B22_PCREL: 564 case fixup_Hexagon_GD_PLT_B22_PCREL: 565 case fixup_Hexagon_LD_PLT_B22_PCREL: 566 case fixup_Hexagon_GD_PLT_B22_PCREL_X: 567 case fixup_Hexagon_LD_PLT_B22_PCREL_X: 568 case fixup_Hexagon_6_PCREL_X: 569 return true; 570 default: 571 return false; 572 } 573 } 574 575 unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI, 576 const MCOperand &MO, const MCExpr *ME, SmallVectorImpl<MCFixup> &Fixups, 577 const MCSubtargetInfo &STI) const { 578 if (isa<HexagonMCExpr>(ME)) 579 ME = &HexagonMCInstrInfo::getExpr(*ME); 580 int64_t Value; 581 if (ME->evaluateAsAbsolute(Value)) { 582 bool InstExtendable = HexagonMCInstrInfo::isExtendable(MCII, MI) || 583 HexagonMCInstrInfo::isExtended(MCII, MI); 584 // Only sub-instruction #1 can be extended in a duplex. If MI is a 585 // sub-instruction #0, it is not extended even if Extended is true 586 // (it can be true for the duplex as a whole). 587 bool IsSub0 = HexagonMCInstrInfo::isSubInstruction(MI) && !State.SubInst1; 588 if (State.Extended && InstExtendable && !IsSub0) { 589 unsigned OpIdx = ~0u; 590 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) { 591 if (&MO != &MI.getOperand(I)) 592 continue; 593 OpIdx = I; 594 break; 595 } 596 assert(OpIdx != ~0u); 597 if (OpIdx == HexagonMCInstrInfo::getExtendableOp(MCII, MI)) { 598 unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MI); 599 Value = (Value & 0x3f) << Shift; 600 } 601 } 602 return Value; 603 } 604 assert(ME->getKind() == MCExpr::SymbolRef || 605 ME->getKind() == MCExpr::Binary); 606 if (ME->getKind() == MCExpr::Binary) { 607 MCBinaryExpr const *Binary = cast<MCBinaryExpr>(ME); 608 getExprOpValue(MI, MO, Binary->getLHS(), Fixups, STI); 609 getExprOpValue(MI, MO, Binary->getRHS(), Fixups, STI); 610 return 0; 611 } 612 613 unsigned FixupKind = fixup_Invalid; 614 const MCSymbolRefExpr *MCSRE = static_cast<const MCSymbolRefExpr *>(ME); 615 const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI); 616 unsigned FixupWidth = HexagonMCInstrInfo::getExtentBits(MCII, MI) - 617 HexagonMCInstrInfo::getExtentAlignment(MCII, MI); 618 MCSymbolRefExpr::VariantKind VarKind = MCSRE->getKind(); 619 unsigned Opc = MCID.getOpcode(); 620 unsigned IType = HexagonMCInstrInfo::getType(MCII, MI); 621 622 LLVM_DEBUG(dbgs() << "----------------------------------------\n" 623 << "Opcode Name: " << HexagonMCInstrInfo::getName(MCII, MI) 624 << "\nOpcode: " << Opc << "\nRelocation bits: " 625 << FixupWidth << "\nAddend: " << State.Addend 626 << "\nVariant: " << unsigned(VarKind) 627 << "\n----------------------------------------\n"); 628 629 // Pick the applicable fixup kind for the symbol. 630 // Handle special cases first, the rest will be looked up in the tables. 631 632 if (FixupWidth == 16 && !State.Extended) { 633 if (VarKind == MCSymbolRefExpr::VK_None) { 634 if (HexagonMCInstrInfo::s27_2_reloc(*MO.getExpr())) { 635 // A2_iconst. 636 FixupKind = Hexagon::fixup_Hexagon_27_REG; 637 } else { 638 // Look for GP-relative fixups. 639 unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MI); 640 static const Hexagon::Fixups GPRelFixups[] = { 641 Hexagon::fixup_Hexagon_GPREL16_0, Hexagon::fixup_Hexagon_GPREL16_1, 642 Hexagon::fixup_Hexagon_GPREL16_2, Hexagon::fixup_Hexagon_GPREL16_3 643 }; 644 assert(Shift < std::size(GPRelFixups)); 645 auto UsesGP = [](const MCInstrDesc &D) { 646 return is_contained(D.implicit_uses(), Hexagon::GP); 647 }; 648 if (UsesGP(MCID)) 649 FixupKind = GPRelFixups[Shift]; 650 } 651 } else if (VarKind == MCSymbolRefExpr::VK_GOTREL) { 652 // Select between LO/HI. 653 if (Opc == Hexagon::LO) 654 FixupKind = Hexagon::fixup_Hexagon_GOTREL_LO16; 655 else if (Opc == Hexagon::HI) 656 FixupKind = Hexagon::fixup_Hexagon_GOTREL_HI16; 657 } 658 } else { 659 bool BranchOrCR = MCID.isBranch() || IType == HexagonII::TypeCR; 660 switch (FixupWidth) { 661 case 9: 662 if (BranchOrCR) 663 FixupKind = State.Extended ? Hexagon::fixup_Hexagon_B9_PCREL_X 664 : Hexagon::fixup_Hexagon_B9_PCREL; 665 break; 666 case 8: 667 case 7: 668 if (State.Extended && VarKind == MCSymbolRefExpr::VK_GOT) 669 FixupKind = HexagonMCInstrInfo::isExtentSigned(MCII, MI) 670 ? Hexagon::fixup_Hexagon_GOT_16_X 671 : Hexagon::fixup_Hexagon_GOT_11_X; 672 else if (FixupWidth == 7 && BranchOrCR) 673 FixupKind = State.Extended ? Hexagon::fixup_Hexagon_B7_PCREL_X 674 : Hexagon::fixup_Hexagon_B7_PCREL; 675 break; 676 case 0: 677 FixupKind = getFixupNoBits(MCII, MI, MO, VarKind); 678 break; 679 } 680 } 681 682 if (FixupKind == fixup_Invalid) { 683 const auto &FixupTable = State.Extended ? ExtFixups : StdFixups; 684 685 auto FindVK = FixupTable.find(VarKind); 686 if (FindVK != FixupTable.end()) 687 FixupKind = FindVK->second[FixupWidth]; 688 } 689 690 if (FixupKind == fixup_Invalid) 691 raise_relocation_error(FixupWidth, VarKind); 692 693 const MCExpr *FixupExpr = MO.getExpr(); 694 if (State.Addend != 0 && isPCRel(FixupKind)) { 695 const MCExpr *C = MCConstantExpr::create(State.Addend, MCT); 696 FixupExpr = MCBinaryExpr::createAdd(FixupExpr, C, MCT); 697 } 698 699 MCFixup Fixup = MCFixup::create(State.Addend, FixupExpr, 700 MCFixupKind(FixupKind), MI.getLoc()); 701 Fixups.push_back(Fixup); 702 // All of the information is in the fixup. 703 return 0; 704 } 705 706 unsigned 707 HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO, 708 SmallVectorImpl<MCFixup> &Fixups, 709 MCSubtargetInfo const &STI) const { 710 size_t OperandNumber = ~0U; 711 for (unsigned i = 0, n = MI.getNumOperands(); i < n; ++i) 712 if (&MI.getOperand(i) == &MO) { 713 OperandNumber = i; 714 break; 715 } 716 assert((OperandNumber != ~0U) && "Operand not found"); 717 718 if (HexagonMCInstrInfo::isNewValue(MCII, MI) && 719 &MO == &HexagonMCInstrInfo::getNewValueOperand(MCII, MI)) { 720 // Calculate the new value distance to the associated producer 721 unsigned SOffset = 0; 722 unsigned VOffset = 0; 723 MCRegister UseReg = MO.getReg(); 724 MCRegister DefReg1; 725 MCRegister DefReg2; 726 727 auto Instrs = HexagonMCInstrInfo::bundleInstructions(*State.Bundle); 728 const MCOperand *I = Instrs.begin() + State.Index - 1; 729 730 for (;; --I) { 731 assert(I != Instrs.begin() - 1 && "Couldn't find producer"); 732 MCInst const &Inst = *I->getInst(); 733 if (HexagonMCInstrInfo::isImmext(Inst)) 734 continue; 735 736 DefReg1 = MCRegister(); 737 DefReg2 = MCRegister(); 738 ++SOffset; 739 if (HexagonMCInstrInfo::isVector(MCII, Inst)) { 740 // Vector instructions don't count scalars. 741 ++VOffset; 742 } 743 if (HexagonMCInstrInfo::hasNewValue(MCII, Inst)) 744 DefReg1 = HexagonMCInstrInfo::getNewValueOperand(MCII, Inst).getReg(); 745 if (HexagonMCInstrInfo::hasNewValue2(MCII, Inst)) 746 DefReg2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, Inst).getReg(); 747 if (!RegisterMatches(UseReg, DefReg1, DefReg2)) { 748 // This isn't the register we're looking for 749 continue; 750 } 751 if (!HexagonMCInstrInfo::isPredicated(MCII, Inst)) { 752 // Producer is unpredicated 753 break; 754 } 755 assert(HexagonMCInstrInfo::isPredicated(MCII, MI) && 756 "Unpredicated consumer depending on predicated producer"); 757 if (HexagonMCInstrInfo::isPredicatedTrue(MCII, Inst) == 758 HexagonMCInstrInfo::isPredicatedTrue(MCII, MI)) 759 // Producer predicate sense matched ours. 760 break; 761 } 762 // Hexagon PRM 10.11 Construct Nt from distance 763 unsigned Offset = HexagonMCInstrInfo::isVector(MCII, MI) ? VOffset 764 : SOffset; 765 Offset <<= 1; 766 Offset |= HexagonMCInstrInfo::SubregisterBit(UseReg, DefReg1, DefReg2); 767 return Offset; 768 } 769 770 assert(!MO.isImm()); 771 if (MO.isReg()) { 772 MCRegister Reg = MO.getReg(); 773 switch (HexagonMCInstrInfo::getDesc(MCII, MI) 774 .operands()[OperandNumber] 775 .RegClass) { 776 case GeneralSubRegsRegClassID: 777 case GeneralDoubleLow8RegsRegClassID: 778 return HexagonMCInstrInfo::getDuplexRegisterNumbering(Reg); 779 default: 780 break; 781 } 782 return MCT.getRegisterInfo()->getEncodingValue(Reg); 783 } 784 785 return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI); 786 } 787 788 MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII, 789 MCContext &MCT) { 790 return new HexagonMCCodeEmitter(MII, MCT); 791 } 792 793 #include "HexagonGenMCCodeEmitter.inc" 794