1 //===- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions -------------===//
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
7 //===----------------------------------------------------------------------===//
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/Endian.h"
28 #include "llvm/Support/EndianStream.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mccodeemitter"
41 using namespace Hexagon
;
43 STATISTIC(MCNumEmitted
, "Number of MC instructions emitted");
45 static const unsigned fixup_Invalid
= ~0u;
47 #define _ fixup_Invalid
48 #define P(x) Hexagon::fixup_Hexagon##x
49 static const std::map
<unsigned, std::vector
<unsigned>> ExtFixups
= {
50 { MCSymbolRefExpr::VK_DTPREL
,
52 _
, _
, P(_DTPREL_16_X
), P(_DTPREL_11_X
),
53 P(_DTPREL_11_X
), P(_9_X
), _
, P(_DTPREL_11_X
),
54 P(_DTPREL_16_X
), _
, _
, _
,
55 P(_DTPREL_16_X
), _
, _
, _
,
60 { MCSymbolRefExpr::VK_GOT
,
62 _
, _
, P(_GOT_11_X
), _
/* [1] */,
63 _
/* [1] */, P(_9_X
), _
, P(_GOT_11_X
),
64 P(_GOT_16_X
), _
, _
, _
,
65 P(_GOT_16_X
), _
, _
, _
,
70 { MCSymbolRefExpr::VK_GOTREL
,
72 _
, _
, P(_GOTREL_11_X
), P(_GOTREL_11_X
),
73 P(_GOTREL_11_X
), P(_9_X
), _
, P(_GOTREL_11_X
),
74 P(_GOTREL_16_X
), _
, _
, _
,
75 P(_GOTREL_16_X
), _
, _
, _
,
80 { MCSymbolRefExpr::VK_TPREL
,
82 _
, _
, P(_TPREL_16_X
), P(_TPREL_11_X
),
83 P(_TPREL_11_X
), P(_9_X
), _
, P(_TPREL_11_X
),
84 P(_TPREL_16_X
), _
, _
, _
,
85 P(_TPREL_16_X
), _
, _
, _
,
90 { MCSymbolRefExpr::VK_Hexagon_GD_GOT
,
92 _
, _
, P(_GD_GOT_16_X
), P(_GD_GOT_11_X
),
93 P(_GD_GOT_11_X
), P(_9_X
), _
, P(_GD_GOT_11_X
),
94 P(_GD_GOT_16_X
), _
, _
, _
,
95 P(_GD_GOT_16_X
), _
, _
, _
,
100 { MCSymbolRefExpr::VK_Hexagon_GD_PLT
,
103 _
, P(_9_X
), _
, P(_GD_PLT_B22_PCREL_X
),
106 _
, _
, P(_GD_PLT_B22_PCREL_X
), _
,
110 { MCSymbolRefExpr::VK_Hexagon_IE
,
112 _
, _
, P(_IE_16_X
), _
,
114 P(_IE_16_X
), _
, _
, _
,
115 P(_IE_16_X
), _
, _
, _
,
120 { MCSymbolRefExpr::VK_Hexagon_IE_GOT
,
122 _
, _
, P(_IE_GOT_11_X
), P(_IE_GOT_11_X
),
123 P(_IE_GOT_11_X
), P(_9_X
), _
, P(_IE_GOT_11_X
),
124 P(_IE_GOT_16_X
), _
, _
, _
,
125 P(_IE_GOT_16_X
), _
, _
, _
,
129 P(_IE_GOT_32_6_X
) }},
130 { MCSymbolRefExpr::VK_Hexagon_LD_GOT
,
132 _
, _
, P(_LD_GOT_11_X
), P(_LD_GOT_11_X
),
133 P(_LD_GOT_11_X
), P(_9_X
), _
, P(_LD_GOT_11_X
),
134 P(_LD_GOT_16_X
), _
, _
, _
,
135 P(_LD_GOT_16_X
), _
, _
, _
,
139 P(_LD_GOT_32_6_X
) }},
140 { MCSymbolRefExpr::VK_Hexagon_LD_PLT
,
143 _
, P(_9_X
), _
, P(_LD_PLT_B22_PCREL_X
),
146 _
, _
, P(_LD_PLT_B22_PCREL_X
), _
,
150 { MCSymbolRefExpr::VK_PCREL
,
152 _
, _
, P(_6_PCREL_X
), _
,
160 { MCSymbolRefExpr::VK_None
,
162 _
, _
, P(_6_X
), P(_8_X
),
163 P(_8_X
), P(_9_X
), P(_10_X
), P(_11_X
),
164 P(_12_X
), P(_B13_PCREL
), _
, P(_B15_PCREL_X
),
166 _
, _
, P(_B22_PCREL_X
), _
,
171 // [1] The fixup is GOT_16_X for signed values and GOT_11_X for unsigned.
173 static const std::map
<unsigned, std::vector
<unsigned>> StdFixups
= {
174 { MCSymbolRefExpr::VK_DTPREL
,
179 P(_DTPREL_16
), _
, _
, _
,
184 { MCSymbolRefExpr::VK_GOT
,
194 { MCSymbolRefExpr::VK_GOTREL
,
199 _
/* [2] */, _
, _
, _
,
204 { MCSymbolRefExpr::VK_PLT
,
210 _
, _
, P(_PLT_B22_PCREL
), _
,
214 { MCSymbolRefExpr::VK_TPREL
,
217 _
, _
, _
, P(_TPREL_11_X
),
219 P(_TPREL_16
), _
, _
, _
,
224 { MCSymbolRefExpr::VK_Hexagon_GD_GOT
,
229 P(_GD_GOT_16
), _
, _
, _
,
234 { MCSymbolRefExpr::VK_Hexagon_GD_PLT
,
240 _
, _
, P(_GD_PLT_B22_PCREL
), _
,
244 { MCSymbolRefExpr::VK_Hexagon_GPREL
,
249 P(_GPREL16_0
), _
, _
, _
,
254 { MCSymbolRefExpr::VK_Hexagon_HI16
,
264 { MCSymbolRefExpr::VK_Hexagon_IE
,
274 { MCSymbolRefExpr::VK_Hexagon_IE_GOT
,
279 P(_IE_GOT_16
), _
, _
, _
,
284 { MCSymbolRefExpr::VK_Hexagon_LD_GOT
,
289 P(_LD_GOT_16
), _
, _
, _
,
294 { MCSymbolRefExpr::VK_Hexagon_LD_PLT
,
300 _
, _
, P(_LD_PLT_B22_PCREL
), _
,
304 { MCSymbolRefExpr::VK_Hexagon_LO16
,
314 { MCSymbolRefExpr::VK_PCREL
,
324 { MCSymbolRefExpr::VK_None
,
328 _
, P(_B13_PCREL
), _
, P(_B15_PCREL
),
330 _
, _
, P(_B22_PCREL
), _
,
336 // [2] The actual fixup is LO16 or HI16, depending on the instruction.
340 uint32_t HexagonMCCodeEmitter::parseBits(size_t Last
, MCInst
const &MCB
,
341 MCInst
const &MCI
) const {
342 bool Duplex
= HexagonMCInstrInfo::isDuplex(MCII
, MCI
);
343 if (State
.Index
== 0) {
344 if (HexagonMCInstrInfo::isInnerLoop(MCB
)) {
346 assert(State
.Index
!= Last
);
347 return HexagonII::INST_PARSE_LOOP_END
;
350 if (State
.Index
== 1) {
351 if (HexagonMCInstrInfo::isOuterLoop(MCB
)) {
353 assert(State
.Index
!= Last
);
354 return HexagonII::INST_PARSE_LOOP_END
;
358 assert(State
.Index
== Last
);
359 return HexagonII::INST_PARSE_DUPLEX
;
361 if (State
.Index
== Last
)
362 return HexagonII::INST_PARSE_PACKET_END
;
363 return HexagonII::INST_PARSE_NOT_END
;
367 void HexagonMCCodeEmitter::encodeInstruction(const MCInst
&MI
, raw_ostream
&OS
,
368 SmallVectorImpl
<MCFixup
> &Fixups
,
369 const MCSubtargetInfo
&STI
) const {
370 MCInst
&HMB
= const_cast<MCInst
&>(MI
);
372 assert(HexagonMCInstrInfo::isBundle(HMB
));
373 LLVM_DEBUG(dbgs() << "Encoding bundle\n";);
375 State
.Extended
= false;
378 size_t Last
= HexagonMCInstrInfo::bundleSize(HMB
) - 1;
379 FeatureBitset Features
= computeAvailableFeatures(STI
.getFeatureBits());
381 for (auto &I
: HexagonMCInstrInfo::bundleInstructions(HMB
)) {
382 MCInst
&HMI
= const_cast<MCInst
&>(*I
.getInst());
383 verifyInstructionPredicates(HMI
, Features
);
385 EncodeSingleInstruction(HMI
, OS
, Fixups
, STI
, parseBits(Last
, HMB
, HMI
));
386 State
.Extended
= HexagonMCInstrInfo::isImmext(HMI
);
387 State
.Addend
+= HEXAGON_INSTR_SIZE
;
392 static bool RegisterMatches(unsigned Consumer
, unsigned Producer
,
393 unsigned Producer2
) {
394 return (Consumer
== Producer
) || (Consumer
== Producer2
) ||
395 HexagonMCInstrInfo::IsSingleConsumerRefPairProducer(Producer
,
399 /// EncodeSingleInstruction - Emit a single
400 void HexagonMCCodeEmitter::EncodeSingleInstruction(const MCInst
&MI
,
401 raw_ostream
&OS
, SmallVectorImpl
<MCFixup
> &Fixups
,
402 const MCSubtargetInfo
&STI
, uint32_t Parse
) const {
403 assert(!HexagonMCInstrInfo::isBundle(MI
));
406 // Pseudo instructions don't get encoded and shouldn't be here
407 // in the first place!
408 assert(!HexagonMCInstrInfo::getDesc(MCII
, MI
).isPseudo() &&
409 "pseudo-instruction found");
410 LLVM_DEBUG(dbgs() << "Encoding insn `"
411 << HexagonMCInstrInfo::getName(MCII
, MI
) << "'\n");
413 Binary
= getBinaryCodeForInstr(MI
, Fixups
, STI
);
414 unsigned Opc
= MI
.getOpcode();
416 // Check for unimplemented instructions. Immediate extenders
417 // are encoded as zero, so they need to be accounted for.
418 if (!Binary
&& Opc
!= DuplexIClass0
&& Opc
!= A4_ext
) {
419 LLVM_DEBUG(dbgs() << "Unimplemented inst `"
420 << HexagonMCInstrInfo::getName(MCII
, MI
) << "'\n");
421 llvm_unreachable("Unimplemented Instruction");
425 // if we need to emit a duplexed instruction
426 if (Opc
>= Hexagon::DuplexIClass0
&& Opc
<= Hexagon::DuplexIClassF
) {
427 assert(Parse
== HexagonII::INST_PARSE_DUPLEX
&&
428 "Emitting duplex without duplex parse bits");
429 unsigned DupIClass
= MI
.getOpcode() - Hexagon::DuplexIClass0
;
430 // 29 is the bit position.
431 // 0b1110 =0xE bits are masked off and down shifted by 1 bit.
432 // Last bit is moved to bit position 13
433 Binary
= ((DupIClass
& 0xE) << (29 - 1)) | ((DupIClass
& 0x1) << 13);
435 const MCInst
*Sub0
= MI
.getOperand(0).getInst();
436 const MCInst
*Sub1
= MI
.getOperand(1).getInst();
438 // Get subinstruction slot 0.
439 unsigned SubBits0
= getBinaryCodeForInstr(*Sub0
, Fixups
, STI
);
440 // Get subinstruction slot 1.
441 State
.SubInst1
= true;
442 unsigned SubBits1
= getBinaryCodeForInstr(*Sub1
, Fixups
, STI
);
443 State
.SubInst1
= false;
445 Binary
|= SubBits0
| (SubBits1
<< 16);
447 support::endian::write
<uint32_t>(OS
, Binary
, support::little
);
451 [[noreturn
]] static void raise_relocation_error(unsigned Width
, unsigned Kind
) {
453 raw_string_ostream
Stream(Text
);
454 Stream
<< "Unrecognized relocation combination: width=" << Width
456 report_fatal_error(Stream
.str());
459 /// Some insns are not extended and thus have no bits. These cases require
460 /// a more brute force method for determining the correct relocation.
461 Hexagon::Fixups
HexagonMCCodeEmitter::getFixupNoBits(
462 MCInstrInfo
const &MCII
, const MCInst
&MI
, const MCOperand
&MO
,
463 const MCSymbolRefExpr::VariantKind VarKind
) const {
464 const MCInstrDesc
&MCID
= HexagonMCInstrInfo::getDesc(MCII
, MI
);
465 unsigned InsnType
= HexagonMCInstrInfo::getType(MCII
, MI
);
466 using namespace Hexagon
;
468 if (InsnType
== HexagonII::TypeEXTENDER
) {
469 if (VarKind
== MCSymbolRefExpr::VK_None
) {
470 auto Instrs
= HexagonMCInstrInfo::bundleInstructions(*State
.Bundle
);
471 for (auto I
= Instrs
.begin(), N
= Instrs
.end(); I
!= N
; ++I
) {
472 if (I
->getInst() != &MI
)
474 assert(I
+1 != N
&& "Extender cannot be last in packet");
475 const MCInst
&NextI
= *(I
+1)->getInst();
476 const MCInstrDesc
&NextD
= HexagonMCInstrInfo::getDesc(MCII
, NextI
);
477 if (NextD
.isBranch() || NextD
.isCall() ||
478 HexagonMCInstrInfo::getType(MCII
, NextI
) == HexagonII::TypeCR
)
479 return fixup_Hexagon_B32_PCREL_X
;
480 return fixup_Hexagon_32_6_X
;
484 static const std::map
<unsigned,unsigned> Relocs
= {
485 { MCSymbolRefExpr::VK_GOTREL
, fixup_Hexagon_GOTREL_32_6_X
},
486 { MCSymbolRefExpr::VK_GOT
, fixup_Hexagon_GOT_32_6_X
},
487 { MCSymbolRefExpr::VK_TPREL
, fixup_Hexagon_TPREL_32_6_X
},
488 { MCSymbolRefExpr::VK_DTPREL
, fixup_Hexagon_DTPREL_32_6_X
},
489 { MCSymbolRefExpr::VK_Hexagon_GD_GOT
, fixup_Hexagon_GD_GOT_32_6_X
},
490 { MCSymbolRefExpr::VK_Hexagon_LD_GOT
, fixup_Hexagon_LD_GOT_32_6_X
},
491 { MCSymbolRefExpr::VK_Hexagon_IE
, fixup_Hexagon_IE_32_6_X
},
492 { MCSymbolRefExpr::VK_Hexagon_IE_GOT
, fixup_Hexagon_IE_GOT_32_6_X
},
493 { MCSymbolRefExpr::VK_PCREL
, fixup_Hexagon_B32_PCREL_X
},
494 { MCSymbolRefExpr::VK_Hexagon_GD_PLT
, fixup_Hexagon_GD_PLT_B32_PCREL_X
},
495 { MCSymbolRefExpr::VK_Hexagon_LD_PLT
, fixup_Hexagon_LD_PLT_B32_PCREL_X
},
498 auto F
= Relocs
.find(VarKind
);
499 if (F
!= Relocs
.end())
500 return Hexagon::Fixups(F
->second
);
501 raise_relocation_error(0, VarKind
);
505 return fixup_Hexagon_B13_PCREL
;
507 static const std::map
<unsigned,unsigned> RelocsLo
= {
508 { MCSymbolRefExpr::VK_GOT
, fixup_Hexagon_GOT_LO16
},
509 { MCSymbolRefExpr::VK_GOTREL
, fixup_Hexagon_GOTREL_LO16
},
510 { MCSymbolRefExpr::VK_Hexagon_GD_GOT
, fixup_Hexagon_GD_GOT_LO16
},
511 { MCSymbolRefExpr::VK_Hexagon_LD_GOT
, fixup_Hexagon_LD_GOT_LO16
},
512 { MCSymbolRefExpr::VK_Hexagon_IE
, fixup_Hexagon_IE_LO16
},
513 { MCSymbolRefExpr::VK_Hexagon_IE_GOT
, fixup_Hexagon_IE_GOT_LO16
},
514 { MCSymbolRefExpr::VK_TPREL
, fixup_Hexagon_TPREL_LO16
},
515 { MCSymbolRefExpr::VK_DTPREL
, fixup_Hexagon_DTPREL_LO16
},
516 { MCSymbolRefExpr::VK_None
, fixup_Hexagon_LO16
},
519 static const std::map
<unsigned,unsigned> RelocsHi
= {
520 { MCSymbolRefExpr::VK_GOT
, fixup_Hexagon_GOT_HI16
},
521 { MCSymbolRefExpr::VK_GOTREL
, fixup_Hexagon_GOTREL_HI16
},
522 { MCSymbolRefExpr::VK_Hexagon_GD_GOT
, fixup_Hexagon_GD_GOT_HI16
},
523 { MCSymbolRefExpr::VK_Hexagon_LD_GOT
, fixup_Hexagon_LD_GOT_HI16
},
524 { MCSymbolRefExpr::VK_Hexagon_IE
, fixup_Hexagon_IE_HI16
},
525 { MCSymbolRefExpr::VK_Hexagon_IE_GOT
, fixup_Hexagon_IE_GOT_HI16
},
526 { MCSymbolRefExpr::VK_TPREL
, fixup_Hexagon_TPREL_HI16
},
527 { MCSymbolRefExpr::VK_DTPREL
, fixup_Hexagon_DTPREL_HI16
},
528 { MCSymbolRefExpr::VK_None
, fixup_Hexagon_HI16
},
531 switch (MCID
.getOpcode()) {
533 case Hexagon::A2_tfril
: {
534 auto F
= RelocsLo
.find(VarKind
);
535 if (F
!= RelocsLo
.end())
536 return Hexagon::Fixups(F
->second
);
540 case Hexagon::A2_tfrih
: {
541 auto F
= RelocsHi
.find(VarKind
);
542 if (F
!= RelocsHi
.end())
543 return Hexagon::Fixups(F
->second
);
548 raise_relocation_error(0, VarKind
);
551 static bool isPCRel(unsigned Kind
) {
553 case fixup_Hexagon_B22_PCREL
:
554 case fixup_Hexagon_B15_PCREL
:
555 case fixup_Hexagon_B7_PCREL
:
556 case fixup_Hexagon_B13_PCREL
:
557 case fixup_Hexagon_B9_PCREL
:
558 case fixup_Hexagon_B32_PCREL_X
:
559 case fixup_Hexagon_B22_PCREL_X
:
560 case fixup_Hexagon_B15_PCREL_X
:
561 case fixup_Hexagon_B13_PCREL_X
:
562 case fixup_Hexagon_B9_PCREL_X
:
563 case fixup_Hexagon_B7_PCREL_X
:
564 case fixup_Hexagon_32_PCREL
:
565 case fixup_Hexagon_PLT_B22_PCREL
:
566 case fixup_Hexagon_GD_PLT_B22_PCREL
:
567 case fixup_Hexagon_LD_PLT_B22_PCREL
:
568 case fixup_Hexagon_GD_PLT_B22_PCREL_X
:
569 case fixup_Hexagon_LD_PLT_B22_PCREL_X
:
570 case fixup_Hexagon_6_PCREL_X
:
577 unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst
&MI
,
578 const MCOperand
&MO
, const MCExpr
*ME
, SmallVectorImpl
<MCFixup
> &Fixups
,
579 const MCSubtargetInfo
&STI
) const {
580 if (isa
<HexagonMCExpr
>(ME
))
581 ME
= &HexagonMCInstrInfo::getExpr(*ME
);
583 if (ME
->evaluateAsAbsolute(Value
)) {
584 bool InstExtendable
= HexagonMCInstrInfo::isExtendable(MCII
, MI
) ||
585 HexagonMCInstrInfo::isExtended(MCII
, MI
);
586 // Only sub-instruction #1 can be extended in a duplex. If MI is a
587 // sub-instruction #0, it is not extended even if Extended is true
588 // (it can be true for the duplex as a whole).
589 bool IsSub0
= HexagonMCInstrInfo::isSubInstruction(MI
) && !State
.SubInst1
;
590 if (State
.Extended
&& InstExtendable
&& !IsSub0
) {
591 unsigned OpIdx
= ~0u;
592 for (unsigned I
= 0, E
= MI
.getNumOperands(); I
!= E
; ++I
) {
593 if (&MO
!= &MI
.getOperand(I
))
598 assert(OpIdx
!= ~0u);
599 if (OpIdx
== HexagonMCInstrInfo::getExtendableOp(MCII
, MI
)) {
600 unsigned Shift
= HexagonMCInstrInfo::getExtentAlignment(MCII
, MI
);
601 Value
= (Value
& 0x3f) << Shift
;
606 assert(ME
->getKind() == MCExpr::SymbolRef
||
607 ME
->getKind() == MCExpr::Binary
);
608 if (ME
->getKind() == MCExpr::Binary
) {
609 MCBinaryExpr
const *Binary
= cast
<MCBinaryExpr
>(ME
);
610 getExprOpValue(MI
, MO
, Binary
->getLHS(), Fixups
, STI
);
611 getExprOpValue(MI
, MO
, Binary
->getRHS(), Fixups
, STI
);
615 unsigned FixupKind
= fixup_Invalid
;
616 const MCSymbolRefExpr
*MCSRE
= static_cast<const MCSymbolRefExpr
*>(ME
);
617 const MCInstrDesc
&MCID
= HexagonMCInstrInfo::getDesc(MCII
, MI
);
618 unsigned FixupWidth
= HexagonMCInstrInfo::getExtentBits(MCII
, MI
) -
619 HexagonMCInstrInfo::getExtentAlignment(MCII
, MI
);
620 MCSymbolRefExpr::VariantKind VarKind
= MCSRE
->getKind();
621 unsigned Opc
= MCID
.getOpcode();
622 unsigned IType
= HexagonMCInstrInfo::getType(MCII
, MI
);
624 LLVM_DEBUG(dbgs() << "----------------------------------------\n"
625 << "Opcode Name: " << HexagonMCInstrInfo::getName(MCII
, MI
)
626 << "\nOpcode: " << Opc
<< "\nRelocation bits: "
627 << FixupWidth
<< "\nAddend: " << State
.Addend
628 << "\nVariant: " << unsigned(VarKind
)
629 << "\n----------------------------------------\n");
631 // Pick the applicable fixup kind for the symbol.
632 // Handle special cases first, the rest will be looked up in the tables.
634 if (FixupWidth
== 16 && !State
.Extended
) {
635 if (VarKind
== MCSymbolRefExpr::VK_None
) {
636 if (HexagonMCInstrInfo::s27_2_reloc(*MO
.getExpr())) {
638 FixupKind
= Hexagon::fixup_Hexagon_27_REG
;
640 // Look for GP-relative fixups.
641 unsigned Shift
= HexagonMCInstrInfo::getExtentAlignment(MCII
, MI
);
642 static const Hexagon::Fixups GPRelFixups
[] = {
643 Hexagon::fixup_Hexagon_GPREL16_0
, Hexagon::fixup_Hexagon_GPREL16_1
,
644 Hexagon::fixup_Hexagon_GPREL16_2
, Hexagon::fixup_Hexagon_GPREL16_3
646 assert(Shift
< array_lengthof(GPRelFixups
));
647 auto UsesGP
= [] (const MCInstrDesc
&D
) {
648 for (const MCPhysReg
*U
= D
.getImplicitUses(); U
&& *U
; ++U
)
649 if (*U
== Hexagon::GP
)
654 FixupKind
= GPRelFixups
[Shift
];
656 } else if (VarKind
== MCSymbolRefExpr::VK_GOTREL
) {
657 // Select between LO/HI.
658 if (Opc
== Hexagon::LO
)
659 FixupKind
= Hexagon::fixup_Hexagon_GOTREL_LO16
;
660 else if (Opc
== Hexagon::HI
)
661 FixupKind
= Hexagon::fixup_Hexagon_GOTREL_HI16
;
664 bool BranchOrCR
= MCID
.isBranch() || IType
== HexagonII::TypeCR
;
665 switch (FixupWidth
) {
668 FixupKind
= State
.Extended
? Hexagon::fixup_Hexagon_B9_PCREL_X
669 : Hexagon::fixup_Hexagon_B9_PCREL
;
673 if (State
.Extended
&& VarKind
== MCSymbolRefExpr::VK_GOT
)
674 FixupKind
= HexagonMCInstrInfo::isExtentSigned(MCII
, MI
)
675 ? Hexagon::fixup_Hexagon_GOT_16_X
676 : Hexagon::fixup_Hexagon_GOT_11_X
;
677 else if (FixupWidth
== 7 && BranchOrCR
)
678 FixupKind
= State
.Extended
? Hexagon::fixup_Hexagon_B7_PCREL_X
679 : Hexagon::fixup_Hexagon_B7_PCREL
;
682 FixupKind
= getFixupNoBits(MCII
, MI
, MO
, VarKind
);
687 if (FixupKind
== fixup_Invalid
) {
688 const auto &FixupTable
= State
.Extended
? ExtFixups
: StdFixups
;
690 auto FindVK
= FixupTable
.find(VarKind
);
691 if (FindVK
!= FixupTable
.end())
692 FixupKind
= FindVK
->second
[FixupWidth
];
695 if (FixupKind
== fixup_Invalid
)
696 raise_relocation_error(FixupWidth
, VarKind
);
698 const MCExpr
*FixupExpr
= MO
.getExpr();
699 if (State
.Addend
!= 0 && isPCRel(FixupKind
)) {
700 const MCExpr
*C
= MCConstantExpr::create(State
.Addend
, MCT
);
701 FixupExpr
= MCBinaryExpr::createAdd(FixupExpr
, C
, MCT
);
704 MCFixup Fixup
= MCFixup::create(State
.Addend
, FixupExpr
,
705 MCFixupKind(FixupKind
), MI
.getLoc());
706 Fixups
.push_back(Fixup
);
707 // All of the information is in the fixup.
712 HexagonMCCodeEmitter::getMachineOpValue(MCInst
const &MI
, MCOperand
const &MO
,
713 SmallVectorImpl
<MCFixup
> &Fixups
,
714 MCSubtargetInfo
const &STI
) const {
716 size_t OperandNumber
= ~0U;
717 for (unsigned i
= 0, n
= MI
.getNumOperands(); i
< n
; ++i
)
718 if (&MI
.getOperand(i
) == &MO
) {
722 assert((OperandNumber
!= ~0U) && "Operand not found");
725 if (HexagonMCInstrInfo::isNewValue(MCII
, MI
) &&
726 &MO
== &HexagonMCInstrInfo::getNewValueOperand(MCII
, MI
)) {
727 // Calculate the new value distance to the associated producer
728 unsigned SOffset
= 0;
729 unsigned VOffset
= 0;
730 unsigned UseReg
= MO
.getReg();
731 unsigned DefReg1
= Hexagon::NoRegister
;
732 unsigned DefReg2
= Hexagon::NoRegister
;
734 auto Instrs
= HexagonMCInstrInfo::bundleInstructions(*State
.Bundle
);
735 const MCOperand
*I
= Instrs
.begin() + State
.Index
- 1;
738 assert(I
!= Instrs
.begin() - 1 && "Couldn't find producer");
739 MCInst
const &Inst
= *I
->getInst();
740 if (HexagonMCInstrInfo::isImmext(Inst
))
743 DefReg1
= Hexagon::NoRegister
;
744 DefReg2
= Hexagon::NoRegister
;
746 if (HexagonMCInstrInfo::isVector(MCII
, Inst
)) {
747 // Vector instructions don't count scalars.
750 if (HexagonMCInstrInfo::hasNewValue(MCII
, Inst
))
751 DefReg1
= HexagonMCInstrInfo::getNewValueOperand(MCII
, Inst
).getReg();
752 if (HexagonMCInstrInfo::hasNewValue2(MCII
, Inst
))
753 DefReg2
= HexagonMCInstrInfo::getNewValueOperand2(MCII
, Inst
).getReg();
754 if (!RegisterMatches(UseReg
, DefReg1
, DefReg2
)) {
755 // This isn't the register we're looking for
758 if (!HexagonMCInstrInfo::isPredicated(MCII
, Inst
)) {
759 // Producer is unpredicated
762 assert(HexagonMCInstrInfo::isPredicated(MCII
, MI
) &&
763 "Unpredicated consumer depending on predicated producer");
764 if (HexagonMCInstrInfo::isPredicatedTrue(MCII
, Inst
) ==
765 HexagonMCInstrInfo::isPredicatedTrue(MCII
, MI
))
766 // Producer predicate sense matched ours.
769 // Hexagon PRM 10.11 Construct Nt from distance
770 unsigned Offset
= HexagonMCInstrInfo::isVector(MCII
, MI
) ? VOffset
773 Offset
|= HexagonMCInstrInfo::SubregisterBit(UseReg
, DefReg1
, DefReg2
);
779 unsigned Reg
= MO
.getReg();
780 if (HexagonMCInstrInfo::isSubInstruction(MI
) ||
781 HexagonMCInstrInfo::getType(MCII
, MI
) == HexagonII::TypeCJ
)
782 return HexagonMCInstrInfo::getDuplexRegisterNumbering(Reg
);
783 return MCT
.getRegisterInfo()->getEncodingValue(Reg
);
786 return getExprOpValue(MI
, MO
, MO
.getExpr(), Fixups
, STI
);
789 MCCodeEmitter
*llvm::createHexagonMCCodeEmitter(MCInstrInfo
const &MII
,
790 MCRegisterInfo
const &MRI
,
792 return new HexagonMCCodeEmitter(MII
, MCT
);
795 #define ENABLE_INSTR_PREDICATE_VERIFIER
796 #include "HexagonGenMCCodeEmitter.inc"