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