blob: 577513bd3c93fd157542ffbd497d2f312ce211ee [file] [log] [blame]
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001//===-- HexagonAsmParser.cpp - Parse Hexagon asm to MCInst instructions----===//
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
10#define DEBUG_TYPE "mcasmparser"
11
12#include "Hexagon.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000013#include "HexagonTargetStreamer.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000014#include "MCTargetDesc/HexagonMCChecker.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000015#include "MCTargetDesc/HexagonMCELFStreamer.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000016#include "MCTargetDesc/HexagonMCExpr.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000017#include "MCTargetDesc/HexagonMCInstrInfo.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000018#include "MCTargetDesc/HexagonMCTargetDesc.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000019#include "MCTargetDesc/HexagonShuffler.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000020#include "llvm/ADT/STLExtras.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000021#include "llvm/ADT/SmallVector.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000022#include "llvm/ADT/StringExtras.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000023#include "llvm/ADT/StringRef.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000024#include "llvm/ADT/Twine.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000025#include "llvm/BinaryFormat/ELF.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000026#include "llvm/MC/MCAssembler.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000027#include "llvm/MC/MCContext.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000028#include "llvm/MC/MCDirectives.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000029#include "llvm/MC/MCELFStreamer.h"
30#include "llvm/MC/MCExpr.h"
31#include "llvm/MC/MCInst.h"
32#include "llvm/MC/MCParser/MCAsmLexer.h"
33#include "llvm/MC/MCParser/MCAsmParser.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000034#include "llvm/MC/MCParser/MCAsmParserExtension.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000035#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000036#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000037#include "llvm/MC/MCRegisterInfo.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000038#include "llvm/MC/MCSectionELF.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000039#include "llvm/MC/MCStreamer.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000040#include "llvm/MC/MCSubtargetInfo.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000041#include "llvm/MC/MCSymbol.h"
Colin LeMahieu5cb6eea2016-03-01 21:37:41 +000042#include "llvm/MC/MCValue.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000043#include "llvm/Support/Casting.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000044#include "llvm/Support/CommandLine.h"
45#include "llvm/Support/Debug.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000046#include "llvm/Support/ErrorHandling.h"
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +000047#include "llvm/Support/Format.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000048#include "llvm/Support/MathExtras.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000049#include "llvm/Support/SMLoc.h"
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +000050#include "llvm/Support/SourceMgr.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000051#include "llvm/Support/TargetRegistry.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000052#include "llvm/Support/raw_ostream.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000053#include <algorithm>
54#include <cassert>
55#include <cctype>
56#include <cstddef>
57#include <cstdint>
58#include <memory>
59#include <string>
60#include <utility>
Colin LeMahieu7cd08922015-11-09 04:07:48 +000061
62using namespace llvm;
63
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +000064static cl::opt<bool> WarnMissingParenthesis(
65 "mwarn-missing-parenthesis",
66 cl::desc("Warn for missing parenthesis around predicate registers"),
67 cl::init(true));
68static cl::opt<bool> ErrorMissingParenthesis(
69 "merror-missing-parenthesis",
70 cl::desc("Error for missing parenthesis around predicate registers"),
71 cl::init(false));
72static cl::opt<bool> WarnSignedMismatch(
73 "mwarn-sign-mismatch",
74 cl::desc("Warn for mismatching a signed and unsigned value"),
75 cl::init(true));
76static cl::opt<bool> WarnNoncontigiousRegister(
77 "mwarn-noncontigious-register",
78 cl::desc("Warn for register names that arent contigious"), cl::init(true));
79static cl::opt<bool> ErrorNoncontigiousRegister(
80 "merror-noncontigious-register",
81 cl::desc("Error for register names that aren't contigious"),
82 cl::init(false));
Colin LeMahieu7cd08922015-11-09 04:07:48 +000083
Colin LeMahieu7cd08922015-11-09 04:07:48 +000084namespace {
Eugene Zelenko82085922016-12-13 22:13:50 +000085
Colin LeMahieu7cd08922015-11-09 04:07:48 +000086struct HexagonOperand;
87
88class HexagonAsmParser : public MCTargetAsmParser {
89
90 HexagonTargetStreamer &getTargetStreamer() {
91 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
92 return static_cast<HexagonTargetStreamer &>(TS);
93 }
94
Colin LeMahieu7cd08922015-11-09 04:07:48 +000095 MCAsmParser &Parser;
Colin LeMahieu7cd08922015-11-09 04:07:48 +000096 MCInst MCB;
97 bool InBrackets;
98
99 MCAsmParser &getParser() const { return Parser; }
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000100 MCAssembler *getAssembler() const {
101 MCAssembler *Assembler = nullptr;
102 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
103 if (!Parser.getStreamer().hasRawTextSupport()) {
104 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
105 Assembler = &MES->getAssembler();
106 }
107 return Assembler;
108 }
109
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000110 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
111
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000112 bool equalIsAsmAssignment() override { return false; }
113 bool isLabel(AsmToken &Token) override;
114
115 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
116 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
117 bool ParseDirectiveFalign(unsigned Size, SMLoc L);
118
Eugene Zelenko82085922016-12-13 22:13:50 +0000119 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000120 bool ParseDirectiveSubsection(SMLoc L);
121 bool ParseDirectiveValue(unsigned Size, SMLoc L);
122 bool ParseDirectiveComm(bool IsLocal, SMLoc L);
123 bool RegisterMatchesArch(unsigned MatchNum) const;
124
125 bool matchBundleOptions();
126 bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);
127 bool finishBundle(SMLoc IDLoc, MCStreamer &Out);
128 void canonicalizeImmediates(MCInst &MCI);
129 bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,
130 OperandVector &InstOperands, uint64_t &ErrorInfo,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000131 bool MatchingInlineAsm);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000132 void eatToEndOfPacket();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000133 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
134 OperandVector &Operands, MCStreamer &Out,
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000135 uint64_t &ErrorInfo,
136 bool MatchingInlineAsm) override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000137
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000138 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
139 unsigned Kind) override;
Nirav Dave2364748a2016-09-16 18:30:20 +0000140 bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000141 int processInstruction(MCInst &Inst, OperandVector const &Operands,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000142 SMLoc IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000143
144 // Check if we have an assembler and, if so, set the ELF e_header flags.
145 void chksetELFHeaderEFlags(unsigned flags) {
146 if (getAssembler())
147 getAssembler()->setELFHeaderEFlags(flags);
148 }
149
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +0000150 unsigned matchRegister(StringRef Name);
151
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000152/// @name Auto-generated Match Functions
153/// {
154
155#define GET_ASSEMBLER_HEADER
156#include "HexagonGenAsmMatcher.inc"
157
158 /// }
159
160public:
Akira Hatanakab11ef082015-11-14 06:35:56 +0000161 HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000162 const MCInstrInfo &MII, const MCTargetOptions &Options)
Oliver Stannard4191b9e2017-10-11 09:17:43 +0000163 : MCTargetAsmParser(Options, _STI, MII), Parser(_Parser),
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000164 InBrackets(false) {
165 MCB.setOpcode(Hexagon::BUNDLE);
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000166 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000167
Eugene Zelenko82085922016-12-13 22:13:50 +0000168 MCAsmParserExtension::Initialize(_Parser);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000169 }
170
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000171 bool splitIdentifier(OperandVector &Operands);
172 bool parseOperand(OperandVector &Operands);
173 bool parseInstruction(OperandVector &Operands);
174 bool implicitExpressionLocation(OperandVector &Operands);
175 bool parseExpressionOrOperand(OperandVector &Operands);
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000176 bool parseExpression(MCExpr const *&Expr);
Eugene Zelenko82085922016-12-13 22:13:50 +0000177
178 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000179 SMLoc NameLoc, OperandVector &Operands) override {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000180 llvm_unreachable("Unimplemented");
181 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000182
Eugene Zelenko82085922016-12-13 22:13:50 +0000183 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
184 OperandVector &Operands) override;
185
186 bool ParseDirective(AsmToken DirectiveID) override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000187};
188
189/// HexagonOperand - Instances of this class represent a parsed Hexagon machine
190/// instruction.
191struct HexagonOperand : public MCParsedAsmOperand {
192 enum KindTy { Token, Immediate, Register } Kind;
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000193 MCContext &Context;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000194
195 SMLoc StartLoc, EndLoc;
196
197 struct TokTy {
198 const char *Data;
199 unsigned Length;
200 };
201
202 struct RegTy {
203 unsigned RegNum;
204 };
205
206 struct ImmTy {
207 const MCExpr *Val;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000208 };
209
210 struct InstTy {
211 OperandVector *SubInsts;
212 };
213
214 union {
215 struct TokTy Tok;
216 struct RegTy Reg;
217 struct ImmTy Imm;
218 };
219
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000220 HexagonOperand(KindTy K, MCContext &Context)
221 : MCParsedAsmOperand(), Kind(K), Context(Context) {}
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000222
223public:
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000224 HexagonOperand(const HexagonOperand &o)
225 : MCParsedAsmOperand(), Context(o.Context) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000226 Kind = o.Kind;
227 StartLoc = o.StartLoc;
228 EndLoc = o.EndLoc;
229 switch (Kind) {
230 case Register:
231 Reg = o.Reg;
232 break;
233 case Immediate:
234 Imm = o.Imm;
235 break;
236 case Token:
237 Tok = o.Tok;
238 break;
239 }
240 }
241
242 /// getStartLoc - Get the location of the first token of this operand.
Eugene Zelenko82085922016-12-13 22:13:50 +0000243 SMLoc getStartLoc() const override { return StartLoc; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000244
245 /// getEndLoc - Get the location of the last token of this operand.
Eugene Zelenko82085922016-12-13 22:13:50 +0000246 SMLoc getEndLoc() const override { return EndLoc; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000247
Eugene Zelenko82085922016-12-13 22:13:50 +0000248 unsigned getReg() const override {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000249 assert(Kind == Register && "Invalid access!");
250 return Reg.RegNum;
251 }
252
253 const MCExpr *getImm() const {
254 assert(Kind == Immediate && "Invalid access!");
255 return Imm.Val;
256 }
257
Eugene Zelenko82085922016-12-13 22:13:50 +0000258 bool isToken() const override { return Kind == Token; }
259 bool isImm() const override { return Kind == Immediate; }
260 bool isMem() const override { llvm_unreachable("No isMem"); }
261 bool isReg() const override { return Kind == Register; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000262
263 bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
264 bool isRelocatable, bool Extendable) const {
265 if (Kind == Immediate) {
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000266 const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000267 if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && !Extendable)
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000268 return false;
269 int64_t Res;
270 if (myMCExpr->evaluateAsAbsolute(Res)) {
271 int bits = immBits + zeroBits;
272 // Field bit range is zerobits + bits
273 // zeroBits must be 0
274 if (Res & ((1 << zeroBits) - 1))
275 return false;
276 if (isSigned) {
277 if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
278 return true;
279 } else {
280 if (bits == 64)
281 return true;
282 if (Res >= 0)
Eugene Zelenko82085922016-12-13 22:13:50 +0000283 return ((uint64_t)Res < (uint64_t)(1ULL << bits));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000284 else {
285 const int64_t high_bit_set = 1ULL << 63;
286 const uint64_t mask = (high_bit_set >> (63 - bits));
Eugene Zelenko82085922016-12-13 22:13:50 +0000287 return (((uint64_t)Res & mask) == mask);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000288 }
289 }
290 } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
291 return true;
292 else if (myMCExpr->getKind() == MCExpr::Binary ||
293 myMCExpr->getKind() == MCExpr::Unary)
294 return true;
295 }
296 return false;
297 }
298
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000299 bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
300 bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
301 bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }
302 bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }
303
304 bool ism32_0Imm() const { return true; }
305
306 bool isf32Imm() const { return false; }
307 bool isf64Imm() const { return false; }
308 bool iss32_0Imm() const { return true; }
309 bool iss31_1Imm() const { return true; }
310 bool iss30_2Imm() const { return true; }
311 bool iss29_3Imm() const { return true; }
Krzysztof Parzyszek57a8bb432017-05-02 18:19:11 +0000312 bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000313 bool iss10_0Imm() const { return CheckImmRange(10, 0, true, false, false); }
314 bool iss10_6Imm() const { return CheckImmRange(10, 6, true, false, false); }
315 bool iss9_0Imm() const { return CheckImmRange(9, 0, true, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000316 bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }
317 bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }
318 bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }
319 bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000320 bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000321 bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }
322 bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }
323 bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }
324 bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000325 bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000326
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000327 bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000328 bool isu32_0Imm() const { return true; }
329 bool isu31_1Imm() const { return true; }
330 bool isu30_2Imm() const { return true; }
331 bool isu29_3Imm() const { return true; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000332 bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000333 bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }
334 bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }
335 bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }
336 bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }
337 bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000338 bool isu10_0Imm() const { return CheckImmRange(10, 0, false, false, false); }
339 bool isu9_0Imm() const { return CheckImmRange(9, 0, false, false, false); }
340 bool isu8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }
341 bool isu7_0Imm() const { return CheckImmRange(7, 0, false, false, false); }
342 bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000343 bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }
344 bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }
345 bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000346 bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000347 bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }
348 bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000349 bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000350 bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000351 bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000352 bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000353 bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }
354 bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000355
Colin LeMahieu81707542016-12-05 04:29:00 +0000356 bool isn1Const() const {
357 if (!isImm())
358 return false;
359 int64_t Value;
360 if (!getImm()->evaluateAsAbsolute(Value))
361 return false;
362 return Value == -1;
363 }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000364 bool iss11_0Imm() const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000365 return CheckImmRange(11 + 26, 0, true, true, true);
366 }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000367 bool iss11_1Imm() const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000368 return CheckImmRange(11 + 26, 1, true, true, true);
369 }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000370 bool iss11_2Imm() const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000371 return CheckImmRange(11 + 26, 2, true, true, true);
372 }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000373 bool iss11_3Imm() const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000374 return CheckImmRange(11 + 26, 3, true, true, true);
375 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000376 bool isu32_0MustExt() const { return isImm(); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000377
378 void addRegOperands(MCInst &Inst, unsigned N) const {
379 assert(N == 1 && "Invalid number of operands!");
380 Inst.addOperand(MCOperand::createReg(getReg()));
381 }
382
383 void addImmOperands(MCInst &Inst, unsigned N) const {
384 assert(N == 1 && "Invalid number of operands!");
385 Inst.addOperand(MCOperand::createExpr(getImm()));
386 }
387
388 void addSignedImmOperands(MCInst &Inst, unsigned N) const {
389 assert(N == 1 && "Invalid number of operands!");
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000390 HexagonMCExpr *Expr =
391 const_cast<HexagonMCExpr *>(cast<HexagonMCExpr>(getImm()));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000392 int64_t Value;
393 if (!Expr->evaluateAsAbsolute(Value)) {
394 Inst.addOperand(MCOperand::createExpr(Expr));
395 return;
396 }
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000397 int64_t Extended = SignExtend64(Value, 32);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000398 HexagonMCExpr *NewExpr = HexagonMCExpr::create(
399 MCConstantExpr::create(Extended, Context), Context);
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000400 if ((Extended < 0) != (Value < 0))
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000401 NewExpr->setSignMismatch();
402 NewExpr->setMustExtend(Expr->mustExtend());
403 NewExpr->setMustNotExtend(Expr->mustNotExtend());
404 Inst.addOperand(MCOperand::createExpr(NewExpr));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000405 }
406
Colin LeMahieu81707542016-12-05 04:29:00 +0000407 void addn1ConstOperands(MCInst &Inst, unsigned N) const {
408 addImmOperands(Inst, N);
409 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000410
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000411 StringRef getToken() const {
412 assert(Kind == Token && "Invalid access!");
413 return StringRef(Tok.Data, Tok.Length);
414 }
415
Eugene Zelenko82085922016-12-13 22:13:50 +0000416 void print(raw_ostream &OS) const override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000417
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000418 static std::unique_ptr<HexagonOperand> CreateToken(MCContext &Context,
419 StringRef Str, SMLoc S) {
420 HexagonOperand *Op = new HexagonOperand(Token, Context);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000421 Op->Tok.Data = Str.data();
422 Op->Tok.Length = Str.size();
423 Op->StartLoc = S;
424 Op->EndLoc = S;
425 return std::unique_ptr<HexagonOperand>(Op);
426 }
427
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000428 static std::unique_ptr<HexagonOperand>
429 CreateReg(MCContext &Context, unsigned RegNum, SMLoc S, SMLoc E) {
430 HexagonOperand *Op = new HexagonOperand(Register, Context);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000431 Op->Reg.RegNum = RegNum;
432 Op->StartLoc = S;
433 Op->EndLoc = E;
434 return std::unique_ptr<HexagonOperand>(Op);
435 }
436
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000437 static std::unique_ptr<HexagonOperand>
438 CreateImm(MCContext &Context, const MCExpr *Val, SMLoc S, SMLoc E) {
439 HexagonOperand *Op = new HexagonOperand(Immediate, Context);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000440 Op->Imm.Val = Val;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000441 Op->StartLoc = S;
442 Op->EndLoc = E;
443 return std::unique_ptr<HexagonOperand>(Op);
444 }
445};
446
Eugene Zelenko82085922016-12-13 22:13:50 +0000447} // end anonymous namespace
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000448
449void HexagonOperand::print(raw_ostream &OS) const {
450 switch (Kind) {
451 case Immediate:
452 getImm()->print(OS, nullptr);
453 break;
454 case Register:
455 OS << "<register R";
456 OS << getReg() << ">";
457 break;
458 case Token:
459 OS << "'" << getToken() << "'";
460 break;
461 }
462}
463
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000464bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000465 LLVM_DEBUG(dbgs() << "Bundle:");
466 LLVM_DEBUG(MCB.dump_pretty(dbgs()));
467 LLVM_DEBUG(dbgs() << "--\n");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000468
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000469 MCB.setLoc(IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000470 // Check the bundle for errors.
471 const MCRegisterInfo *RI = getContext().getRegisterInfo();
Oliver Stannard4191b9e2017-10-11 09:17:43 +0000472 HexagonMCChecker Check(getContext(), MII, getSTI(), MCB, *RI);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000473
Oliver Stannard4191b9e2017-10-11 09:17:43 +0000474 bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MII, getSTI(),
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000475 getContext(), MCB,
476 &Check);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000477
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000478 if (CheckOk) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000479 if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
480 assert(!HexagonMCInstrInfo::isInnerLoop(MCB));
481 assert(!HexagonMCInstrInfo::isOuterLoop(MCB));
482 // Empty packets are valid yet aren't emitted
483 return false;
484 }
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000485 Out.EmitInstruction(MCB, getSTI());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000486 } else {
487 // If compounding and duplexing didn't reduce the size below
488 // 4 or less we have a packet that is too big.
489 if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
490 Error(IDLoc, "invalid instruction packet: out of slots");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000491 }
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000492 return true; // Error
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000493 }
494
495 return false; // No error
496}
497
498bool HexagonAsmParser::matchBundleOptions() {
499 MCAsmParser &Parser = getParser();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000500 while (true) {
501 if (!Parser.getTok().is(AsmToken::Colon))
502 return false;
Nirav Davefd910412016-06-17 16:06:17 +0000503 Lex();
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000504 char const *MemNoShuffMsg =
505 "invalid instruction packet: mem_noshuf specifier not "
506 "supported with this architecture";
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000507 StringRef Option = Parser.getTok().getString();
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000508 auto IDLoc = Parser.getTok().getLoc();
Krzysztof Parzyszek4f998362018-03-30 15:29:47 +0000509 if (Option.compare_lower("endloop01") == 0) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000510 HexagonMCInstrInfo::setInnerLoop(MCB);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000511 HexagonMCInstrInfo::setOuterLoop(MCB);
Krzysztof Parzyszek4f998362018-03-30 15:29:47 +0000512 } else if (Option.compare_lower("endloop0") == 0) {
513 HexagonMCInstrInfo::setInnerLoop(MCB);
514 } else if (Option.compare_lower("endloop1") == 0) {
515 HexagonMCInstrInfo::setOuterLoop(MCB);
516 } else if (Option.compare_lower("mem_noshuf") == 0) {
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000517 if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf])
518 HexagonMCInstrInfo::setMemReorderDisabled(MCB);
519 else
520 return getParser().Error(IDLoc, MemNoShuffMsg);
Krzysztof Parzyszek4f998362018-03-30 15:29:47 +0000521 } else
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000522 return getParser().Error(IDLoc, llvm::Twine("'") + Option +
523 "' is not a valid bundle option");
Nirav Davefd910412016-06-17 16:06:17 +0000524 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000525 }
526}
527
528// For instruction aliases, immediates are generated rather than
529// MCConstantExpr. Convert them for uniform MCExpr.
530// Also check for signed/unsigned mismatches and warn
531void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
532 MCInst NewInst;
533 NewInst.setOpcode(MCI.getOpcode());
534 for (MCOperand &I : MCI)
535 if (I.isImm()) {
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000536 int64_t Value(I.getImm());
Colin LeMahieuc7b21242016-02-15 18:47:55 +0000537 NewInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000538 MCConstantExpr::create(Value, getContext()), getContext())));
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000539 } else {
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000540 if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
541 WarnSignedMismatch)
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000542 Warning(MCI.getLoc(), "Signed/Unsigned mismatch");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000543 NewInst.addOperand(I);
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000544 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000545 MCI = NewInst;
546}
547
548bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
549 OperandVector &InstOperands,
550 uint64_t &ErrorInfo,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000551 bool MatchingInlineAsm) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000552 // Perform matching with tablegen asmmatcher generated function
553 int result =
554 MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
555 if (result == Match_Success) {
556 MCI.setLoc(IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000557 canonicalizeImmediates(MCI);
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000558 result = processInstruction(MCI, InstOperands, IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000559
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000560 LLVM_DEBUG(dbgs() << "Insn:");
561 LLVM_DEBUG(MCI.dump_pretty(dbgs()));
562 LLVM_DEBUG(dbgs() << "\n\n");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000563
564 MCI.setLoc(IDLoc);
565 }
566
567 // Create instruction operand for bundle instruction
568 // Break this into a separate function Code here is less readable
569 // Think about how to get an instruction error to report correctly.
570 // SMLoc will return the "{"
571 switch (result) {
572 default:
573 break;
574 case Match_Success:
575 return false;
576 case Match_MissingFeature:
577 return Error(IDLoc, "invalid instruction");
578 case Match_MnemonicFail:
579 return Error(IDLoc, "unrecognized instruction");
580 case Match_InvalidOperand:
581 SMLoc ErrorLoc = IDLoc;
582 if (ErrorInfo != ~0U) {
583 if (ErrorInfo >= InstOperands.size())
584 return Error(IDLoc, "too few operands for instruction");
585
586 ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
587 ->getStartLoc();
588 if (ErrorLoc == SMLoc())
589 ErrorLoc = IDLoc;
590 }
591 return Error(ErrorLoc, "invalid operand for instruction");
592 }
593 llvm_unreachable("Implement any new match types added!");
594}
595
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000596void HexagonAsmParser::eatToEndOfPacket() {
597 assert(InBrackets);
598 MCAsmLexer &Lexer = getLexer();
599 while (!Lexer.is(AsmToken::RCurly))
600 Lexer.Lex();
601 Lexer.Lex();
602 InBrackets = false;
603}
604
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000605bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
606 OperandVector &Operands,
607 MCStreamer &Out,
608 uint64_t &ErrorInfo,
609 bool MatchingInlineAsm) {
610 if (!InBrackets) {
611 MCB.clear();
612 MCB.addOperand(MCOperand::createImm(0));
613 }
614 HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
615 if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
616 assert(Operands.size() == 1 && "Brackets should be by themselves");
617 if (InBrackets) {
618 getParser().Error(IDLoc, "Already in a packet");
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000619 InBrackets = false;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000620 return true;
621 }
622 InBrackets = true;
623 return false;
624 }
625 if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
626 assert(Operands.size() == 1 && "Brackets should be by themselves");
627 if (!InBrackets) {
628 getParser().Error(IDLoc, "Not in a packet");
629 return true;
630 }
631 InBrackets = false;
632 if (matchBundleOptions())
633 return true;
634 return finishBundle(IDLoc, Out);
635 }
636 MCInst *SubInst = new (getParser().getContext()) MCInst;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000637 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000638 MatchingInlineAsm)) {
639 if (InBrackets)
640 eatToEndOfPacket();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000641 return true;
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000642 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000643 HexagonMCInstrInfo::extendIfNeeded(
Oliver Stannard4191b9e2017-10-11 09:17:43 +0000644 getParser().getContext(), MII, MCB, *SubInst);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000645 MCB.addOperand(MCOperand::createInst(SubInst));
646 if (!InBrackets)
647 return finishBundle(IDLoc, Out);
648 return false;
649}
650
651/// ParseDirective parses the Hexagon specific directives
652bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
653 StringRef IDVal = DirectiveID.getIdentifier();
654 if ((IDVal.lower() == ".word") || (IDVal.lower() == ".4byte"))
655 return ParseDirectiveValue(4, DirectiveID.getLoc());
656 if (IDVal.lower() == ".short" || IDVal.lower() == ".hword" ||
657 IDVal.lower() == ".half")
658 return ParseDirectiveValue(2, DirectiveID.getLoc());
659 if (IDVal.lower() == ".falign")
660 return ParseDirectiveFalign(256, DirectiveID.getLoc());
661 if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
662 return ParseDirectiveComm(true, DirectiveID.getLoc());
663 if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
664 return ParseDirectiveComm(false, DirectiveID.getLoc());
665 if (IDVal.lower() == ".subsection")
666 return ParseDirectiveSubsection(DirectiveID.getLoc());
667
668 return true;
669}
670bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
Eugene Zelenko82085922016-12-13 22:13:50 +0000671 const MCExpr *Subsection = nullptr;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000672 int64_t Res;
673
674 assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
675 "Invalid subsection directive");
676 getParser().parseExpression(Subsection);
677
678 if (!Subsection->evaluateAsAbsolute(Res))
679 return Error(L, "Cannot evaluate subsection number");
680
681 if (getLexer().isNot(AsmToken::EndOfStatement))
682 return TokError("unexpected token in directive");
683
684 // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
685 // negative subsections together and in the same order but at the opposite
686 // end of the section. Only legacy hexagon-gcc created assembly code
687 // used negative subsections.
688 if ((Res < 0) && (Res > -8193))
Colin LeMahieuc7b21242016-02-15 18:47:55 +0000689 Subsection = HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000690 MCConstantExpr::create(8192 + Res, getContext()), getContext());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000691
692 getStreamer().SubSection(Subsection);
693 return false;
694}
695
696/// ::= .falign [expression]
697bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
698
699 int64_t MaxBytesToFill = 15;
700
Simon Pilgrim6ba672e2016-11-17 19:21:20 +0000701 // if there is an argument
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000702 if (getLexer().isNot(AsmToken::EndOfStatement)) {
703 const MCExpr *Value;
704 SMLoc ExprLoc = L;
705
706 // Make sure we have a number (false is returned if expression is a number)
Eugene Zelenko82085922016-12-13 22:13:50 +0000707 if (!getParser().parseExpression(Value)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000708 // Make sure this is a number that is in range
709 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
710 uint64_t IntValue = MCE->getValue();
711 if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
712 return Error(ExprLoc, "literal value out of range (256) for falign");
713 MaxBytesToFill = IntValue;
714 Lex();
715 } else {
716 return Error(ExprLoc, "not a valid expression for falign directive");
717 }
718 }
719
720 getTargetStreamer().emitFAlign(16, MaxBytesToFill);
721 Lex();
722
723 return false;
724}
725
726/// ::= .word [ expression (, expression)* ]
727bool HexagonAsmParser::ParseDirectiveValue(unsigned Size, SMLoc L) {
728 if (getLexer().isNot(AsmToken::EndOfStatement)) {
Eugene Zelenko82085922016-12-13 22:13:50 +0000729 while (true) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000730 const MCExpr *Value;
731 SMLoc ExprLoc = L;
732 if (getParser().parseExpression(Value))
733 return true;
734
735 // Special case constant expressions to match code generator.
736 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
737 assert(Size <= 8 && "Invalid size");
738 uint64_t IntValue = MCE->getValue();
739 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
740 return Error(ExprLoc, "literal value out of range for directive");
741 getStreamer().EmitIntValue(IntValue, Size);
742 } else
743 getStreamer().EmitValue(Value, Size);
744
745 if (getLexer().is(AsmToken::EndOfStatement))
746 break;
747
748 // FIXME: Improve diagnostic.
749 if (getLexer().isNot(AsmToken::Comma))
750 return TokError("unexpected token in directive");
751 Lex();
752 }
753 }
754
755 Lex();
756 return false;
757}
758
759// This is largely a copy of AsmParser's ParseDirectiveComm extended to
760// accept a 3rd argument, AccessAlignment which indicates the smallest
761// memory access made to the symbol, expressed in bytes. If no
762// AccessAlignment is specified it defaults to the Alignment Value.
763// Hexagon's .lcomm:
764// .lcomm Symbol, Length, Alignment, AccessAlignment
765bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
766 // FIXME: need better way to detect if AsmStreamer (upstream removed
767 // getKind())
768 if (getStreamer().hasRawTextSupport())
769 return true; // Only object file output requires special treatment.
770
771 StringRef Name;
772 if (getParser().parseIdentifier(Name))
773 return TokError("expected identifier in directive");
774 // Handle the identifier as the key symbol.
775 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
776
777 if (getLexer().isNot(AsmToken::Comma))
778 return TokError("unexpected token in directive");
779 Lex();
780
781 int64_t Size;
782 SMLoc SizeLoc = getLexer().getLoc();
783 if (getParser().parseAbsoluteExpression(Size))
784 return true;
785
786 int64_t ByteAlignment = 1;
787 SMLoc ByteAlignmentLoc;
788 if (getLexer().is(AsmToken::Comma)) {
789 Lex();
790 ByteAlignmentLoc = getLexer().getLoc();
791 if (getParser().parseAbsoluteExpression(ByteAlignment))
792 return true;
793 if (!isPowerOf2_64(ByteAlignment))
794 return Error(ByteAlignmentLoc, "alignment must be a power of 2");
795 }
796
797 int64_t AccessAlignment = 0;
798 if (getLexer().is(AsmToken::Comma)) {
799 // The optional access argument specifies the size of the smallest memory
800 // access to be made to the symbol, expressed in bytes.
801 SMLoc AccessAlignmentLoc;
802 Lex();
803 AccessAlignmentLoc = getLexer().getLoc();
804 if (getParser().parseAbsoluteExpression(AccessAlignment))
805 return true;
806
807 if (!isPowerOf2_64(AccessAlignment))
808 return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
809 }
810
811 if (getLexer().isNot(AsmToken::EndOfStatement))
812 return TokError("unexpected token in '.comm' or '.lcomm' directive");
813
814 Lex();
815
816 // NOTE: a size of zero for a .comm should create a undefined symbol
817 // but a size of .lcomm creates a bss symbol of size zero.
818 if (Size < 0)
819 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
820 "be less than zero");
821
822 // NOTE: The alignment in the directive is a power of 2 value, the assembler
823 // may internally end up wanting an alignment in bytes.
824 // FIXME: Diagnose overflow.
825 if (ByteAlignment < 0)
826 return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
827 "alignment, can't be less than zero");
828
829 if (!Sym->isUndefined())
830 return Error(Loc, "invalid symbol redefinition");
831
832 HexagonMCELFStreamer &HexagonELFStreamer =
833 static_cast<HexagonMCELFStreamer &>(getStreamer());
834 if (IsLocal) {
835 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(Sym, Size, ByteAlignment,
836 AccessAlignment);
837 return false;
838 }
839
840 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, ByteAlignment,
841 AccessAlignment);
842 return false;
843}
844
845// validate register against architecture
846bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
Krzysztof Parzyszekf9015e62017-02-10 23:46:45 +0000847 if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))
848 if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
849 return false;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000850 return true;
851}
852
853// extern "C" void LLVMInitializeHexagonAsmLexer();
854
855/// Force static initialization.
856extern "C" void LLVMInitializeHexagonAsmParser() {
Mehdi Aminif42454b2016-10-09 23:00:34 +0000857 RegisterMCAsmParser<HexagonAsmParser> X(getTheHexagonTarget());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000858}
859
860#define GET_MATCHER_IMPLEMENTATION
861#define GET_REGISTER_MATCHER
862#include "HexagonGenAsmMatcher.inc"
863
Eugene Zelenko82085922016-12-13 22:13:50 +0000864static bool previousEqual(OperandVector &Operands, size_t Index,
865 StringRef String) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000866 if (Index >= Operands.size())
867 return false;
868 MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
869 if (!Operand.isToken())
870 return false;
871 return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
872}
Eugene Zelenko82085922016-12-13 22:13:50 +0000873
874static bool previousIsLoop(OperandVector &Operands, size_t Index) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000875 return previousEqual(Operands, Index, "loop0") ||
876 previousEqual(Operands, Index, "loop1") ||
877 previousEqual(Operands, Index, "sp1loop0") ||
878 previousEqual(Operands, Index, "sp2loop0") ||
879 previousEqual(Operands, Index, "sp3loop0");
880}
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000881
882bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
883 AsmToken const &Token = getParser().getTok();
884 StringRef String = Token.getString();
885 SMLoc Loc = Token.getLoc();
Nirav Davefd910412016-06-17 16:06:17 +0000886 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000887 do {
888 std::pair<StringRef, StringRef> HeadTail = String.split('.');
889 if (!HeadTail.first.empty())
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000890 Operands.push_back(
891 HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000892 if (!HeadTail.second.empty())
893 Operands.push_back(HexagonOperand::CreateToken(
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000894 getContext(), String.substr(HeadTail.first.size(), 1), Loc));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000895 String = HeadTail.second;
896 } while (!String.empty());
897 return false;
898}
899
900bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
901 unsigned Register;
902 SMLoc Begin;
903 SMLoc End;
904 MCAsmLexer &Lexer = getLexer();
905 if (!ParseRegister(Register, Begin, End)) {
906 if (!ErrorMissingParenthesis)
907 switch (Register) {
908 default:
909 break;
910 case Hexagon::P0:
911 case Hexagon::P1:
912 case Hexagon::P2:
913 case Hexagon::P3:
914 if (previousEqual(Operands, 0, "if")) {
915 if (WarnMissingParenthesis)
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000916 Warning(Begin, "Missing parenthesis around predicate register");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000917 static char const *LParen = "(";
918 static char const *RParen = ")";
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000919 Operands.push_back(
920 HexagonOperand::CreateToken(getContext(), LParen, Begin));
921 Operands.push_back(
922 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
Benjamin Kramer4ca41fd2016-06-12 17:30:47 +0000923 const AsmToken &MaybeDotNew = Lexer.getTok();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000924 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
925 MaybeDotNew.getString().equals_lower(".new"))
926 splitIdentifier(Operands);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000927 Operands.push_back(
928 HexagonOperand::CreateToken(getContext(), RParen, Begin));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000929 return false;
930 }
931 if (previousEqual(Operands, 0, "!") &&
932 previousEqual(Operands, 1, "if")) {
933 if (WarnMissingParenthesis)
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000934 Warning(Begin, "Missing parenthesis around predicate register");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000935 static char const *LParen = "(";
936 static char const *RParen = ")";
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000937 Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(
938 getContext(), LParen, Begin));
939 Operands.push_back(
940 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
Benjamin Kramer4ca41fd2016-06-12 17:30:47 +0000941 const AsmToken &MaybeDotNew = Lexer.getTok();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000942 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
943 MaybeDotNew.getString().equals_lower(".new"))
944 splitIdentifier(Operands);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000945 Operands.push_back(
946 HexagonOperand::CreateToken(getContext(), RParen, Begin));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000947 return false;
948 }
949 break;
950 }
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000951 Operands.push_back(
952 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000953 return false;
954 }
955 return splitIdentifier(Operands);
956}
957
958bool HexagonAsmParser::isLabel(AsmToken &Token) {
959 MCAsmLexer &Lexer = getLexer();
960 AsmToken const &Second = Lexer.getTok();
Krzysztof Parzyszekf9015e62017-02-10 23:46:45 +0000961 AsmToken Third = Lexer.peekTok();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000962 StringRef String = Token.getString();
963 if (Token.is(AsmToken::TokenKind::LCurly) ||
964 Token.is(AsmToken::TokenKind::RCurly))
965 return false;
Krzysztof Parzyszekf9015e62017-02-10 23:46:45 +0000966 // special case for parsing vwhist256:sat
967 if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&
968 Third.getString().lower() == "sat")
969 return false;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000970 if (!Token.is(AsmToken::TokenKind::Identifier))
971 return true;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +0000972 if (!matchRegister(String.lower()))
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000973 return true;
Colin LeMahieu9d851f02015-11-09 21:06:28 +0000974 assert(Second.is(AsmToken::Colon));
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000975 StringRef Raw(String.data(), Third.getString().data() - String.data() +
976 Third.getString().size());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000977 std::string Collapsed = Raw;
Eugene Zelenko82085922016-12-13 22:13:50 +0000978 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000979 StringRef Whole = Collapsed;
980 std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +0000981 if (!matchRegister(DotSplit.first.lower()))
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000982 return true;
983 return false;
984}
985
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000986bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,
987 SMLoc &Loc) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000988 if (!Contigious && ErrorNoncontigiousRegister) {
989 Error(Loc, "Register name is not contigious");
990 return true;
991 }
992 if (!Contigious && WarnNoncontigiousRegister)
993 Warning(Loc, "Register name is not contigious");
994 return false;
995}
996
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000997bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
998 SMLoc &EndLoc) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000999 MCAsmLexer &Lexer = getLexer();
1000 StartLoc = getLexer().getLoc();
1001 SmallVector<AsmToken, 5> Lookahead;
1002 StringRef RawString(Lexer.getTok().getString().data(), 0);
1003 bool Again = Lexer.is(AsmToken::Identifier);
1004 bool NeededWorkaround = false;
1005 while (Again) {
1006 AsmToken const &Token = Lexer.getTok();
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001007 RawString = StringRef(RawString.data(), Token.getString().data() -
1008 RawString.data() +
1009 Token.getString().size());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001010 Lookahead.push_back(Token);
1011 Lexer.Lex();
1012 bool Contigious = Lexer.getTok().getString().data() ==
1013 Lookahead.back().getString().data() +
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001014 Lookahead.back().getString().size();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001015 bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
1016 Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
1017 Lexer.is(AsmToken::Colon);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001018 bool Workaround =
1019 Lexer.is(AsmToken::Colon) || Lookahead.back().is(AsmToken::Colon);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001020 Again = (Contigious && Type) || (Workaround && Type);
1021 NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
1022 }
1023 std::string Collapsed = RawString;
Eugene Zelenko82085922016-12-13 22:13:50 +00001024 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001025 StringRef FullString = Collapsed;
1026 std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001027 unsigned DotReg = matchRegister(DotSplit.first.lower());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001028 if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1029 if (DotSplit.second.empty()) {
1030 RegNo = DotReg;
1031 EndLoc = Lexer.getLoc();
1032 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1033 return true;
1034 return false;
1035 } else {
1036 RegNo = DotReg;
1037 size_t First = RawString.find('.');
1038 StringRef DotString (RawString.data() + First, RawString.size() - First);
1039 Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1040 EndLoc = Lexer.getLoc();
1041 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1042 return true;
1043 return false;
1044 }
1045 }
1046 std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001047 unsigned ColonReg = matchRegister(ColonSplit.first.lower());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001048 if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001049 do {
1050 Lexer.UnLex(Lookahead.back());
1051 Lookahead.pop_back();
1052 } while (!Lookahead.empty () && !Lexer.is(AsmToken::Colon));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001053 RegNo = ColonReg;
1054 EndLoc = Lexer.getLoc();
1055 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1056 return true;
1057 return false;
1058 }
1059 while (!Lookahead.empty()) {
1060 Lexer.UnLex(Lookahead.back());
1061 Lookahead.pop_back();
1062 }
1063 return true;
1064}
1065
1066bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1067 if (previousEqual(Operands, 0, "call"))
1068 return true;
1069 if (previousEqual(Operands, 0, "jump"))
1070 if (!getLexer().getTok().is(AsmToken::Colon))
1071 return true;
1072 if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
1073 return true;
1074 if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
1075 (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
1076 return true;
1077 return false;
1078}
1079
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001080bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {
Eugene Zelenko82085922016-12-13 22:13:50 +00001081 SmallVector<AsmToken, 4> Tokens;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001082 MCAsmLexer &Lexer = getLexer();
1083 bool Done = false;
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001084 static char const *Comma = ",";
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001085 do {
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001086 Tokens.emplace_back(Lexer.getTok());
Nirav Davefd910412016-06-17 16:06:17 +00001087 Lex();
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001088 switch (Tokens.back().getKind()) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001089 case AsmToken::TokenKind::Hash:
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001090 if (Tokens.size() > 1)
1091 if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001092 Tokens.insert(Tokens.end() - 2,
1093 AsmToken(AsmToken::TokenKind::Comma, Comma));
1094 Done = true;
1095 }
1096 break;
1097 case AsmToken::TokenKind::RCurly:
1098 case AsmToken::TokenKind::EndOfStatement:
1099 case AsmToken::TokenKind::Eof:
1100 Done = true;
1101 break;
1102 default:
1103 break;
1104 }
1105 } while (!Done);
1106 while (!Tokens.empty()) {
1107 Lexer.UnLex(Tokens.back());
1108 Tokens.pop_back();
1109 }
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001110 SMLoc Loc = Lexer.getLoc();
1111 return getParser().parseExpression(Expr, Loc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001112}
1113
1114bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1115 if (implicitExpressionLocation(Operands)) {
1116 MCAsmParser &Parser = getParser();
1117 SMLoc Loc = Parser.getLexer().getLoc();
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001118 MCExpr const *Expr = nullptr;
1119 bool Error = parseExpression(Expr);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001120 Expr = HexagonMCExpr::create(Expr, getContext());
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001121 if (!Error)
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001122 Operands.push_back(
1123 HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001124 return Error;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001125 }
1126 return parseOperand(Operands);
1127}
1128
1129/// Parse an instruction.
1130bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1131 MCAsmParser &Parser = getParser();
1132 MCAsmLexer &Lexer = getLexer();
1133 while (true) {
1134 AsmToken const &Token = Parser.getTok();
1135 switch (Token.getKind()) {
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001136 case AsmToken::Eof:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001137 case AsmToken::EndOfStatement: {
Nirav Davefd910412016-06-17 16:06:17 +00001138 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001139 return false;
1140 }
1141 case AsmToken::LCurly: {
1142 if (!Operands.empty())
1143 return true;
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001144 Operands.push_back(HexagonOperand::CreateToken(
1145 getContext(), Token.getString(), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001146 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001147 return false;
1148 }
1149 case AsmToken::RCurly: {
1150 if (Operands.empty()) {
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001151 Operands.push_back(HexagonOperand::CreateToken(
1152 getContext(), Token.getString(), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001153 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001154 }
1155 return false;
1156 }
1157 case AsmToken::Comma: {
Nirav Davefd910412016-06-17 16:06:17 +00001158 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001159 continue;
1160 }
1161 case AsmToken::EqualEqual:
1162 case AsmToken::ExclaimEqual:
1163 case AsmToken::GreaterEqual:
1164 case AsmToken::GreaterGreater:
1165 case AsmToken::LessEqual:
1166 case AsmToken::LessLess: {
1167 Operands.push_back(HexagonOperand::CreateToken(
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001168 getContext(), Token.getString().substr(0, 1), Token.getLoc()));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001169 Operands.push_back(HexagonOperand::CreateToken(
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001170 getContext(), Token.getString().substr(1, 1), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001171 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001172 continue;
1173 }
1174 case AsmToken::Hash: {
1175 bool MustNotExtend = false;
1176 bool ImplicitExpression = implicitExpressionLocation(Operands);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001177 SMLoc ExprLoc = Lexer.getLoc();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001178 if (!ImplicitExpression)
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001179 Operands.push_back(HexagonOperand::CreateToken(
1180 getContext(), Token.getString(), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001181 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001182 bool MustExtend = false;
1183 bool HiOnly = false;
1184 bool LoOnly = false;
1185 if (Lexer.is(AsmToken::Hash)) {
Nirav Davefd910412016-06-17 16:06:17 +00001186 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001187 MustExtend = true;
1188 } else if (ImplicitExpression)
1189 MustNotExtend = true;
1190 AsmToken const &Token = Parser.getTok();
1191 if (Token.is(AsmToken::Identifier)) {
1192 StringRef String = Token.getString();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001193 if (String.lower() == "hi") {
1194 HiOnly = true;
1195 } else if (String.lower() == "lo") {
1196 LoOnly = true;
1197 }
1198 if (HiOnly || LoOnly) {
1199 AsmToken LParen = Lexer.peekTok();
1200 if (!LParen.is(AsmToken::LParen)) {
1201 HiOnly = false;
1202 LoOnly = false;
1203 } else {
Nirav Davefd910412016-06-17 16:06:17 +00001204 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001205 }
1206 }
1207 }
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001208 MCExpr const *Expr = nullptr;
1209 if (parseExpression(Expr))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001210 return true;
1211 int64_t Value;
1212 MCContext &Context = Parser.getContext();
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001213 assert(Expr != nullptr);
1214 if (Expr->evaluateAsAbsolute(Value)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001215 if (HiOnly)
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001216 Expr = MCBinaryExpr::createLShr(
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001217 Expr, MCConstantExpr::create(16, Context), Context);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001218 if (HiOnly || LoOnly)
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001219 Expr = MCBinaryExpr::createAnd(
1220 Expr, MCConstantExpr::create(0xffff, Context), Context);
Colin LeMahieu5cb6eea2016-03-01 21:37:41 +00001221 } else {
1222 MCValue Value;
1223 if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
1224 if (!Value.isAbsolute()) {
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001225 switch (Value.getAccessVariant()) {
Colin LeMahieu5cb6eea2016-03-01 21:37:41 +00001226 case MCSymbolRefExpr::VariantKind::VK_TPREL:
1227 case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1228 // Don't lazy extend these expression variants
1229 MustNotExtend = !MustExtend;
1230 break;
1231 default:
1232 break;
1233 }
1234 }
1235 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001236 }
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001237 Expr = HexagonMCExpr::create(Expr, Context);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001238 HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001239 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001240 std::unique_ptr<HexagonOperand> Operand =
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001241 HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001242 Operands.push_back(std::move(Operand));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001243 continue;
1244 }
1245 default:
1246 break;
1247 }
1248 if (parseExpressionOrOperand(Operands))
1249 return true;
1250 }
1251}
1252
1253bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001254 StringRef Name, AsmToken ID,
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001255 OperandVector &Operands) {
1256 getLexer().UnLex(ID);
1257 return parseInstruction(Operands);
1258}
1259
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001260static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,
1261 MCOperand &MO2) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001262 MCInst TmpInst;
1263 TmpInst.setOpcode(opCode);
1264 TmpInst.addOperand(Rdd);
1265 TmpInst.addOperand(MO1);
1266 TmpInst.addOperand(MO2);
1267
1268 return TmpInst;
1269}
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001270
1271// Define this matcher function after the auto-generated include so we
1272// have the match class enum definitions.
1273unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1274 unsigned Kind) {
1275 HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1276
1277 switch (Kind) {
1278 case MCK_0: {
1279 int64_t Value;
1280 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1281 ? Match_Success
1282 : Match_InvalidOperand;
1283 }
1284 case MCK_1: {
1285 int64_t Value;
1286 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1287 ? Match_Success
1288 : Match_InvalidOperand;
1289 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001290 }
1291 if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1292 StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1293 if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1294 return Match_Success;
1295 if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1296 return Match_Success;
1297 }
1298
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001299 LLVM_DEBUG(dbgs() << "Unmatched Operand:");
1300 LLVM_DEBUG(Op->dump());
1301 LLVM_DEBUG(dbgs() << "\n");
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001302
1303 return Match_InvalidOperand;
1304}
1305
Nirav Dave2364748a2016-09-16 18:30:20 +00001306// FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
1307bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +00001308 std::string errStr;
1309 raw_string_ostream ES(errStr);
Alexey Samsonov44ff2042015-12-02 22:59:22 +00001310 ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001311 if (Max >= 0)
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +00001312 ES << "0-" << Max;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001313 else
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +00001314 ES << Max << "-" << (-Max - 1);
Malcolm Parsons06ac79c2016-11-02 16:43:50 +00001315 return Parser.printError(IDLoc, ES.str());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001316}
1317
1318int HexagonAsmParser::processInstruction(MCInst &Inst,
1319 OperandVector const &Operands,
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001320 SMLoc IDLoc) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001321 MCContext &Context = getParser().getContext();
1322 const MCRegisterInfo *RI = getContext().getRegisterInfo();
1323 std::string r = "r";
1324 std::string v = "v";
1325 std::string Colon = ":";
1326
1327 bool is32bit = false; // used to distinguish between CONST32 and CONST64
1328 switch (Inst.getOpcode()) {
1329 default:
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001330 if (HexagonMCInstrInfo::getDesc(MII, Inst).isPseudo()) {
1331 SMDiagnostic Diag = getSourceManager().GetMessage(
1332 IDLoc, SourceMgr::DK_Error,
1333 "Found pseudo instruction with no expansion");
1334 Diag.print("", errs());
1335 report_fatal_error("Invalid pseudo instruction");
1336 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001337 break;
1338
Krzysztof Parzyszekc5e0ed12018-03-01 21:54:08 +00001339 case Hexagon::J2_trap1:
1340 if (!getSTI().getFeatureBits()[Hexagon::ArchV65]) {
1341 MCOperand &Rx = Inst.getOperand(0);
1342 MCOperand &Ry = Inst.getOperand(1);
1343 if (Rx.getReg() != Hexagon::R0 || Ry.getReg() != Hexagon::R0) {
1344 Error(IDLoc, "trap1 can only have register r0 as operand");
1345 return Match_InvalidOperand;
1346 }
1347 }
1348 break;
1349
Colin LeMahieuecef1d92016-02-16 20:38:17 +00001350 case Hexagon::A2_iconst: {
1351 Inst.setOpcode(Hexagon::A2_addi);
1352 MCOperand Reg = Inst.getOperand(0);
Krzysztof Parzyszek57a8bb432017-05-02 18:19:11 +00001353 MCOperand S27 = Inst.getOperand(1);
1354 HexagonMCInstrInfo::setMustNotExtend(*S27.getExpr());
1355 HexagonMCInstrInfo::setS27_2_reloc(*S27.getExpr());
Colin LeMahieuecef1d92016-02-16 20:38:17 +00001356 Inst.clear();
1357 Inst.addOperand(Reg);
1358 Inst.addOperand(MCOperand::createReg(Hexagon::R0));
Krzysztof Parzyszek57a8bb432017-05-02 18:19:11 +00001359 Inst.addOperand(S27);
Colin LeMahieuecef1d92016-02-16 20:38:17 +00001360 break;
1361 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001362 case Hexagon::M4_mpyrr_addr:
1363 case Hexagon::S4_addi_asl_ri:
1364 case Hexagon::S4_addi_lsr_ri:
1365 case Hexagon::S4_andi_asl_ri:
1366 case Hexagon::S4_andi_lsr_ri:
1367 case Hexagon::S4_ori_asl_ri:
1368 case Hexagon::S4_ori_lsr_ri:
1369 case Hexagon::S4_or_andix:
1370 case Hexagon::S4_subi_asl_ri:
1371 case Hexagon::S4_subi_lsr_ri: {
1372 MCOperand &Ry = Inst.getOperand(0);
1373 MCOperand &src = Inst.getOperand(2);
1374 if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
1375 return Match_InvalidOperand;
1376 break;
1377 }
1378
1379 case Hexagon::C2_cmpgei: {
1380 MCOperand &MO = Inst.getOperand(2);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001381 MO.setExpr(HexagonMCExpr::create(
1382 MCBinaryExpr::createSub(MO.getExpr(),
1383 MCConstantExpr::create(1, Context), Context),
1384 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001385 Inst.setOpcode(Hexagon::C2_cmpgti);
1386 break;
1387 }
1388
1389 case Hexagon::C2_cmpgeui: {
1390 MCOperand &MO = Inst.getOperand(2);
1391 int64_t Value;
1392 bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
Colin LeMahieu9d851f02015-11-09 21:06:28 +00001393 (void)Success;
1394 assert(Success && "Assured by matcher");
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001395 if (Value == 0) {
1396 MCInst TmpInst;
1397 MCOperand &Pd = Inst.getOperand(0);
1398 MCOperand &Rt = Inst.getOperand(1);
1399 TmpInst.setOpcode(Hexagon::C2_cmpeq);
1400 TmpInst.addOperand(Pd);
1401 TmpInst.addOperand(Rt);
1402 TmpInst.addOperand(Rt);
1403 Inst = TmpInst;
1404 } else {
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001405 MO.setExpr(HexagonMCExpr::create(
1406 MCBinaryExpr::createSub(MO.getExpr(),
1407 MCConstantExpr::create(1, Context), Context),
1408 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001409 Inst.setOpcode(Hexagon::C2_cmpgtui);
1410 }
1411 break;
1412 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001413
1414 // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1415 case Hexagon::A2_tfrp: {
1416 MCOperand &MO = Inst.getOperand(1);
1417 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001418 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001419 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001420 MO.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001421 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001422 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001423 StringRef Reg2(R2);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001424 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001425 Inst.setOpcode(Hexagon::A2_combinew);
1426 break;
1427 }
1428
1429 case Hexagon::A2_tfrpt:
1430 case Hexagon::A2_tfrpf: {
1431 MCOperand &MO = Inst.getOperand(2);
1432 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001433 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001434 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001435 MO.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001436 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001437 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001438 StringRef Reg2(R2);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001439 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001440 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
1441 ? Hexagon::C2_ccombinewt
1442 : Hexagon::C2_ccombinewf);
1443 break;
1444 }
1445 case Hexagon::A2_tfrptnew:
1446 case Hexagon::A2_tfrpfnew: {
1447 MCOperand &MO = Inst.getOperand(2);
1448 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001449 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001450 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001451 MO.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001452 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001453 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001454 StringRef Reg2(R2);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001455 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001456 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1457 ? Hexagon::C2_ccombinewnewt
1458 : Hexagon::C2_ccombinewnewf);
1459 break;
1460 }
1461
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001462 // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001463 case Hexagon::V6_vassignp: {
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001464 MCOperand &MO = Inst.getOperand(1);
1465 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001466 std::string R1 = v + utostr(RegPairNum + 1);
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001467 MO.setReg(MatchRegisterName(R1));
1468 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001469 std::string R2 = v + utostr(RegPairNum);
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001470 Inst.addOperand(MCOperand::createReg(MatchRegisterName(R2)));
1471 Inst.setOpcode(Hexagon::V6_vcombine);
1472 break;
1473 }
1474
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001475 // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1476 case Hexagon::CONST32:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001477 is32bit = true;
Simon Pilgrim087e87d2017-07-07 13:21:43 +00001478 LLVM_FALLTHROUGH;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001479 // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
Krzysztof Parzyszeka3386502016-08-10 16:46:36 +00001480 case Hexagon::CONST64:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001481 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1482 if (!Parser.getStreamer().hasRawTextSupport()) {
1483 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
1484 MCOperand &MO_1 = Inst.getOperand(1);
1485 MCOperand &MO_0 = Inst.getOperand(0);
1486
1487 // push section onto section stack
1488 MES->PushSection();
1489
1490 std::string myCharStr;
1491 MCSectionELF *mySection;
1492
1493 // check if this as an immediate or a symbol
1494 int64_t Value;
1495 bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
1496 if (Absolute) {
1497 // Create a new section - one for each constant
1498 // Some or all of the zeros are replaced with the given immediate.
1499 if (is32bit) {
1500 std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
1501 myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
1502 .drop_back(myImmStr.size())
1503 .str() +
1504 myImmStr;
1505 } else {
1506 std::string myImmStr = utohexstr(Value);
1507 myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1508 .drop_back(myImmStr.size())
1509 .str() +
1510 myImmStr;
1511 }
1512
1513 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1514 ELF::SHF_ALLOC | ELF::SHF_WRITE);
1515 } else if (MO_1.isExpr()) {
1516 // .lita - for expressions
1517 myCharStr = ".lita";
1518 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1519 ELF::SHF_ALLOC | ELF::SHF_WRITE);
1520 } else
1521 llvm_unreachable("unexpected type of machine operand!");
1522
1523 MES->SwitchSection(mySection);
1524 unsigned byteSize = is32bit ? 4 : 8;
1525 getStreamer().EmitCodeAlignment(byteSize, byteSize);
1526
1527 MCSymbol *Sym;
1528
1529 // for symbols, get rid of prepended ".gnu.linkonce.lx."
1530
1531 // emit symbol if needed
1532 if (Absolute) {
1533 Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
1534 if (Sym->isUndefined()) {
1535 getStreamer().EmitLabel(Sym);
1536 getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
1537 getStreamer().EmitIntValue(Value, byteSize);
1538 }
1539 } else if (MO_1.isExpr()) {
Eugene Zelenko82085922016-12-13 22:13:50 +00001540 const char *StringStart = nullptr;
1541 const char *StringEnd = nullptr;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001542 if (*Operands[4]->getStartLoc().getPointer() == '#') {
1543 StringStart = Operands[5]->getStartLoc().getPointer();
1544 StringEnd = Operands[6]->getStartLoc().getPointer();
1545 } else { // no pound
1546 StringStart = Operands[4]->getStartLoc().getPointer();
1547 StringEnd = Operands[5]->getStartLoc().getPointer();
1548 }
1549
1550 unsigned size = StringEnd - StringStart;
1551 std::string DotConst = ".CONST_";
1552 Sym = getContext().getOrCreateSymbol(DotConst +
1553 StringRef(StringStart, size));
1554
1555 if (Sym->isUndefined()) {
1556 // case where symbol is not yet defined: emit symbol
1557 getStreamer().EmitLabel(Sym);
1558 getStreamer().EmitSymbolAttribute(Sym, MCSA_Local);
1559 getStreamer().EmitValue(MO_1.getExpr(), 4);
1560 }
1561 } else
1562 llvm_unreachable("unexpected type of machine operand!");
1563
1564 MES->PopSection();
1565
1566 if (Sym) {
1567 MCInst TmpInst;
1568 if (is32bit) // 32 bit
1569 TmpInst.setOpcode(Hexagon::L2_loadrigp);
1570 else // 64 bit
1571 TmpInst.setOpcode(Hexagon::L2_loadrdgp);
1572
1573 TmpInst.addOperand(MO_0);
Krzysztof Parzyszekd0d42f02017-02-02 20:35:12 +00001574 TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001575 MCSymbolRefExpr::create(Sym, getContext()), getContext())));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001576 Inst = TmpInst;
1577 }
1578 }
1579 break;
1580
1581 // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1582 case Hexagon::A2_tfrpi: {
1583 MCOperand &Rdd = Inst.getOperand(0);
1584 MCOperand &MO = Inst.getOperand(1);
1585 int64_t Value;
1586 int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001587 MCOperand imm(MCOperand::createExpr(
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001588 HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001589 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1590 break;
1591 }
1592
1593 // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1594 case Hexagon::TFRI64_V4: {
1595 MCOperand &Rdd = Inst.getOperand(0);
1596 MCOperand &MO = Inst.getOperand(1);
1597 int64_t Value;
1598 if (MO.getExpr()->evaluateAsAbsolute(Value)) {
David Majnemere61e4bf2016-06-21 05:10:24 +00001599 int s8 = Hi_32(Value);
1600 if (!isInt<8>(s8))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001601 OutOfRange(IDLoc, s8, -128);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001602 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001603 MCConstantExpr::create(s8, Context), Context))); // upper 32
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001604 auto Expr = HexagonMCExpr::create(
David Majnemere61e4bf2016-06-21 05:10:24 +00001605 MCConstantExpr::create(Lo_32(Value), Context), Context);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001606 HexagonMCInstrInfo::setMustExtend(
1607 *Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001608 MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001609 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1610 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001611 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001612 MCConstantExpr::create(0, Context), Context))); // upper 32
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001613 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1614 }
1615 break;
1616 }
1617
1618 // Handle $Rdd = combine(##imm, #imm)"
1619 case Hexagon::TFRI64_V2_ext: {
1620 MCOperand &Rdd = Inst.getOperand(0);
1621 MCOperand &MO1 = Inst.getOperand(1);
1622 MCOperand &MO2 = Inst.getOperand(2);
1623 int64_t Value;
1624 if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
1625 int s8 = Value;
1626 if (s8 < -128 || s8 > 127)
1627 OutOfRange(IDLoc, s8, -128);
1628 }
1629 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
1630 break;
1631 }
1632
1633 // Handle $Rdd = combine(#imm, ##imm)"
1634 case Hexagon::A4_combineii: {
1635 MCOperand &Rdd = Inst.getOperand(0);
1636 MCOperand &MO1 = Inst.getOperand(1);
1637 int64_t Value;
1638 if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
1639 int s8 = Value;
1640 if (s8 < -128 || s8 > 127)
1641 OutOfRange(IDLoc, s8, -128);
1642 }
1643 MCOperand &MO2 = Inst.getOperand(2);
1644 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
1645 break;
1646 }
1647
Eugene Zelenko82085922016-12-13 22:13:50 +00001648 case Hexagon::S2_tableidxb_goodsyntax:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001649 Inst.setOpcode(Hexagon::S2_tableidxb);
1650 break;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001651
1652 case Hexagon::S2_tableidxh_goodsyntax: {
1653 MCInst TmpInst;
1654 MCOperand &Rx = Inst.getOperand(0);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001655 MCOperand &Rs = Inst.getOperand(2);
1656 MCOperand &Imm4 = Inst.getOperand(3);
1657 MCOperand &Imm6 = Inst.getOperand(4);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001658 Imm6.setExpr(HexagonMCExpr::create(
1659 MCBinaryExpr::createSub(Imm6.getExpr(),
1660 MCConstantExpr::create(1, Context), Context),
1661 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001662 TmpInst.setOpcode(Hexagon::S2_tableidxh);
1663 TmpInst.addOperand(Rx);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001664 TmpInst.addOperand(Rx);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001665 TmpInst.addOperand(Rs);
1666 TmpInst.addOperand(Imm4);
1667 TmpInst.addOperand(Imm6);
1668 Inst = TmpInst;
1669 break;
1670 }
1671
1672 case Hexagon::S2_tableidxw_goodsyntax: {
1673 MCInst TmpInst;
1674 MCOperand &Rx = Inst.getOperand(0);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001675 MCOperand &Rs = Inst.getOperand(2);
1676 MCOperand &Imm4 = Inst.getOperand(3);
1677 MCOperand &Imm6 = Inst.getOperand(4);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001678 Imm6.setExpr(HexagonMCExpr::create(
1679 MCBinaryExpr::createSub(Imm6.getExpr(),
1680 MCConstantExpr::create(2, Context), Context),
1681 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001682 TmpInst.setOpcode(Hexagon::S2_tableidxw);
1683 TmpInst.addOperand(Rx);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001684 TmpInst.addOperand(Rx);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001685 TmpInst.addOperand(Rs);
1686 TmpInst.addOperand(Imm4);
1687 TmpInst.addOperand(Imm6);
1688 Inst = TmpInst;
1689 break;
1690 }
1691
1692 case Hexagon::S2_tableidxd_goodsyntax: {
1693 MCInst TmpInst;
1694 MCOperand &Rx = Inst.getOperand(0);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001695 MCOperand &Rs = Inst.getOperand(2);
1696 MCOperand &Imm4 = Inst.getOperand(3);
1697 MCOperand &Imm6 = Inst.getOperand(4);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001698 Imm6.setExpr(HexagonMCExpr::create(
1699 MCBinaryExpr::createSub(Imm6.getExpr(),
1700 MCConstantExpr::create(3, Context), Context),
1701 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001702 TmpInst.setOpcode(Hexagon::S2_tableidxd);
1703 TmpInst.addOperand(Rx);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001704 TmpInst.addOperand(Rx);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001705 TmpInst.addOperand(Rs);
1706 TmpInst.addOperand(Imm4);
1707 TmpInst.addOperand(Imm6);
1708 Inst = TmpInst;
1709 break;
1710 }
1711
Eugene Zelenko82085922016-12-13 22:13:50 +00001712 case Hexagon::M2_mpyui:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001713 Inst.setOpcode(Hexagon::M2_mpyi);
1714 break;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001715 case Hexagon::M2_mpysmi: {
1716 MCInst TmpInst;
1717 MCOperand &Rd = Inst.getOperand(0);
1718 MCOperand &Rs = Inst.getOperand(1);
1719 MCOperand &Imm = Inst.getOperand(2);
1720 int64_t Value;
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001721 MCExpr const &Expr = *Imm.getExpr();
1722 bool Absolute = Expr.evaluateAsAbsolute(Value);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001723 assert(Absolute);
1724 (void)Absolute;
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001725 if (!HexagonMCInstrInfo::mustExtend(Expr) &&
1726 ((Value <= -256) || Value >= 256))
1727 return Match_InvalidOperand;
1728 if (Value < 0 && Value > -256) {
1729 Imm.setExpr(HexagonMCExpr::create(
1730 MCConstantExpr::create(Value * -1, Context), Context));
1731 TmpInst.setOpcode(Hexagon::M2_mpysin);
1732 } else
1733 TmpInst.setOpcode(Hexagon::M2_mpysip);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001734 TmpInst.addOperand(Rd);
1735 TmpInst.addOperand(Rs);
1736 TmpInst.addOperand(Imm);
1737 Inst = TmpInst;
1738 break;
1739 }
1740
1741 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1742 MCOperand &Imm = Inst.getOperand(2);
1743 MCInst TmpInst;
1744 int64_t Value;
1745 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1746 assert(Absolute);
1747 (void)Absolute;
1748 if (Value == 0) { // convert to $Rd = $Rs
1749 TmpInst.setOpcode(Hexagon::A2_tfr);
1750 MCOperand &Rd = Inst.getOperand(0);
1751 MCOperand &Rs = Inst.getOperand(1);
1752 TmpInst.addOperand(Rd);
1753 TmpInst.addOperand(Rs);
1754 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001755 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001756 MCBinaryExpr::createSub(Imm.getExpr(),
1757 MCConstantExpr::create(1, Context), Context),
1758 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001759 TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
1760 MCOperand &Rd = Inst.getOperand(0);
1761 MCOperand &Rs = Inst.getOperand(1);
1762 TmpInst.addOperand(Rd);
1763 TmpInst.addOperand(Rs);
1764 TmpInst.addOperand(Imm);
1765 }
1766 Inst = TmpInst;
1767 break;
1768 }
1769
1770 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1771 MCOperand &Rdd = Inst.getOperand(0);
1772 MCOperand &Rss = Inst.getOperand(1);
1773 MCOperand &Imm = Inst.getOperand(2);
1774 int64_t Value;
1775 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1776 assert(Absolute);
1777 (void)Absolute;
1778 if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1779 MCInst TmpInst;
1780 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001781 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001782 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001783 Rss.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001784 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001785 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001786 StringRef Reg2(R2);
1787 TmpInst.setOpcode(Hexagon::A2_combinew);
1788 TmpInst.addOperand(Rdd);
1789 TmpInst.addOperand(Rss);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001790 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001791 Inst = TmpInst;
1792 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001793 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001794 MCBinaryExpr::createSub(Imm.getExpr(),
1795 MCConstantExpr::create(1, Context), Context),
1796 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001797 Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
1798 }
1799 break;
1800 }
1801
1802 case Hexagon::A4_boundscheck: {
1803 MCOperand &Rs = Inst.getOperand(1);
1804 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1805 if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
1806 Inst.setOpcode(Hexagon::A4_boundscheck_hi);
Eugene Zelenko82085922016-12-13 22:13:50 +00001807 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001808 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001809 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001810 } else { // raw:lo
1811 Inst.setOpcode(Hexagon::A4_boundscheck_lo);
Eugene Zelenko82085922016-12-13 22:13:50 +00001812 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001813 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001814 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001815 }
1816 break;
1817 }
1818
1819 case Hexagon::A2_addsp: {
1820 MCOperand &Rs = Inst.getOperand(1);
1821 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1822 if (RegNum & 1) { // Odd mapped to raw:hi
1823 Inst.setOpcode(Hexagon::A2_addsph);
Eugene Zelenko82085922016-12-13 22:13:50 +00001824 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001825 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001826 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001827 } else { // Even mapped raw:lo
1828 Inst.setOpcode(Hexagon::A2_addspl);
Eugene Zelenko82085922016-12-13 22:13:50 +00001829 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001830 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001831 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001832 }
1833 break;
1834 }
1835
1836 case Hexagon::M2_vrcmpys_s1: {
1837 MCOperand &Rt = Inst.getOperand(2);
1838 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1839 if (RegNum & 1) { // Odd mapped to sat:raw:hi
1840 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
Eugene Zelenko82085922016-12-13 22:13:50 +00001841 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001842 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001843 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001844 } else { // Even mapped sat:raw:lo
1845 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
Eugene Zelenko82085922016-12-13 22:13:50 +00001846 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001847 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001848 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001849 }
1850 break;
1851 }
1852
1853 case Hexagon::M2_vrcmpys_acc_s1: {
1854 MCInst TmpInst;
1855 MCOperand &Rxx = Inst.getOperand(0);
1856 MCOperand &Rss = Inst.getOperand(2);
1857 MCOperand &Rt = Inst.getOperand(3);
1858 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1859 if (RegNum & 1) { // Odd mapped to sat:raw:hi
1860 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
Eugene Zelenko82085922016-12-13 22:13:50 +00001861 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001862 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001863 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001864 } else { // Even mapped sat:raw:lo
1865 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
Eugene Zelenko82085922016-12-13 22:13:50 +00001866 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001867 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001868 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001869 }
1870 // Registers are in different positions
1871 TmpInst.addOperand(Rxx);
1872 TmpInst.addOperand(Rxx);
1873 TmpInst.addOperand(Rss);
1874 TmpInst.addOperand(Rt);
1875 Inst = TmpInst;
1876 break;
1877 }
1878
1879 case Hexagon::M2_vrcmpys_s1rp: {
1880 MCOperand &Rt = Inst.getOperand(2);
1881 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1882 if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
1883 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
Eugene Zelenko82085922016-12-13 22:13:50 +00001884 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001885 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001886 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001887 } else { // Even mapped rnd:sat:raw:lo
1888 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
Eugene Zelenko82085922016-12-13 22:13:50 +00001889 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001890 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001891 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001892 }
1893 break;
1894 }
1895
1896 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1897 MCOperand &Imm = Inst.getOperand(2);
1898 int64_t Value;
1899 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1900 assert(Absolute);
1901 (void)Absolute;
1902 if (Value == 0)
1903 Inst.setOpcode(Hexagon::S2_vsathub);
1904 else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001905 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001906 MCBinaryExpr::createSub(Imm.getExpr(),
1907 MCConstantExpr::create(1, Context), Context),
1908 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001909 Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
1910 }
1911 break;
1912 }
1913
1914 case Hexagon::S5_vasrhrnd_goodsyntax: {
1915 MCOperand &Rdd = Inst.getOperand(0);
1916 MCOperand &Rss = Inst.getOperand(1);
1917 MCOperand &Imm = Inst.getOperand(2);
1918 int64_t Value;
1919 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1920 assert(Absolute);
1921 (void)Absolute;
1922 if (Value == 0) {
1923 MCInst TmpInst;
1924 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001925 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001926 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001927 Rss.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001928 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001929 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001930 StringRef Reg2(R2);
1931 TmpInst.setOpcode(Hexagon::A2_combinew);
1932 TmpInst.addOperand(Rdd);
1933 TmpInst.addOperand(Rss);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001934 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001935 Inst = TmpInst;
1936 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001937 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001938 MCBinaryExpr::createSub(Imm.getExpr(),
1939 MCConstantExpr::create(1, Context), Context),
1940 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001941 Inst.setOpcode(Hexagon::S5_vasrhrnd);
1942 }
1943 break;
1944 }
1945
1946 case Hexagon::A2_not: {
1947 MCInst TmpInst;
1948 MCOperand &Rd = Inst.getOperand(0);
1949 MCOperand &Rs = Inst.getOperand(1);
1950 TmpInst.setOpcode(Hexagon::A2_subri);
1951 TmpInst.addOperand(Rd);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001952 TmpInst.addOperand(MCOperand::createExpr(
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001953 HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001954 TmpInst.addOperand(Rs);
1955 Inst = TmpInst;
1956 break;
1957 }
Krzysztof Parzyszek5b4a6b62017-02-06 23:18:57 +00001958 case Hexagon::PS_loadrubabs:
1959 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1960 Inst.setOpcode(Hexagon::L2_loadrubgp);
1961 break;
1962 case Hexagon::PS_loadrbabs:
1963 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1964 Inst.setOpcode(Hexagon::L2_loadrbgp);
1965 break;
1966 case Hexagon::PS_loadruhabs:
1967 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1968 Inst.setOpcode(Hexagon::L2_loadruhgp);
1969 break;
1970 case Hexagon::PS_loadrhabs:
1971 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1972 Inst.setOpcode(Hexagon::L2_loadrhgp);
1973 break;
1974 case Hexagon::PS_loadriabs:
1975 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1976 Inst.setOpcode(Hexagon::L2_loadrigp);
1977 break;
1978 case Hexagon::PS_loadrdabs:
1979 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1980 Inst.setOpcode(Hexagon::L2_loadrdgp);
1981 break;
1982 case Hexagon::PS_storerbabs:
1983 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1984 Inst.setOpcode(Hexagon::S2_storerbgp);
1985 break;
1986 case Hexagon::PS_storerhabs:
1987 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1988 Inst.setOpcode(Hexagon::S2_storerhgp);
1989 break;
1990 case Hexagon::PS_storerfabs:
1991 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1992 Inst.setOpcode(Hexagon::S2_storerfgp);
1993 break;
1994 case Hexagon::PS_storeriabs:
1995 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1996 Inst.setOpcode(Hexagon::S2_storerigp);
1997 break;
1998 case Hexagon::PS_storerdabs:
1999 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2000 Inst.setOpcode(Hexagon::S2_storerdgp);
2001 break;
2002 case Hexagon::PS_storerbnewabs:
2003 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2004 Inst.setOpcode(Hexagon::S2_storerbnewgp);
2005 break;
2006 case Hexagon::PS_storerhnewabs:
2007 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2008 Inst.setOpcode(Hexagon::S2_storerhnewgp);
2009 break;
2010 case Hexagon::PS_storerinewabs:
2011 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2012 Inst.setOpcode(Hexagon::S2_storerinewgp);
2013 break;
Krzysztof Parzyszekc8d676e2017-02-07 17:42:11 +00002014 case Hexagon::A2_zxtb: {
2015 Inst.setOpcode(Hexagon::A2_andir);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00002016 Inst.addOperand(
2017 MCOperand::createExpr(MCConstantExpr::create(255, Context)));
Krzysztof Parzyszekc8d676e2017-02-07 17:42:11 +00002018 break;
2019 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002020 } // switch
2021
2022 return Match_Success;
2023}
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002024
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002025unsigned HexagonAsmParser::matchRegister(StringRef Name) {
2026 if (unsigned Reg = MatchRegisterName(Name))
2027 return Reg;
2028 return MatchRegisterAltName(Name);
2029}