| Craig Topper | f3f6650 | 2012-03-17 09:39:20 +0000 | [diff] [blame] | 1 | //===-- HexagonMCTargetDesc.cpp - Hexagon Target Descriptions -------------===// | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
| Craig Topper | bc3168b | 2012-03-17 09:28:37 +0000 | [diff] [blame] | 10 | // This file provides Hexagon specific target descriptions. | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 14 | #include "MCTargetDesc/HexagonMCTargetDesc.h" | 
| Eugene Zelenko | 401f381 | 2016-12-17 01:29:35 +0000 | [diff] [blame] | 15 | #include "Hexagon.h" | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 16 | #include "HexagonTargetStreamer.h" | 
| Colin LeMahieu | ff06261 | 2014-11-20 21:56:35 +0000 | [diff] [blame] | 17 | #include "MCTargetDesc/HexagonInstPrinter.h" | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 18 | #include "MCTargetDesc/HexagonMCAsmInfo.h" | 
|  | 19 | #include "MCTargetDesc/HexagonMCELFStreamer.h" | 
| Eugene Zelenko | 5015689 | 2016-12-17 01:17:18 +0000 | [diff] [blame] | 20 | #include "MCTargetDesc/HexagonMCInstrInfo.h" | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 21 | #include "llvm/ADT/StringRef.h" | 
| Zachary Turner | 264b5d9 | 2017-06-07 03:48:56 +0000 | [diff] [blame] | 22 | #include "llvm/BinaryFormat/ELF.h" | 
| Lang Hames | 02d3305 | 2017-10-11 01:57:21 +0000 | [diff] [blame^] | 23 | #include "llvm/MC/MCAsmBackend.h" | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 24 | #include "llvm/MC/MCContext.h" | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 25 | #include "llvm/MC/MCDwarf.h" | 
| Colin LeMahieu | 2c76920 | 2014-11-06 17:05:51 +0000 | [diff] [blame] | 26 | #include "llvm/MC/MCELFStreamer.h" | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 27 | #include "llvm/MC/MCInstrAnalysis.h" | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 28 | #include "llvm/MC/MCInstrInfo.h" | 
|  | 29 | #include "llvm/MC/MCRegisterInfo.h" | 
| Jyotsna Verma | 7503a62 | 2013-02-20 16:13:27 +0000 | [diff] [blame] | 30 | #include "llvm/MC/MCStreamer.h" | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 31 | #include "llvm/MC/MCSubtargetInfo.h" | 
| Craig Topper | c4965bc | 2012-02-05 07:21:30 +0000 | [diff] [blame] | 32 | #include "llvm/Support/ErrorHandling.h" | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 33 | #include "llvm/Support/TargetRegistry.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 34 | #include "llvm/Support/raw_ostream.h" | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 35 | #include <cassert> | 
|  | 36 | #include <cstdint> | 
|  | 37 | #include <new> | 
|  | 38 | #include <string> | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 39 |  | 
| Chandler Carruth | d174b72 | 2014-04-22 02:03:14 +0000 | [diff] [blame] | 40 | using namespace llvm; | 
|  | 41 |  | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 42 | #define GET_INSTRINFO_MC_DESC | 
|  | 43 | #include "HexagonGenInstrInfo.inc" | 
|  | 44 |  | 
|  | 45 | #define GET_SUBTARGETINFO_MC_DESC | 
|  | 46 | #include "HexagonGenSubtargetInfo.inc" | 
|  | 47 |  | 
|  | 48 | #define GET_REGINFO_MC_DESC | 
|  | 49 | #include "HexagonGenRegisterInfo.inc" | 
|  | 50 |  | 
| Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 51 | cl::opt<bool> llvm::HexagonDisableCompound | 
|  | 52 | ("mno-compound", | 
|  | 53 | cl::desc("Disable looking for compound instructions for Hexagon")); | 
|  | 54 |  | 
|  | 55 | cl::opt<bool> llvm::HexagonDisableDuplex | 
|  | 56 | ("mno-pairing", | 
|  | 57 | cl::desc("Disable looking for duplex instructions for Hexagon")); | 
|  | 58 |  | 
| Krzysztof Parzyszek | 64d4e2b | 2016-04-20 21:17:40 +0000 | [diff] [blame] | 59 | static cl::opt<bool> HexagonV4ArchVariant("mv4", cl::Hidden, cl::init(false), | 
|  | 60 | cl::desc("Build for Hexagon V4")); | 
|  | 61 |  | 
|  | 62 | static cl::opt<bool> HexagonV5ArchVariant("mv5", cl::Hidden, cl::init(false), | 
|  | 63 | cl::desc("Build for Hexagon V5")); | 
|  | 64 |  | 
|  | 65 | static cl::opt<bool> HexagonV55ArchVariant("mv55", cl::Hidden, cl::init(false), | 
|  | 66 | cl::desc("Build for Hexagon V55")); | 
|  | 67 |  | 
|  | 68 | static cl::opt<bool> HexagonV60ArchVariant("mv60", cl::Hidden, cl::init(false), | 
|  | 69 | cl::desc("Build for Hexagon V60")); | 
|  | 70 |  | 
| Krzysztof Parzyszek | f9015e6 | 2017-02-10 23:46:45 +0000 | [diff] [blame] | 71 | static cl::opt<bool> HexagonV62ArchVariant("mv62", cl::Hidden, cl::init(false), | 
|  | 72 | cl::desc("Build for Hexagon V62")); | 
|  | 73 |  | 
| Krzysztof Parzyszek | 7a0981a | 2017-03-09 17:05:11 +0000 | [diff] [blame] | 74 | static cl::opt<bool> EnableHVX("mhvx", cl::Hidden, cl::init(false), | 
|  | 75 | cl::desc("Enable Hexagon Vector Extension (HVX)")); | 
|  | 76 |  | 
| Krzysztof Parzyszek | 64d4e2b | 2016-04-20 21:17:40 +0000 | [diff] [blame] | 77 | static StringRef DefaultArch = "hexagonv60"; | 
|  | 78 |  | 
|  | 79 | static StringRef HexagonGetArchVariant() { | 
|  | 80 | if (HexagonV4ArchVariant) | 
|  | 81 | return "hexagonv4"; | 
|  | 82 | if (HexagonV5ArchVariant) | 
|  | 83 | return "hexagonv5"; | 
|  | 84 | if (HexagonV55ArchVariant) | 
|  | 85 | return "hexagonv55"; | 
|  | 86 | if (HexagonV60ArchVariant) | 
|  | 87 | return "hexagonv60"; | 
| Krzysztof Parzyszek | f9015e6 | 2017-02-10 23:46:45 +0000 | [diff] [blame] | 88 | if (HexagonV62ArchVariant) | 
|  | 89 | return "hexagonv62"; | 
| Krzysztof Parzyszek | 64d4e2b | 2016-04-20 21:17:40 +0000 | [diff] [blame] | 90 | return ""; | 
|  | 91 | } | 
|  | 92 |  | 
| Krzysztof Parzyszek | 75e74ee | 2016-08-19 14:09:47 +0000 | [diff] [blame] | 93 | StringRef Hexagon_MC::selectHexagonCPU(const Triple &TT, StringRef CPU) { | 
| Krzysztof Parzyszek | 64d4e2b | 2016-04-20 21:17:40 +0000 | [diff] [blame] | 94 | StringRef ArchV = HexagonGetArchVariant(); | 
|  | 95 | if (!ArchV.empty() && !CPU.empty()) { | 
|  | 96 | if (ArchV != CPU) | 
|  | 97 | report_fatal_error("conflicting architectures specified."); | 
|  | 98 | return CPU; | 
|  | 99 | } | 
|  | 100 | if (ArchV.empty()) { | 
|  | 101 | if (CPU.empty()) | 
|  | 102 | CPU = DefaultArch; | 
|  | 103 | return CPU; | 
|  | 104 | } | 
|  | 105 | return ArchV; | 
| Krzysztof Parzyszek | 759a7d0 | 2015-12-14 15:03:54 +0000 | [diff] [blame] | 106 | } | 
|  | 107 |  | 
| Benjamin Kramer | efcf06f | 2017-02-11 11:06:55 +0000 | [diff] [blame] | 108 | unsigned llvm::HexagonGetLastSlot() { return HexagonItinerariesV4FU::SLOT3; } | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 109 |  | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 110 | namespace { | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 111 |  | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 112 | class HexagonTargetAsmStreamer : public HexagonTargetStreamer { | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 113 | public: | 
|  | 114 | HexagonTargetAsmStreamer(MCStreamer &S, | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 115 | formatted_raw_ostream &OS, | 
|  | 116 | bool isVerboseAsm, | 
|  | 117 | MCInstPrinter &IP) | 
| Colin LeMahieu | fa38972 | 2015-06-18 21:03:13 +0000 | [diff] [blame] | 118 | : HexagonTargetStreamer(S) {} | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 119 |  | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 120 | void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS, | 
|  | 121 | const MCInst &Inst, const MCSubtargetInfo &STI) override { | 
|  | 122 | assert(HexagonMCInstrInfo::isBundle(Inst)); | 
|  | 123 | assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE); | 
|  | 124 | std::string Buffer; | 
|  | 125 | { | 
|  | 126 | raw_string_ostream TempStream(Buffer); | 
|  | 127 | InstPrinter.printInst(&Inst, TempStream, "", STI); | 
|  | 128 | } | 
|  | 129 | StringRef Contents(Buffer); | 
|  | 130 | auto PacketBundle = Contents.rsplit('\n'); | 
|  | 131 | auto HeadTail = PacketBundle.first.split('\n'); | 
| Colin LeMahieu | b7a5f9f | 2015-11-10 00:22:00 +0000 | [diff] [blame] | 132 | StringRef Separator = "\n"; | 
|  | 133 | StringRef Indent = "\t\t"; | 
|  | 134 | OS << "\t{\n"; | 
|  | 135 | while (!HeadTail.first.empty()) { | 
|  | 136 | StringRef InstTxt; | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 137 | auto Duplex = HeadTail.first.split('\v'); | 
| Colin LeMahieu | b7a5f9f | 2015-11-10 00:22:00 +0000 | [diff] [blame] | 138 | if (!Duplex.second.empty()) { | 
|  | 139 | OS << Indent << Duplex.first << Separator; | 
|  | 140 | InstTxt = Duplex.second; | 
|  | 141 | } else if (!HeadTail.first.trim().startswith("immext")) { | 
|  | 142 | InstTxt = Duplex.first; | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 143 | } | 
| Colin LeMahieu | b7a5f9f | 2015-11-10 00:22:00 +0000 | [diff] [blame] | 144 | if (!InstTxt.empty()) | 
|  | 145 | OS << Indent << InstTxt << Separator; | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 146 | HeadTail = HeadTail.second.split('\n'); | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 147 | } | 
| Colin LeMahieu | b7a5f9f | 2015-11-10 00:22:00 +0000 | [diff] [blame] | 148 | OS << "\t}" << PacketBundle.second; | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 149 | } | 
|  | 150 | }; | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 151 |  | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 152 | class HexagonTargetELFStreamer : public HexagonTargetStreamer { | 
|  | 153 | public: | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 154 | MCELFStreamer &getStreamer() { | 
|  | 155 | return static_cast<MCELFStreamer &>(Streamer); | 
|  | 156 | } | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 157 | HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI) | 
|  | 158 | : HexagonTargetStreamer(S) { | 
|  | 159 | MCAssembler &MCA = getStreamer().getAssembler(); | 
|  | 160 | MCA.setELFHeaderEFlags(Hexagon_MC::GetELFFlags(STI)); | 
|  | 161 | } | 
|  | 162 |  | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 163 |  | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 164 | void EmitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, | 
|  | 165 | unsigned ByteAlignment, | 
|  | 166 | unsigned AccessSize) override { | 
|  | 167 | HexagonMCELFStreamer &HexagonELFStreamer = | 
|  | 168 | static_cast<HexagonMCELFStreamer &>(getStreamer()); | 
|  | 169 | HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment, | 
|  | 170 | AccessSize); | 
|  | 171 | } | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 172 |  | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 173 | void EmitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, | 
|  | 174 | unsigned ByteAlignment, | 
|  | 175 | unsigned AccessSize) override { | 
|  | 176 | HexagonMCELFStreamer &HexagonELFStreamer = | 
|  | 177 | static_cast<HexagonMCELFStreamer &>(getStreamer()); | 
|  | 178 | HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol( | 
|  | 179 | Symbol, Size, ByteAlignment, AccessSize); | 
|  | 180 | } | 
|  | 181 | }; | 
| Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 182 |  | 
|  | 183 | } // end anonymous namespace | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 184 |  | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 185 | llvm::MCInstrInfo *llvm::createHexagonMCInstrInfo() { | 
|  | 186 | MCInstrInfo *X = new MCInstrInfo(); | 
|  | 187 | InitHexagonMCInstrInfo(X); | 
|  | 188 | return X; | 
|  | 189 | } | 
|  | 190 |  | 
|  | 191 | static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) { | 
|  | 192 | MCRegisterInfo *X = new MCRegisterInfo(); | 
|  | 193 | InitHexagonMCRegisterInfo(X, Hexagon::R31); | 
|  | 194 | return X; | 
|  | 195 | } | 
|  | 196 |  | 
| Rafael Espindola | 227144c | 2013-05-13 01:16:13 +0000 | [diff] [blame] | 197 | static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI, | 
| Daniel Sanders | 50f1723 | 2015-09-15 16:17:27 +0000 | [diff] [blame] | 198 | const Triple &TT) { | 
| Rafael Espindola | 140a837 | 2013-05-10 18:16:59 +0000 | [diff] [blame] | 199 | MCAsmInfo *MAI = new HexagonMCAsmInfo(TT); | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 200 |  | 
|  | 201 | // VirtualFP = (R30 + #0). | 
| Sid Manning | 7da3f9a | 2014-10-03 13:18:11 +0000 | [diff] [blame] | 202 | MCCFIInstruction Inst = | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 203 | MCCFIInstruction::createDefCfa(nullptr, | 
|  | 204 | MRI.getDwarfRegNum(Hexagon::R30, true), 0); | 
| Rafael Espindola | 227144c | 2013-05-13 01:16:13 +0000 | [diff] [blame] | 205 | MAI->addInitialFrameState(Inst); | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 206 |  | 
|  | 207 | return MAI; | 
|  | 208 | } | 
|  | 209 |  | 
| Daniel Sanders | 50f1723 | 2015-09-15 16:17:27 +0000 | [diff] [blame] | 210 | static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T, | 
| Eric Christopher | f801940 | 2015-03-31 00:10:04 +0000 | [diff] [blame] | 211 | unsigned SyntaxVariant, | 
| Sid Manning | 12cd21a | 2014-10-15 18:27:40 +0000 | [diff] [blame] | 212 | const MCAsmInfo &MAI, | 
|  | 213 | const MCInstrInfo &MII, | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 214 | const MCRegisterInfo &MRI) | 
|  | 215 | { | 
| Eric Christopher | fbe80f5 | 2015-04-09 19:20:37 +0000 | [diff] [blame] | 216 | if (SyntaxVariant == 0) | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 217 | return new HexagonInstPrinter(MAI, MII, MRI); | 
| Eric Christopher | fbe80f5 | 2015-04-09 19:20:37 +0000 | [diff] [blame] | 218 | else | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 219 | return nullptr; | 
|  | 220 | } | 
|  | 221 |  | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 222 | static MCTargetStreamer * | 
|  | 223 | createMCAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, | 
|  | 224 | MCInstPrinter *IP, bool IsVerboseAsm) { | 
|  | 225 | return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *IP); | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 226 | } | 
|  | 227 |  | 
| Lang Hames | 02d3305 | 2017-10-11 01:57:21 +0000 | [diff] [blame^] | 228 | static MCStreamer *createMCStreamer(Triple const &T, MCContext &Context, | 
|  | 229 | std::unique_ptr<MCAsmBackend> &&MAB, | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 230 | raw_pwrite_stream &OS, | 
| Lang Hames | 02d3305 | 2017-10-11 01:57:21 +0000 | [diff] [blame^] | 231 | MCCodeEmitter *Emitter, bool RelaxAll) { | 
|  | 232 | return createHexagonELFStreamer(T, Context, std::move(MAB), OS, Emitter); | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 233 | } | 
|  | 234 |  | 
|  | 235 | static MCTargetStreamer * | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 236 | createHexagonObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 237 | return new HexagonTargetELFStreamer(S, STI); | 
| Sid Manning | 12cd21a | 2014-10-15 18:27:40 +0000 | [diff] [blame] | 238 | } | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 239 |  | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 240 | static void LLVM_ATTRIBUTE_UNUSED clearFeature(MCSubtargetInfo* STI, uint64_t F) { | 
|  | 241 | uint64_t FB = STI->getFeatureBits().to_ullong(); | 
|  | 242 | if (FB & (1ULL << F)) | 
|  | 243 | STI->ToggleFeature(F); | 
|  | 244 | } | 
|  | 245 |  | 
|  | 246 | static bool LLVM_ATTRIBUTE_UNUSED checkFeature(MCSubtargetInfo* STI, uint64_t F) { | 
|  | 247 | uint64_t FB = STI->getFeatureBits().to_ullong(); | 
|  | 248 | return (FB & (1ULL << F)) != 0; | 
|  | 249 | } | 
|  | 250 |  | 
|  | 251 | StringRef Hexagon_MC::ParseHexagonTriple(const Triple &TT, StringRef CPU) { | 
|  | 252 | StringRef CPUName = Hexagon_MC::selectHexagonCPU(TT, CPU); | 
|  | 253 | StringRef FS = ""; | 
| Krzysztof Parzyszek | 7a0981a | 2017-03-09 17:05:11 +0000 | [diff] [blame] | 254 | if (EnableHVX) { | 
|  | 255 | if (CPUName.equals_lower("hexagonv60") || | 
|  | 256 | CPUName.equals_lower("hexagonv62")) | 
|  | 257 | FS = "+hvx"; | 
|  | 258 | } | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 259 | return FS; | 
|  | 260 | } | 
|  | 261 |  | 
|  | 262 | static bool isCPUValid(std::string CPU) | 
|  | 263 | { | 
|  | 264 | std::vector<std::string> table | 
|  | 265 | { | 
|  | 266 | "hexagonv4", | 
|  | 267 | "hexagonv5", | 
|  | 268 | "hexagonv55", | 
|  | 269 | "hexagonv60", | 
| Krzysztof Parzyszek | f9015e6 | 2017-02-10 23:46:45 +0000 | [diff] [blame] | 270 | "hexagonv62", | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 271 | }; | 
|  | 272 |  | 
|  | 273 | return std::find(table.begin(), table.end(), CPU) != table.end(); | 
|  | 274 | } | 
|  | 275 |  | 
|  | 276 | MCSubtargetInfo *Hexagon_MC::createHexagonMCSubtargetInfo(const Triple &TT, | 
|  | 277 | StringRef CPU, | 
|  | 278 | StringRef FS) { | 
|  | 279 | StringRef ArchFS = (FS.size()) ? FS : Hexagon_MC::ParseHexagonTriple(TT, CPU); | 
|  | 280 | StringRef CPUName = Hexagon_MC::selectHexagonCPU(TT, CPU); | 
| Krzysztof Parzyszek | f9015e6 | 2017-02-10 23:46:45 +0000 | [diff] [blame] | 281 | if (!isCPUValid(CPUName.str())) { | 
|  | 282 | errs() << "error: invalid CPU \"" << CPUName.str().c_str() | 
|  | 283 | << "\" specified\n"; | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 284 | return nullptr; | 
|  | 285 | } | 
|  | 286 |  | 
|  | 287 | MCSubtargetInfo *X = createHexagonMCSubtargetInfoImpl(TT, CPUName, ArchFS); | 
|  | 288 | if (X->getFeatureBits()[Hexagon::ExtensionHVXDbl]) { | 
|  | 289 | llvm::FeatureBitset Features = X->getFeatureBits(); | 
|  | 290 | X->setFeatureBits(Features.set(Hexagon::ExtensionHVX)); | 
|  | 291 | } | 
|  | 292 | return X; | 
|  | 293 | } | 
|  | 294 |  | 
|  | 295 | unsigned Hexagon_MC::GetELFFlags(const MCSubtargetInfo &STI) { | 
|  | 296 | static std::map<StringRef,unsigned> ElfFlags = { | 
|  | 297 | {"hexagonv4",  ELF::EF_HEXAGON_MACH_V4}, | 
|  | 298 | {"hexagonv5",  ELF::EF_HEXAGON_MACH_V5}, | 
|  | 299 | {"hexagonv55", ELF::EF_HEXAGON_MACH_V55}, | 
|  | 300 | {"hexagonv60", ELF::EF_HEXAGON_MACH_V60}, | 
| Krzysztof Parzyszek | f9015e6 | 2017-02-10 23:46:45 +0000 | [diff] [blame] | 301 | {"hexagonv62", ELF::EF_HEXAGON_MACH_V62}, | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 302 | }; | 
|  | 303 |  | 
|  | 304 | auto F = ElfFlags.find(STI.getCPU()); | 
|  | 305 | assert(F != ElfFlags.end() && "Unrecognized Architecture"); | 
|  | 306 | return F->second; | 
|  | 307 | } | 
|  | 308 |  | 
|  | 309 | namespace { | 
|  | 310 | class HexagonMCInstrAnalysis : public MCInstrAnalysis { | 
|  | 311 | public: | 
|  | 312 | HexagonMCInstrAnalysis(MCInstrInfo const *Info) : MCInstrAnalysis(Info) {} | 
|  | 313 |  | 
|  | 314 | bool isUnconditionalBranch(MCInst const &Inst) const override { | 
|  | 315 | //assert(!HexagonMCInstrInfo::isBundle(Inst)); | 
|  | 316 | return MCInstrAnalysis::isUnconditionalBranch(Inst); | 
|  | 317 | } | 
|  | 318 |  | 
|  | 319 | bool isConditionalBranch(MCInst const &Inst) const override { | 
|  | 320 | //assert(!HexagonMCInstrInfo::isBundle(Inst)); | 
|  | 321 | return MCInstrAnalysis::isConditionalBranch(Inst); | 
|  | 322 | } | 
|  | 323 |  | 
|  | 324 | bool evaluateBranch(MCInst const &Inst, uint64_t Addr, | 
|  | 325 | uint64_t Size, uint64_t &Target) const override { | 
|  | 326 | //assert(!HexagonMCInstrInfo::isBundle(Inst)); | 
|  | 327 | if(!HexagonMCInstrInfo::isExtendable(*Info, Inst)) | 
|  | 328 | return false; | 
|  | 329 | auto const &Extended(HexagonMCInstrInfo::getExtendableOperand(*Info, Inst)); | 
|  | 330 | assert(Extended.isExpr()); | 
|  | 331 | int64_t Value; | 
|  | 332 | if(!Extended.getExpr()->evaluateAsAbsolute(Value)) | 
|  | 333 | return false; | 
|  | 334 | Target = Value; | 
|  | 335 | return true; | 
|  | 336 | } | 
|  | 337 | }; | 
|  | 338 | } | 
|  | 339 |  | 
|  | 340 | static MCInstrAnalysis *createHexagonMCInstrAnalysis(const MCInstrInfo *Info) { | 
|  | 341 | return new HexagonMCInstrAnalysis(Info); | 
|  | 342 | } | 
|  | 343 |  | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 344 | // Force static initialization. | 
|  | 345 | extern "C" void LLVMInitializeHexagonTargetMC() { | 
|  | 346 | // Register the MC asm info. | 
| Mehdi Amini | f42454b | 2016-10-09 23:00:34 +0000 | [diff] [blame] | 347 | RegisterMCAsmInfoFn X(getTheHexagonTarget(), createHexagonMCAsmInfo); | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 348 |  | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 349 | // Register the MC instruction info. | 
| Mehdi Amini | f42454b | 2016-10-09 23:00:34 +0000 | [diff] [blame] | 350 | TargetRegistry::RegisterMCInstrInfo(getTheHexagonTarget(), | 
| Sid Manning | 7da3f9a | 2014-10-03 13:18:11 +0000 | [diff] [blame] | 351 | createHexagonMCInstrInfo); | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 352 |  | 
|  | 353 | // Register the MC register info. | 
| Mehdi Amini | f42454b | 2016-10-09 23:00:34 +0000 | [diff] [blame] | 354 | TargetRegistry::RegisterMCRegInfo(getTheHexagonTarget(), | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 355 | createHexagonMCRegisterInfo); | 
|  | 356 |  | 
|  | 357 | // Register the MC subtarget info. | 
| Mehdi Amini | f42454b | 2016-10-09 23:00:34 +0000 | [diff] [blame] | 358 | TargetRegistry::RegisterMCSubtargetInfo(getTheHexagonTarget(), | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 359 | Hexagon_MC::createHexagonMCSubtargetInfo); | 
| Sid Manning | 7da3f9a | 2014-10-03 13:18:11 +0000 | [diff] [blame] | 360 |  | 
|  | 361 | // Register the MC Code Emitter | 
| Mehdi Amini | f42454b | 2016-10-09 23:00:34 +0000 | [diff] [blame] | 362 | TargetRegistry::RegisterMCCodeEmitter(getTheHexagonTarget(), | 
| Sid Manning | 7da3f9a | 2014-10-03 13:18:11 +0000 | [diff] [blame] | 363 | createHexagonMCCodeEmitter); | 
| Sid Manning | 12cd21a | 2014-10-15 18:27:40 +0000 | [diff] [blame] | 364 |  | 
| Colin LeMahieu | a675077 | 2015-06-03 17:34:16 +0000 | [diff] [blame] | 365 | // Register the asm backend | 
| Mehdi Amini | f42454b | 2016-10-09 23:00:34 +0000 | [diff] [blame] | 366 | TargetRegistry::RegisterMCAsmBackend(getTheHexagonTarget(), | 
| Colin LeMahieu | a675077 | 2015-06-03 17:34:16 +0000 | [diff] [blame] | 367 | createHexagonAsmBackend); | 
|  | 368 |  | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 369 |  | 
|  | 370 | // Register the MC instruction analyzer. | 
|  | 371 | TargetRegistry::RegisterMCInstrAnalysis(getTheHexagonTarget(), | 
|  | 372 | createHexagonMCInstrAnalysis); | 
|  | 373 |  | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 374 | // Register the obj streamer | 
| Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 375 | TargetRegistry::RegisterELFStreamer(getTheHexagonTarget(), | 
|  | 376 | createMCStreamer); | 
|  | 377 |  | 
|  | 378 | // Register the obj target streamer | 
|  | 379 | TargetRegistry::RegisterObjectTargetStreamer(getTheHexagonTarget(), | 
|  | 380 | createHexagonObjectTargetStreamer); | 
| Colin LeMahieu | be99a02 | 2015-06-17 03:06:16 +0000 | [diff] [blame] | 381 |  | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 382 | // Register the asm streamer | 
| Mehdi Amini | f42454b | 2016-10-09 23:00:34 +0000 | [diff] [blame] | 383 | TargetRegistry::RegisterAsmTargetStreamer(getTheHexagonTarget(), | 
| Colin LeMahieu | d215875 | 2015-06-18 20:43:50 +0000 | [diff] [blame] | 384 | createMCAsmTargetStreamer); | 
|  | 385 |  | 
| Sid Manning | 12cd21a | 2014-10-15 18:27:40 +0000 | [diff] [blame] | 386 | // Register the MC Inst Printer | 
| Mehdi Amini | f42454b | 2016-10-09 23:00:34 +0000 | [diff] [blame] | 387 | TargetRegistry::RegisterMCInstPrinter(getTheHexagonTarget(), | 
| Sid Manning | 12cd21a | 2014-10-15 18:27:40 +0000 | [diff] [blame] | 388 | createHexagonMCInstPrinter); | 
| Tony Linthicum | b3705e0 | 2011-12-15 22:29:08 +0000 | [diff] [blame] | 389 | } |