xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCCodeEmitter.h"
100b57cec5SDimitry Andric #include "MCTargetDesc/HexagonBaseInfo.h"
110b57cec5SDimitry Andric #include "MCTargetDesc/HexagonFixupKinds.h"
120b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCExpr.h"
130b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCInstrInfo.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCTargetDesc.h"
150b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
240b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
250b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
260b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
270b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
280b57cec5SDimitry Andric #include "llvm/Support/EndianStream.h"
290b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
300b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
310b57cec5SDimitry Andric #include <cassert>
320b57cec5SDimitry Andric #include <cstddef>
330b57cec5SDimitry Andric #include <cstdint>
340b57cec5SDimitry Andric #include <map>
350b57cec5SDimitry Andric #include <string>
360b57cec5SDimitry Andric #include <vector>
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric #define DEBUG_TYPE "mccodeemitter"
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric using namespace llvm;
410b57cec5SDimitry Andric using namespace Hexagon;
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric static const unsigned fixup_Invalid = ~0u;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric #define _ fixup_Invalid
480b57cec5SDimitry Andric #define P(x) Hexagon::fixup_Hexagon##x
490b57cec5SDimitry Andric static const std::map<unsigned, std::vector<unsigned>> ExtFixups = {
500b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_DTPREL,
510b57cec5SDimitry Andric     { _,                _,              _,                      _,
520b57cec5SDimitry Andric       _,                _,              P(_DTPREL_16_X),        P(_DTPREL_11_X),
530b57cec5SDimitry Andric       P(_DTPREL_11_X),  P(_9_X),        _,                      P(_DTPREL_11_X),
540b57cec5SDimitry Andric       P(_DTPREL_16_X),  _,              _,                      _,
550b57cec5SDimitry Andric       P(_DTPREL_16_X),  _,              _,                      _,
560b57cec5SDimitry Andric       _,                _,              _,                      _,
570b57cec5SDimitry Andric       _,                _,              _,                      _,
580b57cec5SDimitry Andric       _,                _,              _,                      _,
590b57cec5SDimitry Andric       P(_DTPREL_32_6_X) }},
600b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_GOT,
610b57cec5SDimitry Andric     { _,                _,              _,                      _,
620b57cec5SDimitry Andric       _,                _,              P(_GOT_11_X),           _ /* [1] */,
630b57cec5SDimitry Andric       _ /* [1] */,      P(_9_X),        _,                      P(_GOT_11_X),
640b57cec5SDimitry Andric       P(_GOT_16_X),     _,              _,                      _,
650b57cec5SDimitry Andric       P(_GOT_16_X),     _,              _,                      _,
660b57cec5SDimitry Andric       _,                _,              _,                      _,
670b57cec5SDimitry Andric       _,                _,              _,                      _,
680b57cec5SDimitry Andric       _,                _,              _,                      _,
690b57cec5SDimitry Andric       P(_GOT_32_6_X)    }},
700b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_GOTREL,
710b57cec5SDimitry Andric     { _,                _,              _,                      _,
720b57cec5SDimitry Andric       _,                _,              P(_GOTREL_11_X),        P(_GOTREL_11_X),
730b57cec5SDimitry Andric       P(_GOTREL_11_X),  P(_9_X),        _,                      P(_GOTREL_11_X),
740b57cec5SDimitry Andric       P(_GOTREL_16_X),  _,              _,                      _,
750b57cec5SDimitry Andric       P(_GOTREL_16_X),  _,              _,                      _,
760b57cec5SDimitry Andric       _,                _,              _,                      _,
770b57cec5SDimitry Andric       _,                _,              _,                      _,
780b57cec5SDimitry Andric       _,                _,              _,                      _,
790b57cec5SDimitry Andric       P(_GOTREL_32_6_X) }},
800b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_TPREL,
810b57cec5SDimitry Andric     { _,                _,              _,                      _,
820b57cec5SDimitry Andric       _,                _,              P(_TPREL_16_X),         P(_TPREL_11_X),
830b57cec5SDimitry Andric       P(_TPREL_11_X),   P(_9_X),        _,                      P(_TPREL_11_X),
840b57cec5SDimitry Andric       P(_TPREL_16_X),   _,              _,                      _,
850b57cec5SDimitry Andric       P(_TPREL_16_X),   _,              _,                      _,
860b57cec5SDimitry Andric       _,                _,              _,                      _,
870b57cec5SDimitry Andric       _,                _,              _,                      _,
880b57cec5SDimitry Andric       _,                _,              _,                      _,
890b57cec5SDimitry Andric       P(_TPREL_32_6_X)  }},
900b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_GD_GOT,
910b57cec5SDimitry Andric     { _,                _,              _,                      _,
920b57cec5SDimitry Andric       _,                _,              P(_GD_GOT_16_X),        P(_GD_GOT_11_X),
930b57cec5SDimitry Andric       P(_GD_GOT_11_X),  P(_9_X),        _,                      P(_GD_GOT_11_X),
940b57cec5SDimitry Andric       P(_GD_GOT_16_X),  _,              _,                      _,
950b57cec5SDimitry Andric       P(_GD_GOT_16_X),  _,              _,                      _,
960b57cec5SDimitry Andric       _,                _,              _,                      _,
970b57cec5SDimitry Andric       _,                _,              _,                      _,
980b57cec5SDimitry Andric       _,                _,              _,                      _,
990b57cec5SDimitry Andric       P(_GD_GOT_32_6_X) }},
1000b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_GD_PLT,
1010b57cec5SDimitry Andric     { _,                _,              _,                      _,
1020b57cec5SDimitry Andric       _,                _,              _,                      _,
1030b57cec5SDimitry Andric       _,                P(_9_X),        _,                      P(_GD_PLT_B22_PCREL_X),
1040b57cec5SDimitry Andric       _,                _,              _,                      _,
1050b57cec5SDimitry Andric       _,                _,              _,                      _,
1060b57cec5SDimitry Andric       _,                _,              P(_GD_PLT_B22_PCREL_X), _,
1070b57cec5SDimitry Andric       _,                _,              _,                      _,
1080b57cec5SDimitry Andric       _,                _,              _,                      _,
1090b57cec5SDimitry Andric       _                 }},
1100b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_IE,
1110b57cec5SDimitry Andric     { _,                _,              _,                      _,
1120b57cec5SDimitry Andric       _,                _,              P(_IE_16_X),            _,
1130b57cec5SDimitry Andric       _,                P(_9_X),        _,                      _,
1140b57cec5SDimitry Andric       P(_IE_16_X),      _,              _,                      _,
1150b57cec5SDimitry Andric       P(_IE_16_X),      _,              _,                      _,
1160b57cec5SDimitry Andric       _,                _,              _,                      _,
1170b57cec5SDimitry Andric       _,                _,              _,                      _,
1180b57cec5SDimitry Andric       _,                _,              _,                      _,
1190b57cec5SDimitry Andric       P(_IE_32_6_X)     }},
1200b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_IE_GOT,
1210b57cec5SDimitry Andric     { _,                _,              _,                      _,
1220b57cec5SDimitry Andric       _,                _,              P(_IE_GOT_11_X),        P(_IE_GOT_11_X),
1230b57cec5SDimitry Andric       P(_IE_GOT_11_X),  P(_9_X),        _,                      P(_IE_GOT_11_X),
1240b57cec5SDimitry Andric       P(_IE_GOT_16_X),  _,              _,                      _,
1250b57cec5SDimitry Andric       P(_IE_GOT_16_X),  _,              _,                      _,
1260b57cec5SDimitry Andric       _,                _,              _,                      _,
1270b57cec5SDimitry Andric       _,                _,              _,                      _,
1280b57cec5SDimitry Andric       _,                _,              _,                      _,
1290b57cec5SDimitry Andric       P(_IE_GOT_32_6_X) }},
1300b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_LD_GOT,
1310b57cec5SDimitry Andric     { _,                _,              _,                      _,
1320b57cec5SDimitry Andric       _,                _,              P(_LD_GOT_11_X),        P(_LD_GOT_11_X),
1330b57cec5SDimitry Andric       P(_LD_GOT_11_X),  P(_9_X),        _,                      P(_LD_GOT_11_X),
1340b57cec5SDimitry Andric       P(_LD_GOT_16_X),  _,              _,                      _,
1350b57cec5SDimitry Andric       P(_LD_GOT_16_X),  _,              _,                      _,
1360b57cec5SDimitry Andric       _,                _,              _,                      _,
1370b57cec5SDimitry Andric       _,                _,              _,                      _,
1380b57cec5SDimitry Andric       _,                _,              _,                      _,
1390b57cec5SDimitry Andric       P(_LD_GOT_32_6_X) }},
1400b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_LD_PLT,
1410b57cec5SDimitry Andric     { _,                _,              _,                      _,
1420b57cec5SDimitry Andric       _,                _,              _,                      _,
1430b57cec5SDimitry Andric       _,                P(_9_X),        _,                      P(_LD_PLT_B22_PCREL_X),
1440b57cec5SDimitry Andric       _,                _,              _,                      _,
1450b57cec5SDimitry Andric       _,                _,              _,                      _,
1460b57cec5SDimitry Andric       _,                _,              P(_LD_PLT_B22_PCREL_X), _,
1470b57cec5SDimitry Andric       _,                _,              _,                      _,
1480b57cec5SDimitry Andric       _,                _,              _,                      _,
1490b57cec5SDimitry Andric       _                 }},
1505ffd83dbSDimitry Andric   { MCSymbolRefExpr::VK_PCREL,
1510b57cec5SDimitry Andric     { _,                _,              _,                      _,
1520b57cec5SDimitry Andric       _,                _,              P(_6_PCREL_X),          _,
1530b57cec5SDimitry Andric       _,                P(_9_X),        _,                      _,
1540b57cec5SDimitry Andric       _,                _,              _,                      _,
1550b57cec5SDimitry Andric       _,                _,              _,                      _,
1560b57cec5SDimitry Andric       _,                _,              _,                      _,
1570b57cec5SDimitry Andric       _,                _,              _,                      _,
1580b57cec5SDimitry Andric       _,                _,              _,                      _,
1590b57cec5SDimitry Andric       P(_32_PCREL)      }},
1600b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_None,
1610b57cec5SDimitry Andric     { _,                _,              _,                      _,
1620b57cec5SDimitry Andric       _,                _,              P(_6_X),                P(_8_X),
1630b57cec5SDimitry Andric       P(_8_X),          P(_9_X),        P(_10_X),               P(_11_X),
1640b57cec5SDimitry Andric       P(_12_X),         P(_B13_PCREL),  _,                      P(_B15_PCREL_X),
1650b57cec5SDimitry Andric       P(_16_X),         _,              _,                      _,
1660b57cec5SDimitry Andric       _,                _,              P(_B22_PCREL_X),        _,
1670b57cec5SDimitry Andric       _,                _,              _,                      _,
1680b57cec5SDimitry Andric       _,                _,              _,                      _,
1690b57cec5SDimitry Andric       P(_32_6_X)        }},
1700b57cec5SDimitry Andric };
1710b57cec5SDimitry Andric // [1] The fixup is GOT_16_X for signed values and GOT_11_X for unsigned.
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric static const std::map<unsigned, std::vector<unsigned>> StdFixups = {
1740b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_DTPREL,
1750b57cec5SDimitry Andric     { _,                _,              _,                      _,
1760b57cec5SDimitry Andric       _,                _,              _,                      _,
1770b57cec5SDimitry Andric       _,                _,              _,                      _,
1780b57cec5SDimitry Andric       _,                _,              _,                      _,
1790b57cec5SDimitry Andric       P(_DTPREL_16),    _,              _,                      _,
1800b57cec5SDimitry Andric       _,                _,              _,                      _,
1810b57cec5SDimitry Andric       _,                _,              _,                      _,
1820b57cec5SDimitry Andric       _,                _,              _,                      _,
1830b57cec5SDimitry Andric       P(_DTPREL_32)     }},
1840b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_GOT,
1850b57cec5SDimitry Andric     { _,                _,              _,                      _,
1860b57cec5SDimitry Andric       _,                _,              _,                      _,
1870b57cec5SDimitry Andric       _,                _,              _,                      _,
1880b57cec5SDimitry Andric       _,                _,              _,                      _,
1890b57cec5SDimitry Andric       _,                _,              _,                      _,
1900b57cec5SDimitry Andric       _,                _,              _,                      _,
1910b57cec5SDimitry Andric       _,                _,              _,                      _,
1920b57cec5SDimitry Andric       _,                _,              _,                      _,
1930b57cec5SDimitry Andric       P(_GOT_32)        }},
1940b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_GOTREL,
1950b57cec5SDimitry Andric     { _,                _,              _,                      _,
1960b57cec5SDimitry Andric       _,                _,              _,                      _,
1970b57cec5SDimitry Andric       _,                _,              _,                      _,
1980b57cec5SDimitry Andric       _,                _,              _,                      _,
1990b57cec5SDimitry Andric       _ /* [2] */,      _,              _,                      _,
2000b57cec5SDimitry Andric       _,                _,              _,                      _,
2010b57cec5SDimitry Andric       _,                _,              _,                      _,
2020b57cec5SDimitry Andric       _,                _,              _,                      _,
2030b57cec5SDimitry Andric       P(_GOTREL_32)     }},
2040b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_PLT,
2050b57cec5SDimitry Andric     { _,                _,              _,                      _,
2060b57cec5SDimitry Andric       _,                _,              _,                      _,
2070b57cec5SDimitry Andric       _,                _,              _,                      _,
2080b57cec5SDimitry Andric       _,                _,              _,                      _,
2090b57cec5SDimitry Andric       _,                _,              _,                      _,
2100b57cec5SDimitry Andric       _,                _,              P(_PLT_B22_PCREL),      _,
2110b57cec5SDimitry Andric       _,                _,              _,                      _,
2120b57cec5SDimitry Andric       _,                _,              _,                      _,
2130b57cec5SDimitry Andric       _                 }},
2140b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_TPREL,
2150b57cec5SDimitry Andric     { _,                _,              _,                      _,
2160b57cec5SDimitry Andric       _,                _,              _,                      _,
2170b57cec5SDimitry Andric       _,                _,              _,                      P(_TPREL_11_X),
2180b57cec5SDimitry Andric       _,                _,              _,                      _,
2190b57cec5SDimitry Andric       P(_TPREL_16),     _,              _,                      _,
2200b57cec5SDimitry Andric       _,                _,              _,                      _,
2210b57cec5SDimitry Andric       _,                _,              _,                      _,
2220b57cec5SDimitry Andric       _,                _,              _,                      _,
2230b57cec5SDimitry Andric       P(_TPREL_32)      }},
2240b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_GD_GOT,
2250b57cec5SDimitry Andric     { _,                _,              _,                      _,
2260b57cec5SDimitry Andric       _,                _,              _,                      _,
2270b57cec5SDimitry Andric       _,                _,              _,                      _,
2280b57cec5SDimitry Andric       _,                _,              _,                      _,
2290b57cec5SDimitry Andric       P(_GD_GOT_16),    _,              _,                      _,
2300b57cec5SDimitry Andric       _,                _,              _,                      _,
2310b57cec5SDimitry Andric       _,                _,              _,                      _,
2320b57cec5SDimitry Andric       _,                _,              _,                      _,
2330b57cec5SDimitry Andric       P(_GD_GOT_32)     }},
2340b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_GD_PLT,
2350b57cec5SDimitry Andric     { _,                _,              _,                      _,
2360b57cec5SDimitry Andric       _,                _,              _,                      _,
2370b57cec5SDimitry Andric       _,                _,              _,                      _,
2380b57cec5SDimitry Andric       _,                _,              _,                      _,
2390b57cec5SDimitry Andric       _,                _,              _,                      _,
2400b57cec5SDimitry Andric       _,                _,              P(_GD_PLT_B22_PCREL),   _,
2410b57cec5SDimitry Andric       _,                _,              _,                      _,
2420b57cec5SDimitry Andric       _,                _,              _,                      _,
2430b57cec5SDimitry Andric       _                 }},
2440b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_GPREL,
2450b57cec5SDimitry Andric     { _,                _,              _,                      _,
2460b57cec5SDimitry Andric       _,                _,              _,                      _,
2470b57cec5SDimitry Andric       _,                _,              _,                      _,
2480b57cec5SDimitry Andric       _,                _,              _,                      _,
2490b57cec5SDimitry Andric       P(_GPREL16_0),    _,              _,                      _,
2500b57cec5SDimitry Andric       _,                _,              _,                      _,
2510b57cec5SDimitry Andric       _,                _,              _,                      _,
2520b57cec5SDimitry Andric       _,                _,              _,                      _,
2530b57cec5SDimitry Andric       _                 }},
2540b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_HI16,
2550b57cec5SDimitry Andric     { _,                _,              _,                      _,
2560b57cec5SDimitry Andric       _,                _,              _,                      _,
2570b57cec5SDimitry Andric       _,                _,              _,                      _,
2580b57cec5SDimitry Andric       _,                _,              _,                      _,
2590b57cec5SDimitry Andric       P(_HI16),         _,              _,                      _,
2600b57cec5SDimitry Andric       _,                _,              _,                      _,
2610b57cec5SDimitry Andric       _,                _,              _,                      _,
2620b57cec5SDimitry Andric       _,                _,              _,                      _,
2630b57cec5SDimitry Andric       _                 }},
2640b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_IE,
2650b57cec5SDimitry Andric     { _,                _,              _,                      _,
2660b57cec5SDimitry Andric       _,                _,              _,                      _,
2670b57cec5SDimitry Andric       _,                _,              _,                      _,
2680b57cec5SDimitry Andric       _,                _,              _,                      _,
2690b57cec5SDimitry Andric       _,                _,              _,                      _,
2700b57cec5SDimitry Andric       _,                _,              _,                      _,
2710b57cec5SDimitry Andric       _,                _,              _,                      _,
2720b57cec5SDimitry Andric       _,                _,              _,                      _,
2730b57cec5SDimitry Andric       P(_IE_32)         }},
2740b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_IE_GOT,
2750b57cec5SDimitry Andric     { _,                _,              _,                      _,
2760b57cec5SDimitry Andric       _,                _,              _,                      _,
2770b57cec5SDimitry Andric       _,                _,              _,                      _,
2780b57cec5SDimitry Andric       _,                _,              _,                      _,
2790b57cec5SDimitry Andric       P(_IE_GOT_16),    _,              _,                      _,
2800b57cec5SDimitry Andric       _,                _,              _,                      _,
2810b57cec5SDimitry Andric       _,                _,              _,                      _,
2820b57cec5SDimitry Andric       _,                _,              _,                      _,
2830b57cec5SDimitry Andric       P(_IE_GOT_32)     }},
2840b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_LD_GOT,
2850b57cec5SDimitry Andric     { _,                _,              _,                      _,
2860b57cec5SDimitry Andric       _,                _,              _,                      _,
2870b57cec5SDimitry Andric       _,                _,              _,                      _,
2880b57cec5SDimitry Andric       _,                _,              _,                      _,
2890b57cec5SDimitry Andric       P(_LD_GOT_16),    _,              _,                      _,
2900b57cec5SDimitry Andric       _,                _,              _,                      _,
2910b57cec5SDimitry Andric       _,                _,              _,                      _,
2920b57cec5SDimitry Andric       _,                _,              _,                      _,
2930b57cec5SDimitry Andric       P(_LD_GOT_32)     }},
2940b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_LD_PLT,
2950b57cec5SDimitry Andric     { _,                _,              _,                      _,
2960b57cec5SDimitry Andric       _,                _,              _,                      _,
2970b57cec5SDimitry Andric       _,                _,              _,                      _,
2980b57cec5SDimitry Andric       _,                _,              _,                      _,
2990b57cec5SDimitry Andric       _,                _,              _,                      _,
3000b57cec5SDimitry Andric       _,                _,              P(_LD_PLT_B22_PCREL),   _,
3010b57cec5SDimitry Andric       _,                _,              _,                      _,
3020b57cec5SDimitry Andric       _,                _,              _,                      _,
3030b57cec5SDimitry Andric       _                 }},
3040b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_Hexagon_LO16,
3050b57cec5SDimitry Andric     { _,                _,              _,                      _,
3060b57cec5SDimitry Andric       _,                _,              _,                      _,
3070b57cec5SDimitry Andric       _,                _,              _,                      _,
3080b57cec5SDimitry Andric       _,                _,              _,                      _,
3090b57cec5SDimitry Andric       P(_LO16),         _,              _,                      _,
3100b57cec5SDimitry Andric       _,                _,              _,                      _,
3110b57cec5SDimitry Andric       _,                _,              _,                      _,
3120b57cec5SDimitry Andric       _,                _,              _,                      _,
3130b57cec5SDimitry Andric       _                 }},
3145ffd83dbSDimitry Andric   { MCSymbolRefExpr::VK_PCREL,
3150b57cec5SDimitry Andric     { _,                _,              _,                      _,
3160b57cec5SDimitry Andric       _,                _,              _,                      _,
3170b57cec5SDimitry Andric       _,                _,              _,                      _,
3180b57cec5SDimitry Andric       _,                _,              _,                      _,
3190b57cec5SDimitry Andric       _,                _,              _,                      _,
3200b57cec5SDimitry Andric       _,                _,              _,                      _,
3210b57cec5SDimitry Andric       _,                _,              _,                      _,
3220b57cec5SDimitry Andric       _,                _,              _,                      _,
3230b57cec5SDimitry Andric       P(_32_PCREL)      }},
3240b57cec5SDimitry Andric   { MCSymbolRefExpr::VK_None,
3250b57cec5SDimitry Andric     { _,                _,              _,                      _,
3260b57cec5SDimitry Andric       _,                _,              _,                      _,
3270b57cec5SDimitry Andric       _,                _,              _,                      _,
3280b57cec5SDimitry Andric       _,                P(_B13_PCREL),  _,                      P(_B15_PCREL),
3290b57cec5SDimitry Andric       _,                _,              _,                      _,
3300b57cec5SDimitry Andric       _,                _,              P(_B22_PCREL),          _,
3310b57cec5SDimitry Andric       _,                _,              _,                      _,
3320b57cec5SDimitry Andric       _,                _,              _,                      _,
3330b57cec5SDimitry Andric       P(_32)            }},
3340b57cec5SDimitry Andric };
3350b57cec5SDimitry Andric //
3360b57cec5SDimitry Andric // [2] The actual fixup is LO16 or HI16, depending on the instruction.
3370b57cec5SDimitry Andric #undef P
3380b57cec5SDimitry Andric #undef _
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric uint32_t HexagonMCCodeEmitter::parseBits(size_t Last, MCInst const &MCB,
3410b57cec5SDimitry Andric                                          MCInst const &MCI) const {
3420b57cec5SDimitry Andric   bool Duplex = HexagonMCInstrInfo::isDuplex(MCII, MCI);
3430b57cec5SDimitry Andric   if (State.Index == 0) {
3440b57cec5SDimitry Andric     if (HexagonMCInstrInfo::isInnerLoop(MCB)) {
3450b57cec5SDimitry Andric       assert(!Duplex);
3460b57cec5SDimitry Andric       assert(State.Index != Last);
3470b57cec5SDimitry Andric       return HexagonII::INST_PARSE_LOOP_END;
3480b57cec5SDimitry Andric     }
3490b57cec5SDimitry Andric   }
3500b57cec5SDimitry Andric   if (State.Index == 1) {
3510b57cec5SDimitry Andric     if (HexagonMCInstrInfo::isOuterLoop(MCB)) {
3520b57cec5SDimitry Andric       assert(!Duplex);
3530b57cec5SDimitry Andric       assert(State.Index != Last);
3540b57cec5SDimitry Andric       return HexagonII::INST_PARSE_LOOP_END;
3550b57cec5SDimitry Andric     }
3560b57cec5SDimitry Andric   }
3570b57cec5SDimitry Andric   if (Duplex) {
3580b57cec5SDimitry Andric     assert(State.Index == Last);
3590b57cec5SDimitry Andric     return HexagonII::INST_PARSE_DUPLEX;
3600b57cec5SDimitry Andric   }
3610b57cec5SDimitry Andric   if (State.Index == Last)
3620b57cec5SDimitry Andric     return HexagonII::INST_PARSE_PACKET_END;
3630b57cec5SDimitry Andric   return HexagonII::INST_PARSE_NOT_END;
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric /// Emit the bundle.
36706c3fb27SDimitry Andric void HexagonMCCodeEmitter::encodeInstruction(const MCInst &MI,
36806c3fb27SDimitry Andric                                              SmallVectorImpl<char> &CB,
3690b57cec5SDimitry Andric                                              SmallVectorImpl<MCFixup> &Fixups,
3700b57cec5SDimitry Andric                                              const MCSubtargetInfo &STI) const {
3710b57cec5SDimitry Andric   MCInst &HMB = const_cast<MCInst &>(MI);
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric   assert(HexagonMCInstrInfo::isBundle(HMB));
3740b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Encoding bundle\n";);
3750b57cec5SDimitry Andric   State.Addend = 0;
3760b57cec5SDimitry Andric   State.Extended = false;
3770b57cec5SDimitry Andric   State.Bundle = &MI;
3780b57cec5SDimitry Andric   State.Index = 0;
3790b57cec5SDimitry Andric   size_t Last = HexagonMCInstrInfo::bundleSize(HMB) - 1;
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric   for (auto &I : HexagonMCInstrInfo::bundleInstructions(HMB)) {
3820b57cec5SDimitry Andric     MCInst &HMI = const_cast<MCInst &>(*I.getInst());
3830b57cec5SDimitry Andric 
38406c3fb27SDimitry Andric     encodeSingleInstruction(HMI, CB, Fixups, STI, parseBits(Last, HMB, HMI));
3850b57cec5SDimitry Andric     State.Extended = HexagonMCInstrInfo::isImmext(HMI);
3860b57cec5SDimitry Andric     State.Addend += HEXAGON_INSTR_SIZE;
3870b57cec5SDimitry Andric     ++State.Index;
3880b57cec5SDimitry Andric   }
3890b57cec5SDimitry Andric }
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric static bool RegisterMatches(unsigned Consumer, unsigned Producer,
3920b57cec5SDimitry Andric                             unsigned Producer2) {
3935ffd83dbSDimitry Andric   return (Consumer == Producer) || (Consumer == Producer2) ||
3945ffd83dbSDimitry Andric          HexagonMCInstrInfo::IsSingleConsumerRefPairProducer(Producer,
3955ffd83dbSDimitry Andric                                                              Consumer);
3960b57cec5SDimitry Andric }
3970b57cec5SDimitry Andric 
39806c3fb27SDimitry Andric void HexagonMCCodeEmitter::encodeSingleInstruction(
39906c3fb27SDimitry Andric     const MCInst &MI, SmallVectorImpl<char> &CB,
40006c3fb27SDimitry Andric     SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI,
40106c3fb27SDimitry Andric     uint32_t Parse) const {
4020b57cec5SDimitry Andric   assert(!HexagonMCInstrInfo::isBundle(MI));
4030b57cec5SDimitry Andric   uint64_t Binary;
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric   // Pseudo instructions don't get encoded and shouldn't be here
4060b57cec5SDimitry Andric   // in the first place!
4070b57cec5SDimitry Andric   assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo() &&
4080b57cec5SDimitry Andric          "pseudo-instruction found");
4090b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Encoding insn `"
4100b57cec5SDimitry Andric                     << HexagonMCInstrInfo::getName(MCII, MI) << "'\n");
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   Binary = getBinaryCodeForInstr(MI, Fixups, STI);
4130b57cec5SDimitry Andric   unsigned Opc = MI.getOpcode();
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric   // Check for unimplemented instructions. Immediate extenders
4160b57cec5SDimitry Andric   // are encoded as zero, so they need to be accounted for.
4170b57cec5SDimitry Andric   if (!Binary && Opc != DuplexIClass0 && Opc != A4_ext) {
4180b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Unimplemented inst `"
4190b57cec5SDimitry Andric                       << HexagonMCInstrInfo::getName(MCII, MI) << "'\n");
4200b57cec5SDimitry Andric     llvm_unreachable("Unimplemented Instruction");
4210b57cec5SDimitry Andric   }
4220b57cec5SDimitry Andric   Binary |= Parse;
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric   // if we need to emit a duplexed instruction
4250b57cec5SDimitry Andric   if (Opc >= Hexagon::DuplexIClass0 && Opc <= Hexagon::DuplexIClassF) {
4260b57cec5SDimitry Andric     assert(Parse == HexagonII::INST_PARSE_DUPLEX &&
4270b57cec5SDimitry Andric            "Emitting duplex without duplex parse bits");
4280b57cec5SDimitry Andric     unsigned DupIClass = MI.getOpcode() - Hexagon::DuplexIClass0;
4290b57cec5SDimitry Andric     // 29 is the bit position.
4300b57cec5SDimitry Andric     // 0b1110 =0xE bits are masked off and down shifted by 1 bit.
4310b57cec5SDimitry Andric     // Last bit is moved to bit position 13
4320b57cec5SDimitry Andric     Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13);
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric     const MCInst *Sub0 = MI.getOperand(0).getInst();
4350b57cec5SDimitry Andric     const MCInst *Sub1 = MI.getOperand(1).getInst();
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric     // Get subinstruction slot 0.
4380b57cec5SDimitry Andric     unsigned SubBits0 = getBinaryCodeForInstr(*Sub0, Fixups, STI);
4390b57cec5SDimitry Andric     // Get subinstruction slot 1.
4400b57cec5SDimitry Andric     State.SubInst1 = true;
4410b57cec5SDimitry Andric     unsigned SubBits1 = getBinaryCodeForInstr(*Sub1, Fixups, STI);
4420b57cec5SDimitry Andric     State.SubInst1 = false;
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric     Binary |= SubBits0 | (SubBits1 << 16);
4450b57cec5SDimitry Andric   }
446*5f757f3fSDimitry Andric   support::endian::write<uint32_t>(CB, Binary, llvm::endianness::little);
4470b57cec5SDimitry Andric   ++MCNumEmitted;
4480b57cec5SDimitry Andric }
4490b57cec5SDimitry Andric 
450349cc55cSDimitry Andric [[noreturn]] static void raise_relocation_error(unsigned Width, unsigned Kind) {
4510b57cec5SDimitry Andric   std::string Text;
4520b57cec5SDimitry Andric   raw_string_ostream Stream(Text);
4530b57cec5SDimitry Andric   Stream << "Unrecognized relocation combination: width=" << Width
4540b57cec5SDimitry Andric          << " kind=" << Kind;
455349cc55cSDimitry Andric   report_fatal_error(Twine(Stream.str()));
4560b57cec5SDimitry Andric }
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric /// Some insns are not extended and thus have no bits. These cases require
4590b57cec5SDimitry Andric /// a more brute force method for determining the correct relocation.
4600b57cec5SDimitry Andric Hexagon::Fixups HexagonMCCodeEmitter::getFixupNoBits(
4610b57cec5SDimitry Andric       MCInstrInfo const &MCII, const MCInst &MI, const MCOperand &MO,
4620b57cec5SDimitry Andric       const MCSymbolRefExpr::VariantKind VarKind) const {
4630b57cec5SDimitry Andric   const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI);
4640b57cec5SDimitry Andric   unsigned InsnType = HexagonMCInstrInfo::getType(MCII, MI);
4650b57cec5SDimitry Andric   using namespace Hexagon;
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric   if (InsnType == HexagonII::TypeEXTENDER) {
4680b57cec5SDimitry Andric     if (VarKind == MCSymbolRefExpr::VK_None) {
4690b57cec5SDimitry Andric       auto Instrs = HexagonMCInstrInfo::bundleInstructions(*State.Bundle);
4700b57cec5SDimitry Andric       for (auto I = Instrs.begin(), N = Instrs.end(); I != N; ++I) {
4710b57cec5SDimitry Andric         if (I->getInst() != &MI)
4720b57cec5SDimitry Andric           continue;
4730b57cec5SDimitry Andric         assert(I+1 != N && "Extender cannot be last in packet");
4740b57cec5SDimitry Andric         const MCInst &NextI = *(I+1)->getInst();
4750b57cec5SDimitry Andric         const MCInstrDesc &NextD = HexagonMCInstrInfo::getDesc(MCII, NextI);
4760b57cec5SDimitry Andric         if (NextD.isBranch() || NextD.isCall() ||
4770b57cec5SDimitry Andric             HexagonMCInstrInfo::getType(MCII, NextI) == HexagonII::TypeCR)
4780b57cec5SDimitry Andric           return fixup_Hexagon_B32_PCREL_X;
4790b57cec5SDimitry Andric         return fixup_Hexagon_32_6_X;
4800b57cec5SDimitry Andric       }
4810b57cec5SDimitry Andric     }
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric     static const std::map<unsigned,unsigned> Relocs = {
4840b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_GOTREL,         fixup_Hexagon_GOTREL_32_6_X },
4850b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_GOT,            fixup_Hexagon_GOT_32_6_X },
4860b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_TPREL,          fixup_Hexagon_TPREL_32_6_X },
4870b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_DTPREL,         fixup_Hexagon_DTPREL_32_6_X },
4880b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_32_6_X },
4890b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_32_6_X },
4900b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_Hexagon_IE,     fixup_Hexagon_IE_32_6_X },
4910b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_32_6_X },
4925ffd83dbSDimitry Andric       { MCSymbolRefExpr::VK_PCREL,          fixup_Hexagon_B32_PCREL_X },
4930b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_Hexagon_GD_PLT, fixup_Hexagon_GD_PLT_B32_PCREL_X },
4940b57cec5SDimitry Andric       { MCSymbolRefExpr::VK_Hexagon_LD_PLT, fixup_Hexagon_LD_PLT_B32_PCREL_X },
4950b57cec5SDimitry Andric     };
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric     auto F = Relocs.find(VarKind);
4980b57cec5SDimitry Andric     if (F != Relocs.end())
4990b57cec5SDimitry Andric       return Hexagon::Fixups(F->second);
5000b57cec5SDimitry Andric     raise_relocation_error(0, VarKind);
5010b57cec5SDimitry Andric   }
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric   if (MCID.isBranch())
5040b57cec5SDimitry Andric     return fixup_Hexagon_B13_PCREL;
5050b57cec5SDimitry Andric 
5060b57cec5SDimitry Andric   static const std::map<unsigned,unsigned> RelocsLo = {
5070b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_GOT,            fixup_Hexagon_GOT_LO16 },
5080b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_GOTREL,         fixup_Hexagon_GOTREL_LO16 },
5090b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_LO16 },
5100b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_LO16 },
5110b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_Hexagon_IE,     fixup_Hexagon_IE_LO16 },
5120b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_LO16 },
5130b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_TPREL,          fixup_Hexagon_TPREL_LO16 },
5140b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_DTPREL,         fixup_Hexagon_DTPREL_LO16 },
5150b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_None,           fixup_Hexagon_LO16 },
5160b57cec5SDimitry Andric   };
5170b57cec5SDimitry Andric 
5180b57cec5SDimitry Andric   static const std::map<unsigned,unsigned> RelocsHi = {
5190b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_GOT,            fixup_Hexagon_GOT_HI16 },
5200b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_GOTREL,         fixup_Hexagon_GOTREL_HI16 },
5210b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_HI16 },
5220b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_HI16 },
5230b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_Hexagon_IE,     fixup_Hexagon_IE_HI16 },
5240b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_HI16 },
5250b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_TPREL,          fixup_Hexagon_TPREL_HI16 },
5260b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_DTPREL,         fixup_Hexagon_DTPREL_HI16 },
5270b57cec5SDimitry Andric     { MCSymbolRefExpr::VK_None,           fixup_Hexagon_HI16 },
5280b57cec5SDimitry Andric   };
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric   switch (MCID.getOpcode()) {
5310b57cec5SDimitry Andric     case Hexagon::LO:
5320b57cec5SDimitry Andric     case Hexagon::A2_tfril: {
5330b57cec5SDimitry Andric       auto F = RelocsLo.find(VarKind);
5340b57cec5SDimitry Andric       if (F != RelocsLo.end())
5350b57cec5SDimitry Andric         return Hexagon::Fixups(F->second);
5360b57cec5SDimitry Andric       break;
5370b57cec5SDimitry Andric     }
5380b57cec5SDimitry Andric     case Hexagon::HI:
5390b57cec5SDimitry Andric     case Hexagon::A2_tfrih: {
5400b57cec5SDimitry Andric       auto F = RelocsHi.find(VarKind);
5410b57cec5SDimitry Andric       if (F != RelocsHi.end())
5420b57cec5SDimitry Andric         return Hexagon::Fixups(F->second);
5430b57cec5SDimitry Andric       break;
5440b57cec5SDimitry Andric     }
5450b57cec5SDimitry Andric   }
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   raise_relocation_error(0, VarKind);
5480b57cec5SDimitry Andric }
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric static bool isPCRel(unsigned Kind) {
5510b57cec5SDimitry Andric   switch (Kind){
5520b57cec5SDimitry Andric   case fixup_Hexagon_B22_PCREL:
5530b57cec5SDimitry Andric   case fixup_Hexagon_B15_PCREL:
5540b57cec5SDimitry Andric   case fixup_Hexagon_B7_PCREL:
5550b57cec5SDimitry Andric   case fixup_Hexagon_B13_PCREL:
5560b57cec5SDimitry Andric   case fixup_Hexagon_B9_PCREL:
5570b57cec5SDimitry Andric   case fixup_Hexagon_B32_PCREL_X:
5580b57cec5SDimitry Andric   case fixup_Hexagon_B22_PCREL_X:
5590b57cec5SDimitry Andric   case fixup_Hexagon_B15_PCREL_X:
5600b57cec5SDimitry Andric   case fixup_Hexagon_B13_PCREL_X:
5610b57cec5SDimitry Andric   case fixup_Hexagon_B9_PCREL_X:
5620b57cec5SDimitry Andric   case fixup_Hexagon_B7_PCREL_X:
5630b57cec5SDimitry Andric   case fixup_Hexagon_32_PCREL:
5640b57cec5SDimitry Andric   case fixup_Hexagon_PLT_B22_PCREL:
5650b57cec5SDimitry Andric   case fixup_Hexagon_GD_PLT_B22_PCREL:
5660b57cec5SDimitry Andric   case fixup_Hexagon_LD_PLT_B22_PCREL:
5670b57cec5SDimitry Andric   case fixup_Hexagon_GD_PLT_B22_PCREL_X:
5680b57cec5SDimitry Andric   case fixup_Hexagon_LD_PLT_B22_PCREL_X:
5690b57cec5SDimitry Andric   case fixup_Hexagon_6_PCREL_X:
5700b57cec5SDimitry Andric     return true;
5710b57cec5SDimitry Andric   default:
5720b57cec5SDimitry Andric     return false;
5730b57cec5SDimitry Andric   }
5740b57cec5SDimitry Andric }
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
5770b57cec5SDimitry Andric       const MCOperand &MO, const MCExpr *ME, SmallVectorImpl<MCFixup> &Fixups,
5780b57cec5SDimitry Andric       const MCSubtargetInfo &STI) const {
5790b57cec5SDimitry Andric   if (isa<HexagonMCExpr>(ME))
5800b57cec5SDimitry Andric     ME = &HexagonMCInstrInfo::getExpr(*ME);
5810b57cec5SDimitry Andric   int64_t Value;
5820b57cec5SDimitry Andric   if (ME->evaluateAsAbsolute(Value)) {
5830b57cec5SDimitry Andric     bool InstExtendable = HexagonMCInstrInfo::isExtendable(MCII, MI) ||
5840b57cec5SDimitry Andric                           HexagonMCInstrInfo::isExtended(MCII, MI);
5850b57cec5SDimitry Andric     // Only sub-instruction #1 can be extended in a duplex. If MI is a
5860b57cec5SDimitry Andric     // sub-instruction #0, it is not extended even if Extended is true
5870b57cec5SDimitry Andric     // (it can be true for the duplex as a whole).
5880b57cec5SDimitry Andric     bool IsSub0 = HexagonMCInstrInfo::isSubInstruction(MI) && !State.SubInst1;
5890b57cec5SDimitry Andric     if (State.Extended && InstExtendable && !IsSub0) {
5900b57cec5SDimitry Andric       unsigned OpIdx = ~0u;
5910b57cec5SDimitry Andric       for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
5920b57cec5SDimitry Andric         if (&MO != &MI.getOperand(I))
5930b57cec5SDimitry Andric           continue;
5940b57cec5SDimitry Andric         OpIdx = I;
5950b57cec5SDimitry Andric         break;
5960b57cec5SDimitry Andric       }
5970b57cec5SDimitry Andric       assert(OpIdx != ~0u);
5980b57cec5SDimitry Andric       if (OpIdx == HexagonMCInstrInfo::getExtendableOp(MCII, MI)) {
5990b57cec5SDimitry Andric         unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
6000b57cec5SDimitry Andric         Value = (Value & 0x3f) << Shift;
6010b57cec5SDimitry Andric       }
6020b57cec5SDimitry Andric     }
6030b57cec5SDimitry Andric     return Value;
6040b57cec5SDimitry Andric   }
6050b57cec5SDimitry Andric   assert(ME->getKind() == MCExpr::SymbolRef ||
6060b57cec5SDimitry Andric          ME->getKind() == MCExpr::Binary);
6070b57cec5SDimitry Andric   if (ME->getKind() == MCExpr::Binary) {
6080b57cec5SDimitry Andric     MCBinaryExpr const *Binary = cast<MCBinaryExpr>(ME);
6090b57cec5SDimitry Andric     getExprOpValue(MI, MO, Binary->getLHS(), Fixups, STI);
6100b57cec5SDimitry Andric     getExprOpValue(MI, MO, Binary->getRHS(), Fixups, STI);
6110b57cec5SDimitry Andric     return 0;
6120b57cec5SDimitry Andric   }
6130b57cec5SDimitry Andric 
6140b57cec5SDimitry Andric   unsigned FixupKind = fixup_Invalid;
6150b57cec5SDimitry Andric   const MCSymbolRefExpr *MCSRE = static_cast<const MCSymbolRefExpr *>(ME);
6160b57cec5SDimitry Andric   const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI);
6170b57cec5SDimitry Andric   unsigned FixupWidth = HexagonMCInstrInfo::getExtentBits(MCII, MI) -
6180b57cec5SDimitry Andric                         HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
6190b57cec5SDimitry Andric   MCSymbolRefExpr::VariantKind VarKind = MCSRE->getKind();
6200b57cec5SDimitry Andric   unsigned Opc = MCID.getOpcode();
6210b57cec5SDimitry Andric   unsigned IType = HexagonMCInstrInfo::getType(MCII, MI);
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "----------------------------------------\n"
6240b57cec5SDimitry Andric                     << "Opcode Name: " << HexagonMCInstrInfo::getName(MCII, MI)
6250b57cec5SDimitry Andric                     << "\nOpcode: " << Opc << "\nRelocation bits: "
6260b57cec5SDimitry Andric                     << FixupWidth << "\nAddend: " << State.Addend
6270b57cec5SDimitry Andric                     << "\nVariant: " << unsigned(VarKind)
6280b57cec5SDimitry Andric                     << "\n----------------------------------------\n");
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric   // Pick the applicable fixup kind for the symbol.
6310b57cec5SDimitry Andric   // Handle special cases first, the rest will be looked up in the tables.
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric   if (FixupWidth == 16 && !State.Extended) {
6340b57cec5SDimitry Andric     if (VarKind == MCSymbolRefExpr::VK_None) {
6350b57cec5SDimitry Andric       if (HexagonMCInstrInfo::s27_2_reloc(*MO.getExpr())) {
6360b57cec5SDimitry Andric         // A2_iconst.
6370b57cec5SDimitry Andric         FixupKind = Hexagon::fixup_Hexagon_27_REG;
6380b57cec5SDimitry Andric       } else {
6390b57cec5SDimitry Andric         // Look for GP-relative fixups.
6400b57cec5SDimitry Andric         unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
6410b57cec5SDimitry Andric         static const Hexagon::Fixups GPRelFixups[] = {
6420b57cec5SDimitry Andric           Hexagon::fixup_Hexagon_GPREL16_0, Hexagon::fixup_Hexagon_GPREL16_1,
6430b57cec5SDimitry Andric           Hexagon::fixup_Hexagon_GPREL16_2, Hexagon::fixup_Hexagon_GPREL16_3
6440b57cec5SDimitry Andric         };
645bdd1243dSDimitry Andric         assert(Shift < std::size(GPRelFixups));
6460b57cec5SDimitry Andric         auto UsesGP = [](const MCInstrDesc &D) {
647bdd1243dSDimitry Andric           return is_contained(D.implicit_uses(), Hexagon::GP);
6480b57cec5SDimitry Andric         };
6490b57cec5SDimitry Andric         if (UsesGP(MCID))
6500b57cec5SDimitry Andric           FixupKind = GPRelFixups[Shift];
6510b57cec5SDimitry Andric       }
6520b57cec5SDimitry Andric     } else if (VarKind == MCSymbolRefExpr::VK_GOTREL) {
6530b57cec5SDimitry Andric       // Select between LO/HI.
6540b57cec5SDimitry Andric       if (Opc == Hexagon::LO)
6550b57cec5SDimitry Andric         FixupKind = Hexagon::fixup_Hexagon_GOTREL_LO16;
6560b57cec5SDimitry Andric       else if (Opc == Hexagon::HI)
6570b57cec5SDimitry Andric         FixupKind = Hexagon::fixup_Hexagon_GOTREL_HI16;
6580b57cec5SDimitry Andric     }
6590b57cec5SDimitry Andric   } else {
6600b57cec5SDimitry Andric     bool BranchOrCR = MCID.isBranch() || IType == HexagonII::TypeCR;
6610b57cec5SDimitry Andric     switch (FixupWidth) {
6620b57cec5SDimitry Andric       case 9:
6630b57cec5SDimitry Andric         if (BranchOrCR)
6640b57cec5SDimitry Andric           FixupKind = State.Extended ? Hexagon::fixup_Hexagon_B9_PCREL_X
6650b57cec5SDimitry Andric                                      : Hexagon::fixup_Hexagon_B9_PCREL;
6660b57cec5SDimitry Andric         break;
6670b57cec5SDimitry Andric       case 8:
6680b57cec5SDimitry Andric       case 7:
6690b57cec5SDimitry Andric         if (State.Extended && VarKind == MCSymbolRefExpr::VK_GOT)
6700b57cec5SDimitry Andric           FixupKind = HexagonMCInstrInfo::isExtentSigned(MCII, MI)
6710b57cec5SDimitry Andric                         ? Hexagon::fixup_Hexagon_GOT_16_X
6720b57cec5SDimitry Andric                         : Hexagon::fixup_Hexagon_GOT_11_X;
6730b57cec5SDimitry Andric         else if (FixupWidth == 7 && BranchOrCR)
6740b57cec5SDimitry Andric           FixupKind = State.Extended ? Hexagon::fixup_Hexagon_B7_PCREL_X
6750b57cec5SDimitry Andric                                      : Hexagon::fixup_Hexagon_B7_PCREL;
6760b57cec5SDimitry Andric         break;
6770b57cec5SDimitry Andric       case 0:
6780b57cec5SDimitry Andric         FixupKind = getFixupNoBits(MCII, MI, MO, VarKind);
6790b57cec5SDimitry Andric         break;
6800b57cec5SDimitry Andric     }
6810b57cec5SDimitry Andric   }
6820b57cec5SDimitry Andric 
6830b57cec5SDimitry Andric   if (FixupKind == fixup_Invalid) {
6840b57cec5SDimitry Andric     const auto &FixupTable = State.Extended ? ExtFixups : StdFixups;
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric     auto FindVK = FixupTable.find(VarKind);
6870b57cec5SDimitry Andric     if (FindVK != FixupTable.end())
6880b57cec5SDimitry Andric       FixupKind = FindVK->second[FixupWidth];
6890b57cec5SDimitry Andric   }
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric   if (FixupKind == fixup_Invalid)
6920b57cec5SDimitry Andric     raise_relocation_error(FixupWidth, VarKind);
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   const MCExpr *FixupExpr = MO.getExpr();
6950b57cec5SDimitry Andric   if (State.Addend != 0 && isPCRel(FixupKind)) {
6960b57cec5SDimitry Andric     const MCExpr *C = MCConstantExpr::create(State.Addend, MCT);
6970b57cec5SDimitry Andric     FixupExpr = MCBinaryExpr::createAdd(FixupExpr, C, MCT);
6980b57cec5SDimitry Andric   }
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(State.Addend, FixupExpr,
7010b57cec5SDimitry Andric                                   MCFixupKind(FixupKind), MI.getLoc());
7020b57cec5SDimitry Andric   Fixups.push_back(Fixup);
7030b57cec5SDimitry Andric   // All of the information is in the fixup.
7040b57cec5SDimitry Andric   return 0;
7050b57cec5SDimitry Andric }
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric unsigned
7080b57cec5SDimitry Andric HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO,
7090b57cec5SDimitry Andric                                         SmallVectorImpl<MCFixup> &Fixups,
7100b57cec5SDimitry Andric                                         MCSubtargetInfo const &STI) const {
7110b57cec5SDimitry Andric   size_t OperandNumber = ~0U;
7120b57cec5SDimitry Andric   for (unsigned i = 0, n = MI.getNumOperands(); i < n; ++i)
7130b57cec5SDimitry Andric     if (&MI.getOperand(i) == &MO) {
7140b57cec5SDimitry Andric       OperandNumber = i;
7150b57cec5SDimitry Andric       break;
7160b57cec5SDimitry Andric     }
7170b57cec5SDimitry Andric   assert((OperandNumber != ~0U) && "Operand not found");
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric   if (HexagonMCInstrInfo::isNewValue(MCII, MI) &&
7200b57cec5SDimitry Andric       &MO == &HexagonMCInstrInfo::getNewValueOperand(MCII, MI)) {
7210b57cec5SDimitry Andric     // Calculate the new value distance to the associated producer
7220b57cec5SDimitry Andric     unsigned SOffset = 0;
7230b57cec5SDimitry Andric     unsigned VOffset = 0;
7240b57cec5SDimitry Andric     unsigned UseReg = MO.getReg();
7255ffd83dbSDimitry Andric     unsigned DefReg1 = Hexagon::NoRegister;
7265ffd83dbSDimitry Andric     unsigned DefReg2 = Hexagon::NoRegister;
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric     auto Instrs = HexagonMCInstrInfo::bundleInstructions(*State.Bundle);
7290b57cec5SDimitry Andric     const MCOperand *I = Instrs.begin() + State.Index - 1;
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric     for (;; --I) {
7320b57cec5SDimitry Andric       assert(I != Instrs.begin() - 1 && "Couldn't find producer");
7330b57cec5SDimitry Andric       MCInst const &Inst = *I->getInst();
7340b57cec5SDimitry Andric       if (HexagonMCInstrInfo::isImmext(Inst))
7350b57cec5SDimitry Andric         continue;
7360b57cec5SDimitry Andric 
7375ffd83dbSDimitry Andric       DefReg1 = Hexagon::NoRegister;
7385ffd83dbSDimitry Andric       DefReg2 = Hexagon::NoRegister;
7390b57cec5SDimitry Andric       ++SOffset;
7400b57cec5SDimitry Andric       if (HexagonMCInstrInfo::isVector(MCII, Inst)) {
7410b57cec5SDimitry Andric         // Vector instructions don't count scalars.
7420b57cec5SDimitry Andric         ++VOffset;
7430b57cec5SDimitry Andric       }
7440b57cec5SDimitry Andric       if (HexagonMCInstrInfo::hasNewValue(MCII, Inst))
7450b57cec5SDimitry Andric         DefReg1 = HexagonMCInstrInfo::getNewValueOperand(MCII, Inst).getReg();
7460b57cec5SDimitry Andric       if (HexagonMCInstrInfo::hasNewValue2(MCII, Inst))
7470b57cec5SDimitry Andric         DefReg2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, Inst).getReg();
7480b57cec5SDimitry Andric       if (!RegisterMatches(UseReg, DefReg1, DefReg2)) {
7490b57cec5SDimitry Andric         // This isn't the register we're looking for
7500b57cec5SDimitry Andric         continue;
7510b57cec5SDimitry Andric       }
7520b57cec5SDimitry Andric       if (!HexagonMCInstrInfo::isPredicated(MCII, Inst)) {
7530b57cec5SDimitry Andric         // Producer is unpredicated
7540b57cec5SDimitry Andric         break;
7550b57cec5SDimitry Andric       }
7560b57cec5SDimitry Andric       assert(HexagonMCInstrInfo::isPredicated(MCII, MI) &&
7570b57cec5SDimitry Andric              "Unpredicated consumer depending on predicated producer");
7580b57cec5SDimitry Andric       if (HexagonMCInstrInfo::isPredicatedTrue(MCII, Inst) ==
7590b57cec5SDimitry Andric           HexagonMCInstrInfo::isPredicatedTrue(MCII, MI))
7600b57cec5SDimitry Andric         // Producer predicate sense matched ours.
7610b57cec5SDimitry Andric         break;
7620b57cec5SDimitry Andric     }
7630b57cec5SDimitry Andric     // Hexagon PRM 10.11 Construct Nt from distance
7640b57cec5SDimitry Andric     unsigned Offset = HexagonMCInstrInfo::isVector(MCII, MI) ? VOffset
7650b57cec5SDimitry Andric                                                              : SOffset;
7660b57cec5SDimitry Andric     Offset <<= 1;
7670b57cec5SDimitry Andric     Offset |= HexagonMCInstrInfo::SubregisterBit(UseReg, DefReg1, DefReg2);
7680b57cec5SDimitry Andric     return Offset;
7690b57cec5SDimitry Andric   }
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric   assert(!MO.isImm());
7720b57cec5SDimitry Andric   if (MO.isReg()) {
7730b57cec5SDimitry Andric     unsigned Reg = MO.getReg();
774bdd1243dSDimitry Andric     switch (HexagonMCInstrInfo::getDesc(MCII, MI)
775bdd1243dSDimitry Andric                 .operands()[OperandNumber]
776bdd1243dSDimitry Andric                 .RegClass) {
77704eeddc0SDimitry Andric     case GeneralSubRegsRegClassID:
77804eeddc0SDimitry Andric     case GeneralDoubleLow8RegsRegClassID:
7790b57cec5SDimitry Andric       return HexagonMCInstrInfo::getDuplexRegisterNumbering(Reg);
78004eeddc0SDimitry Andric     default:
78104eeddc0SDimitry Andric       break;
78204eeddc0SDimitry Andric     }
7830b57cec5SDimitry Andric     return MCT.getRegisterInfo()->getEncodingValue(Reg);
7840b57cec5SDimitry Andric   }
7850b57cec5SDimitry Andric 
7860b57cec5SDimitry Andric   return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI);
7870b57cec5SDimitry Andric }
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII,
7900b57cec5SDimitry Andric                                                 MCContext &MCT) {
7910b57cec5SDimitry Andric   return new HexagonMCCodeEmitter(MII, MCT);
7920b57cec5SDimitry Andric }
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric #include "HexagonGenMCCodeEmitter.inc"
795