LLVM: lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

29#include

30#include

31#include

32#include

33#include

34#include

35

36#define DEBUG_TYPE "mccodeemitter"

37

38using namespace llvm;

40

41STATISTIC(MCNumEmitted, "Number of MC instructions emitted");

42

44

45

46#define _ fixup_Invalid

47#define P(x) Hexagon::fixup_Hexagon##x

48static const std::map<unsigned, std::vector> ExtFixups = {

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), _, _, _,

58 P(_DTPREL_32_6_X) }},

61 _, _, P(_GOT_11_X), _ ,

62 _ , P(_9_X), _, P(_GOT_11_X),

63 P(_GOT_16_X), _, _, _,

64 P(_GOT_16_X), _, _, _,

68 P(_GOT_32_6_X) }},

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), _, _, _,

78 P(_GOTREL_32_6_X) }},

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), _, _, _,

88 P(_TPREL_32_6_X) }},

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), _, _, _,

98 P(_GD_GOT_32_6_X) }},

100 { _, _, _, _,

102 _, P(_9_X), _, P(_GD_PLT_B22_PCREL_X),

105 _, _, P(_GD_PLT_B22_PCREL_X), _,

108 _ }},

110 { _, _, _, _,

111 _, _, P(_IE_16_X), _,

112 _, P(_9_X), _, _,

113 P(_IE_16_X), _, _, _,

114 P(_IE_16_X), _, _, _,

118 P(_IE_32_6_X) }},

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), _, _, _,

128 P(_IE_GOT_32_6_X) }},

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), _, _, _,

138 P(_LD_GOT_32_6_X) }},

140 { _, _, _, _,

142 _, P(_9_X), _, P(_LD_PLT_B22_PCREL_X),

145 _, _, P(_LD_PLT_B22_PCREL_X), _,

148 _ }},

150 { _, _, _, _,

151 _, _, P(_6_PCREL_X), _,

152 _, P(_9_X), _, _,

158 P(_32_PCREL) }},

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), _,

168 P(_32_6_X) }},

169};

170

171

172static const std::map<unsigned, std::vector> StdFixups = {

174 { _, _, _, _,

178 P(_DTPREL_16), _, _, _,

182 P(_DTPREL_32) }},

184 { _, _, _, _,

192 P(_GOT_32) }},

194 { _, _, _, _,

198 _ , _, _, _,

202 P(_GOTREL_32) }},

204 { _, _, _, _,

209 _, _, P(_PLT_B22_PCREL), _,

212 _ }},

214 { _, _, _, _,

216 _, _, _, P(_TPREL_11_X),

218 P(_TPREL_16), _, _, _,

222 P(_TPREL_32) }},

224 { _, _, _, _,

228 P(_GD_GOT_16), _, _, _,

232 P(_GD_GOT_32) }},

234 { _, _, _, _,

239 _, _, P(_GD_PLT_B22_PCREL), _,

242 _ }},

244 { _, _, _, _,

248 P(_GPREL16_0), _, _, _,

252 _ }},

254 { _, _, _, _,

258 P(_HI16), _, _, _,

262 _ }},

264 { _, _, _, _,

272 P(_IE_32) }},

274 { _, _, _, _,

278 P(_IE_GOT_16), _, _, _,

282 P(_IE_GOT_32) }},

284 { _, _, _, _,

288 P(_LD_GOT_16), _, _, _,

292 P(_LD_GOT_32) }},

294 { _, _, _, _,

299 _, _, P(_LD_PLT_B22_PCREL), _,

302 _ }},

304 { _, _, _, _,

308 P(_LO16), _, _, _,

312 _ }},

314 { _, _, _, _,

322 P(_32_PCREL) }},

324 { _, _, _, _,

327 _, P(_B13_PCREL), _, P(_B15_PCREL),

329 _, _, P(_B22_PCREL), _,

332 P(_32) }},

333};

334

335

336#undef P

337#undef _

338

341 bool PCRel = false;

342 switch (Kind) {

363 PCRel = true;

364 }

366}

367

368uint32_t HexagonMCCodeEmitter::parseBits(size_t Last, MCInst const &MCB,

369 MCInst const &MCI) const {

371 if (State.Index == 0) {

376 }

377 }

378 if (State.Index == 1) {

383 }

384 }

385 if (Duplex) {

388 }

389 if (State.Index == Last)

392}

393

394

400

403 State.Addend = 0;

404 State.Extended = false;

405 State.Bundle = &MI;

