Bug Summary

File:lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
Warning:line 637, 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~svn329677/build-llvm/lib/Target/Hexagon/AsmParser -I /build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser -I /build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/lib/Target/Hexagon -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/lib/Target/Hexagon/AsmParser/.. -I /build/llvm-toolchain-snapshot-7~svn329677/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~svn329677/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-04-11-031539-24776-1 -x c++ /build/llvm-toolchain-snapshot-7~svn329677/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~svn329677/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~svn329677/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~svn329677/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~svn329677/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~svn329677/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~svn329677/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~svn329677/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~svn329677/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~svn329677/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~svn329677/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("endloop01") == 0) {
510 HexagonMCInstrInfo::setInnerLoop(MCB);
511 HexagonMCInstrInfo::setOuterLoop(MCB);
512 } 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) {
517 if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf])
518 HexagonMCInstrInfo::setMemReorderDisabled(MCB);
519 else
520 return getParser().Error(IDLoc, MemNoShuffMsg);
521 } else
522 return getParser().Error(IDLoc, llvm::Twine("'") + Option +
523 "' is not a valid bundle option");
524 Lex();
525 }
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()) {
536 int64_t Value(I.getImm());
537 NewInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
538 MCConstantExpr::create(Value, getContext()), getContext())));
539 } else {
540 if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
541 WarnSignedMismatch)
542 Warning(MCI.getLoc(), "Signed/Unsigned mismatch");
543 NewInst.addOperand(I);
544 }
545 MCI = NewInst;
546}
547
548bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
549 OperandVector &InstOperands,
550 uint64_t &ErrorInfo,
551 bool MatchingInlineAsm) {
552 // 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);
557 canonicalizeImmediates(MCI);
558 result = processInstruction(MCI, InstOperands, IDLoc);
559
560 DEBUG(dbgs() << "Insn:")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "Insn:"; } } while (false)
;
561 DEBUG(MCI.dump_pretty(dbgs()))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { MCI.dump_pretty(dbgs()); } } while (false)
;
562 DEBUG(dbgs() << "\n\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "\n\n"; } } while (false)
;
563
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!")::llvm::llvm_unreachable_internal("Implement any new match types added!"
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 593)
;
594}
595
596void HexagonAsmParser::eatToEndOfPacket() {
597 assert(InBrackets)(static_cast <bool> (InBrackets) ? void (0) : __assert_fail
("InBrackets", "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 597, __extension__ __PRETTY_FUNCTION__))
;
598 MCAsmLexer &Lexer = getLexer();
599 while (!Lexer.is(AsmToken::RCurly))
600 Lexer.Lex();
601 Lexer.Lex();
602 InBrackets = false;
603}
604
605bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
606 OperandVector &Operands,
607 MCStreamer &Out,
608 uint64_t &ErrorInfo,
609 bool MatchingInlineAsm) {
610 if (!InBrackets) {
1
Assuming the condition is false
2
Taking false branch
611 MCB.clear();
612 MCB.addOperand(MCOperand::createImm(0));
613 }
614 HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
615 if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
3
Assuming the condition is false
4
Taking false branch
616 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~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 616, __extension__ __PRETTY_FUNCTION__))
;
617 if (InBrackets) {
618 getParser().Error(IDLoc, "Already in a packet");
619 InBrackets = false;
620 return true;
621 }
622 InBrackets = true;
623 return false;
624 }
625 if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
5
Assuming the condition is false
6
Taking false branch
626 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~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 626, __extension__ __PRETTY_FUNCTION__))
;
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;
7
'SubInst' initialized to a null pointer value
637 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
8
Forming reference to null pointer
638 MatchingInlineAsm)) {
639 if (InBrackets)
640 eatToEndOfPacket();
641 return true;
642 }
643 HexagonMCInstrInfo::extendIfNeeded(
644 getParser().getContext(), MII, MCB, *SubInst);
645 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) {
671 const MCExpr *Subsection = nullptr;
672 int64_t Res;
673
674 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~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 675, __extension__ __PRETTY_FUNCTION__))
675 "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~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 675, __extension__ __PRETTY_FUNCTION__))
;
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))
689 Subsection = HexagonMCExpr::create(
690 MCConstantExpr::create(8192 + Res, getContext()), getContext());
691
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
701 // if there is an argument
702 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)
707 if (!getParser().parseExpression(Value)) {
708 // 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)) {
729 while (true) {
730 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")(static_cast <bool> (Size <= 8 && "Invalid size"
) ? void (0) : __assert_fail ("Size <= 8 && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 737, __extension__ __PRETTY_FUNCTION__))
;
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 {
847 if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))
848 if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
849 return false;
850 return true;
851}
852
853// extern "C" void LLVMInitializeHexagonAsmLexer();
854
855/// Force static initialization.
856extern "C" void LLVMInitializeHexagonAsmParser() {
857 RegisterMCAsmParser<HexagonAsmParser> X(getTheHexagonTarget());
858}
859
860#define GET_MATCHER_IMPLEMENTATION
861#define GET_REGISTER_MATCHER
862#include "HexagonGenAsmMatcher.inc"
863
864static bool previousEqual(OperandVector &Operands, size_t Index,
865 StringRef String) {
866 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}
873
874static bool previousIsLoop(OperandVector &Operands, size_t Index) {
875 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}
881
882bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
883 AsmToken const &Token = getParser().getTok();
884 StringRef String = Token.getString();
885 SMLoc Loc = Token.getLoc();
886 Lex();
887 do {
888 std::pair<StringRef, StringRef> HeadTail = String.split('.');
889 if (!HeadTail.first.empty())
890 Operands.push_back(
891 HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
892 if (!HeadTail.second.empty())
893 Operands.push_back(HexagonOperand::CreateToken(
894 getContext(), String.substr(HeadTail.first.size(), 1), Loc));
895 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)
916 Warning(Begin, "Missing parenthesis around predicate register");
917 static char const *LParen = "(";
918 static char const *RParen = ")";
919 Operands.push_back(
920 HexagonOperand::CreateToken(getContext(), LParen, Begin));
921 Operands.push_back(
922 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
923 const AsmToken &MaybeDotNew = Lexer.getTok();
924 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
925 MaybeDotNew.getString().equals_lower(".new"))
926 splitIdentifier(Operands);
927 Operands.push_back(
928 HexagonOperand::CreateToken(getContext(), RParen, Begin));
929 return false;
930 }
931 if (previousEqual(Operands, 0, "!") &&
932 previousEqual(Operands, 1, "if")) {
933 if (WarnMissingParenthesis)
934 Warning(Begin, "Missing parenthesis around predicate register");
935 static char const *LParen = "(";
936 static char const *RParen = ")";
937 Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(
938 getContext(), LParen, Begin));
939 Operands.push_back(
940 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
941 const AsmToken &MaybeDotNew = Lexer.getTok();
942 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
943 MaybeDotNew.getString().equals_lower(".new"))
944 splitIdentifier(Operands);
945 Operands.push_back(
946 HexagonOperand::CreateToken(getContext(), RParen, Begin));
947 return false;
948 }
949 break;
950 }
951 Operands.push_back(
952 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
953 return false;
954 }
955 return splitIdentifier(Operands);
956}
957
958bool HexagonAsmParser::isLabel(AsmToken &Token) {
959 MCAsmLexer &Lexer = getLexer();
960 AsmToken const &Second = Lexer.getTok();
961 AsmToken Third = Lexer.peekTok();
962 StringRef String = Token.getString();
963 if (Token.is(AsmToken::TokenKind::LCurly) ||
964 Token.is(AsmToken::TokenKind::RCurly))
965 return false;
966 // special case for parsing vwhist256:sat
967 if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&
968 Third.getString().lower() == "sat")
969 return false;
970 if (!Token.is(AsmToken::TokenKind::Identifier))
971 return true;
972 if (!matchRegister(String.lower()))
973 return true;
974 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~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 974, __extension__ __PRETTY_FUNCTION__))
;
975 StringRef Raw(String.data(), Third.getString().data() - String.data() +
976 Third.getString().size());
977 std::string Collapsed = Raw;
978 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
979 StringRef Whole = Collapsed;
980 std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
981 if (!matchRegister(DotSplit.first.lower()))
982 return true;
983 return false;
984}
985
986bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,
987 SMLoc &Loc) {
988 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
997bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
998 SMLoc &EndLoc) {
999 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();
1007 RawString = StringRef(RawString.data(), Token.getString().data() -
1008 RawString.data() +
1009 Token.getString().size());
1010 Lookahead.push_back(Token);
1011 Lexer.Lex();
1012 bool Contigious = Lexer.getTok().getString().data() ==
1013 Lookahead.back().getString().data() +
1014 Lookahead.back().getString().size();
1015 bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
1016 Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
1017 Lexer.is(AsmToken::Colon);
1018 bool Workaround =
1019 Lexer.is(AsmToken::Colon) || Lookahead.back().is(AsmToken::Colon);
1020 Again = (Contigious && Type) || (Workaround && Type);
1021 NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
1022 }
1023 std::string Collapsed = RawString;
1024 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
1025 StringRef FullString = Collapsed;
1026 std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
1027 unsigned DotReg = matchRegister(DotSplit.first.lower());
1028 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(':');
1047 unsigned ColonReg = matchRegister(ColonSplit.first.lower());
1048 if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1049 do {
1050 Lexer.UnLex(Lookahead.back());
1051 Lookahead.pop_back();
1052 } while (!Lookahead.empty () && !Lexer.is(AsmToken::Colon));
1053 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
1080bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {
1081 SmallVector<AsmToken, 4> Tokens;
1082 MCAsmLexer &Lexer = getLexer();
1083 bool Done = false;
1084 static char const *Comma = ",";
1085 do {
1086 Tokens.emplace_back(Lexer.getTok());
1087 Lex();
1088 switch (Tokens.back().getKind()) {
1089 case AsmToken::TokenKind::Hash:
1090 if (Tokens.size() > 1)
1091 if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
1092 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 }
1110 SMLoc Loc = Lexer.getLoc();
1111 return getParser().parseExpression(Expr, Loc);
1112}
1113
1114bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1115 if (implicitExpressionLocation(Operands)) {
1116 MCAsmParser &Parser = getParser();
1117 SMLoc Loc = Parser.getLexer().getLoc();
1118 MCExpr const *Expr = nullptr;
1119 bool Error = parseExpression(Expr);
1120 Expr = HexagonMCExpr::create(Expr, getContext());
1121 if (!Error)
1122 Operands.push_back(
1123 HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
1124 return Error;
1125 }
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()) {
1136 case AsmToken::Eof:
1137 case AsmToken::EndOfStatement: {
1138 Lex();
1139 return false;
1140 }
1141 case AsmToken::LCurly: {
1142 if (!Operands.empty())
1143 return true;
1144 Operands.push_back(HexagonOperand::CreateToken(
1145 getContext(), Token.getString(), Token.getLoc()));
1146 Lex();
1147 return false;
1148 }
1149 case AsmToken::RCurly: {
1150 if (Operands.empty()) {
1151 Operands.push_back(HexagonOperand::CreateToken(
1152 getContext(), Token.getString(), Token.getLoc()));
1153 Lex();
1154 }
1155 return false;
1156 }
1157 case AsmToken::Comma: {
1158 Lex();
1159 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(
1168 getContext(), Token.getString().substr(0, 1), Token.getLoc()));
1169 Operands.push_back(HexagonOperand::CreateToken(
1170 getContext(), Token.getString().substr(1, 1), Token.getLoc()));
1171 Lex();
1172 continue;
1173 }
1174 case AsmToken::Hash: {
1175 bool MustNotExtend = false;
1176 bool ImplicitExpression = implicitExpressionLocation(Operands);
1177 SMLoc ExprLoc = Lexer.getLoc();
1178 if (!ImplicitExpression)
1179 Operands.push_back(HexagonOperand::CreateToken(
1180 getContext(), Token.getString(), Token.getLoc()));
1181 Lex();
1182 bool MustExtend = false;
1183 bool HiOnly = false;
1184 bool LoOnly = false;
1185 if (Lexer.is(AsmToken::Hash)) {
1186 Lex();
1187 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();
1193 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 {
1204 Lex();
1205 }
1206 }
1207 }
1208 MCExpr const *Expr = nullptr;
1209 if (parseExpression(Expr))
1210 return true;
1211 int64_t Value;
1212 MCContext &Context = Parser.getContext();
1213 assert(Expr != nullptr)(static_cast <bool> (Expr != nullptr) ? void (0) : __assert_fail
("Expr != nullptr", "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1213, __extension__ __PRETTY_FUNCTION__))
;
1214 if (Expr->evaluateAsAbsolute(Value)) {
1215 if (HiOnly)
1216 Expr = MCBinaryExpr::createLShr(
1217 Expr, MCConstantExpr::create(16, Context), Context);
1218 if (HiOnly || LoOnly)
1219 Expr = MCBinaryExpr::createAnd(
1220 Expr, MCConstantExpr::create(0xffff, Context), Context);
1221 } else {
1222 MCValue Value;
1223 if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
1224 if (!Value.isAbsolute()) {
1225 switch (Value.getAccessVariant()) {
1226 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 }
1236 }
1237 Expr = HexagonMCExpr::create(Expr, Context);
1238 HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
1239 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
1240 std::unique_ptr<HexagonOperand> Operand =
1241 HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
1242 Operands.push_back(std::move(Operand));
1243 continue;
1244 }
1245 default:
1246 break;
1247 }
1248 if (parseExpressionOrOperand(Operands))
1249 return true;
1250 }
1251}
1252
1253bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1254 StringRef Name, AsmToken ID,
1255 OperandVector &Operands) {
1256 getLexer().UnLex(ID);
1257 return parseInstruction(Operands);
1258}
1259
1260static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,
1261 MCOperand &MO2) {
1262 MCInst TmpInst;
1263 TmpInst.setOpcode(opCode);
1264 TmpInst.addOperand(Rdd);
1265 TmpInst.addOperand(MO1);
1266 TmpInst.addOperand(MO2);
1267
1268 return TmpInst;
1269}
1270
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 }
1290 }
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
1299 DEBUG(dbgs() << "Unmatched Operand:")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "Unmatched Operand:"; } } while
(false)
;
1300 DEBUG(Op->dump())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { Op->dump(); } } while (false)
;
1301 DEBUG(dbgs() << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mcasmparser")) { dbgs() << "\n"; } } while (false)
;
1302
1303 return Match_InvalidOperand;
1304}
1305
1306// FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
1307bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
1308 std::string errStr;
1309 raw_string_ostream ES(errStr);
1310 ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
1311 if (Max >= 0)
1312 ES << "0-" << Max;
1313 else
1314 ES << Max << "-" << (-Max - 1);
1315 return Parser.printError(IDLoc, ES.str());
1316}
1317
1318int HexagonAsmParser::processInstruction(MCInst &Inst,
1319 OperandVector const &Operands,
1320 SMLoc IDLoc) {
1321 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:
1330 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 }
1337 break;
1338
1339 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
1350 case Hexagon::A2_iconst: {
1351 Inst.setOpcode(Hexagon::A2_addi);
1352 MCOperand Reg = Inst.getOperand(0);
1353 MCOperand S27 = Inst.getOperand(1);
1354 HexagonMCInstrInfo::setMustNotExtend(*S27.getExpr());
1355 HexagonMCInstrInfo::setS27_2_reloc(*S27.getExpr());
1356 Inst.clear();
1357 Inst.addOperand(Reg);
1358 Inst.addOperand(MCOperand::createReg(Hexagon::R0));
1359 Inst.addOperand(S27);
1360 break;
1361 }
1362 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);
1381 MO.setExpr(HexagonMCExpr::create(
1382 MCBinaryExpr::createSub(MO.getExpr(),
1383 MCConstantExpr::create(1, Context), Context),
1384 Context));
1385 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);
1393 (void)Success;
1394 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~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1394, __extension__ __PRETTY_FUNCTION__))
;
1395 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 {
1405 MO.setExpr(HexagonMCExpr::create(
1406 MCBinaryExpr::createSub(MO.getExpr(),
1407 MCConstantExpr::create(1, Context), Context),
1408 Context));
1409 Inst.setOpcode(Hexagon::C2_cmpgtui);
1410 }
1411 break;
1412 }
1413
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());
1418 std::string R1 = r + utostr(RegPairNum + 1);
1419 StringRef Reg1(R1);
1420 MO.setReg(matchRegister(Reg1));
1421 // Add a new operand for the second register in the pair.
1422 std::string R2 = r + utostr(RegPairNum);
1423 StringRef Reg2(R2);
1424 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1425 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());
1433 std::string R1 = r + utostr(RegPairNum + 1);
1434 StringRef Reg1(R1);
1435 MO.setReg(matchRegister(Reg1));
1436 // Add a new operand for the second register in the pair.
1437 std::string R2 = r + utostr(RegPairNum);
1438 StringRef Reg2(R2);
1439 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1440 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());
1449 std::string R1 = r + utostr(RegPairNum + 1);
1450 StringRef Reg1(R1);
1451 MO.setReg(matchRegister(Reg1));
1452 // Add a new operand for the second register in the pair.
1453 std::string R2 = r + utostr(RegPairNum);
1454 StringRef Reg2(R2);
1455 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1456 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1457 ? Hexagon::C2_ccombinewnewt
1458 : Hexagon::C2_ccombinewnewf);
1459 break;
1460 }
1461
1462 // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
1463 case Hexagon::V6_vassignp: {
1464 MCOperand &MO = Inst.getOperand(1);
1465 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1466 std::string R1 = v + utostr(RegPairNum + 1);
1467 MO.setReg(MatchRegisterName(R1));
1468 // Add a new operand for the second register in the pair.
1469 std::string R2 = v + utostr(RegPairNum);
1470 Inst.addOperand(MCOperand::createReg(MatchRegisterName(R2)));
1471 Inst.setOpcode(Hexagon::V6_vcombine);
1472 break;
1473 }
1474
1475 // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1476 case Hexagon::CONST32:
1477 is32bit = true;
1478 LLVM_FALLTHROUGH[[clang::fallthrough]];
1479 // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
1480 case Hexagon::CONST64:
1481 // 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!")::llvm::llvm_unreachable_internal("unexpected type of machine operand!"
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1521)
;
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()) {
1540 const char *StringStart = nullptr;
1541 const char *StringEnd = nullptr;
1542 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!")::llvm::llvm_unreachable_internal("unexpected type of machine operand!"
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1562)
;
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);
1574 TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
1575 MCSymbolRefExpr::create(Sym, getContext()), getContext())));
1576 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;
1587 MCOperand imm(MCOperand::createExpr(
1588 HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
1589 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)) {
1599 int s8 = Hi_32(Value);
1600 if (!isInt<8>(s8))
1601 OutOfRange(IDLoc, s8, -128);
1602 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
1603 MCConstantExpr::create(s8, Context), Context))); // upper 32
1604 auto Expr = HexagonMCExpr::create(
1605 MCConstantExpr::create(Lo_32(Value), Context), Context);
1606 HexagonMCInstrInfo::setMustExtend(
1607 *Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
1608 MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
1609 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1610 } else {
1611 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
1612 MCConstantExpr::create(0, Context), Context))); // upper 32
1613 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
1648 case Hexagon::S2_tableidxb_goodsyntax:
1649 Inst.setOpcode(Hexagon::S2_tableidxb);
1650 break;
1651
1652 case Hexagon::S2_tableidxh_goodsyntax: {
1653 MCInst TmpInst;
1654 MCOperand &Rx = Inst.getOperand(0);
1655 MCOperand &Rs = Inst.getOperand(2);
1656 MCOperand &Imm4 = Inst.getOperand(3);
1657 MCOperand &Imm6 = Inst.getOperand(4);
1658 Imm6.setExpr(HexagonMCExpr::create(
1659 MCBinaryExpr::createSub(Imm6.getExpr(),
1660 MCConstantExpr::create(1, Context), Context),
1661 Context));
1662 TmpInst.setOpcode(Hexagon::S2_tableidxh);
1663 TmpInst.addOperand(Rx);
1664 TmpInst.addOperand(Rx);
1665 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);
1675 MCOperand &Rs = Inst.getOperand(2);
1676 MCOperand &Imm4 = Inst.getOperand(3);
1677 MCOperand &Imm6 = Inst.getOperand(4);
1678 Imm6.setExpr(HexagonMCExpr::create(
1679 MCBinaryExpr::createSub(Imm6.getExpr(),
1680 MCConstantExpr::create(2, Context), Context),
1681 Context));
1682 TmpInst.setOpcode(Hexagon::S2_tableidxw);
1683 TmpInst.addOperand(Rx);
1684 TmpInst.addOperand(Rx);
1685 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);
1695 MCOperand &Rs = Inst.getOperand(2);
1696 MCOperand &Imm4 = Inst.getOperand(3);
1697 MCOperand &Imm6 = Inst.getOperand(4);
1698 Imm6.setExpr(HexagonMCExpr::create(
1699 MCBinaryExpr::createSub(Imm6.getExpr(),
1700 MCConstantExpr::create(3, Context), Context),
1701 Context));
1702 TmpInst.setOpcode(Hexagon::S2_tableidxd);
1703 TmpInst.addOperand(Rx);
1704 TmpInst.addOperand(Rx);
1705 TmpInst.addOperand(Rs);
1706 TmpInst.addOperand(Imm4);
1707 TmpInst.addOperand(Imm6);
1708 Inst = TmpInst;
1709 break;
1710 }
1711
1712 case Hexagon::M2_mpyui:
1713 Inst.setOpcode(Hexagon::M2_mpyi);
1714 break;
1715 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;
1721 MCExpr const &Expr = *Imm.getExpr();
1722 bool Absolute = Expr.evaluateAsAbsolute(Value);
1723 assert(Absolute)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1723, __extension__ __PRETTY_FUNCTION__))
;
1724 (void)Absolute;
1725 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);
1734 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)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1746, __extension__ __PRETTY_FUNCTION__))
;
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 {
1755 Imm.setExpr(HexagonMCExpr::create(
1756 MCBinaryExpr::createSub(Imm.getExpr(),
1757 MCConstantExpr::create(1, Context), Context),
1758 Context));
1759 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)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1776, __extension__ __PRETTY_FUNCTION__))
;
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());
1781 std::string R1 = r + utostr(RegPairNum + 1);
1782 StringRef Reg1(R1);
1783 Rss.setReg(matchRegister(Reg1));
1784 // Add a new operand for the second register in the pair.
1785 std::string R2 = r + utostr(RegPairNum);
1786 StringRef Reg2(R2);
1787 TmpInst.setOpcode(Hexagon::A2_combinew);
1788 TmpInst.addOperand(Rdd);
1789 TmpInst.addOperand(Rss);
1790 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1791 Inst = TmpInst;
1792 } else {
1793 Imm.setExpr(HexagonMCExpr::create(
1794 MCBinaryExpr::createSub(Imm.getExpr(),
1795 MCConstantExpr::create(1, Context), Context),
1796 Context));
1797 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);
1807 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1808 StringRef RegPair = Name;
1809 Rs.setReg(matchRegister(RegPair));
1810 } else { // raw:lo
1811 Inst.setOpcode(Hexagon::A4_boundscheck_lo);
1812 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1813 StringRef RegPair = Name;
1814 Rs.setReg(matchRegister(RegPair));
1815 }
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);
1824 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1825 StringRef RegPair = Name;
1826 Rs.setReg(matchRegister(RegPair));
1827 } else { // Even mapped raw:lo
1828 Inst.setOpcode(Hexagon::A2_addspl);
1829 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1830 StringRef RegPair = Name;
1831 Rs.setReg(matchRegister(RegPair));
1832 }
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);
1841 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1842 StringRef RegPair = Name;
1843 Rt.setReg(matchRegister(RegPair));
1844 } else { // Even mapped sat:raw:lo
1845 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
1846 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1847 StringRef RegPair = Name;
1848 Rt.setReg(matchRegister(RegPair));
1849 }
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);
1861 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1862 StringRef RegPair = Name;
1863 Rt.setReg(matchRegister(RegPair));
1864 } else { // Even mapped sat:raw:lo
1865 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
1866 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1867 StringRef RegPair = Name;
1868 Rt.setReg(matchRegister(RegPair));
1869 }
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);
1884 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1885 StringRef RegPair = Name;
1886 Rt.setReg(matchRegister(RegPair));
1887 } else { // Even mapped rnd:sat:raw:lo
1888 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
1889 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1890 StringRef RegPair = Name;
1891 Rt.setReg(matchRegister(RegPair));
1892 }
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)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1900, __extension__ __PRETTY_FUNCTION__))
;
1901 (void)Absolute;
1902 if (Value == 0)
1903 Inst.setOpcode(Hexagon::S2_vsathub);
1904 else {
1905 Imm.setExpr(HexagonMCExpr::create(
1906 MCBinaryExpr::createSub(Imm.getExpr(),
1907 MCConstantExpr::create(1, Context), Context),
1908 Context));
1909 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)(static_cast <bool> (Absolute) ? void (0) : __assert_fail
("Absolute", "/build/llvm-toolchain-snapshot-7~svn329677/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp"
, 1920, __extension__ __PRETTY_FUNCTION__))
;
1921 (void)Absolute;
1922 if (Value == 0) {
1923 MCInst TmpInst;
1924 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1925 std::string R1 = r + utostr(RegPairNum + 1);
1926 StringRef Reg1(R1);
1927 Rss.setReg(matchRegister(Reg1));
1928 // Add a new operand for the second register in the pair.
1929 std::string R2 = r + utostr(RegPairNum);
1930 StringRef Reg2(R2);
1931 TmpInst.setOpcode(Hexagon::A2_combinew);
1932 TmpInst.addOperand(Rdd);
1933 TmpInst.addOperand(Rss);
1934 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1935 Inst = TmpInst;
1936 } else {
1937 Imm.setExpr(HexagonMCExpr::create(
1938 MCBinaryExpr::createSub(Imm.getExpr(),
1939 MCConstantExpr::create(1, Context), Context),
1940 Context));
1941 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);
1952 TmpInst.addOperand(MCOperand::createExpr(
1953 HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
1954 TmpInst.addOperand(Rs);
1955 Inst = TmpInst;
1956 break;
1957 }
1958 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;
2014 case Hexagon::A2_zxtb: {
2015 Inst.setOpcode(Hexagon::A2_andir);
2016 Inst.addOperand(
2017 MCOperand::createExpr(MCConstantExpr::create(255, Context)));
2018 break;
2019 }
2020 } // switch
2021
2022 return Match_Success;
2023}
2024
2025unsigned HexagonAsmParser::matchRegister(StringRef Name) {
2026 if (unsigned Reg = MatchRegisterName(Name))
2027 return Reg;
2028 return MatchRegisterAltName(Name);
2029}