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

1

2

3

4

5

6

7

8

30#include

31#include

32#include

33#include

34#include

35#include

36

37#define DEBUG_TYPE "mccodeemitter"

38

39using namespace llvm;

40using namespace Hexagon;

41

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

43

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

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

340 MCInst const &MCI) const {

342 if (State.Index == 0) {

347 }

348 }

349 if (State.Index == 1) {

354 }

355 }

356 if (Duplex) {

359 }

360 if (State.Index == Last)

363}

364

365

371

374 State.Addend = 0;

375 State.Extended = false;

376 State.Bundle = &MI;

377 State.Index = 0;

379

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

382

386 ++State.Index;

387 }

388}

389

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

394 Consumer);

395}

396

403

404

405

407 "pseudo-instruction found");

410

412 unsigned Opc = MI.getOpcode();

413

414

415

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

420 }

421 Binary |= Parse;

422

423

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

426 "Emitting duplex without duplex parse bits");

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

428

429

430

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

438

439 State.SubInst1 = true;

441 State.SubInst1 = false;

442

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

444 }

446 ++MCNumEmitted;

447}

448

450 std::string Text;

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

453 << " kind=" << Kind;

455}

456

457

458

464 using namespace Hexagon;

465

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();

479 }

480 }

481

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

494 };

495

496 auto F = Relocs.find(VarKind);

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

500 }

501

504

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

515 };

516

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

527 };

528

530 case Hexagon::LO:

531 case Hexagon::A2_tfril: {

532 auto F = RelocsLo.find(VarKind);

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

535 break;

536 }

537 case Hexagon::HI:

538 case Hexagon::A2_tfrih: {

539 auto F = RelocsHi.find(VarKind);

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

542 break;

543 }

544 }

545

547}

548

550 switch (Kind){

569 return true;

570 default:

571 return false;

572 }

573}

574

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

578 if (isa(ME))

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

584

585

586

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);

600 }

601 }

603 }

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

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

610 return 0;

611 }

612

621

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

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

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

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

627 << "\n----------------------------------------\n");

628

629

630

631

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

635

637 } else {

638

643 };

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

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

647 };

648 if (UsesGP(MCID))

650 }

652

653 if (Opc == Hexagon::LO)

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

657 }

658 } else {

660 switch (FixupWidth) {

661 case 9:

662 if (BranchOrCR)

665 break;

666 case 8:

667 case 7:

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

675 break;

676 case 0:

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

678 break;

679 }

680 }

681

684

685 auto FindVK = FixupTable.find(VarKind);

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

687 FixupKind = FindVK->second[FixupWidth];

688 }

689

692

694 if (State.Addend != 0 && isPCRel(FixupKind)) {

697 }

698

702

703 return 0;

704}

705

706unsigned

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

720

721 unsigned SOffset = 0;

722 unsigned VOffset = 0;

726

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();

734 continue;

735

738 ++SOffset;

740

741 ++VOffset;

742 }

748

749 continue;

750 }

752

753 break;

754 }

756 "Unpredicated consumer depending on predicated producer");

759

760 break;

761 }

762

764 : SOffset;

768 }

769

771 if (MO.isReg()) {

774 .operands()[OperandNumber]

775 .RegClass) {

776 case GeneralSubRegsRegClassID:

777 case GeneralDoubleLow8RegsRegClassID:

779 default:

780 break;

781 }

783 }

784

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

786}

787

791}

792

793#include "HexagonGenMCCodeEmitter.inc"

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

static Register UseReg(const MachineOperand &MO)

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

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

static const unsigned fixup_Invalid

static void raise_relocation_error(unsigned Width, unsigned Kind)

static bool isPCRel(unsigned Kind)

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

Definition for classes that emit Hexagon machine code from MCInsts.

#define HEXAGON_INSTR_SIZE

PowerPC TLS Dynamic Call Fixup

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

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

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

Return binary encoding of operand.

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.

Binary assembler expressions.

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

MCCodeEmitter - Generic instruction encoding interface.

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

Context object for machine code objects.

const MCRegisterInfo * getRegisterInfo() const

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

@ SymbolRef

References to labels and assigned expressions.

@ Binary

Binary expressions.

Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...

static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())

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

Describe properties that are true of each instruction in the target description file.

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

uint16_t getEncodingValue(MCRegister Reg) const

Returns the encoding for Reg.

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

Generic base class for all target subtargets.

Represent a reference to a symbol from inside an expression.

VariantKind getKind() 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

This is an optimization pass for GlobalISel generic memory operations.

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

raw_ostream & dbgs()

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

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

MCFixupKind

Extensible enumeration to represent the type of a fixup.

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

Returns true if Element is found in Range.