406 State.Index = 0;

408

410 MCInst &HMI = const_cast<MCInst &>(*I.getInst());

411

415 ++State.Index;

416 }

417}

418

421 return (Consumer == Producer) || (Consumer == Producer2) ||

423 Consumer);

424}

425

432

433

434

436 "pseudo-instruction found");

439

441 unsigned Opc = MI.getOpcode();

442

443

444

445 if (!Binary && Opc != DuplexIClass0 && Opc != A4_ext) {

449 }

450 Binary |= Parse;

451

452

453 if (Opc >= Hexagon::DuplexIClass0 && Opc <= Hexagon::DuplexIClassF) {

455 "Emitting duplex without duplex parse bits");

456 unsigned DupIClass = MI.getOpcode() - Hexagon::DuplexIClass0;

457

458

459

460 Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13);

461

462 const MCInst *Sub0 = MI.getOperand(0).getInst();

463 const MCInst *Sub1 = MI.getOperand(1).getInst();

464

465

467

468 State.SubInst1 = true;

470 State.SubInst1 = false;

471

472 Binary |= SubBits0 | (SubBits1 << 16);

473 }

475 ++MCNumEmitted;

476}

477

479 std::string Text;

481 Stream << "Unrecognized relocation combination: width=" << Width

482 << " kind=" << Kind;

484}

485

486

487

489HexagonMCCodeEmitter::getFixupNoBits(MCInstrInfo const &MCII, const MCInst &MI,

494 using namespace Hexagon;

495

499 for (auto I = Instrs.begin(), N = Instrs.end(); I != N; ++I) {

500 if (I->getInst() != &MI)

501 continue;

502 assert(I+1 != N && "Extender cannot be last in packet");

503 const MCInst &NextI = *(I+1)->getInst();

509 }

510 }

511

512 static const std::map<unsigned, unsigned> Relocs = {

524 };

525

526 auto F = Relocs.find(VarKind);

527 if (F != Relocs.end())

530 }

531

534

535 static const std::map<unsigned, unsigned> RelocsLo = {

545 };

546

547 static const std::map<unsigned, unsigned> RelocsHi = {

557 };

558

560 case Hexagon::LO:

561 case Hexagon::A2_tfril: {

562 auto F = RelocsLo.find(VarKind);

563 if (F != RelocsLo.end())

565 break;

566 }

567 case Hexagon::HI:

568 case Hexagon::A2_tfrih: {

569 auto F = RelocsHi.find(VarKind);

570 if (F != RelocsHi.end())

572 break;

573 }

574 }

575

577}

578

580 switch (Kind){

599 return true;

600 default:

601 return false;

602 }

603}

604

605unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,

611 if (ME->evaluateAsAbsolute(Value)) {

614

615

616

618 if (State.Extended && InstExtendable && !IsSub0) {

619 unsigned OpIdx = ~0u;

620 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {

621 if (&MO != &MI.getOperand(I))

622 continue;

624 break;

625 }

630 }

631 }

633 }

638 getExprOpValue(MI, MO, Binary->getLHS(), Fixups, STI);

639 getExprOpValue(MI, MO, Binary->getRHS(), Fixups, STI);

640 return 0;

641 }

642

644 const MCSymbolRefExpr *MCSRE = static_cast<const MCSymbolRefExpr *>(ME);

651

652 LLVM_DEBUG(dbgs() << "----------------------------------------\n"

654 << "\nOpcode: " << Opc << "\nRelocation bits: "

655 << FixupWidth << "\nAddend: " << State.Addend

656 << "\nVariant: " << unsigned(VarKind)

657 << "\n----------------------------------------\n");

658

659

660

661

662 if (FixupWidth == 16 && !State.Extended) {

665

667 } else {

668

673 };

674 assert(Shift < std::size(GPRelFixups));

675 auto UsesGP = [](const MCInstrDesc &D) {

676 return is_contained(D.implicit_uses(), Hexagon::GP);

677 };

678 if (UsesGP(MCID))

680 }

682

683 if (Opc == Hexagon::LO)

685 else if (Opc == Hexagon::HI)

687 }

688 } else {

690 switch (FixupWidth) {

691 case 9:

692 if (BranchOrCR)

695 break;

696 case 8:

697 case 7:

702 else if (FixupWidth == 7 && BranchOrCR)

705 break;

706 case 0:

707 FixupKind = getFixupNoBits(MCII, MI, MO, VarKind);

708 break;

709 }

710 }

