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_Hexagon_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_Hexagon_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 if (Consumer
== Producer
)
396 if (Consumer
== Producer2
)
398 // Calculate if we're a single vector consumer referencing a double producer
399 if (Producer
>= Hexagon::W0
&& Producer
<= Hexagon::W15
)
400 if (Consumer
>= Hexagon::V0
&& Consumer
<= Hexagon::V31
)
401 return ((Consumer
- Hexagon::V0
) >> 1) == (Producer
- Hexagon::W0
);
405 /// EncodeSingleInstruction - Emit a single
406 void HexagonMCCodeEmitter::EncodeSingleInstruction(const MCInst
&MI
,
407 raw_ostream
&OS
, SmallVectorImpl
<MCFixup
> &Fixups
,
408 const MCSubtargetInfo
&STI
, uint32_t Parse
) const {
409 assert(!HexagonMCInstrInfo::isBundle(MI
));
412 // Pseudo instructions don't get encoded and shouldn't be here
413 // in the first place!
414 assert(!HexagonMCInstrInfo::getDesc(MCII
, MI
).isPseudo() &&
415 "pseudo-instruction found");
416 LLVM_DEBUG(dbgs() << "Encoding insn `"
417 << HexagonMCInstrInfo::getName(MCII
, MI
) << "'\n");
419 Binary
= getBinaryCodeForInstr(MI
, Fixups
, STI
);
420 unsigned Opc
= MI
.getOpcode();
422 // Check for unimplemented instructions. Immediate extenders
423 // are encoded as zero, so they need to be accounted for.
424 if (!Binary
&& Opc
!= DuplexIClass0
&& Opc
!= A4_ext
) {
425 LLVM_DEBUG(dbgs() << "Unimplemented inst `"
426 << HexagonMCInstrInfo::getName(MCII
, MI
) << "'\n");
427 llvm_unreachable("Unimplemented Instruction");
431 // if we need to emit a duplexed instruction
432 if (Opc
>= Hexagon::DuplexIClass0
&& Opc
<= Hexagon::DuplexIClassF
) {
433 assert(Parse
== HexagonII::INST_PARSE_DUPLEX
&&
434 "Emitting duplex without duplex parse bits");
435 unsigned DupIClass
= MI
.getOpcode() - Hexagon::DuplexIClass0
;
436 // 29 is the bit position.
437 // 0b1110 =0xE bits are masked off and down shifted by 1 bit.
438 // Last bit is moved to bit position 13
439 Binary
= ((DupIClass
& 0xE) << (29 - 1)) | ((DupIClass
& 0x1) << 13);
441 const MCInst
*Sub0
= MI
.getOperand(0).getInst();
442 const MCInst
*Sub1
= MI
.getOperand(1).getInst();
444 // Get subinstruction slot 0.
445 unsigned SubBits0
= getBinaryCodeForInstr(*Sub0
, Fixups
, STI
);
446 // Get subinstruction slot 1.
447 State
.SubInst1
= true;
448 unsigned SubBits1
= getBinaryCodeForInstr(*Sub1
, Fixups
, STI
);
449 State
.SubInst1
= false;
451 Binary
|= SubBits0
| (SubBits1
<< 16);
453 support::endian::write
<uint32_t>(OS
, Binary
, support::little
);
457 LLVM_ATTRIBUTE_NORETURN
458 static void raise_relocation_error(unsigned Width
, unsigned Kind
) {
460 raw_string_ostream
Stream(Text
);
461 Stream
<< "Unrecognized relocation combination: width=" << Width
463 report_fatal_error(Stream
.str());
466 /// Some insns are not extended and thus have no bits. These cases require
467 /// a more brute force method for determining the correct relocation.
468 Hexagon::Fixups
HexagonMCCodeEmitter::getFixupNoBits(
469 MCInstrInfo
const &MCII
, const MCInst
&MI
, const MCOperand
&MO
,
470 const MCSymbolRefExpr::VariantKind VarKind
) const {
471 const MCInstrDesc
&MCID
= HexagonMCInstrInfo::getDesc(MCII
, MI
);
472 unsigned InsnType
= HexagonMCInstrInfo::getType(MCII
, MI
);
473 using namespace Hexagon
;
475 if (InsnType
== HexagonII::TypeEXTENDER
) {
476 if (VarKind
== MCSymbolRefExpr::VK_None
) {
477 auto Instrs
= HexagonMCInstrInfo::bundleInstructions(*State
.Bundle
);
478 for (auto I
= Instrs
.begin(), N
= Instrs
.end(); I
!= N
; ++I
) {
479 if (I
->getInst() != &MI
)
481 assert(I
+1 != N
&& "Extender cannot be last in packet");
482 const MCInst
&NextI
= *(I
+1)->getInst();
483 const MCInstrDesc
&NextD
= HexagonMCInstrInfo::getDesc(MCII
, NextI
);
484 if (NextD
.isBranch() || NextD
.isCall() ||
485 HexagonMCInstrInfo::getType(MCII
, NextI
) == HexagonII::TypeCR
)
486 return fixup_Hexagon_B32_PCREL_X
;
487 return fixup_Hexagon_32_6_X
;
491 static const std::map
<unsigned,unsigned> Relocs
= {
492 { MCSymbolRefExpr::VK_GOTREL
, fixup_Hexagon_GOTREL_32_6_X
},
493 { MCSymbolRefExpr::VK_GOT
, fixup_Hexagon_GOT_32_6_X
},
494 { MCSymbolRefExpr::VK_TPREL
, fixup_Hexagon_TPREL_32_6_X
},
495 { MCSymbolRefExpr::VK_DTPREL
, fixup_Hexagon_DTPREL_32_6_X
},
496 { MCSymbolRefExpr::VK_Hexagon_GD_GOT
, fixup_Hexagon_GD_GOT_32_6_X
},
497 { MCSymbolRefExpr::VK_Hexagon_LD_GOT
, fixup_Hexagon_LD_GOT_32_6_X
},
498 { MCSymbolRefExpr::VK_Hexagon_IE
, fixup_Hexagon_IE_32_6_X
},
499 { MCSymbolRefExpr::VK_Hexagon_IE_GOT
, fixup_Hexagon_IE_GOT_32_6_X
},
500 { MCSymbolRefExpr::VK_Hexagon_PCREL
, fixup_Hexagon_B32_PCREL_X
},
501 { MCSymbolRefExpr::VK_Hexagon_GD_PLT
, fixup_Hexagon_GD_PLT_B32_PCREL_X
},
502 { MCSymbolRefExpr::VK_Hexagon_LD_PLT
, fixup_Hexagon_LD_PLT_B32_PCREL_X
},
505 auto F
= Relocs
.find(VarKind
);
506 if (F
!= Relocs
.end())
507 return Hexagon::Fixups(F
->second
);
508 raise_relocation_error(0, VarKind
);
512 return fixup_Hexagon_B13_PCREL
;
514 static const std::map
<unsigned,unsigned> RelocsLo
= {
515 { MCSymbolRefExpr::VK_GOT
, fixup_Hexagon_GOT_LO16
},
516 { MCSymbolRefExpr::VK_GOTREL
, fixup_Hexagon_GOTREL_LO16
},
517 { MCSymbolRefExpr::VK_Hexagon_GD_GOT
, fixup_Hexagon_GD_GOT_LO16
},
518 { MCSymbolRefExpr::VK_Hexagon_LD_GOT
, fixup_Hexagon_LD_GOT_LO16
},
519 { MCSymbolRefExpr::VK_Hexagon_IE
, fixup_Hexagon_IE_LO16
},
520 { MCSymbolRefExpr::VK_Hexagon_IE_GOT
, fixup_Hexagon_IE_GOT_LO16
},
521 { MCSymbolRefExpr::VK_TPREL
, fixup_Hexagon_TPREL_LO16
},
522 { MCSymbolRefExpr::VK_DTPREL
, fixup_Hexagon_DTPREL_LO16
},
523 { MCSymbolRefExpr::VK_None
, fixup_Hexagon_LO16
},
526 static const std::map
<unsigned,unsigned> RelocsHi
= {
527 { MCSymbolRefExpr::VK_GOT
, fixup_Hexagon_GOT_HI16
},
528 { MCSymbolRefExpr::VK_GOTREL
, fixup_Hexagon_GOTREL_HI16
},
529 { MCSymbolRefExpr::VK_Hexagon_GD_GOT
, fixup_Hexagon_GD_GOT_HI16
},
530 { MCSymbolRefExpr::VK_Hexagon_LD_GOT
, fixup_Hexagon_LD_GOT_HI16
},
531 { MCSymbolRefExpr::VK_Hexagon_IE
, fixup_Hexagon_IE_HI16
},
532 { MCSymbolRefExpr::VK_Hexagon_IE_GOT
, fixup_Hexagon_IE_GOT_HI16
},
533 { MCSymbolRefExpr::VK_TPREL
, fixup_Hexagon_TPREL_HI16
},
534 { MCSymbolRefExpr::VK_DTPREL
, fixup_Hexagon_DTPREL_HI16
},
535 { MCSymbolRefExpr::VK_None
, fixup_Hexagon_HI16
},
538 switch (MCID
.getOpcode()) {
540 case Hexagon::A2_tfril
: {
541 auto F
= RelocsLo
.find(VarKind
);
542 if (F
!= RelocsLo
.end())
543 return Hexagon::Fixups(F
->second
);
547 case Hexagon::A2_tfrih
: {
548 auto F
= RelocsHi
.find(VarKind
);
549 if (F
!= RelocsHi
.end())
550 return Hexagon::Fixups(F
->second
);
555 raise_relocation_error(0, VarKind
);
558 static bool isPCRel(unsigned Kind
) {
560 case fixup_Hexagon_B22_PCREL
:
561 case fixup_Hexagon_B15_PCREL
:
562 case fixup_Hexagon_B7_PCREL
:
563 case fixup_Hexagon_B13_PCREL
:
564 case fixup_Hexagon_B9_PCREL
:
565 case fixup_Hexagon_B32_PCREL_X
:
566 case fixup_Hexagon_B22_PCREL_X
:
567 case fixup_Hexagon_B15_PCREL_X
:
568 case fixup_Hexagon_B13_PCREL_X
:
569 case fixup_Hexagon_B9_PCREL_X
:
570 case fixup_Hexagon_B7_PCREL_X
:
571 case fixup_Hexagon_32_PCREL
:
572 case fixup_Hexagon_PLT_B22_PCREL
:
573 case fixup_Hexagon_GD_PLT_B22_PCREL
:
574 case fixup_Hexagon_LD_PLT_B22_PCREL
:
575 case fixup_Hexagon_GD_PLT_B22_PCREL_X
:
576 case fixup_Hexagon_LD_PLT_B22_PCREL_X
:
577 case fixup_Hexagon_6_PCREL_X
:
584 unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst
&MI
,
585 const MCOperand
&MO
, const MCExpr
*ME
, SmallVectorImpl
<MCFixup
> &Fixups
,
586 const MCSubtargetInfo
&STI
) const {
587 if (isa
<HexagonMCExpr
>(ME
))
588 ME
= &HexagonMCInstrInfo::getExpr(*ME
);
590 if (ME
->evaluateAsAbsolute(Value
)) {
591 bool InstExtendable
= HexagonMCInstrInfo::isExtendable(MCII
, MI
) ||
592 HexagonMCInstrInfo::isExtended(MCII
, MI
);
593 // Only sub-instruction #1 can be extended in a duplex. If MI is a
594 // sub-instruction #0, it is not extended even if Extended is true
595 // (it can be true for the duplex as a whole).
596 bool IsSub0
= HexagonMCInstrInfo::isSubInstruction(MI
) && !State
.SubInst1
;
597 if (State
.Extended
&& InstExtendable
&& !IsSub0
) {
598 unsigned OpIdx
= ~0u;
599 for (unsigned I
= 0, E
= MI
.getNumOperands(); I
!= E
; ++I
) {
600 if (&MO
!= &MI
.getOperand(I
))
605 assert(OpIdx
!= ~0u);
606 if (OpIdx
== HexagonMCInstrInfo::getExtendableOp(MCII
, MI
)) {
607 unsigned Shift
= HexagonMCInstrInfo::getExtentAlignment(MCII
, MI
);
608 Value
= (Value
& 0x3f) << Shift
;
613 assert(ME
->getKind() == MCExpr::SymbolRef
||
614 ME
->getKind() == MCExpr::Binary
);
615 if (ME
->getKind() == MCExpr::Binary
) {
616 MCBinaryExpr
const *Binary
= cast
<MCBinaryExpr
>(ME
);
617 getExprOpValue(MI
, MO
, Binary
->getLHS(), Fixups
, STI
);
618 getExprOpValue(MI
, MO
, Binary
->getRHS(), Fixups
, STI
);
622 unsigned FixupKind
= fixup_Invalid
;
623 const MCSymbolRefExpr
*MCSRE
= static_cast<const MCSymbolRefExpr
*>(ME
);
624 const MCInstrDesc
&MCID
= HexagonMCInstrInfo::getDesc(MCII
, MI
);
625 unsigned FixupWidth
= HexagonMCInstrInfo::getExtentBits(MCII
, MI
) -
626 HexagonMCInstrInfo::getExtentAlignment(MCII
, MI
);
627 MCSymbolRefExpr::VariantKind VarKind
= MCSRE
->getKind();
628 unsigned Opc
= MCID
.getOpcode();
629 unsigned IType
= HexagonMCInstrInfo::getType(MCII
, MI
);
631 LLVM_DEBUG(dbgs() << "----------------------------------------\n"
632 << "Opcode Name: " << HexagonMCInstrInfo::getName(MCII
, MI
)
633 << "\nOpcode: " << Opc
<< "\nRelocation bits: "
634 << FixupWidth
<< "\nAddend: " << State
.Addend
635 << "\nVariant: " << unsigned(VarKind
)
636 << "\n----------------------------------------\n");
638 // Pick the applicable fixup kind for the symbol.
639 // Handle special cases first, the rest will be looked up in the tables.
641 if (FixupWidth
== 16 && !State
.Extended
) {
642 if (VarKind
== MCSymbolRefExpr::VK_None
) {
643 if (HexagonMCInstrInfo::s27_2_reloc(*MO
.getExpr())) {
645 FixupKind
= Hexagon::fixup_Hexagon_27_REG
;
647 // Look for GP-relative fixups.
648 unsigned Shift
= HexagonMCInstrInfo::getExtentAlignment(MCII
, MI
);
649 static const Hexagon::Fixups GPRelFixups
[] = {
650 Hexagon::fixup_Hexagon_GPREL16_0
, Hexagon::fixup_Hexagon_GPREL16_1
,
651 Hexagon::fixup_Hexagon_GPREL16_2
, Hexagon::fixup_Hexagon_GPREL16_3
653 assert(Shift
< array_lengthof(GPRelFixups
));
654 auto UsesGP
= [] (const MCInstrDesc
&D
) {
655 for (const MCPhysReg
*U
= D
.getImplicitUses(); U
&& *U
; ++U
)
656 if (*U
== Hexagon::GP
)
661 FixupKind
= GPRelFixups
[Shift
];
663 } else if (VarKind
== MCSymbolRefExpr::VK_GOTREL
) {
664 // Select between LO/HI.
665 if (Opc
== Hexagon::LO
)
666 FixupKind
= Hexagon::fixup_Hexagon_GOTREL_LO16
;
667 else if (Opc
== Hexagon::HI
)
668 FixupKind
= Hexagon::fixup_Hexagon_GOTREL_HI16
;
671 bool BranchOrCR
= MCID
.isBranch() || IType
== HexagonII::TypeCR
;
672 switch (FixupWidth
) {
675 FixupKind
= State
.Extended
? Hexagon::fixup_Hexagon_B9_PCREL_X
676 : Hexagon::fixup_Hexagon_B9_PCREL
;
680 if (State
.Extended
&& VarKind
== MCSymbolRefExpr::VK_GOT
)
681 FixupKind
= HexagonMCInstrInfo::isExtentSigned(MCII
, MI
)
682 ? Hexagon::fixup_Hexagon_GOT_16_X
683 : Hexagon::fixup_Hexagon_GOT_11_X
;
684 else if (FixupWidth
== 7 && BranchOrCR
)
685 FixupKind
= State
.Extended
? Hexagon::fixup_Hexagon_B7_PCREL_X
686 : Hexagon::fixup_Hexagon_B7_PCREL
;
689 FixupKind
= getFixupNoBits(MCII
, MI
, MO
, VarKind
);
694 if (FixupKind
== fixup_Invalid
) {
695 const auto &FixupTable
= State
.Extended
? ExtFixups
: StdFixups
;
697 auto FindVK
= FixupTable
.find(VarKind
);
698 if (FindVK
!= FixupTable
.end())
699 FixupKind
= FindVK
->second
[FixupWidth
];
702 if (FixupKind
== fixup_Invalid
)
703 raise_relocation_error(FixupWidth
, VarKind
);
705 const MCExpr
*FixupExpr
= MO
.getExpr();
706 if (State
.Addend
!= 0 && isPCRel(FixupKind
)) {
707 const MCExpr
*C
= MCConstantExpr::create(State
.Addend
, MCT
);
708 FixupExpr
= MCBinaryExpr::createAdd(FixupExpr
, C
, MCT
);
711 MCFixup Fixup
= MCFixup::create(State
.Addend
, FixupExpr
,
712 MCFixupKind(FixupKind
), MI
.getLoc());
713 Fixups
.push_back(Fixup
);
714 // All of the information is in the fixup.
719 HexagonMCCodeEmitter::getMachineOpValue(MCInst
const &MI
, MCOperand
const &MO
,
720 SmallVectorImpl
<MCFixup
> &Fixups
,
721 MCSubtargetInfo
const &STI
) const {
723 size_t OperandNumber
= ~0U;
724 for (unsigned i
= 0, n
= MI
.getNumOperands(); i
< n
; ++i
)
725 if (&MI
.getOperand(i
) == &MO
) {
729 assert((OperandNumber
!= ~0U) && "Operand not found");
732 if (HexagonMCInstrInfo::isNewValue(MCII
, MI
) &&
733 &MO
== &HexagonMCInstrInfo::getNewValueOperand(MCII
, MI
)) {
734 // Calculate the new value distance to the associated producer
735 unsigned SOffset
= 0;
736 unsigned VOffset
= 0;
737 unsigned UseReg
= MO
.getReg();
738 unsigned DefReg1
, DefReg2
;
740 auto Instrs
= HexagonMCInstrInfo::bundleInstructions(*State
.Bundle
);
741 const MCOperand
*I
= Instrs
.begin() + State
.Index
- 1;
744 assert(I
!= Instrs
.begin() - 1 && "Couldn't find producer");
745 MCInst
const &Inst
= *I
->getInst();
746 if (HexagonMCInstrInfo::isImmext(Inst
))
749 DefReg1
= DefReg2
= 0;
751 if (HexagonMCInstrInfo::isVector(MCII
, Inst
)) {
752 // Vector instructions don't count scalars.
755 if (HexagonMCInstrInfo::hasNewValue(MCII
, Inst
))
756 DefReg1
= HexagonMCInstrInfo::getNewValueOperand(MCII
, Inst
).getReg();
757 if (HexagonMCInstrInfo::hasNewValue2(MCII
, Inst
))
758 DefReg2
= HexagonMCInstrInfo::getNewValueOperand2(MCII
, Inst
).getReg();
759 if (!RegisterMatches(UseReg
, DefReg1
, DefReg2
)) {
760 // This isn't the register we're looking for
763 if (!HexagonMCInstrInfo::isPredicated(MCII
, Inst
)) {
764 // Producer is unpredicated
767 assert(HexagonMCInstrInfo::isPredicated(MCII
, MI
) &&
768 "Unpredicated consumer depending on predicated producer");
769 if (HexagonMCInstrInfo::isPredicatedTrue(MCII
, Inst
) ==
770 HexagonMCInstrInfo::isPredicatedTrue(MCII
, MI
))
771 // Producer predicate sense matched ours.
774 // Hexagon PRM 10.11 Construct Nt from distance
775 unsigned Offset
= HexagonMCInstrInfo::isVector(MCII
, MI
) ? VOffset
778 Offset
|= HexagonMCInstrInfo::SubregisterBit(UseReg
, DefReg1
, DefReg2
);
784 unsigned Reg
= MO
.getReg();
785 if (HexagonMCInstrInfo::isSubInstruction(MI
) ||
786 HexagonMCInstrInfo::getType(MCII
, MI
) == HexagonII::TypeCJ
)
787 return HexagonMCInstrInfo::getDuplexRegisterNumbering(Reg
);
788 return MCT
.getRegisterInfo()->getEncodingValue(Reg
);
791 return getExprOpValue(MI
, MO
, MO
.getExpr(), Fixups
, STI
);
794 MCCodeEmitter
*llvm::createHexagonMCCodeEmitter(MCInstrInfo
const &MII
,
795 MCRegisterInfo
const &MRI
,
797 return new HexagonMCCodeEmitter(MII
, MCT
);
800 #define ENABLE_INSTR_PREDICATE_VERIFIER
801 #include "HexagonGenMCCodeEmitter.inc"