Bug Summary

File:lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
Warning:line 634, column 7
Forming reference to null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name HexagonAsmParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/lib/Target/Hexagon/AsmParser -I /build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser -I /build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/lib/Target/Hexagon -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn325118/include -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/lib/Target/Hexagon/AsmParser/.. -I /build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/.. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/lib/Target/Hexagon/AsmParser -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-02-14-150435-17243-1 -x c++ /build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
1//===-- 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" "mcasmparser"
11
12#include "Hexagon.h"
13#include "HexagonTargetStreamer.h"
14#include "MCTargetDesc/HexagonMCChecker.h"
15#include "MCTargetDesc/HexagonMCELFStreamer.h"
16#include "MCTargetDesc/HexagonMCExpr.h"
17#include "MCTargetDesc/HexagonMCInstrInfo.h"
18#include "MCTargetDesc/HexagonMCTargetDesc.h"
19#include "MCTargetDesc/HexagonShuffler.h"
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringExtras.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/ADT/Twine.h"
25#include "llvm/BinaryFormat/ELF.h"
26#include "llvm/MC/MCAssembler.h"
27#include "llvm/MC/MCContext.h"
28#include "llvm/MC/MCDirectives.h"
29#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"
34#include "llvm/MC/MCParser/MCAsmParserExtension.h"
35#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
36#include "llvm/MC/MCParser/MCTargetAsmParser.h"
37#include "llvm/MC/MCRegisterInfo.h"
38#include "llvm/MC/MCSectionELF.h"
39#include "llvm/MC/MCStreamer.h"
40#include "llvm/MC/MCSubtargetInfo.h"
41#include "llvm/MC/MCSymbol.h"
42#include "llvm/MC/MCValue.h"
43#include "llvm/Support/Casting.h"
44#include "llvm/Support/CommandLine.h"
45#include "llvm/Support/Debug.h"
46#include "llvm/Support/ErrorHandling.h"
47#include "llvm/Support/Format.h"
48#include "llvm/Support/MathExtras.h"
49#include "llvm/Support/SMLoc.h"
50#include "llvm/Support/SourceMgr.h"
51#include "llvm/Support/TargetRegistry.h"
52#include "llvm/Support/raw_ostream.h"
53#include <algorithm>
54#include <cassert>
55#include <cctype>
56#include <cstddef>
57#include <cstdint>
58#include <memory>
59#include <string>
60#include <utility>
61
62using namespace llvm;
63
64static 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));
83
84namespace {
85
86struct HexagonOperand;
87
88class HexagonAsmParser : public MCTargetAsmParser {
89
90 HexagonTargetStreamer &getTargetStreamer() {
91 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
92 return static_cast<HexagonTargetStreamer &>(TS);
93 }
94
95 MCAsmParser &Parser;
96 MCInst MCB;
97 bool InBrackets;
98
99 MCAsmParser &getParser() const { return Parser; }
100 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
110 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
111
112 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
119 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
120 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,
131 bool MatchingInlineAsm);
132 void eatToEndOfPacket();
133 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
134 OperandVector &Operands, MCStreamer &Out,
135 uint64_t &ErrorInfo,
136 bool MatchingInlineAsm) override;
137
138 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
139 unsigned Kind) override;
140 bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
141 int processInstruction(MCInst &Inst, OperandVector const &Operands,
142 SMLoc IDLoc);
143
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
150 unsigned matchRegister(StringRef Name);
151
152/// @name Auto-generated Match Functions
153/// {
154
155#define GET_ASSEMBLER_HEADER
156#include "HexagonGenAsmMatcher.inc"
157
158 /// }
159
160public:
161 HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
162 const MCInstrInfo &MII, const MCTargetOptions &Options)
163 : MCTargetAsmParser(Options, _STI, MII), Parser(_Parser),
164 InBrackets(false) {
165 MCB.setOpcode(Hexagon::BUNDLE);
166 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
167
168 MCAsmParserExtension::Initialize(_Parser);
169 }
170
171 bool splitIdentifier(OperandVector &Operands);
172 bool parseOperand(OperandVector &Operands);
173 bool parseInstruction(OperandVector &Operands);
174 bool implicitExpressionLocation(OperandVector &Operands);
175 bool parseExpressionOrOperand(OperandVector &Operands);
176 bool parseExpression(MCExpr const *&Expr);
177
178 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
179 SMLoc NameLoc, OperandVector &Operands) override {
180 llvm_unreachable("Unimplemented")::llvm::llvm_unreachable_internal("Unimplemented", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 180)
;
181 }
182
183 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
184 OperandVector &Operands) override;
185
186 bool ParseDirective(AsmToken DirectiveID) override;
187};
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;
193 MCContext &Context;
194
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;
208 };
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
220 HexagonOperand(KindTy K, MCContext &Context)
221 : MCParsedAsmOperand(), Kind(K), Context(Context) {}
222
223public:
224 HexagonOperand(const HexagonOperand &o)
225 : MCParsedAsmOperand(), Context(o.Context) {
226 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.
243 SMLoc getStartLoc() const override { return StartLoc; }
244
245 /// getEndLoc - Get the location of the last token of this operand.
246 SMLoc getEndLoc() const override { return EndLoc; }
247
248 unsigned getReg() const override {
249 assert(Kind == Register && "Invalid access!")(static_cast <bool> (Kind == Register && "Invalid access!"
) ? void (0) : __assert_fail ("Kind == Register && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 249, __extension__ __PRETTY_FUNCTION__))
;
250 return Reg.RegNum;
251 }
252
253 const MCExpr *getImm() const {
254 assert(Kind == Immediate && "Invalid access!")(static_cast <bool> (Kind == Immediate && "Invalid access!"
) ? void (0) : __assert_fail ("Kind == Immediate && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 254, __extension__ __PRETTY_FUNCTION__))
;
255 return Imm.Val;
256 }
257
258 bool isToken() const override { return Kind == Token; }
259 bool isImm() const override { return Kind == Immediate; }
260 bool isMem() const override { llvm_unreachable("No isMem")::llvm::llvm_unreachable_internal("No isMem", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 260)
; }
261 bool isReg() const override { return Kind == Register; }
262
263 bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
264 bool isRelocatable, bool Extendable) const {
265 if (Kind == Immediate) {
266 const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());
267 if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && !Extendable)
268 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)
283 return ((uint64_t)Res < (uint64_t)(1ULL << bits));
284 else {
285 const int64_t high_bit_set = 1ULL << 63;
286 const uint64_t mask = (high_bit_set >> (63 - bits));
287 return (((uint64_t)Res & mask) == mask);
288 }
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
299 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; }
312 bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }
313 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); }
316 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); }
320 bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }
321 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); }
325 bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }
326
327 bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }
328 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; }
332 bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
333 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); }
338 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); }
343 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); }
346 bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }
347 bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }
348 bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }
349 bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }
350 bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }
351 bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }
352 bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }
353 bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }
354 bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }
355
356 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 }
364 bool iss11_0Imm() const {
365 return CheckImmRange(11 + 26, 0, true, true, true);
366 }
367 bool iss11_1Imm() const {
368 return CheckImmRange(11 + 26, 1, true, true, true);
369 }
370 bool iss11_2Imm() const {
371 return CheckImmRange(11 + 26, 2, true, true, true);
372 }
373 bool iss11_3Imm() const {
374 return CheckImmRange(11 + 26, 3, true, true, true);
375 }
376 bool isu32_0MustExt() const { return isImm(); }
377
378 void addRegOperands(MCInst &Inst, unsigned N) const {
379 assert(N == 1 && "Invalid number of operands!")(static_cast <bool> (N == 1 && "Invalid number of operands!"
) ? void (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 379, __extension__ __PRETTY_FUNCTION__))
;
380 Inst.addOperand(MCOperand::createReg(getReg()));
381 }
382
383 void addImmOperands(MCInst &Inst, unsigned N) const {
384 assert(N == 1 && "Invalid number of operands!")(static_cast <bool> (N == 1 && "Invalid number of operands!"
) ? void (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 384, __extension__ __PRETTY_FUNCTION__))
;
385 Inst.addOperand(MCOperand::createExpr(getImm()));
386 }
387
388 void addSignedImmOperands(MCInst &Inst, unsigned N) const {
389 assert(N == 1 && "Invalid number of operands!")(static_cast <bool> (N == 1 && "Invalid number of operands!"
) ? void (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 389, __extension__ __PRETTY_FUNCTION__))
;
390 HexagonMCExpr *Expr =
391 const_cast<HexagonMCExpr *>(cast<HexagonMCExpr>(getImm()));
392 int64_t Value;
393 if (!Expr->evaluateAsAbsolute(Value)) {
394 Inst.addOperand(MCOperand::createExpr(Expr));
395 return;
396 }
397 int64_t Extended = SignExtend64(Value, 32);
398 HexagonMCExpr *NewExpr = HexagonMCExpr::create(
399 MCConstantExpr::create(Extended, Context), Context);
400 if ((Extended < 0) != (Value < 0))
401 NewExpr->setSignMismatch();
402 NewExpr->setMustExtend(Expr->mustExtend());
403 NewExpr->setMustNotExtend(Expr->mustNotExtend());
404 Inst.addOperand(MCOperand::createExpr(NewExpr));
405 }
406
407 void addn1ConstOperands(MCInst &Inst, unsigned N) const {
408 addImmOperands(Inst, N);
409 }
410
411 StringRef getToken() const {
412 assert(Kind == Token && "Invalid access!")(static_cast <bool> (Kind == Token && "Invalid access!"
) ? void (0) : __assert_fail ("Kind == Token && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 412, __extension__ __PRETTY_FUNCTION__))
;
413 return StringRef(Tok.Data, Tok.Length);
414 }
415
416 void print(raw_ostream &OS) const override;
417
418 static std::unique_ptr<HexagonOperand> CreateToken(MCContext &Context,
419 StringRef Str, SMLoc S) {
420 HexagonOperand *Op = new HexagonOperand(Token, Context);
421 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
428 static std::unique_ptr<HexagonOperand>
429 CreateReg(MCContext &Context, unsigned RegNum, SMLoc S, SMLoc E) {
430 HexagonOperand *Op = new HexagonOperand(Register, Context);
431 Op->Reg.RegNum = RegNum;
432 Op->StartLoc = S;
433 Op->EndLoc = E;
434 return std::unique_ptr<HexagonOperand>(Op);
435 }
436
437 static std::unique_ptr<HexagonOperand>
438 CreateImm(MCContext &Context, const MCExpr *Val, SMLoc S, SMLoc E) {
439 HexagonOperand *Op = new HexagonOperand(Immediate, Context);
440 Op->Imm.Val = Val;
441 Op->StartLoc = S;
442 Op->EndLoc = E;
443 return std::unique_ptr<HexagonOperand>(Op);
444 }
445};
446
447} // end anonymous namespace
448
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
464bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
465 DEBUG(dbgs() << "Bundle:")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "Bundle:"; } } while (false
)
;
466 DEBUG(MCB.dump_pretty(dbgs()))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { MCB.dump_pretty(dbgs()); } } while (false)
;
467 DEBUG(dbgs() << "--\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "--\n"; } } while (false)
;
468
469 MCB.setLoc(IDLoc);
470 // Check the bundle for errors.
471 const MCRegisterInfo *RI = getContext().getRegisterInfo();
472 HexagonMCChecker Check(getContext(), MII, getSTI(), MCB, *RI);
473
474 bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MII, getSTI(),
475 getContext(), MCB,
476 &Check);
477
478 if (CheckOk) {
479 if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
480 assert(!HexagonMCInstrInfo::isInnerLoop(MCB))(static_cast <bool> (!HexagonMCInstrInfo::isInnerLoop(MCB
)) ? void (0) : __assert_fail ("!HexagonMCInstrInfo::isInnerLoop(MCB)"
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 480, __extension__ __PRETTY_FUNCTION__))
;
481 assert(!HexagonMCInstrInfo::isOuterLoop(MCB))(static_cast <bool> (!HexagonMCInstrInfo::isOuterLoop(MCB
)) ? void (0) : __assert_fail ("!HexagonMCInstrInfo::isOuterLoop(MCB)"
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 481, __extension__ __PRETTY_FUNCTION__))
;
482 // Empty packets are valid yet aren't emitted
483 return false;
484 }
485 Out.EmitInstruction(MCB, getSTI());
486 } 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_SIZE4) {
490 Error(IDLoc, "invalid instruction packet: out of slots");
491 }
492 return true; // Error
493 }
494
495 return false; // No error
496}
497
498bool HexagonAsmParser::matchBundleOptions() {
499 MCAsmParser &Parser = getParser();
500 while (true) {
501 if (!Parser.getTok().is(AsmToken::Colon))
502 return false;
503 Lex();
504 char const *MemNoShuffMsg =
505 "invalid instruction packet: mem_noshuf specifier not "
506 "supported with this architecture";
507 StringRef Option = Parser.getTok().getString();
508 auto IDLoc = Parser.getTok().getLoc();
509 if (Option.compare_lower("endloop0") == 0)
510 HexagonMCInstrInfo::setInnerLoop(MCB);
511 else if (Option.compare_lower("endloop1") == 0)
512 HexagonMCInstrInfo::setOuterLoop(MCB);
513 else if (Option.compare_lower("mem_noshuf") == 0)
514 if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf])
515 HexagonMCInstrInfo::setMemReorderDisabled(MCB);
516 else
517 return getParser().Error(IDLoc, MemNoShuffMsg);
518 else
519 return getParser().Error(IDLoc, llvm::Twine("'") + Option +
520 "' is not a valid bundle option");
521 Lex();
522 }
523}
524
525// For instruction aliases, immediates are generated rather than
526// MCConstantExpr. Convert them for uniform MCExpr.
527// Also check for signed/unsigned mismatches and warn
528void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
529 MCInst NewInst;
530 NewInst.setOpcode(MCI.getOpcode());
531 for (MCOperand &I : MCI)
532 if (I.isImm()) {
533 int64_t Value(I.getImm());
534 NewInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
535 MCConstantExpr::create(Value, getContext()), getContext())));
536 } else {
537 if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
538 WarnSignedMismatch)
539 Warning(MCI.getLoc(), "Signed/Unsigned mismatch");
540 NewInst.addOperand(I);
541 }
542 MCI = NewInst;
543}
544
545bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
546 OperandVector &InstOperands,
547 uint64_t &ErrorInfo,
548 bool MatchingInlineAsm) {
549 // Perform matching with tablegen asmmatcher generated function
550 int result =
551 MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
552 if (result == Match_Success) {
553 MCI.setLoc(IDLoc);
554 canonicalizeImmediates(MCI);
555 result = processInstruction(MCI, InstOperands, IDLoc);
556
557 DEBUG(dbgs() << "Insn:")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "Insn:"; } } while (false)
;
558 DEBUG(MCI.dump_pretty(dbgs()))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { MCI.dump_pretty(dbgs()); } } while (false)
;
559 DEBUG(dbgs() << "\n\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "\n\n"; } } while (false)
;
560
561 MCI.setLoc(IDLoc);
562 }
563
564 // Create instruction operand for bundle instruction
565 // Break this into a separate function Code here is less readable
566 // Think about how to get an instruction error to report correctly.
567 // SMLoc will return the "{"
568 switch (result) {
569 default:
570 break;
571 case Match_Success:
572 return false;
573 case Match_MissingFeature:
574 return Error(IDLoc, "invalid instruction");
575 case Match_MnemonicFail:
576 return Error(IDLoc, "unrecognized instruction");
577 case Match_InvalidOperand:
578 SMLoc ErrorLoc = IDLoc;
579 if (ErrorInfo != ~0U) {
580 if (ErrorInfo >= InstOperands.size())
581 return Error(IDLoc, "too few operands for instruction");
582
583 ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
584 ->getStartLoc();
585 if (ErrorLoc == SMLoc())
586 ErrorLoc = IDLoc;
587 }
588 return Error(ErrorLoc, "invalid operand for instruction");
589 }
590 llvm_unreachable("Implement any new match types added!")::llvm::llvm_unreachable_internal("Implement any new match types added!"
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 590)
;
591}
592
593void HexagonAsmParser::eatToEndOfPacket() {
594 assert(InBrackets)(static_cast <bool> (InBrackets) ? void (0) : __assert_fail
("InBrackets", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 594, __extension__ __PRETTY_FUNCTION__))
;
595 MCAsmLexer &Lexer = getLexer();
596 while (!Lexer.is(AsmToken::RCurly))
597 Lexer.Lex();
598 Lexer.Lex();
599 InBrackets = false;
600}
601
602bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
603 OperandVector &Operands,
604 MCStreamer &Out,
605 uint64_t &ErrorInfo,
606 bool MatchingInlineAsm) {
607 if (!InBrackets) {
1
Assuming the condition is false
2
Taking false branch
608 MCB.clear();
609 MCB.addOperand(MCOperand::createImm(0));
610 }
611 HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
612 if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
3
Assuming the condition is false
4
Taking false branch
613 assert(Operands.size() == 1 && "Brackets should be by themselves")(static_cast <bool> (Operands.size() == 1 && "Brackets should be by themselves"
) ? void (0) : __assert_fail ("Operands.size() == 1 && \"Brackets should be by themselves\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 613, __extension__ __PRETTY_FUNCTION__))
;
614 if (InBrackets) {
615 getParser().Error(IDLoc, "Already in a packet");
616 InBrackets = false;
617 return true;
618 }
619 InBrackets = true;
620 return false;
621 }
622 if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
5
Assuming the condition is false
6
Taking false branch
623 assert(Operands.size() == 1 && "Brackets should be by themselves")(static_cast <bool> (Operands.size() == 1 && "Brackets should be by themselves"
) ? void (0) : __assert_fail ("Operands.size() == 1 && \"Brackets should be by themselves\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 623, __extension__ __PRETTY_FUNCTION__))
;
624 if (!InBrackets) {
625 getParser().Error(IDLoc, "Not in a packet");
626 return true;
627 }
628 InBrackets = false;
629 if (matchBundleOptions())
630 return true;
631 return finishBundle(IDLoc, Out);
632 }
633 MCInst *SubInst = new (getParser().getContext()) MCInst;
7
'SubInst' initialized to a null pointer value
634 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
8
Forming reference to null pointer
635 MatchingInlineAsm)) {
636 if (InBrackets)
637 eatToEndOfPacket();
638 return true;
639 }
640 HexagonMCInstrInfo::extendIfNeeded(
641 getParser().getContext(), MII, MCB, *SubInst);
642 MCB.addOperand(MCOperand::createInst(SubInst));
643 if (!InBrackets)
644 return finishBundle(IDLoc, Out);
645 return false;
646}
647
648/// ParseDirective parses the Hexagon specific directives
649bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
650 StringRef IDVal = DirectiveID.getIdentifier();
651 if ((IDVal.lower() == ".word") || (IDVal.lower() == ".4byte"))
652 return ParseDirectiveValue(4, DirectiveID.getLoc());
653 if (IDVal.lower() == ".short" || IDVal.lower() == ".hword" ||
654 IDVal.lower() == ".half")
655 return ParseDirectiveValue(2, DirectiveID.getLoc());
656 if (IDVal.lower() == ".falign")
657 return ParseDirectiveFalign(256, DirectiveID.getLoc());
658 if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
659 return ParseDirectiveComm(true, DirectiveID.getLoc());
660 if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
661 return ParseDirectiveComm(false, DirectiveID.getLoc());
662 if (IDVal.lower() == ".subsection")
663 return ParseDirectiveSubsection(DirectiveID.getLoc());
664
665 return true;
666}
667bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
668 const MCExpr *Subsection = nullptr;
669 int64_t Res;
670
671 assert((getLexer().isNot(AsmToken::EndOfStatement)) &&(static_cast <bool> ((getLexer().isNot(AsmToken::EndOfStatement
)) && "Invalid subsection directive") ? void (0) : __assert_fail
("(getLexer().isNot(AsmToken::EndOfStatement)) && \"Invalid subsection directive\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 672, __extension__ __PRETTY_FUNCTION__))
672 "Invalid subsection directive")(static_cast <bool> ((getLexer().isNot(AsmToken::EndOfStatement
)) && "Invalid subsection directive") ? void (0) : __assert_fail
("(getLexer().isNot(AsmToken::EndOfStatement)) && \"Invalid subsection directive\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 672, __extension__ __PRETTY_FUNCTION__))
;
673 getParser().parseExpression(Subsection);
674
675 if (!Subsection->evaluateAsAbsolute(Res))
676 return Error(L, "Cannot evaluate subsection number");
677
678 if (getLexer().isNot(AsmToken::EndOfStatement))
679 return TokError("unexpected token in directive");
680
681 // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
682 // negative subsections together and in the same order but at the opposite
683 // end of the section. Only legacy hexagon-gcc created assembly code
684 // used negative subsections.
685 if ((Res < 0) && (Res > -8193))
686 Subsection = HexagonMCExpr::create(
687 MCConstantExpr::create(8192 + Res, getContext()), getContext());
688
689 getStreamer().SubSection(Subsection);
690 return false;
691}
692
693/// ::= .falign [expression]
694bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
695
696 int64_t MaxBytesToFill = 15;
697
698 // if there is an argument
699 if (getLexer().isNot(AsmToken::EndOfStatement)) {
700 const MCExpr *Value;
701 SMLoc ExprLoc = L;
702
703 // Make sure we have a number (false is returned if expression is a number)
704 if (!getParser().parseExpression(Value)) {
705 // Make sure this is a number that is in range
706 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
707 uint64_t IntValue = MCE->getValue();
708 if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
709 return Error(ExprLoc, "literal value out of range (256) for falign");
710 MaxBytesToFill = IntValue;
711 Lex();
712 } else {
713 return Error(ExprLoc, "not a valid expression for falign directive");
714 }
715 }
716
717 getTargetStreamer().emitFAlign(16, MaxBytesToFill);
718 Lex();
719
720 return false;
721}
722
723/// ::= .word [ expression (, expression)* ]
724bool HexagonAsmParser::ParseDirectiveValue(unsigned Size, SMLoc L) {
725 if (getLexer().isNot(AsmToken::EndOfStatement)) {
726 while (true) {
727 const MCExpr *Value;
728 SMLoc ExprLoc = L;
729 if (getParser().parseExpression(Value))
730 return true;
731
732 // Special case constant expressions to match code generator.
733 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
734 assert(Size <= 8 && "Invalid size")(static_cast <bool> (Size <= 8 && "Invalid size"
) ? void (0) : __assert_fail ("Size <= 8 && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 734, __extension__ __PRETTY_FUNCTION__))
;
735 uint64_t IntValue = MCE->getValue();
736 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
737 return Error(ExprLoc, "literal value out of range for directive");
738 getStreamer().EmitIntValue(IntValue, Size);
739 } else
740 getStreamer().EmitValue(Value, Size);
741
742 if (getLexer().is(AsmToken::EndOfStatement))
743 break;
744
745 // FIXME: Improve diagnostic.
746 if (getLexer().isNot(AsmToken::Comma))
747 return TokError("unexpected token in directive");
748 Lex();
749 }
750 }
751
752 Lex();
753 return false;
754}
755
756// This is largely a copy of AsmParser's ParseDirectiveComm extended to
757// accept a 3rd argument, AccessAlignment which indicates the smallest
758// memory access made to the symbol, expressed in bytes. If no
759// AccessAlignment is specified it defaults to the Alignment Value.
760// Hexagon's .lcomm:
761// .lcomm Symbol, Length, Alignment, AccessAlignment
762bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
763 // FIXME: need better way to detect if AsmStreamer (upstream removed
764 // getKind())
765 if (getStreamer().hasRawTextSupport())
766 return true; // Only object file output requires special treatment.
767
768 StringRef Name;
769 if (getParser().parseIdentifier(Name))
770 return TokError("expected identifier in directive");
771 // Handle the identifier as the key symbol.
772 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
773
774 if (getLexer().isNot(AsmToken::Comma))
775 return TokError("unexpected token in directive");
776 Lex();
777
778 int64_t Size;
779 SMLoc SizeLoc = getLexer().getLoc();
780 if (getParser().parseAbsoluteExpression(Size))
781 return true;
782
783 int64_t ByteAlignment = 1;
784 SMLoc ByteAlignmentLoc;
785 if (getLexer().is(AsmToken::Comma)) {
786 Lex();
787 ByteAlignmentLoc = getLexer().getLoc();
788 if (getParser().parseAbsoluteExpression(ByteAlignment))
789 return true;
790 if (!isPowerOf2_64(ByteAlignment))
791 return Error(ByteAlignmentLoc, "alignment must be a power of 2");
792 }
793
794 int64_t AccessAlignment = 0;
795 if (getLexer().is(AsmToken::Comma)) {
796 // The optional access argument specifies the size of the smallest memory
797 // access to be made to the symbol, expressed in bytes.
798 SMLoc AccessAlignmentLoc;
799 Lex();
800 AccessAlignmentLoc = getLexer().getLoc();
801 if (getParser().parseAbsoluteExpression(AccessAlignment))
802 return true;
803
804 if (!isPowerOf2_64(AccessAlignment))
805 return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
806 }
807
808 if (getLexer().isNot(AsmToken::EndOfStatement))
809 return TokError("unexpected token in '.comm' or '.lcomm' directive");
810
811 Lex();
812
813 // NOTE: a size of zero for a .comm should create a undefined symbol
814 // but a size of .lcomm creates a bss symbol of size zero.
815 if (Size < 0)
816 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
817 "be less than zero");
818
819 // NOTE: The alignment in the directive is a power of 2 value, the assembler
820 // may internally end up wanting an alignment in bytes.
821 // FIXME: Diagnose overflow.
822 if (ByteAlignment < 0)
823 return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
824 "alignment, can't be less than zero");
825
826 if (!Sym->isUndefined())
827 return Error(Loc, "invalid symbol redefinition");
828
829 HexagonMCELFStreamer &HexagonELFStreamer =
830 static_cast<HexagonMCELFStreamer &>(getStreamer());
831 if (IsLocal) {
832 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(Sym, Size, ByteAlignment,
833 AccessAlignment);
834 return false;
835 }
836
837 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, ByteAlignment,
838 AccessAlignment);
839 return false;
840}
841
842// validate register against architecture
843bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
844 if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))
845 if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
846 return false;
847 return true;
848}
849
850// extern "C" void LLVMInitializeHexagonAsmLexer();
851
852/// Force static initialization.
853extern "C" void LLVMInitializeHexagonAsmParser() {
854 RegisterMCAsmParser<HexagonAsmParser> X(getTheHexagonTarget());
855}
856
857#define GET_MATCHER_IMPLEMENTATION
858#define GET_REGISTER_MATCHER
859#include "HexagonGenAsmMatcher.inc"
860
861static bool previousEqual(OperandVector &Operands, size_t Index,
862 StringRef String) {
863 if (Index >= Operands.size())
864 return false;
865 MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
866 if (!Operand.isToken())
867 return false;
868 return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
869}
870
871static bool previousIsLoop(OperandVector &Operands, size_t Index) {
872 return previousEqual(Operands, Index, "loop0") ||
873 previousEqual(Operands, Index, "loop1") ||
874 previousEqual(Operands, Index, "sp1loop0") ||
875 previousEqual(Operands, Index, "sp2loop0") ||
876 previousEqual(Operands, Index, "sp3loop0");
877}
878
879bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
880 AsmToken const &Token = getParser().getTok();
881 StringRef String = Token.getString();
882 SMLoc Loc = Token.getLoc();
883 Lex();
884 do {
885 std::pair<StringRef, StringRef> HeadTail = String.split('.');
886 if (!HeadTail.first.empty())
887 Operands.push_back(
888 HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
889 if (!HeadTail.second.empty())
890 Operands.push_back(HexagonOperand::CreateToken(
891 getContext(), String.substr(HeadTail.first.size(), 1), Loc));
892 String = HeadTail.second;
893 } while (!String.empty());
894 return false;
895}
896
897bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
898 unsigned Register;
899 SMLoc Begin;
900 SMLoc End;
901 MCAsmLexer &Lexer = getLexer();
902 if (!ParseRegister(Register, Begin, End)) {
903 if (!ErrorMissingParenthesis)
904 switch (Register) {
905 default:
906 break;
907 case Hexagon::P0:
908 case Hexagon::P1:
909 case Hexagon::P2:
910 case Hexagon::P3:
911 if (previousEqual(Operands, 0, "if")) {
912 if (WarnMissingParenthesis)
913 Warning(Begin, "Missing parenthesis around predicate register");
914 static char const *LParen = "(";
915 static char const *RParen = ")";
916 Operands.push_back(
917 HexagonOperand::CreateToken(getContext(), LParen, Begin));
918 Operands.push_back(
919 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
920 const AsmToken &MaybeDotNew = Lexer.getTok();
921 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
922 MaybeDotNew.getString().equals_lower(".new"))
923 splitIdentifier(Operands);
924 Operands.push_back(
925 HexagonOperand::CreateToken(getContext(), RParen, Begin));
926 return false;
927 }
928 if (previousEqual(Operands, 0, "!") &&
929 previousEqual(Operands, 1, "if")) {
930 if (WarnMissingParenthesis)
931 Warning(Begin, "Missing parenthesis around predicate register");
932 static char const *LParen = "(";
933 static char const *RParen = ")";
934 Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(
935 getContext(), LParen, Begin));
936 Operands.push_back(
937 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
938 const AsmToken &MaybeDotNew = Lexer.getTok();
939 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
940 MaybeDotNew.getString().equals_lower(".new"))
941 splitIdentifier(Operands);
942 Operands.push_back(
943 HexagonOperand::CreateToken(getContext(), RParen, Begin));
944 return false;
945 }
946 break;
947 }
948 Operands.push_back(
949 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
950 return false;
951 }
952 return splitIdentifier(Operands);
953}
954
955bool HexagonAsmParser::isLabel(AsmToken &Token) {
956 MCAsmLexer &Lexer = getLexer();
957 AsmToken const &Second = Lexer.getTok();
958 AsmToken Third = Lexer.peekTok();
959 StringRef String = Token.getString();
960 if (Token.is(AsmToken::TokenKind::LCurly) ||
961 Token.is(AsmToken::TokenKind::RCurly))
962 return false;
963 // special case for parsing vwhist256:sat
964 if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&
965 Third.getString().lower() == "sat")
966 return false;
967 if (!Token.is(AsmToken::TokenKind::Identifier))
968 return true;
969 if (!matchRegister(String.lower()))
970 return true;
971 assert(Second.is(AsmToken::Colon))(static_cast <bool> (Second.is(AsmToken::Colon)) ? void
(0) : __assert_fail ("Second.is(AsmToken::Colon)", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 971, __extension__ __PRETTY_FUNCTION__))
;
972 StringRef Raw(String.data(), Third.getString().data() - String.data() +
973 Third.getString().size());
974 std::string Collapsed = Raw;
975 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
976 StringRef Whole = Collapsed;
977 std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
978 if (!matchRegister(DotSplit.first.lower()))
979 return true;
980 return false;
981}
982
983bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,
984 SMLoc &Loc) {
985 if (!Contigious && ErrorNoncontigiousRegister) {
986 Error(Loc, "Register name is not contigious");
987 return true;
988 }
989 if (!Contigious && WarnNoncontigiousRegister)
990 Warning(Loc, "Register name is not contigious");
991 return false;
992}
993
994bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
995 SMLoc &EndLoc) {
996 MCAsmLexer &Lexer = getLexer();
997 StartLoc = getLexer().getLoc();
998 SmallVector<AsmToken, 5> Lookahead;
999 StringRef RawString(Lexer.getTok().getString().data(), 0);
1000 bool Again = Lexer.is(AsmToken::Identifier);
1001 bool NeededWorkaround = false;
1002 while (Again) {
1003 AsmToken const &Token = Lexer.getTok();
1004 RawString = StringRef(RawString.data(), Token.getString().data() -
1005 RawString.data() +
1006 Token.getString().size());
1007 Lookahead.push_back(Token);
1008 Lexer.Lex();
1009 bool Contigious = Lexer.getTok().getString().data() ==
1010 Lookahead.back().getString().data() +
1011 Lookahead.back().getString().size();
1012 bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
1013 Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
1014 Lexer.is(AsmToken::Colon);
1015 bool Workaround =
1016 Lexer.is(AsmToken::Colon) || Lookahead.back().is(AsmToken::Colon);
1017 Again = (Contigious && Type) || (Workaround && Type);
1018 NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
1019 }
1020 std::string Collapsed = RawString;
1021 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
1022 StringRef FullString = Collapsed;
1023 std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
1024 unsigned DotReg = matchRegister(DotSplit.first.lower());
1025 if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1026 if (DotSplit.second.empty()) {
1027 RegNo = DotReg;
1028 EndLoc = Lexer.getLoc();
1029 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1030 return true;
1031 return false;
1032 } else {
1033 RegNo = DotReg;
1034 size_t First = RawString.find('.');
1035 StringRef DotString (RawString.data() + First, RawString.size() - First);
1036 Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1037 EndLoc = Lexer.getLoc();
1038 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1039 return true;
1040 return false;
1041 }
1042 }
1043 std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
1044 unsigned ColonReg = matchRegister(ColonSplit.first.lower());
1045 if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1046 do {
1047 Lexer.UnLex(Lookahead.back());
1048 Lookahead.pop_back();
1049 } while (!Lookahead.empty () && !Lexer.is(AsmToken::Colon));
1050 RegNo = ColonReg;
1051 EndLoc = Lexer.getLoc();
1052 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1053 return true;
1054 return false;
1055 }
1056 while (!Lookahead.empty()) {
1057 Lexer.UnLex(Lookahead.back());
1058 Lookahead.pop_back();
1059 }
1060 return true;
1061}
1062
1063bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1064 if (previousEqual(Operands, 0, "call"))
1065 return true;
1066 if (previousEqual(Operands, 0, "jump"))
1067 if (!getLexer().getTok().is(AsmToken::Colon))
1068 return true;
1069 if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
1070 return true;
1071 if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
1072 (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
1073 return true;
1074 return false;
1075}
1076
1077bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {
1078 SmallVector<AsmToken, 4> Tokens;
1079 MCAsmLexer &Lexer = getLexer();
1080 bool Done = false;
1081 static char const *Comma = ",";
1082 do {
1083 Tokens.emplace_back(Lexer.getTok());
1084 Lex();
1085 switch (Tokens.back().getKind()) {
1086 case AsmToken::TokenKind::Hash:
1087 if (Tokens.size() > 1)
1088 if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
1089 Tokens.insert(Tokens.end() - 2,
1090 AsmToken(AsmToken::TokenKind::Comma, Comma));
1091 Done = true;
1092 }
1093 break;
1094 case AsmToken::TokenKind::RCurly:
1095 case AsmToken::TokenKind::EndOfStatement:
1096 case AsmToken::TokenKind::Eof:
1097 Done = true;
1098 break;
1099 default:
1100 break;
1101 }
1102 } while (!Done);
1103 while (!Tokens.empty()) {
1104 Lexer.UnLex(Tokens.back());
1105 Tokens.pop_back();
1106 }
1107 SMLoc Loc = Lexer.getLoc();
1108 return getParser().parseExpression(Expr, Loc);
1109}
1110
1111bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1112 if (implicitExpressionLocation(Operands)) {
1113 MCAsmParser &Parser = getParser();
1114 SMLoc Loc = Parser.getLexer().getLoc();
1115 MCExpr const *Expr = nullptr;
1116 bool Error = parseExpression(Expr);
1117 Expr = HexagonMCExpr::create(Expr, getContext());
1118 if (!Error)
1119 Operands.push_back(
1120 HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
1121 return Error;
1122 }
1123 return parseOperand(Operands);
1124}
1125
1126/// Parse an instruction.
1127bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1128 MCAsmParser &Parser = getParser();
1129 MCAsmLexer &Lexer = getLexer();
1130 while (true) {
1131 AsmToken const &Token = Parser.getTok();
1132 switch (Token.getKind()) {
1133 case AsmToken::Eof:
1134 case AsmToken::EndOfStatement: {
1135 Lex();
1136 return false;
1137 }
1138 case AsmToken::LCurly: {
1139 if (!Operands.empty())
1140 return true;
1141 Operands.push_back(HexagonOperand::CreateToken(
1142 getContext(), Token.getString(), Token.getLoc()));
1143 Lex();
1144 return false;
1145 }
1146 case AsmToken::RCurly: {
1147 if (Operands.empty()) {
1148 Operands.push_back(HexagonOperand::CreateToken(
1149 getContext(), Token.getString(), Token.getLoc()));
1150 Lex();
1151 }
1152 return false;
1153 }
1154 case AsmToken::Comma: {
1155 Lex();
1156 continue;
1157 }
1158 case AsmToken::EqualEqual:
1159 case AsmToken::ExclaimEqual:
1160 case AsmToken::GreaterEqual:
1161 case AsmToken::GreaterGreater:
1162 case AsmToken::LessEqual:
1163 case AsmToken::LessLess: {
1164 Operands.push_back(HexagonOperand::CreateToken(
1165 getContext(), Token.getString().substr(0, 1), Token.getLoc()));
1166 Operands.push_back(HexagonOperand::CreateToken(
1167 getContext(), Token.getString().substr(1, 1), Token.getLoc()));
1168 Lex();
1169 continue;
1170 }
1171 case AsmToken::Hash: {
1172 bool MustNotExtend = false;
1173 bool ImplicitExpression = implicitExpressionLocation(Operands);
1174 SMLoc ExprLoc = Lexer.getLoc();
1175 if (!ImplicitExpression)
1176 Operands.push_back(HexagonOperand::CreateToken(
1177 getContext(), Token.getString(), Token.getLoc()));
1178 Lex();
1179 bool MustExtend = false;
1180 bool HiOnly = false;
1181 bool LoOnly = false;
1182 if (Lexer.is(AsmToken::Hash)) {
1183 Lex();
1184 MustExtend = true;
1185 } else if (ImplicitExpression)
1186 MustNotExtend = true;
1187 AsmToken const &Token = Parser.getTok();
1188 if (Token.is(AsmToken::Identifier)) {
1189 StringRef String = Token.getString();
1190 if (String.lower() == "hi") {
1191 HiOnly = true;
1192 } else if (String.lower() == "lo") {
1193 LoOnly = true;
1194 }
1195 if (HiOnly || LoOnly) {
1196 AsmToken LParen = Lexer.peekTok();
1197 if (!LParen.is(AsmToken::LParen)) {
1198 HiOnly = false;
1199 LoOnly = false;
1200 } else {
1201 Lex();
1202 }
1203 }
1204 }
1205 MCExpr const *Expr = nullptr;
1206 if (parseExpression(Expr))
1207 return true;
1208 int64_t Value;
1209 MCContext &Context = Parser.getContext();
1210 assert(Expr != nullptr)(static_cast <bool> (Expr != nullptr) ? void (0) : __assert_fail
("Expr != nullptr", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1210, __extension__ __PRETTY_FUNCTION__))
;
1211 if (Expr->evaluateAsAbsolute(Value)) {
1212 if (HiOnly)
1213 Expr = MCBinaryExpr::createLShr(
1214 Expr, MCConstantExpr::create(16, Context), Context);
1215 if (HiOnly || LoOnly)
1216 Expr = MCBinaryExpr::createAnd(
1217 Expr, MCConstantExpr::create(0xffff, Context), Context);
1218 } else {
1219 MCValue Value;
1220 if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
1221 if (!Value.isAbsolute()) {
1222 switch (Value.getAccessVariant()) {
1223 case MCSymbolRefExpr::VariantKind::VK_TPREL:
1224 case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1225 // Don't lazy extend these expression variants
1226 MustNotExtend = !MustExtend;
1227 break;
1228 default:
1229 break;
1230 }
1231 }
1232 }
1233 }
1234 Expr = HexagonMCExpr::create(Expr, Context);
1235 HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
1236 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
1237 std::unique_ptr<HexagonOperand> Operand =
1238 HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
1239 Operands.push_back(std::move(Operand));
1240 continue;
1241 }
1242 default:
1243 break;
1244 }
1245 if (parseExpressionOrOperand(Operands))
1246 return true;
1247 }
1248}
1249
1250bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1251 StringRef Name, AsmToken ID,
1252 OperandVector &Operands) {
1253 getLexer().UnLex(ID);
1254 return parseInstruction(Operands);
1255}
1256
1257static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,
1258 MCOperand &MO2) {
1259 MCInst TmpInst;
1260 TmpInst.setOpcode(opCode);
1261 TmpInst.addOperand(Rdd);
1262 TmpInst.addOperand(MO1);
1263 TmpInst.addOperand(MO2);
1264
1265 return TmpInst;
1266}
1267
1268// Define this matcher function after the auto-generated include so we
1269// have the match class enum definitions.
1270unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1271 unsigned Kind) {
1272 HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1273
1274 switch (Kind) {
1275 case MCK_0: {
1276 int64_t Value;
1277 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1278 ? Match_Success
1279 : Match_InvalidOperand;
1280 }
1281 case MCK_1: {
1282 int64_t Value;
1283 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1284 ? Match_Success
1285 : Match_InvalidOperand;
1286 }
1287 }
1288 if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1289 StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1290 if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1291 return Match_Success;
1292 if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1293 return Match_Success;
1294 }
1295
1296 DEBUG(dbgs() << "Unmatched Operand:")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "Unmatched Operand:"; } } while
(false)
;
1297 DEBUG(Op->dump())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { Op->dump(); } } while (false)
;
1298 DEBUG(dbgs() << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "\n"; } } while (false)
;
1299
1300 return Match_InvalidOperand;
1301}
1302
1303// FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
1304bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
1305 std::string errStr;
1306 raw_string_ostream ES(errStr);
1307 ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
1308 if (Max >= 0)
1309 ES << "0-" << Max;
1310 else
1311 ES << Max << "-" << (-Max - 1);
1312 return Parser.printError(IDLoc, ES.str());
1313}
1314
1315int HexagonAsmParser::processInstruction(MCInst &Inst,
1316 OperandVector const &Operands,
1317 SMLoc IDLoc) {
1318 MCContext &Context = getParser().getContext();
1319 const MCRegisterInfo *RI = getContext().getRegisterInfo();
1320 std::string r = "r";
1321 std::string v = "v";
1322 std::string Colon = ":";
1323
1324 bool is32bit = false; // used to distinguish between CONST32 and CONST64
1325 switch (Inst.getOpcode()) {
1326 default:
1327 if (HexagonMCInstrInfo::getDesc(MII, Inst).isPseudo()) {
1328 SMDiagnostic Diag = getSourceManager().GetMessage(
1329 IDLoc, SourceMgr::DK_Error,
1330 "Found pseudo instruction with no expansion");
1331 Diag.print("", errs());
1332 report_fatal_error("Invalid pseudo instruction");
1333 }
1334 break;
1335
1336 case Hexagon::A2_iconst: {
1337 Inst.setOpcode(Hexagon::A2_addi);
1338 MCOperand Reg = Inst.getOperand(0);
1339 MCOperand S27 = Inst.getOperand(1);
1340 HexagonMCInstrInfo::setMustNotExtend(*S27.getExpr());
1341 HexagonMCInstrInfo::setS27_2_reloc(*S27.getExpr());
1342 Inst.clear();
1343 Inst.addOperand(Reg);
1344 Inst.addOperand(MCOperand::createReg(Hexagon::R0));
1345 Inst.addOperand(S27);
1346 break;
1347 }
1348 case Hexagon::M4_mpyrr_addr:
1349 case Hexagon::S4_addi_asl_ri:
1350 case Hexagon::S4_addi_lsr_ri:
1351 case Hexagon::S4_andi_asl_ri:
1352 case Hexagon::S4_andi_lsr_ri:
1353 case Hexagon::S4_ori_asl_ri:
1354 case Hexagon::S4_ori_lsr_ri:
1355 case Hexagon::S4_or_andix:
1356 case Hexagon::S4_subi_asl_ri:
1357 case Hexagon::S4_subi_lsr_ri: {
1358 MCOperand &Ry = Inst.getOperand(0);
1359 MCOperand &src = Inst.getOperand(2);
1360 if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
1361 return Match_InvalidOperand;
1362 break;
1363 }
1364
1365 case Hexagon::C2_cmpgei: {
1366 MCOperand &MO = Inst.getOperand(2);
1367 MO.setExpr(HexagonMCExpr::create(
1368 MCBinaryExpr::createSub(MO.getExpr(),
1369 MCConstantExpr::create(1, Context), Context),
1370 Context));
1371 Inst.setOpcode(Hexagon::C2_cmpgti);
1372 break;
1373 }
1374
1375 case Hexagon::C2_cmpgeui: {
1376 MCOperand &MO = Inst.getOperand(2);
1377 int64_t Value;
1378 bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
1379 (void)Success;
1380 assert(Success && "Assured by matcher")(static_cast <bool> (Success && "Assured by matcher"
) ? void (0) : __assert_fail ("Success && \"Assured by matcher\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1380, __extension__ __PRETTY_FUNCTION__))
;
1381 if (Value == 0) {
1382 MCInst TmpInst;
1383 MCOperand &Pd = Inst.getOperand(0);
1384 MCOperand &Rt = Inst.getOperand(1);
1385 TmpInst.setOpcode(Hexagon::C2_cmpeq);
1386 TmpInst.addOperand(Pd);
1387 TmpInst.addOperand(Rt);
1388 TmpInst.addOperand(Rt);
1389 Inst = TmpInst;
1390 } else {
1391 MO.setExpr(HexagonMCExpr::create(
1392 MCBinaryExpr::createSub(MO.getExpr(),
1393 MCConstantExpr::create(1, Context), Context),
1394 Context));
1395 Inst.setOpcode(Hexagon::C2_cmpgtui);
1396 }
1397 break;
1398 }
1399
1400 // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1401 case Hexagon::A2_tfrp: {
1402 MCOperand &MO = Inst.getOperand(1);
1403 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1404 std::string R1 = r + utostr(RegPairNum + 1);
1405 StringRef Reg1(R1);
1406 MO.setReg(matchRegister(Reg1));
1407 // Add a new operand for the second register in the pair.
1408 std::string R2 = r + utostr(RegPairNum);
1409 StringRef Reg2(R2);
1410 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1411 Inst.setOpcode(Hexagon::A2_combinew);
1412 break;
1413 }
1414
1415 case Hexagon::A2_tfrpt:
1416 case Hexagon::A2_tfrpf: {
1417 MCOperand &MO = Inst.getOperand(2);
1418 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1419 std::string R1 = r + utostr(RegPairNum + 1);
1420 StringRef Reg1(R1);
1421 MO.setReg(matchRegister(Reg1));
1422 // Add a new operand for the second register in the pair.
1423 std::string R2 = r + utostr(RegPairNum);
1424 StringRef Reg2(R2);
1425 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1426 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
1427 ? Hexagon::C2_ccombinewt
1428 : Hexagon::C2_ccombinewf);
1429 break;
1430 }
1431 case Hexagon::A2_tfrptnew:
1432 case Hexagon::A2_tfrpfnew: {
1433 MCOperand &MO = Inst.getOperand(2);
1434 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1435 std::string R1 = r + utostr(RegPairNum + 1);
1436 StringRef Reg1(R1);
1437 MO.setReg(matchRegister(Reg1));
1438 // Add a new operand for the second register in the pair.
1439 std::string R2 = r + utostr(RegPairNum);
1440 StringRef Reg2(R2);
1441 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1442 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1443 ? Hexagon::C2_ccombinewnewt
1444 : Hexagon::C2_ccombinewnewf);
1445 break;
1446 }
1447
1448 // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
1449 case Hexagon::V6_vassignp: {
1450 MCOperand &MO = Inst.getOperand(1);
1451 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1452 std::string R1 = v + utostr(RegPairNum + 1);
1453 MO.setReg(MatchRegisterName(R1));
1454 // Add a new operand for the second register in the pair.
1455 std::string R2 = v + utostr(RegPairNum);
1456 Inst.addOperand(MCOperand::createReg(MatchRegisterName(R2)));
1457 Inst.setOpcode(Hexagon::V6_vcombine);
1458 break;
1459 }
1460
1461 // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1462 case Hexagon::CONST32:
1463 is32bit = true;
1464 LLVM_FALLTHROUGH[[clang::fallthrough]];
1465 // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
1466 case Hexagon::CONST64:
1467 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1468 if (!Parser.getStreamer().hasRawTextSupport()) {
1469 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
1470 MCOperand &MO_1 = Inst.getOperand(1);
1471 MCOperand &MO_0 = Inst.getOperand(0);
1472
1473 // push section onto section stack
1474 MES->PushSection();
1475
1476 std::string myCharStr;
1477 MCSectionELF *mySection;
1478
1479 // check if this as an immediate or a symbol
1480 int64_t Value;
1481 bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
1482 if (Absolute) {
1483 // Create a new section - one for each constant
1484 // Some or all of the zeros are replaced with the given immediate.
1485 if (is32bit) {
1486 std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
1487 myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
1488 .drop_back(myImmStr.size())
1489 .str() +
1490 myImmStr;
1491 } else {
1492 std::string myImmStr = utohexstr(Value);
1493 myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1494 .drop_back(myImmStr.size())
1495 .str() +
1496 myImmStr;
1497 }
1498
1499 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1500 ELF::SHF_ALLOC | ELF::SHF_WRITE);
1501 } else if (MO_1.isExpr()) {
1502 // .lita - for expressions
1503 myCharStr = ".lita";
1504 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1505 ELF::SHF_ALLOC | ELF::SHF_WRITE);
1506 } else
1507 llvm_unreachable("unexpected type of machine operand!")::llvm::llvm_unreachable_internal("unexpected type of machine operand!"
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1507)
;
1508
1509 MES->SwitchSection(mySection);
1510 unsigned byteSize = is32bit ? 4 : 8;
1511 getStreamer().EmitCodeAlignment(byteSize, byteSize);
1512
1513 MCSymbol *Sym;
1514
1515 // for symbols, get rid of prepended ".gnu.linkonce.lx."
1516
1517 // emit symbol if needed
1518 if (Absolute) {
1519 Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
1520 if (Sym->isUndefined()) {
1521 getStreamer().EmitLabel(Sym);
1522 getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
1523 getStreamer().EmitIntValue(Value, byteSize);
1524 }
1525 } else if (MO_1.isExpr()) {
1526 const char *StringStart = nullptr;
1527 const char *StringEnd = nullptr;
1528 if (*Operands[4]->getStartLoc().getPointer() == '#') {
1529 StringStart = Operands[5]->getStartLoc().getPointer();
1530 StringEnd = Operands[6]->getStartLoc().getPointer();
1531 } else { // no pound
1532 StringStart = Operands[4]->getStartLoc().getPointer();
1533 StringEnd = Operands[5]->getStartLoc().getPointer();
1534 }
1535
1536 unsigned size = StringEnd - StringStart;
1537 std::string DotConst = ".CONST_";
1538 Sym = getContext().getOrCreateSymbol(DotConst +
1539 StringRef(StringStart, size));
1540
1541 if (Sym->isUndefined()) {
1542 // case where symbol is not yet defined: emit symbol
1543 getStreamer().EmitLabel(Sym);
1544 getStreamer().EmitSymbolAttribute(Sym, MCSA_Local);
1545 getStreamer().EmitValue(MO_1.getExpr(), 4);
1546 }
1547 } else
1548 llvm_unreachable("unexpected type of machine operand!")::llvm::llvm_unreachable_internal("unexpected type of machine operand!"
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1548)
;
1549
1550 MES->PopSection();
1551
1552 if (Sym) {
1553 MCInst TmpInst;
1554 if (is32bit) // 32 bit
1555 TmpInst.setOpcode(Hexagon::L2_loadrigp);
1556 else // 64 bit
1557 TmpInst.setOpcode(Hexagon::L2_loadrdgp);
1558
1559 TmpInst.addOperand(MO_0);
1560 TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
1561 MCSymbolRefExpr::create(Sym, getContext()), getContext())));
1562 Inst = TmpInst;
1563 }
1564 }
1565 break;
1566
1567 // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1568 case Hexagon::A2_tfrpi: {
1569 MCOperand &Rdd = Inst.getOperand(0);
1570 MCOperand &MO = Inst.getOperand(1);
1571 int64_t Value;
1572 int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
1573 MCOperand imm(MCOperand::createExpr(
1574 HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
1575 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1576 break;
1577 }
1578
1579 // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1580 case Hexagon::TFRI64_V4: {
1581 MCOperand &Rdd = Inst.getOperand(0);
1582 MCOperand &MO = Inst.getOperand(1);
1583 int64_t Value;
1584 if (MO.getExpr()->evaluateAsAbsolute(Value)) {
1585 int s8 = Hi_32(Value);
1586 if (!isInt<8>(s8))
1587 OutOfRange(IDLoc, s8, -128);
1588 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
1589 MCConstantExpr::create(s8, Context), Context))); // upper 32
1590 auto Expr = HexagonMCExpr::create(
1591 MCConstantExpr::create(Lo_32(Value), Context), Context);
1592 HexagonMCInstrInfo::setMustExtend(
1593 *Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
1594 MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
1595 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1596 } else {
1597 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
1598 MCConstantExpr::create(0, Context), Context))); // upper 32
1599 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1600 }
1601 break;
1602 }
1603
1604 // Handle $Rdd = combine(##imm, #imm)"
1605 case Hexagon::TFRI64_V2_ext: {
1606 MCOperand &Rdd = Inst.getOperand(0);
1607 MCOperand &MO1 = Inst.getOperand(1);
1608 MCOperand &MO2 = Inst.getOperand(2);
1609 int64_t Value;
1610 if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
1611 int s8 = Value;
1612 if (s8 < -128 || s8 > 127)
1613 OutOfRange(IDLoc, s8, -128);
1614 }
1615 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
1616 break;
1617 }
1618
1619 // Handle $Rdd = combine(#imm, ##imm)"
1620 case Hexagon::A4_combineii: {
1621 MCOperand &Rdd = Inst.getOperand(0);
1622 MCOperand &MO1 = Inst.getOperand(1);
1623 int64_t Value;
1624 if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
1625 int s8 = Value;
1626 if (s8 < -128 || s8 > 127)
1627 OutOfRange(IDLoc, s8, -128);
1628 }
1629 MCOperand &MO2 = Inst.getOperand(2);
1630 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
1631 break;
1632 }
1633
1634 case Hexagon::S2_tableidxb_goodsyntax:
1635 Inst.setOpcode(Hexagon::S2_tableidxb);
1636 break;
1637
1638 case Hexagon::S2_tableidxh_goodsyntax: {
1639 MCInst TmpInst;
1640 MCOperand &Rx = Inst.getOperand(0);
1641 MCOperand &Rs = Inst.getOperand(2);
1642 MCOperand &Imm4 = Inst.getOperand(3);
1643 MCOperand &Imm6 = Inst.getOperand(4);
1644 Imm6.setExpr(HexagonMCExpr::create(
1645 MCBinaryExpr::createSub(Imm6.getExpr(),
1646 MCConstantExpr::create(1, Context), Context),
1647 Context));
1648 TmpInst.setOpcode(Hexagon::S2_tableidxh);
1649 TmpInst.addOperand(Rx);
1650 TmpInst.addOperand(Rx);
1651 TmpInst.addOperand(Rs);
1652 TmpInst.addOperand(Imm4);
1653 TmpInst.addOperand(Imm6);
1654 Inst = TmpInst;
1655 break;
1656 }
1657
1658 case Hexagon::S2_tableidxw_goodsyntax: {
1659 MCInst TmpInst;
1660 MCOperand &Rx = Inst.getOperand(0);
1661 MCOperand &Rs = Inst.getOperand(2);
1662 MCOperand &Imm4 = Inst.getOperand(3);
1663 MCOperand &Imm6 = Inst.getOperand(4);
1664 Imm6.setExpr(HexagonMCExpr::create(
1665 MCBinaryExpr::createSub(Imm6.getExpr(),
1666 MCConstantExpr::create(2, Context), Context),
1667 Context));
1668 TmpInst.setOpcode(Hexagon::S2_tableidxw);
1669 TmpInst.addOperand(Rx);
1670 TmpInst.addOperand(Rx);
1671 TmpInst.addOperand(Rs);
1672 TmpInst.addOperand(Imm4);
1673 TmpInst.addOperand(Imm6);
1674 Inst = TmpInst;
1675 break;
1676 }
1677
1678 case Hexagon::S2_tableidxd_goodsyntax: {
1679 MCInst TmpInst;
1680 MCOperand &Rx = Inst.getOperand(0);
1681 MCOperand &Rs = Inst.getOperand(2);
1682 MCOperand &Imm4 = Inst.getOperand(3);
1683 MCOperand &Imm6 = Inst.getOperand(4);
1684 Imm6.setExpr(HexagonMCExpr::create(
1685 MCBinaryExpr::createSub(Imm6.getExpr(),
1686 MCConstantExpr::create(3, Context), Context),
1687 Context));
1688 TmpInst.setOpcode(Hexagon::S2_tableidxd);
1689 TmpInst.addOperand(Rx);
1690 TmpInst.addOperand(Rx);
1691 TmpInst.addOperand(Rs);
1692 TmpInst.addOperand(Imm4);
1693 TmpInst.addOperand(Imm6);
1694 Inst = TmpInst;
1695 break;
1696 }
1697
1698 case Hexagon::M2_mpyui:
1699 Inst.setOpcode(Hexagon::M2_mpyi);
1700 break;
1701 case Hexagon::M2_mpysmi: {
1702 MCInst TmpInst;
1703 MCOperand &Rd = Inst.getOperand(0);
1704 MCOperand &Rs = Inst.getOperand(1);
1705 MCOperand &Imm = Inst.getOperand(2);
1706 int64_t Value;
1707 MCExpr const &Expr = *Imm.getExpr();
1708 bool Absolute = Expr.evaluateAsAbsolute(Value);
1709 assert(Absolute)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1709, __extension__ __PRETTY_FUNCTION__))
;
1710 (void)Absolute;
1711 if (!HexagonMCInstrInfo::mustExtend(Expr) &&
1712 ((Value <= -256) || Value >= 256))
1713 return Match_InvalidOperand;
1714 if (Value < 0 && Value > -256) {
1715 Imm.setExpr(HexagonMCExpr::create(
1716 MCConstantExpr::create(Value * -1, Context), Context));
1717 TmpInst.setOpcode(Hexagon::M2_mpysin);
1718 } else
1719 TmpInst.setOpcode(Hexagon::M2_mpysip);
1720 TmpInst.addOperand(Rd);
1721 TmpInst.addOperand(Rs);
1722 TmpInst.addOperand(Imm);
1723 Inst = TmpInst;
1724 break;
1725 }
1726
1727 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1728 MCOperand &Imm = Inst.getOperand(2);
1729 MCInst TmpInst;
1730 int64_t Value;
1731 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1732 assert(Absolute)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1732, __extension__ __PRETTY_FUNCTION__))
;
1733 (void)Absolute;
1734 if (Value == 0) { // convert to $Rd = $Rs
1735 TmpInst.setOpcode(Hexagon::A2_tfr);
1736 MCOperand &Rd = Inst.getOperand(0);
1737 MCOperand &Rs = Inst.getOperand(1);
1738 TmpInst.addOperand(Rd);
1739 TmpInst.addOperand(Rs);
1740 } else {
1741 Imm.setExpr(HexagonMCExpr::create(
1742 MCBinaryExpr::createSub(Imm.getExpr(),
1743 MCConstantExpr::create(1, Context), Context),
1744 Context));
1745 TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
1746 MCOperand &Rd = Inst.getOperand(0);
1747 MCOperand &Rs = Inst.getOperand(1);
1748 TmpInst.addOperand(Rd);
1749 TmpInst.addOperand(Rs);
1750 TmpInst.addOperand(Imm);
1751 }
1752 Inst = TmpInst;
1753 break;
1754 }
1755
1756 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1757 MCOperand &Rdd = Inst.getOperand(0);
1758 MCOperand &Rss = Inst.getOperand(1);
1759 MCOperand &Imm = Inst.getOperand(2);
1760 int64_t Value;
1761 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1762 assert(Absolute)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1762, __extension__ __PRETTY_FUNCTION__))
;
1763 (void)Absolute;
1764 if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1765 MCInst TmpInst;
1766 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1767 std::string R1 = r + utostr(RegPairNum + 1);
1768 StringRef Reg1(R1);
1769 Rss.setReg(matchRegister(Reg1));
1770 // Add a new operand for the second register in the pair.
1771 std::string R2 = r + utostr(RegPairNum);
1772 StringRef Reg2(R2);
1773 TmpInst.setOpcode(Hexagon::A2_combinew);
1774 TmpInst.addOperand(Rdd);
1775 TmpInst.addOperand(Rss);
1776 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1777 Inst = TmpInst;
1778 } else {
1779 Imm.setExpr(HexagonMCExpr::create(
1780 MCBinaryExpr::createSub(Imm.getExpr(),
1781 MCConstantExpr::create(1, Context), Context),
1782 Context));
1783 Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
1784 }
1785 break;
1786 }
1787
1788 case Hexagon::A4_boundscheck: {
1789 MCOperand &Rs = Inst.getOperand(1);
1790 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1791 if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
1792 Inst.setOpcode(Hexagon::A4_boundscheck_hi);
1793 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1794 StringRef RegPair = Name;
1795 Rs.setReg(matchRegister(RegPair));
1796 } else { // raw:lo
1797 Inst.setOpcode(Hexagon::A4_boundscheck_lo);
1798 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1799 StringRef RegPair = Name;
1800 Rs.setReg(matchRegister(RegPair));
1801 }
1802 break;
1803 }
1804
1805 case Hexagon::A2_addsp: {
1806 MCOperand &Rs = Inst.getOperand(1);
1807 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1808 if (RegNum & 1) { // Odd mapped to raw:hi
1809 Inst.setOpcode(Hexagon::A2_addsph);
1810 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1811 StringRef RegPair = Name;
1812 Rs.setReg(matchRegister(RegPair));
1813 } else { // Even mapped raw:lo
1814 Inst.setOpcode(Hexagon::A2_addspl);
1815 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1816 StringRef RegPair = Name;
1817 Rs.setReg(matchRegister(RegPair));
1818 }
1819 break;
1820 }
1821
1822 case Hexagon::M2_vrcmpys_s1: {
1823 MCOperand &Rt = Inst.getOperand(2);
1824 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1825 if (RegNum & 1) { // Odd mapped to sat:raw:hi
1826 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
1827 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1828 StringRef RegPair = Name;
1829 Rt.setReg(matchRegister(RegPair));
1830 } else { // Even mapped sat:raw:lo
1831 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
1832 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1833 StringRef RegPair = Name;
1834 Rt.setReg(matchRegister(RegPair));
1835 }
1836 break;
1837 }
1838
1839 case Hexagon::M2_vrcmpys_acc_s1: {
1840 MCInst TmpInst;
1841 MCOperand &Rxx = Inst.getOperand(0);
1842 MCOperand &Rss = Inst.getOperand(2);
1843 MCOperand &Rt = Inst.getOperand(3);
1844 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1845 if (RegNum & 1) { // Odd mapped to sat:raw:hi
1846 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
1847 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1848 StringRef RegPair = Name;
1849 Rt.setReg(matchRegister(RegPair));
1850 } else { // Even mapped sat:raw:lo
1851 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
1852 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1853 StringRef RegPair = Name;
1854 Rt.setReg(matchRegister(RegPair));
1855 }
1856 // Registers are in different positions
1857 TmpInst.addOperand(Rxx);
1858 TmpInst.addOperand(Rxx);
1859 TmpInst.addOperand(Rss);
1860 TmpInst.addOperand(Rt);
1861 Inst = TmpInst;
1862 break;
1863 }
1864
1865 case Hexagon::M2_vrcmpys_s1rp: {
1866 MCOperand &Rt = Inst.getOperand(2);
1867 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1868 if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
1869 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
1870 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1871 StringRef RegPair = Name;
1872 Rt.setReg(matchRegister(RegPair));
1873 } else { // Even mapped rnd:sat:raw:lo
1874 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
1875 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1876 StringRef RegPair = Name;
1877 Rt.setReg(matchRegister(RegPair));
1878 }
1879 break;
1880 }
1881
1882 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1883 MCOperand &Imm = Inst.getOperand(2);
1884 int64_t Value;
1885 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1886 assert(Absolute)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1886, __extension__ __PRETTY_FUNCTION__))
;
1887 (void)Absolute;
1888 if (Value == 0)
1889 Inst.setOpcode(Hexagon::S2_vsathub);
1890 else {
1891 Imm.setExpr(HexagonMCExpr::create(
1892 MCBinaryExpr::createSub(Imm.getExpr(),
1893 MCConstantExpr::create(1, Context), Context),
1894 Context));
1895 Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
1896 }
1897 break;
1898 }
1899
1900 case Hexagon::S5_vasrhrnd_goodsyntax: {
1901 MCOperand &Rdd = Inst.getOperand(0);
1902 MCOperand &Rss = Inst.getOperand(1);
1903 MCOperand &Imm = Inst.getOperand(2);
1904 int64_t Value;
1905 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1906 assert(Absolute)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn325118/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1906, __extension__ __PRETTY_FUNCTION__))
;
1907 (void)Absolute;
1908 if (Value == 0) {
1909 MCInst TmpInst;
1910 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1911 std::string R1 = r + utostr(RegPairNum + 1);
1912 StringRef Reg1(R1);
1913 Rss.setReg(matchRegister(Reg1));
1914 // Add a new operand for the second register in the pair.
1915 std::string R2 = r + utostr(RegPairNum);
1916 StringRef Reg2(R2);
1917 TmpInst.setOpcode(Hexagon::A2_combinew);
1918 TmpInst.addOperand(Rdd);
1919 TmpInst.addOperand(Rss);
1920 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1921 Inst = TmpInst;
1922 } else {
1923 Imm.setExpr(HexagonMCExpr::create(
1924 MCBinaryExpr::createSub(Imm.getExpr(),
1925 MCConstantExpr::create(1, Context), Context),
1926 Context));
1927 Inst.setOpcode(Hexagon::S5_vasrhrnd);
1928 }
1929 break;
1930 }
1931
1932 case Hexagon::A2_not: {
1933 MCInst TmpInst;
1934 MCOperand &Rd = Inst.getOperand(0);
1935 MCOperand &Rs = Inst.getOperand(1);
1936 TmpInst.setOpcode(Hexagon::A2_subri);
1937 TmpInst.addOperand(Rd);
1938 TmpInst.addOperand(MCOperand::createExpr(
1939 HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
1940 TmpInst.addOperand(Rs);
1941 Inst = TmpInst;
1942 break;
1943 }
1944 case Hexagon::PS_loadrubabs:
1945 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1946 Inst.setOpcode(Hexagon::L2_loadrubgp);
1947 break;
1948 case Hexagon::PS_loadrbabs:
1949 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1950 Inst.setOpcode(Hexagon::L2_loadrbgp);
1951 break;
1952 case Hexagon::PS_loadruhabs:
1953 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1954 Inst.setOpcode(Hexagon::L2_loadruhgp);
1955 break;
1956 case Hexagon::PS_loadrhabs:
1957 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1958 Inst.setOpcode(Hexagon::L2_loadrhgp);
1959 break;
1960 case Hexagon::PS_loadriabs:
1961 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1962 Inst.setOpcode(Hexagon::L2_loadrigp);
1963 break;
1964 case Hexagon::PS_loadrdabs:
1965 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1966 Inst.setOpcode(Hexagon::L2_loadrdgp);
1967 break;
1968 case Hexagon::PS_storerbabs:
1969 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1970 Inst.setOpcode(Hexagon::S2_storerbgp);
1971 break;
1972 case Hexagon::PS_storerhabs:
1973 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1974 Inst.setOpcode(Hexagon::S2_storerhgp);
1975 break;
1976 case Hexagon::PS_storerfabs:
1977 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1978 Inst.setOpcode(Hexagon::S2_storerfgp);
1979 break;
1980 case Hexagon::PS_storeriabs:
1981 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1982 Inst.setOpcode(Hexagon::S2_storerigp);
1983 break;
1984 case Hexagon::PS_storerdabs:
1985 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1986 Inst.setOpcode(Hexagon::S2_storerdgp);
1987 break;
1988 case Hexagon::PS_storerbnewabs:
1989 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1990 Inst.setOpcode(Hexagon::S2_storerbnewgp);
1991 break;
1992 case Hexagon::PS_storerhnewabs:
1993 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1994 Inst.setOpcode(Hexagon::S2_storerhnewgp);
1995 break;
1996 case Hexagon::PS_storerinewabs:
1997 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1998 Inst.setOpcode(Hexagon::S2_storerinewgp);
1999 break;
2000 case Hexagon::A2_zxtb: {
2001 Inst.setOpcode(Hexagon::A2_andir);
2002 Inst.addOperand(
2003 MCOperand::createExpr(MCConstantExpr::create(255, Context)));
2004 break;
2005 }
2006 } // switch
2007
2008 return Match_Success;
2009}
2010
2011unsigned HexagonAsmParser::matchRegister(StringRef Name) {
2012 if (unsigned Reg = MatchRegisterName(Name))
2013 return Reg;
2014 return MatchRegisterAltName(Name);
2015}