711

714

715 auto FindVK = FixupTable.find(VarKind);

716 if (FindVK != FixupTable.end())

717 FixupKind = FindVK->second[FixupWidth];

718 }

719

722

723 const MCExpr *FixupExpr = MO.getExpr();

727 }

728

730 return 0;

731}

732

733unsigned

737 size_t OperandNumber = ~0U;

738 for (unsigned i = 0, n = MI.getNumOperands(); i < n; ++i)

739 if (&MI.getOperand(i) == &MO) {

740 OperandNumber = i;

741 break;

742 }

743 assert((OperandNumber != ~0U) && "Operand not found");

744

747

748 unsigned SOffset = 0;

749 unsigned VOffset = 0;

753

755 const MCOperand *I = Instrs.begin() + State.Index - 1;

756

757 for (;; --I) {

758 assert(I != Instrs.begin() - 1 && "Couldn't find producer");

759 MCInst const &Inst = *I->getInst();

761 continue;

762

765 ++SOffset;

767

768 ++VOffset;

769 }

775

776 continue;

777 }

779

780 break;

781 }

783 "Unpredicated consumer depending on predicated producer");

786

787 break;

788 }

789

791 : SOffset;

795 }

796

798 if (MO.isReg()) {

801 .operands()[OperandNumber]

802 .RegClass) {

803 case GeneralSubRegsRegClassID:

804 case GeneralDoubleLow8RegsRegClassID:

806 default:

807 break;

808 }

809 return MCT.getRegisterInfo()->getEncodingValue(Reg);

810 }

811

812 return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI);

813}

814

819

820#include "HexagonGenMCCodeEmitter.inc"

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static Register UseReg(const MachineOperand &MO)

static const std::map< unsigned, std::vector< unsigned > > ExtFixups

Definition HexagonMCCodeEmitter.cpp:48

#define P(x)

Definition HexagonMCCodeEmitter.cpp:47

static bool RegisterMatches(MCRegister Consumer, MCRegister Producer, MCRegister Producer2)

Definition HexagonMCCodeEmitter.cpp:419

static const unsigned fixup_Invalid

Definition HexagonMCCodeEmitter.cpp:43

static void raise_relocation_error(unsigned Width, unsigned Kind)

Definition HexagonMCCodeEmitter.cpp:478

static bool isPCRel(unsigned Kind)

Definition HexagonMCCodeEmitter.cpp:579

static const std::map< unsigned, std::vector< unsigned > > StdFixups

Definition HexagonMCCodeEmitter.cpp:172

#define _

Definition HexagonMCCodeEmitter.cpp:46

Definition for classes that emit Hexagon machine code from MCInsts.

#define HEXAGON_INSTR_SIZE

MachineInstr unsigned OpIdx

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

void encodeSingleInstruction(const MCInst &MI, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI, uint32_t Parse) const

Definition HexagonMCCodeEmitter.cpp:426

unsigned getMachineOpValue(MCInst const &MI, MCOperand const &MO, SmallVectorImpl< MCFixup > &Fixups, MCSubtargetInfo const &STI) const

Return binary encoding of operand.

Definition HexagonMCCodeEmitter.cpp:734

uint64_t getBinaryCodeForInstr(MCInst const &MI, SmallVectorImpl< MCFixup > &Fixups, MCSubtargetInfo const &STI) const

void encodeInstruction(MCInst const &MI, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, MCSubtargetInfo const &STI) const override

Emit the bundle.

Definition HexagonMCCodeEmitter.cpp:395

static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

MCCodeEmitter - Generic instruction encoding interface.

static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

Base class for the full range of assembler expressions which are needed for parsing.

@ SymbolRef

References to labels and assigned expressions.

@ Binary

Binary expressions.

static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)

Consider bit fields if we need more flags.

Instances of this class represent a single low-level machine instruction.

bool isBranch() const

Returns true if this is a conditional, unconditional, or indirect branch.

bool isCall() const

Return true if the instruction is a call.

unsigned getOpcode() const

Return the opcode number for this descriptor.

Interface to description of machine instruction set.

Instances of this class represent operands of the MCInst class.

MCRegister getReg() const

Returns the register number.

const MCExpr * getExpr() const

Wrapper class representing physical registers. Should be passed by value.

Generic base class for all target subtargets.

uint16_t getSpecifier() const

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

A raw_ostream that writes to an std::string.

std::string & str()

Returns the string's reference.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ C

The default llvm calling convention, compatible with C.

