109467b48Spatrick //===- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions -------------===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick 909467b48Spatrick #include "MCTargetDesc/HexagonMCCodeEmitter.h" 1009467b48Spatrick #include "MCTargetDesc/HexagonBaseInfo.h" 1109467b48Spatrick #include "MCTargetDesc/HexagonFixupKinds.h" 1209467b48Spatrick #include "MCTargetDesc/HexagonMCExpr.h" 1309467b48Spatrick #include "MCTargetDesc/HexagonMCInstrInfo.h" 1409467b48Spatrick #include "MCTargetDesc/HexagonMCTargetDesc.h" 1509467b48Spatrick #include "llvm/ADT/Statistic.h" 1609467b48Spatrick #include "llvm/MC/MCContext.h" 1709467b48Spatrick #include "llvm/MC/MCExpr.h" 1809467b48Spatrick #include "llvm/MC/MCFixup.h" 1909467b48Spatrick #include "llvm/MC/MCInst.h" 2009467b48Spatrick #include "llvm/MC/MCInstrDesc.h" 2109467b48Spatrick #include "llvm/MC/MCInstrInfo.h" 2209467b48Spatrick #include "llvm/MC/MCRegisterInfo.h" 2309467b48Spatrick #include "llvm/MC/MCSubtargetInfo.h" 2409467b48Spatrick #include "llvm/Support/Casting.h" 2509467b48Spatrick #include "llvm/Support/Compiler.h" 2609467b48Spatrick #include "llvm/Support/Debug.h" 2709467b48Spatrick #include "llvm/Support/Endian.h" 2809467b48Spatrick #include "llvm/Support/EndianStream.h" 2909467b48Spatrick #include "llvm/Support/ErrorHandling.h" 3009467b48Spatrick #include "llvm/Support/raw_ostream.h" 3109467b48Spatrick #include <cassert> 3209467b48Spatrick #include <cstddef> 3309467b48Spatrick #include <cstdint> 3409467b48Spatrick #include <map> 3509467b48Spatrick #include <string> 3609467b48Spatrick #include <vector> 3709467b48Spatrick 3809467b48Spatrick #define DEBUG_TYPE "mccodeemitter" 3909467b48Spatrick 4009467b48Spatrick using namespace llvm; 4109467b48Spatrick using namespace Hexagon; 4209467b48Spatrick 4309467b48Spatrick STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 4409467b48Spatrick 4509467b48Spatrick static const unsigned fixup_Invalid = ~0u; 4609467b48Spatrick 4709467b48Spatrick #define _ fixup_Invalid 4809467b48Spatrick #define P(x) Hexagon::fixup_Hexagon##x 4909467b48Spatrick static const std::map<unsigned, std::vector<unsigned>> ExtFixups = { 5009467b48Spatrick { MCSymbolRefExpr::VK_DTPREL, 5109467b48Spatrick { _, _, _, _, 5209467b48Spatrick _, _, P(_DTPREL_16_X), P(_DTPREL_11_X), 5309467b48Spatrick P(_DTPREL_11_X), P(_9_X), _, P(_DTPREL_11_X), 5409467b48Spatrick P(_DTPREL_16_X), _, _, _, 5509467b48Spatrick P(_DTPREL_16_X), _, _, _, 5609467b48Spatrick _, _, _, _, 5709467b48Spatrick _, _, _, _, 5809467b48Spatrick _, _, _, _, 5909467b48Spatrick P(_DTPREL_32_6_X) }}, 6009467b48Spatrick { MCSymbolRefExpr::VK_GOT, 6109467b48Spatrick { _, _, _, _, 6209467b48Spatrick _, _, P(_GOT_11_X), _ /* [1] */, 6309467b48Spatrick _ /* [1] */, P(_9_X), _, P(_GOT_11_X), 6409467b48Spatrick P(_GOT_16_X), _, _, _, 6509467b48Spatrick P(_GOT_16_X), _, _, _, 6609467b48Spatrick _, _, _, _, 6709467b48Spatrick _, _, _, _, 6809467b48Spatrick _, _, _, _, 6909467b48Spatrick P(_GOT_32_6_X) }}, 7009467b48Spatrick { MCSymbolRefExpr::VK_GOTREL, 7109467b48Spatrick { _, _, _, _, 7209467b48Spatrick _, _, P(_GOTREL_11_X), P(_GOTREL_11_X), 7309467b48Spatrick P(_GOTREL_11_X), P(_9_X), _, P(_GOTREL_11_X), 7409467b48Spatrick P(_GOTREL_16_X), _, _, _, 7509467b48Spatrick P(_GOTREL_16_X), _, _, _, 7609467b48Spatrick _, _, _, _, 7709467b48Spatrick _, _, _, _, 7809467b48Spatrick _, _, _, _, 7909467b48Spatrick P(_GOTREL_32_6_X) }}, 8009467b48Spatrick { MCSymbolRefExpr::VK_TPREL, 8109467b48Spatrick { _, _, _, _, 8209467b48Spatrick _, _, P(_TPREL_16_X), P(_TPREL_11_X), 8309467b48Spatrick P(_TPREL_11_X), P(_9_X), _, P(_TPREL_11_X), 8409467b48Spatrick P(_TPREL_16_X), _, _, _, 8509467b48Spatrick P(_TPREL_16_X), _, _, _, 8609467b48Spatrick _, _, _, _, 8709467b48Spatrick _, _, _, _, 8809467b48Spatrick _, _, _, _, 8909467b48Spatrick P(_TPREL_32_6_X) }}, 9009467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_GD_GOT, 9109467b48Spatrick { _, _, _, _, 9209467b48Spatrick _, _, P(_GD_GOT_16_X), P(_GD_GOT_11_X), 9309467b48Spatrick P(_GD_GOT_11_X), P(_9_X), _, P(_GD_GOT_11_X), 9409467b48Spatrick P(_GD_GOT_16_X), _, _, _, 9509467b48Spatrick P(_GD_GOT_16_X), _, _, _, 9609467b48Spatrick _, _, _, _, 9709467b48Spatrick _, _, _, _, 9809467b48Spatrick _, _, _, _, 9909467b48Spatrick P(_GD_GOT_32_6_X) }}, 10009467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_GD_PLT, 10109467b48Spatrick { _, _, _, _, 10209467b48Spatrick _, _, _, _, 10309467b48Spatrick _, P(_9_X), _, P(_GD_PLT_B22_PCREL_X), 10409467b48Spatrick _, _, _, _, 10509467b48Spatrick _, _, _, _, 10609467b48Spatrick _, _, P(_GD_PLT_B22_PCREL_X), _, 10709467b48Spatrick _, _, _, _, 10809467b48Spatrick _, _, _, _, 10909467b48Spatrick _ }}, 11009467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE, 11109467b48Spatrick { _, _, _, _, 11209467b48Spatrick _, _, P(_IE_16_X), _, 11309467b48Spatrick _, P(_9_X), _, _, 11409467b48Spatrick P(_IE_16_X), _, _, _, 11509467b48Spatrick P(_IE_16_X), _, _, _, 11609467b48Spatrick _, _, _, _, 11709467b48Spatrick _, _, _, _, 11809467b48Spatrick _, _, _, _, 11909467b48Spatrick P(_IE_32_6_X) }}, 12009467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE_GOT, 12109467b48Spatrick { _, _, _, _, 12209467b48Spatrick _, _, P(_IE_GOT_11_X), P(_IE_GOT_11_X), 12309467b48Spatrick P(_IE_GOT_11_X), P(_9_X), _, P(_IE_GOT_11_X), 12409467b48Spatrick P(_IE_GOT_16_X), _, _, _, 12509467b48Spatrick P(_IE_GOT_16_X), _, _, _, 12609467b48Spatrick _, _, _, _, 12709467b48Spatrick _, _, _, _, 12809467b48Spatrick _, _, _, _, 12909467b48Spatrick P(_IE_GOT_32_6_X) }}, 13009467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_LD_GOT, 13109467b48Spatrick { _, _, _, _, 13209467b48Spatrick _, _, P(_LD_GOT_11_X), P(_LD_GOT_11_X), 13309467b48Spatrick P(_LD_GOT_11_X), P(_9_X), _, P(_LD_GOT_11_X), 13409467b48Spatrick P(_LD_GOT_16_X), _, _, _, 13509467b48Spatrick P(_LD_GOT_16_X), _, _, _, 13609467b48Spatrick _, _, _, _, 13709467b48Spatrick _, _, _, _, 13809467b48Spatrick _, _, _, _, 13909467b48Spatrick P(_LD_GOT_32_6_X) }}, 14009467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_LD_PLT, 14109467b48Spatrick { _, _, _, _, 14209467b48Spatrick _, _, _, _, 14309467b48Spatrick _, P(_9_X), _, P(_LD_PLT_B22_PCREL_X), 14409467b48Spatrick _, _, _, _, 14509467b48Spatrick _, _, _, _, 14609467b48Spatrick _, _, P(_LD_PLT_B22_PCREL_X), _, 14709467b48Spatrick _, _, _, _, 14809467b48Spatrick _, _, _, _, 14909467b48Spatrick _ }}, 150*097a140dSpatrick { MCSymbolRefExpr::VK_PCREL, 15109467b48Spatrick { _, _, _, _, 15209467b48Spatrick _, _, P(_6_PCREL_X), _, 15309467b48Spatrick _, P(_9_X), _, _, 15409467b48Spatrick _, _, _, _, 15509467b48Spatrick _, _, _, _, 15609467b48Spatrick _, _, _, _, 15709467b48Spatrick _, _, _, _, 15809467b48Spatrick _, _, _, _, 15909467b48Spatrick P(_32_PCREL) }}, 16009467b48Spatrick { MCSymbolRefExpr::VK_None, 16109467b48Spatrick { _, _, _, _, 16209467b48Spatrick _, _, P(_6_X), P(_8_X), 16309467b48Spatrick P(_8_X), P(_9_X), P(_10_X), P(_11_X), 16409467b48Spatrick P(_12_X), P(_B13_PCREL), _, P(_B15_PCREL_X), 16509467b48Spatrick P(_16_X), _, _, _, 16609467b48Spatrick _, _, P(_B22_PCREL_X), _, 16709467b48Spatrick _, _, _, _, 16809467b48Spatrick _, _, _, _, 16909467b48Spatrick P(_32_6_X) }}, 17009467b48Spatrick }; 17109467b48Spatrick // [1] The fixup is GOT_16_X for signed values and GOT_11_X for unsigned. 17209467b48Spatrick 17309467b48Spatrick static const std::map<unsigned, std::vector<unsigned>> StdFixups = { 17409467b48Spatrick { MCSymbolRefExpr::VK_DTPREL, 17509467b48Spatrick { _, _, _, _, 17609467b48Spatrick _, _, _, _, 17709467b48Spatrick _, _, _, _, 17809467b48Spatrick _, _, _, _, 17909467b48Spatrick P(_DTPREL_16), _, _, _, 18009467b48Spatrick _, _, _, _, 18109467b48Spatrick _, _, _, _, 18209467b48Spatrick _, _, _, _, 18309467b48Spatrick P(_DTPREL_32) }}, 18409467b48Spatrick { MCSymbolRefExpr::VK_GOT, 18509467b48Spatrick { _, _, _, _, 18609467b48Spatrick _, _, _, _, 18709467b48Spatrick _, _, _, _, 18809467b48Spatrick _, _, _, _, 18909467b48Spatrick _, _, _, _, 19009467b48Spatrick _, _, _, _, 19109467b48Spatrick _, _, _, _, 19209467b48Spatrick _, _, _, _, 19309467b48Spatrick P(_GOT_32) }}, 19409467b48Spatrick { MCSymbolRefExpr::VK_GOTREL, 19509467b48Spatrick { _, _, _, _, 19609467b48Spatrick _, _, _, _, 19709467b48Spatrick _, _, _, _, 19809467b48Spatrick _, _, _, _, 19909467b48Spatrick _ /* [2] */, _, _, _, 20009467b48Spatrick _, _, _, _, 20109467b48Spatrick _, _, _, _, 20209467b48Spatrick _, _, _, _, 20309467b48Spatrick P(_GOTREL_32) }}, 20409467b48Spatrick { MCSymbolRefExpr::VK_PLT, 20509467b48Spatrick { _, _, _, _, 20609467b48Spatrick _, _, _, _, 20709467b48Spatrick _, _, _, _, 20809467b48Spatrick _, _, _, _, 20909467b48Spatrick _, _, _, _, 21009467b48Spatrick _, _, P(_PLT_B22_PCREL), _, 21109467b48Spatrick _, _, _, _, 21209467b48Spatrick _, _, _, _, 21309467b48Spatrick _ }}, 21409467b48Spatrick { MCSymbolRefExpr::VK_TPREL, 21509467b48Spatrick { _, _, _, _, 21609467b48Spatrick _, _, _, _, 21709467b48Spatrick _, _, _, P(_TPREL_11_X), 21809467b48Spatrick _, _, _, _, 21909467b48Spatrick P(_TPREL_16), _, _, _, 22009467b48Spatrick _, _, _, _, 22109467b48Spatrick _, _, _, _, 22209467b48Spatrick _, _, _, _, 22309467b48Spatrick P(_TPREL_32) }}, 22409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_GD_GOT, 22509467b48Spatrick { _, _, _, _, 22609467b48Spatrick _, _, _, _, 22709467b48Spatrick _, _, _, _, 22809467b48Spatrick _, _, _, _, 22909467b48Spatrick P(_GD_GOT_16), _, _, _, 23009467b48Spatrick _, _, _, _, 23109467b48Spatrick _, _, _, _, 23209467b48Spatrick _, _, _, _, 23309467b48Spatrick P(_GD_GOT_32) }}, 23409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_GD_PLT, 23509467b48Spatrick { _, _, _, _, 23609467b48Spatrick _, _, _, _, 23709467b48Spatrick _, _, _, _, 23809467b48Spatrick _, _, _, _, 23909467b48Spatrick _, _, _, _, 24009467b48Spatrick _, _, P(_GD_PLT_B22_PCREL), _, 24109467b48Spatrick _, _, _, _, 24209467b48Spatrick _, _, _, _, 24309467b48Spatrick _ }}, 24409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_GPREL, 24509467b48Spatrick { _, _, _, _, 24609467b48Spatrick _, _, _, _, 24709467b48Spatrick _, _, _, _, 24809467b48Spatrick _, _, _, _, 24909467b48Spatrick P(_GPREL16_0), _, _, _, 25009467b48Spatrick _, _, _, _, 25109467b48Spatrick _, _, _, _, 25209467b48Spatrick _, _, _, _, 25309467b48Spatrick _ }}, 25409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_HI16, 25509467b48Spatrick { _, _, _, _, 25609467b48Spatrick _, _, _, _, 25709467b48Spatrick _, _, _, _, 25809467b48Spatrick _, _, _, _, 25909467b48Spatrick P(_HI16), _, _, _, 26009467b48Spatrick _, _, _, _, 26109467b48Spatrick _, _, _, _, 26209467b48Spatrick _, _, _, _, 26309467b48Spatrick _ }}, 26409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE, 26509467b48Spatrick { _, _, _, _, 26609467b48Spatrick _, _, _, _, 26709467b48Spatrick _, _, _, _, 26809467b48Spatrick _, _, _, _, 26909467b48Spatrick _, _, _, _, 27009467b48Spatrick _, _, _, _, 27109467b48Spatrick _, _, _, _, 27209467b48Spatrick _, _, _, _, 27309467b48Spatrick P(_IE_32) }}, 27409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE_GOT, 27509467b48Spatrick { _, _, _, _, 27609467b48Spatrick _, _, _, _, 27709467b48Spatrick _, _, _, _, 27809467b48Spatrick _, _, _, _, 27909467b48Spatrick P(_IE_GOT_16), _, _, _, 28009467b48Spatrick _, _, _, _, 28109467b48Spatrick _, _, _, _, 28209467b48Spatrick _, _, _, _, 28309467b48Spatrick P(_IE_GOT_32) }}, 28409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_LD_GOT, 28509467b48Spatrick { _, _, _, _, 28609467b48Spatrick _, _, _, _, 28709467b48Spatrick _, _, _, _, 28809467b48Spatrick _, _, _, _, 28909467b48Spatrick P(_LD_GOT_16), _, _, _, 29009467b48Spatrick _, _, _, _, 29109467b48Spatrick _, _, _, _, 29209467b48Spatrick _, _, _, _, 29309467b48Spatrick P(_LD_GOT_32) }}, 29409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_LD_PLT, 29509467b48Spatrick { _, _, _, _, 29609467b48Spatrick _, _, _, _, 29709467b48Spatrick _, _, _, _, 29809467b48Spatrick _, _, _, _, 29909467b48Spatrick _, _, _, _, 30009467b48Spatrick _, _, P(_LD_PLT_B22_PCREL), _, 30109467b48Spatrick _, _, _, _, 30209467b48Spatrick _, _, _, _, 30309467b48Spatrick _ }}, 30409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_LO16, 30509467b48Spatrick { _, _, _, _, 30609467b48Spatrick _, _, _, _, 30709467b48Spatrick _, _, _, _, 30809467b48Spatrick _, _, _, _, 30909467b48Spatrick P(_LO16), _, _, _, 31009467b48Spatrick _, _, _, _, 31109467b48Spatrick _, _, _, _, 31209467b48Spatrick _, _, _, _, 31309467b48Spatrick _ }}, 314*097a140dSpatrick { MCSymbolRefExpr::VK_PCREL, 31509467b48Spatrick { _, _, _, _, 31609467b48Spatrick _, _, _, _, 31709467b48Spatrick _, _, _, _, 31809467b48Spatrick _, _, _, _, 31909467b48Spatrick _, _, _, _, 32009467b48Spatrick _, _, _, _, 32109467b48Spatrick _, _, _, _, 32209467b48Spatrick _, _, _, _, 32309467b48Spatrick P(_32_PCREL) }}, 32409467b48Spatrick { MCSymbolRefExpr::VK_None, 32509467b48Spatrick { _, _, _, _, 32609467b48Spatrick _, _, _, _, 32709467b48Spatrick _, _, _, _, 32809467b48Spatrick _, P(_B13_PCREL), _, P(_B15_PCREL), 32909467b48Spatrick _, _, _, _, 33009467b48Spatrick _, _, P(_B22_PCREL), _, 33109467b48Spatrick _, _, _, _, 33209467b48Spatrick _, _, _, _, 33309467b48Spatrick P(_32) }}, 33409467b48Spatrick }; 33509467b48Spatrick // 33609467b48Spatrick // [2] The actual fixup is LO16 or HI16, depending on the instruction. 33709467b48Spatrick #undef P 33809467b48Spatrick #undef _ 33909467b48Spatrick 34009467b48Spatrick uint32_t HexagonMCCodeEmitter::parseBits(size_t Last, MCInst const &MCB, 34109467b48Spatrick MCInst const &MCI) const { 34209467b48Spatrick bool Duplex = HexagonMCInstrInfo::isDuplex(MCII, MCI); 34309467b48Spatrick if (State.Index == 0) { 34409467b48Spatrick if (HexagonMCInstrInfo::isInnerLoop(MCB)) { 34509467b48Spatrick assert(!Duplex); 34609467b48Spatrick assert(State.Index != Last); 34709467b48Spatrick return HexagonII::INST_PARSE_LOOP_END; 34809467b48Spatrick } 34909467b48Spatrick } 35009467b48Spatrick if (State.Index == 1) { 35109467b48Spatrick if (HexagonMCInstrInfo::isOuterLoop(MCB)) { 35209467b48Spatrick assert(!Duplex); 35309467b48Spatrick assert(State.Index != Last); 35409467b48Spatrick return HexagonII::INST_PARSE_LOOP_END; 35509467b48Spatrick } 35609467b48Spatrick } 35709467b48Spatrick if (Duplex) { 35809467b48Spatrick assert(State.Index == Last); 35909467b48Spatrick return HexagonII::INST_PARSE_DUPLEX; 36009467b48Spatrick } 36109467b48Spatrick if (State.Index == Last) 36209467b48Spatrick return HexagonII::INST_PARSE_PACKET_END; 36309467b48Spatrick return HexagonII::INST_PARSE_NOT_END; 36409467b48Spatrick } 36509467b48Spatrick 36609467b48Spatrick /// Emit the bundle. 36709467b48Spatrick void HexagonMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 36809467b48Spatrick SmallVectorImpl<MCFixup> &Fixups, 36909467b48Spatrick const MCSubtargetInfo &STI) const { 37009467b48Spatrick MCInst &HMB = const_cast<MCInst &>(MI); 37109467b48Spatrick 37209467b48Spatrick assert(HexagonMCInstrInfo::isBundle(HMB)); 37309467b48Spatrick LLVM_DEBUG(dbgs() << "Encoding bundle\n";); 37409467b48Spatrick State.Addend = 0; 37509467b48Spatrick State.Extended = false; 37609467b48Spatrick State.Bundle = &MI; 37709467b48Spatrick State.Index = 0; 37809467b48Spatrick size_t Last = HexagonMCInstrInfo::bundleSize(HMB) - 1; 37909467b48Spatrick FeatureBitset Features = computeAvailableFeatures(STI.getFeatureBits()); 38009467b48Spatrick 38109467b48Spatrick for (auto &I : HexagonMCInstrInfo::bundleInstructions(HMB)) { 38209467b48Spatrick MCInst &HMI = const_cast<MCInst &>(*I.getInst()); 38309467b48Spatrick verifyInstructionPredicates(HMI, Features); 38409467b48Spatrick 38509467b48Spatrick EncodeSingleInstruction(HMI, OS, Fixups, STI, parseBits(Last, HMB, HMI)); 38609467b48Spatrick State.Extended = HexagonMCInstrInfo::isImmext(HMI); 38709467b48Spatrick State.Addend += HEXAGON_INSTR_SIZE; 38809467b48Spatrick ++State.Index; 38909467b48Spatrick } 39009467b48Spatrick } 39109467b48Spatrick 39209467b48Spatrick static bool RegisterMatches(unsigned Consumer, unsigned Producer, 39309467b48Spatrick unsigned Producer2) { 394*097a140dSpatrick return (Consumer == Producer) || (Consumer == Producer2) || 395*097a140dSpatrick HexagonMCInstrInfo::IsSingleConsumerRefPairProducer(Producer, 396*097a140dSpatrick Consumer); 39709467b48Spatrick } 39809467b48Spatrick 39909467b48Spatrick /// EncodeSingleInstruction - Emit a single 40009467b48Spatrick void HexagonMCCodeEmitter::EncodeSingleInstruction(const MCInst &MI, 40109467b48Spatrick raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, 40209467b48Spatrick const MCSubtargetInfo &STI, uint32_t Parse) const { 40309467b48Spatrick assert(!HexagonMCInstrInfo::isBundle(MI)); 40409467b48Spatrick uint64_t Binary; 40509467b48Spatrick 40609467b48Spatrick // Pseudo instructions don't get encoded and shouldn't be here 40709467b48Spatrick // in the first place! 40809467b48Spatrick assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo() && 40909467b48Spatrick "pseudo-instruction found"); 41009467b48Spatrick LLVM_DEBUG(dbgs() << "Encoding insn `" 41109467b48Spatrick << HexagonMCInstrInfo::getName(MCII, MI) << "'\n"); 41209467b48Spatrick 41309467b48Spatrick Binary = getBinaryCodeForInstr(MI, Fixups, STI); 41409467b48Spatrick unsigned Opc = MI.getOpcode(); 41509467b48Spatrick 41609467b48Spatrick // Check for unimplemented instructions. Immediate extenders 41709467b48Spatrick // are encoded as zero, so they need to be accounted for. 41809467b48Spatrick if (!Binary && Opc != DuplexIClass0 && Opc != A4_ext) { 41909467b48Spatrick LLVM_DEBUG(dbgs() << "Unimplemented inst `" 42009467b48Spatrick << HexagonMCInstrInfo::getName(MCII, MI) << "'\n"); 42109467b48Spatrick llvm_unreachable("Unimplemented Instruction"); 42209467b48Spatrick } 42309467b48Spatrick Binary |= Parse; 42409467b48Spatrick 42509467b48Spatrick // if we need to emit a duplexed instruction 42609467b48Spatrick if (Opc >= Hexagon::DuplexIClass0 && Opc <= Hexagon::DuplexIClassF) { 42709467b48Spatrick assert(Parse == HexagonII::INST_PARSE_DUPLEX && 42809467b48Spatrick "Emitting duplex without duplex parse bits"); 42909467b48Spatrick unsigned DupIClass = MI.getOpcode() - Hexagon::DuplexIClass0; 43009467b48Spatrick // 29 is the bit position. 43109467b48Spatrick // 0b1110 =0xE bits are masked off and down shifted by 1 bit. 43209467b48Spatrick // Last bit is moved to bit position 13 43309467b48Spatrick Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13); 43409467b48Spatrick 43509467b48Spatrick const MCInst *Sub0 = MI.getOperand(0).getInst(); 43609467b48Spatrick const MCInst *Sub1 = MI.getOperand(1).getInst(); 43709467b48Spatrick 43809467b48Spatrick // Get subinstruction slot 0. 43909467b48Spatrick unsigned SubBits0 = getBinaryCodeForInstr(*Sub0, Fixups, STI); 44009467b48Spatrick // Get subinstruction slot 1. 44109467b48Spatrick State.SubInst1 = true; 44209467b48Spatrick unsigned SubBits1 = getBinaryCodeForInstr(*Sub1, Fixups, STI); 44309467b48Spatrick State.SubInst1 = false; 44409467b48Spatrick 44509467b48Spatrick Binary |= SubBits0 | (SubBits1 << 16); 44609467b48Spatrick } 44709467b48Spatrick support::endian::write<uint32_t>(OS, Binary, support::little); 44809467b48Spatrick ++MCNumEmitted; 44909467b48Spatrick } 45009467b48Spatrick 45109467b48Spatrick LLVM_ATTRIBUTE_NORETURN 45209467b48Spatrick static void raise_relocation_error(unsigned Width, unsigned Kind) { 45309467b48Spatrick std::string Text; 45409467b48Spatrick raw_string_ostream Stream(Text); 45509467b48Spatrick Stream << "Unrecognized relocation combination: width=" << Width 45609467b48Spatrick << " kind=" << Kind; 45709467b48Spatrick report_fatal_error(Stream.str()); 45809467b48Spatrick } 45909467b48Spatrick 46009467b48Spatrick /// Some insns are not extended and thus have no bits. These cases require 46109467b48Spatrick /// a more brute force method for determining the correct relocation. 46209467b48Spatrick Hexagon::Fixups HexagonMCCodeEmitter::getFixupNoBits( 46309467b48Spatrick MCInstrInfo const &MCII, const MCInst &MI, const MCOperand &MO, 46409467b48Spatrick const MCSymbolRefExpr::VariantKind VarKind) const { 46509467b48Spatrick const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI); 46609467b48Spatrick unsigned InsnType = HexagonMCInstrInfo::getType(MCII, MI); 46709467b48Spatrick using namespace Hexagon; 46809467b48Spatrick 46909467b48Spatrick if (InsnType == HexagonII::TypeEXTENDER) { 47009467b48Spatrick if (VarKind == MCSymbolRefExpr::VK_None) { 47109467b48Spatrick auto Instrs = HexagonMCInstrInfo::bundleInstructions(*State.Bundle); 47209467b48Spatrick for (auto I = Instrs.begin(), N = Instrs.end(); I != N; ++I) { 47309467b48Spatrick if (I->getInst() != &MI) 47409467b48Spatrick continue; 47509467b48Spatrick assert(I+1 != N && "Extender cannot be last in packet"); 47609467b48Spatrick const MCInst &NextI = *(I+1)->getInst(); 47709467b48Spatrick const MCInstrDesc &NextD = HexagonMCInstrInfo::getDesc(MCII, NextI); 47809467b48Spatrick if (NextD.isBranch() || NextD.isCall() || 47909467b48Spatrick HexagonMCInstrInfo::getType(MCII, NextI) == HexagonII::TypeCR) 48009467b48Spatrick return fixup_Hexagon_B32_PCREL_X; 48109467b48Spatrick return fixup_Hexagon_32_6_X; 48209467b48Spatrick } 48309467b48Spatrick } 48409467b48Spatrick 48509467b48Spatrick static const std::map<unsigned,unsigned> Relocs = { 48609467b48Spatrick { MCSymbolRefExpr::VK_GOTREL, fixup_Hexagon_GOTREL_32_6_X }, 48709467b48Spatrick { MCSymbolRefExpr::VK_GOT, fixup_Hexagon_GOT_32_6_X }, 48809467b48Spatrick { MCSymbolRefExpr::VK_TPREL, fixup_Hexagon_TPREL_32_6_X }, 48909467b48Spatrick { MCSymbolRefExpr::VK_DTPREL, fixup_Hexagon_DTPREL_32_6_X }, 49009467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_32_6_X }, 49109467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_32_6_X }, 49209467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE, fixup_Hexagon_IE_32_6_X }, 49309467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_32_6_X }, 494*097a140dSpatrick { MCSymbolRefExpr::VK_PCREL, fixup_Hexagon_B32_PCREL_X }, 49509467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_GD_PLT, fixup_Hexagon_GD_PLT_B32_PCREL_X }, 49609467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_LD_PLT, fixup_Hexagon_LD_PLT_B32_PCREL_X }, 49709467b48Spatrick }; 49809467b48Spatrick 49909467b48Spatrick auto F = Relocs.find(VarKind); 50009467b48Spatrick if (F != Relocs.end()) 50109467b48Spatrick return Hexagon::Fixups(F->second); 50209467b48Spatrick raise_relocation_error(0, VarKind); 50309467b48Spatrick } 50409467b48Spatrick 50509467b48Spatrick if (MCID.isBranch()) 50609467b48Spatrick return fixup_Hexagon_B13_PCREL; 50709467b48Spatrick 50809467b48Spatrick static const std::map<unsigned,unsigned> RelocsLo = { 50909467b48Spatrick { MCSymbolRefExpr::VK_GOT, fixup_Hexagon_GOT_LO16 }, 51009467b48Spatrick { MCSymbolRefExpr::VK_GOTREL, fixup_Hexagon_GOTREL_LO16 }, 51109467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_LO16 }, 51209467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_LO16 }, 51309467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE, fixup_Hexagon_IE_LO16 }, 51409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_LO16 }, 51509467b48Spatrick { MCSymbolRefExpr::VK_TPREL, fixup_Hexagon_TPREL_LO16 }, 51609467b48Spatrick { MCSymbolRefExpr::VK_DTPREL, fixup_Hexagon_DTPREL_LO16 }, 51709467b48Spatrick { MCSymbolRefExpr::VK_None, fixup_Hexagon_LO16 }, 51809467b48Spatrick }; 51909467b48Spatrick 52009467b48Spatrick static const std::map<unsigned,unsigned> RelocsHi = { 52109467b48Spatrick { MCSymbolRefExpr::VK_GOT, fixup_Hexagon_GOT_HI16 }, 52209467b48Spatrick { MCSymbolRefExpr::VK_GOTREL, fixup_Hexagon_GOTREL_HI16 }, 52309467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_HI16 }, 52409467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_HI16 }, 52509467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE, fixup_Hexagon_IE_HI16 }, 52609467b48Spatrick { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_HI16 }, 52709467b48Spatrick { MCSymbolRefExpr::VK_TPREL, fixup_Hexagon_TPREL_HI16 }, 52809467b48Spatrick { MCSymbolRefExpr::VK_DTPREL, fixup_Hexagon_DTPREL_HI16 }, 52909467b48Spatrick { MCSymbolRefExpr::VK_None, fixup_Hexagon_HI16 }, 53009467b48Spatrick }; 53109467b48Spatrick 53209467b48Spatrick switch (MCID.getOpcode()) { 53309467b48Spatrick case Hexagon::LO: 53409467b48Spatrick case Hexagon::A2_tfril: { 53509467b48Spatrick auto F = RelocsLo.find(VarKind); 53609467b48Spatrick if (F != RelocsLo.end()) 53709467b48Spatrick return Hexagon::Fixups(F->second); 53809467b48Spatrick break; 53909467b48Spatrick } 54009467b48Spatrick case Hexagon::HI: 54109467b48Spatrick case Hexagon::A2_tfrih: { 54209467b48Spatrick auto F = RelocsHi.find(VarKind); 54309467b48Spatrick if (F != RelocsHi.end()) 54409467b48Spatrick return Hexagon::Fixups(F->second); 54509467b48Spatrick break; 54609467b48Spatrick } 54709467b48Spatrick } 54809467b48Spatrick 54909467b48Spatrick raise_relocation_error(0, VarKind); 55009467b48Spatrick } 55109467b48Spatrick 55209467b48Spatrick static bool isPCRel(unsigned Kind) { 55309467b48Spatrick switch (Kind){ 55409467b48Spatrick case fixup_Hexagon_B22_PCREL: 55509467b48Spatrick case fixup_Hexagon_B15_PCREL: 55609467b48Spatrick case fixup_Hexagon_B7_PCREL: 55709467b48Spatrick case fixup_Hexagon_B13_PCREL: 55809467b48Spatrick case fixup_Hexagon_B9_PCREL: 55909467b48Spatrick case fixup_Hexagon_B32_PCREL_X: 56009467b48Spatrick case fixup_Hexagon_B22_PCREL_X: 56109467b48Spatrick case fixup_Hexagon_B15_PCREL_X: 56209467b48Spatrick case fixup_Hexagon_B13_PCREL_X: 56309467b48Spatrick case fixup_Hexagon_B9_PCREL_X: 56409467b48Spatrick case fixup_Hexagon_B7_PCREL_X: 56509467b48Spatrick case fixup_Hexagon_32_PCREL: 56609467b48Spatrick case fixup_Hexagon_PLT_B22_PCREL: 56709467b48Spatrick case fixup_Hexagon_GD_PLT_B22_PCREL: 56809467b48Spatrick case fixup_Hexagon_LD_PLT_B22_PCREL: 56909467b48Spatrick case fixup_Hexagon_GD_PLT_B22_PCREL_X: 57009467b48Spatrick case fixup_Hexagon_LD_PLT_B22_PCREL_X: 57109467b48Spatrick case fixup_Hexagon_6_PCREL_X: 57209467b48Spatrick return true; 57309467b48Spatrick default: 57409467b48Spatrick return false; 57509467b48Spatrick } 57609467b48Spatrick } 57709467b48Spatrick 57809467b48Spatrick unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI, 57909467b48Spatrick const MCOperand &MO, const MCExpr *ME, SmallVectorImpl<MCFixup> &Fixups, 58009467b48Spatrick const MCSubtargetInfo &STI) const { 58109467b48Spatrick if (isa<HexagonMCExpr>(ME)) 58209467b48Spatrick ME = &HexagonMCInstrInfo::getExpr(*ME); 58309467b48Spatrick int64_t Value; 58409467b48Spatrick if (ME->evaluateAsAbsolute(Value)) { 58509467b48Spatrick bool InstExtendable = HexagonMCInstrInfo::isExtendable(MCII, MI) || 58609467b48Spatrick HexagonMCInstrInfo::isExtended(MCII, MI); 58709467b48Spatrick // Only sub-instruction #1 can be extended in a duplex. If MI is a 58809467b48Spatrick // sub-instruction #0, it is not extended even if Extended is true 58909467b48Spatrick // (it can be true for the duplex as a whole). 59009467b48Spatrick bool IsSub0 = HexagonMCInstrInfo::isSubInstruction(MI) && !State.SubInst1; 59109467b48Spatrick if (State.Extended && InstExtendable && !IsSub0) { 59209467b48Spatrick unsigned OpIdx = ~0u; 59309467b48Spatrick for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) { 59409467b48Spatrick if (&MO != &MI.getOperand(I)) 59509467b48Spatrick continue; 59609467b48Spatrick OpIdx = I; 59709467b48Spatrick break; 59809467b48Spatrick } 59909467b48Spatrick assert(OpIdx != ~0u); 60009467b48Spatrick if (OpIdx == HexagonMCInstrInfo::getExtendableOp(MCII, MI)) { 60109467b48Spatrick unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MI); 60209467b48Spatrick Value = (Value & 0x3f) << Shift; 60309467b48Spatrick } 60409467b48Spatrick } 60509467b48Spatrick return Value; 60609467b48Spatrick } 60709467b48Spatrick assert(ME->getKind() == MCExpr::SymbolRef || 60809467b48Spatrick ME->getKind() == MCExpr::Binary); 60909467b48Spatrick if (ME->getKind() == MCExpr::Binary) { 61009467b48Spatrick MCBinaryExpr const *Binary = cast<MCBinaryExpr>(ME); 61109467b48Spatrick getExprOpValue(MI, MO, Binary->getLHS(), Fixups, STI); 61209467b48Spatrick getExprOpValue(MI, MO, Binary->getRHS(), Fixups, STI); 61309467b48Spatrick return 0; 61409467b48Spatrick } 61509467b48Spatrick 61609467b48Spatrick unsigned FixupKind = fixup_Invalid; 61709467b48Spatrick const MCSymbolRefExpr *MCSRE = static_cast<const MCSymbolRefExpr *>(ME); 61809467b48Spatrick const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI); 61909467b48Spatrick unsigned FixupWidth = HexagonMCInstrInfo::getExtentBits(MCII, MI) - 62009467b48Spatrick HexagonMCInstrInfo::getExtentAlignment(MCII, MI); 62109467b48Spatrick MCSymbolRefExpr::VariantKind VarKind = MCSRE->getKind(); 62209467b48Spatrick unsigned Opc = MCID.getOpcode(); 62309467b48Spatrick unsigned IType = HexagonMCInstrInfo::getType(MCII, MI); 62409467b48Spatrick 62509467b48Spatrick LLVM_DEBUG(dbgs() << "----------------------------------------\n" 62609467b48Spatrick << "Opcode Name: " << HexagonMCInstrInfo::getName(MCII, MI) 62709467b48Spatrick << "\nOpcode: " << Opc << "\nRelocation bits: " 62809467b48Spatrick << FixupWidth << "\nAddend: " << State.Addend 62909467b48Spatrick << "\nVariant: " << unsigned(VarKind) 63009467b48Spatrick << "\n----------------------------------------\n"); 63109467b48Spatrick 63209467b48Spatrick // Pick the applicable fixup kind for the symbol. 63309467b48Spatrick // Handle special cases first, the rest will be looked up in the tables. 63409467b48Spatrick 63509467b48Spatrick if (FixupWidth == 16 && !State.Extended) { 63609467b48Spatrick if (VarKind == MCSymbolRefExpr::VK_None) { 63709467b48Spatrick if (HexagonMCInstrInfo::s27_2_reloc(*MO.getExpr())) { 63809467b48Spatrick // A2_iconst. 63909467b48Spatrick FixupKind = Hexagon::fixup_Hexagon_27_REG; 64009467b48Spatrick } else { 64109467b48Spatrick // Look for GP-relative fixups. 64209467b48Spatrick unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MI); 64309467b48Spatrick static const Hexagon::Fixups GPRelFixups[] = { 64409467b48Spatrick Hexagon::fixup_Hexagon_GPREL16_0, Hexagon::fixup_Hexagon_GPREL16_1, 64509467b48Spatrick Hexagon::fixup_Hexagon_GPREL16_2, Hexagon::fixup_Hexagon_GPREL16_3 64609467b48Spatrick }; 64709467b48Spatrick assert(Shift < array_lengthof(GPRelFixups)); 64809467b48Spatrick auto UsesGP = [] (const MCInstrDesc &D) { 64909467b48Spatrick for (const MCPhysReg *U = D.getImplicitUses(); U && *U; ++U) 65009467b48Spatrick if (*U == Hexagon::GP) 65109467b48Spatrick return true; 65209467b48Spatrick return false; 65309467b48Spatrick }; 65409467b48Spatrick if (UsesGP(MCID)) 65509467b48Spatrick FixupKind = GPRelFixups[Shift]; 65609467b48Spatrick } 65709467b48Spatrick } else if (VarKind == MCSymbolRefExpr::VK_GOTREL) { 65809467b48Spatrick // Select between LO/HI. 65909467b48Spatrick if (Opc == Hexagon::LO) 66009467b48Spatrick FixupKind = Hexagon::fixup_Hexagon_GOTREL_LO16; 66109467b48Spatrick else if (Opc == Hexagon::HI) 66209467b48Spatrick FixupKind = Hexagon::fixup_Hexagon_GOTREL_HI16; 66309467b48Spatrick } 66409467b48Spatrick } else { 66509467b48Spatrick bool BranchOrCR = MCID.isBranch() || IType == HexagonII::TypeCR; 66609467b48Spatrick switch (FixupWidth) { 66709467b48Spatrick case 9: 66809467b48Spatrick if (BranchOrCR) 66909467b48Spatrick FixupKind = State.Extended ? Hexagon::fixup_Hexagon_B9_PCREL_X 67009467b48Spatrick : Hexagon::fixup_Hexagon_B9_PCREL; 67109467b48Spatrick break; 67209467b48Spatrick case 8: 67309467b48Spatrick case 7: 67409467b48Spatrick if (State.Extended && VarKind == MCSymbolRefExpr::VK_GOT) 67509467b48Spatrick FixupKind = HexagonMCInstrInfo::isExtentSigned(MCII, MI) 67609467b48Spatrick ? Hexagon::fixup_Hexagon_GOT_16_X 67709467b48Spatrick : Hexagon::fixup_Hexagon_GOT_11_X; 67809467b48Spatrick else if (FixupWidth == 7 && BranchOrCR) 67909467b48Spatrick FixupKind = State.Extended ? Hexagon::fixup_Hexagon_B7_PCREL_X 68009467b48Spatrick : Hexagon::fixup_Hexagon_B7_PCREL; 68109467b48Spatrick break; 68209467b48Spatrick case 0: 68309467b48Spatrick FixupKind = getFixupNoBits(MCII, MI, MO, VarKind); 68409467b48Spatrick break; 68509467b48Spatrick } 68609467b48Spatrick } 68709467b48Spatrick 68809467b48Spatrick if (FixupKind == fixup_Invalid) { 68909467b48Spatrick const auto &FixupTable = State.Extended ? ExtFixups : StdFixups; 69009467b48Spatrick 69109467b48Spatrick auto FindVK = FixupTable.find(VarKind); 69209467b48Spatrick if (FindVK != FixupTable.end()) 69309467b48Spatrick FixupKind = FindVK->second[FixupWidth]; 69409467b48Spatrick } 69509467b48Spatrick 69609467b48Spatrick if (FixupKind == fixup_Invalid) 69709467b48Spatrick raise_relocation_error(FixupWidth, VarKind); 69809467b48Spatrick 69909467b48Spatrick const MCExpr *FixupExpr = MO.getExpr(); 70009467b48Spatrick if (State.Addend != 0 && isPCRel(FixupKind)) { 70109467b48Spatrick const MCExpr *C = MCConstantExpr::create(State.Addend, MCT); 70209467b48Spatrick FixupExpr = MCBinaryExpr::createAdd(FixupExpr, C, MCT); 70309467b48Spatrick } 70409467b48Spatrick 70509467b48Spatrick MCFixup Fixup = MCFixup::create(State.Addend, FixupExpr, 70609467b48Spatrick MCFixupKind(FixupKind), MI.getLoc()); 70709467b48Spatrick Fixups.push_back(Fixup); 70809467b48Spatrick // All of the information is in the fixup. 70909467b48Spatrick return 0; 71009467b48Spatrick } 71109467b48Spatrick 71209467b48Spatrick unsigned 71309467b48Spatrick HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO, 71409467b48Spatrick SmallVectorImpl<MCFixup> &Fixups, 71509467b48Spatrick MCSubtargetInfo const &STI) const { 71609467b48Spatrick #ifndef NDEBUG 71709467b48Spatrick size_t OperandNumber = ~0U; 71809467b48Spatrick for (unsigned i = 0, n = MI.getNumOperands(); i < n; ++i) 71909467b48Spatrick if (&MI.getOperand(i) == &MO) { 72009467b48Spatrick OperandNumber = i; 72109467b48Spatrick break; 72209467b48Spatrick } 72309467b48Spatrick assert((OperandNumber != ~0U) && "Operand not found"); 72409467b48Spatrick #endif 72509467b48Spatrick 72609467b48Spatrick if (HexagonMCInstrInfo::isNewValue(MCII, MI) && 72709467b48Spatrick &MO == &HexagonMCInstrInfo::getNewValueOperand(MCII, MI)) { 72809467b48Spatrick // Calculate the new value distance to the associated producer 72909467b48Spatrick unsigned SOffset = 0; 73009467b48Spatrick unsigned VOffset = 0; 73109467b48Spatrick unsigned UseReg = MO.getReg(); 732*097a140dSpatrick unsigned DefReg1 = Hexagon::NoRegister; 733*097a140dSpatrick unsigned DefReg2 = Hexagon::NoRegister; 73409467b48Spatrick 73509467b48Spatrick auto Instrs = HexagonMCInstrInfo::bundleInstructions(*State.Bundle); 73609467b48Spatrick const MCOperand *I = Instrs.begin() + State.Index - 1; 73709467b48Spatrick 73809467b48Spatrick for (;; --I) { 73909467b48Spatrick assert(I != Instrs.begin() - 1 && "Couldn't find producer"); 74009467b48Spatrick MCInst const &Inst = *I->getInst(); 74109467b48Spatrick if (HexagonMCInstrInfo::isImmext(Inst)) 74209467b48Spatrick continue; 74309467b48Spatrick 744*097a140dSpatrick DefReg1 = Hexagon::NoRegister; 745*097a140dSpatrick DefReg2 = Hexagon::NoRegister; 74609467b48Spatrick ++SOffset; 74709467b48Spatrick if (HexagonMCInstrInfo::isVector(MCII, Inst)) { 74809467b48Spatrick // Vector instructions don't count scalars. 74909467b48Spatrick ++VOffset; 75009467b48Spatrick } 75109467b48Spatrick if (HexagonMCInstrInfo::hasNewValue(MCII, Inst)) 75209467b48Spatrick DefReg1 = HexagonMCInstrInfo::getNewValueOperand(MCII, Inst).getReg(); 75309467b48Spatrick if (HexagonMCInstrInfo::hasNewValue2(MCII, Inst)) 75409467b48Spatrick DefReg2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, Inst).getReg(); 75509467b48Spatrick if (!RegisterMatches(UseReg, DefReg1, DefReg2)) { 75609467b48Spatrick // This isn't the register we're looking for 75709467b48Spatrick continue; 75809467b48Spatrick } 75909467b48Spatrick if (!HexagonMCInstrInfo::isPredicated(MCII, Inst)) { 76009467b48Spatrick // Producer is unpredicated 76109467b48Spatrick break; 76209467b48Spatrick } 76309467b48Spatrick assert(HexagonMCInstrInfo::isPredicated(MCII, MI) && 76409467b48Spatrick "Unpredicated consumer depending on predicated producer"); 76509467b48Spatrick if (HexagonMCInstrInfo::isPredicatedTrue(MCII, Inst) == 76609467b48Spatrick HexagonMCInstrInfo::isPredicatedTrue(MCII, MI)) 76709467b48Spatrick // Producer predicate sense matched ours. 76809467b48Spatrick break; 76909467b48Spatrick } 77009467b48Spatrick // Hexagon PRM 10.11 Construct Nt from distance 77109467b48Spatrick unsigned Offset = HexagonMCInstrInfo::isVector(MCII, MI) ? VOffset 77209467b48Spatrick : SOffset; 77309467b48Spatrick Offset <<= 1; 77409467b48Spatrick Offset |= HexagonMCInstrInfo::SubregisterBit(UseReg, DefReg1, DefReg2); 77509467b48Spatrick return Offset; 77609467b48Spatrick } 77709467b48Spatrick 77809467b48Spatrick assert(!MO.isImm()); 77909467b48Spatrick if (MO.isReg()) { 78009467b48Spatrick unsigned Reg = MO.getReg(); 78109467b48Spatrick if (HexagonMCInstrInfo::isSubInstruction(MI) || 78209467b48Spatrick HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCJ) 78309467b48Spatrick return HexagonMCInstrInfo::getDuplexRegisterNumbering(Reg); 78409467b48Spatrick return MCT.getRegisterInfo()->getEncodingValue(Reg); 78509467b48Spatrick } 78609467b48Spatrick 78709467b48Spatrick return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI); 78809467b48Spatrick } 78909467b48Spatrick 79009467b48Spatrick MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII, 79109467b48Spatrick MCRegisterInfo const &MRI, 79209467b48Spatrick MCContext &MCT) { 79309467b48Spatrick return new HexagonMCCodeEmitter(MII, MCT); 79409467b48Spatrick } 79509467b48Spatrick 79609467b48Spatrick #define ENABLE_INSTR_PREDICATE_VERIFIER 79709467b48Spatrick #include "HexagonGenMCCodeEmitter.inc" 798