bool isExtentSigned(MCInstrInfo const &MCII, MCInst const &MCI)

bool isOuterLoop(MCInst const &MCI)

size_t bundleSize(MCInst const &MCI)

bool isDuplex(MCInstrInfo const &MCII, MCInst const &MCI)

bool IsSingleConsumerRefPairProducer(MCRegister Producer, MCRegister Consumer)

unsigned getExtentBits(MCInstrInfo const &MCII, MCInst const &MCI)

bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI)

Return whether the insn expects newly produced value.

unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI)

MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)

iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)

bool isBundle(MCInst const &MCI)

MCExpr const & getExpr(MCExpr const &Expr)

bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)

unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)

Return the Hexagon ISA class for the insn.

bool isImmext(MCInst const &MCI)

MCOperand const & getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI)

bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI)

unsigned SubregisterBit(MCRegister Consumer, MCRegister Producer, MCRegister Producer2)

bool s27_2_reloc(MCExpr const &Expr)

bool isInnerLoop(MCInst const &MCI)

bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI)

Return whether the insn produces a second value.

unsigned getExtentAlignment(MCInstrInfo const &MCII, MCInst const &MCI)

StringRef getName(MCInstrInfo const &MCII, MCInst const &MCI)

bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI)

bool isVector(MCInstrInfo const &MCII, MCInst const &MCI)

bool isSubInstruction(MCInst const &MCI)

MCOperand const & getNewValueOperand2(MCInstrInfo const &MCII, MCInst const &MCI)

unsigned getDuplexRegisterNumbering(MCRegister Reg)

bool isExtended(MCInstrInfo const &MCII, MCInst const &MCI)

bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI)

Return whether the insn produces a value.

@ fixup_Hexagon_LD_PLT_B32_PCREL_X

@ fixup_Hexagon_GPREL16_3

@ fixup_Hexagon_GD_GOT_HI16

@ fixup_Hexagon_LD_PLT_B22_PCREL

@ fixup_Hexagon_TPREL_32_6_X

@ fixup_Hexagon_B7_PCREL_X

@ fixup_Hexagon_B13_PCREL

@ fixup_Hexagon_DTPREL_HI16

@ fixup_Hexagon_IE_GOT_LO16

@ fixup_Hexagon_LD_PLT_B22_PCREL_X

@ fixup_Hexagon_GD_GOT_32_6_X

@ fixup_Hexagon_LD_GOT_HI16

@ fixup_Hexagon_B13_PCREL_X

@ fixup_Hexagon_GOTREL_HI16

@ fixup_Hexagon_IE_GOT_32_6_X

@ fixup_Hexagon_PLT_B22_PCREL

@ fixup_Hexagon_B32_PCREL_X

@ fixup_Hexagon_DTPREL_32_6_X

@ fixup_Hexagon_GD_GOT_LO16

@ fixup_Hexagon_GD_PLT_B32_PCREL_X

@ fixup_Hexagon_GPREL16_2

@ fixup_Hexagon_GPREL16_1

@ fixup_Hexagon_DTPREL_LO16

@ fixup_Hexagon_B15_PCREL

@ fixup_Hexagon_GPREL16_0

@ fixup_Hexagon_6_PCREL_X

@ fixup_Hexagon_GD_PLT_B22_PCREL_X

@ fixup_Hexagon_GD_PLT_B22_PCREL

@ fixup_Hexagon_B22_PCREL

@ fixup_Hexagon_TPREL_LO16

@ fixup_Hexagon_TPREL_HI16

@ fixup_Hexagon_LD_GOT_32_6_X

@ fixup_Hexagon_LD_GOT_LO16

@ fixup_Hexagon_GOTREL_LO16

@ fixup_Hexagon_IE_GOT_HI16

@ fixup_Hexagon_GOT_32_6_X

@ fixup_Hexagon_B15_PCREL_X

@ fixup_Hexagon_B22_PCREL_X

@ fixup_Hexagon_IE_32_6_X

@ fixup_Hexagon_GOTREL_32_6_X

@ fixup_Hexagon_B9_PCREL_X

void write(void *memory, value_type value, endianness endian)

Write a value to memory with a particular endianness.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

MCCodeEmitter * createHexagonMCCodeEmitter(const MCInstrInfo &MCII, MCContext &MCT)

Definition HexagonMCCodeEmitter.cpp:815

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

static Lanai::Fixups FixupKind(const MCExpr *Expr)

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind)

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.