Bug Summary

File:lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
Warning:line 500, column 26
1st function call argument is an uninitialized value

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 MSP430AsmParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -analyzer-config-compatibility-mode=true -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-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn350071/build-llvm/lib/Target/MSP430/AsmParser -I /build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser -I /build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430 -I /build/llvm-toolchain-snapshot-8~svn350071/build-llvm/lib/Target/MSP430 -I /build/llvm-toolchain-snapshot-8~svn350071/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn350071/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.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-8~svn350071/build-llvm/lib/Target/MSP430/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-8~svn350071=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-12-27-042839-1215-1 -x c++ /build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp -faddrsig
1//===- MSP430AsmParser.cpp - Parse MSP430 assembly 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#include "MSP430.h"
11#include "MSP430RegisterInfo.h"
12#include "MCTargetDesc/MSP430MCTargetDesc.h"
13
14#include "llvm/ADT/APInt.h"
15#include "llvm/ADT/StringSwitch.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
19#include "llvm/MC/MCInstBuilder.h"
20#include "llvm/MC/MCParser/MCAsmLexer.h"
21#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22#include "llvm/MC/MCParser/MCTargetAsmParser.h"
23#include "llvm/MC/MCStreamer.h"
24#include "llvm/MC/MCSubtargetInfo.h"
25#include "llvm/MC/MCSymbol.h"
26#include "llvm/MC/MCValue.h"
27#include "llvm/Support/Debug.h"
28#include "llvm/Support/MathExtras.h"
29#include "llvm/Support/TargetRegistry.h"
30
31#define DEBUG_TYPE"msp430-asm-parser" "msp430-asm-parser"
32
33using namespace llvm;
34
35namespace {
36
37/// Parses MSP430 assembly from a stream.
38class MSP430AsmParser : public MCTargetAsmParser {
39 const MCSubtargetInfo &STI;
40 MCAsmParser &Parser;
41 const MCRegisterInfo *MRI;
42
43 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
44 OperandVector &Operands, MCStreamer &Out,
45 uint64_t &ErrorInfo,
46 bool MatchingInlineAsm) override;
47
48 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
49
50 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
51 SMLoc NameLoc, OperandVector &Operands) override;
52
53 bool ParseDirective(AsmToken DirectiveID) override;
54 bool ParseDirectiveRefSym(AsmToken DirectiveID);
55
56 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
57 unsigned Kind) override;
58
59 bool parseJccInstruction(ParseInstructionInfo &Info, StringRef Name,
60 SMLoc NameLoc, OperandVector &Operands);
61
62 bool ParseOperand(OperandVector &Operands);
63
64 bool ParseLiteralValues(unsigned Size, SMLoc L);
65
66 MCAsmParser &getParser() const { return Parser; }
67 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
68
69 /// @name Auto-generated Matcher Functions
70 /// {
71
72#define GET_ASSEMBLER_HEADER
73#include "MSP430GenAsmMatcher.inc"
74
75 /// }
76
77public:
78 MSP430AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
79 const MCInstrInfo &MII, const MCTargetOptions &Options)
80 : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) {
81 MCAsmParserExtension::Initialize(Parser);
82 MRI = getContext().getRegisterInfo();
83
84 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
85 }
86};
87
88/// A parsed MSP430 assembly operand.
89class MSP430Operand : public MCParsedAsmOperand {
90 typedef MCParsedAsmOperand Base;
91
92 enum KindTy {
93 k_Imm,
94 k_Reg,
95 k_Tok,
96 k_Mem,
97 k_IndReg,
98 k_PostIndReg
99 } Kind;
100
101 struct Memory {
102 unsigned Reg;
103 const MCExpr *Offset;
104 };
105 union {
106 const MCExpr *Imm;
107 unsigned Reg;
108 StringRef Tok;
109 Memory Mem;
110 };
111
112 SMLoc Start, End;
113
114public:
115 MSP430Operand(StringRef Tok, SMLoc const &S)
116 : Base(), Kind(k_Tok), Tok(Tok), Start(S), End(S) {}
117 MSP430Operand(KindTy Kind, unsigned Reg, SMLoc const &S, SMLoc const &E)
118 : Base(), Kind(Kind), Reg(Reg), Start(S), End(E) {}
119 MSP430Operand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
120 : Base(), Kind(k_Imm), Imm(Imm), Start(S), End(E) {}
121 MSP430Operand(unsigned Reg, MCExpr const *Expr, SMLoc const &S, SMLoc const &E)
122 : Base(), Kind(k_Mem), Mem({Reg, Expr}), Start(S), End(E) {}
123
124 void addRegOperands(MCInst &Inst, unsigned N) const {
125 assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) &&(((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg)
&& "Unexpected operand kind") ? static_cast<void>
(0) : __assert_fail ("(Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) && \"Unexpected operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 126, __PRETTY_FUNCTION__))
126 "Unexpected operand kind")(((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg)
&& "Unexpected operand kind") ? static_cast<void>
(0) : __assert_fail ("(Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) && \"Unexpected operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 126, __PRETTY_FUNCTION__))
;
127 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 127, __PRETTY_FUNCTION__))
;
128
129 Inst.addOperand(MCOperand::createReg(Reg));
130 }
131
132 void addExprOperand(MCInst &Inst, const MCExpr *Expr) const {
133 // Add as immediate when possible
134 if (!Expr)
135 Inst.addOperand(MCOperand::createImm(0));
136 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
137 Inst.addOperand(MCOperand::createImm(CE->getValue()));
138 else
139 Inst.addOperand(MCOperand::createExpr(Expr));
140 }
141
142 void addImmOperands(MCInst &Inst, unsigned N) const {
143 assert(Kind == k_Imm && "Unexpected operand kind")((Kind == k_Imm && "Unexpected operand kind") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Imm && \"Unexpected operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 143, __PRETTY_FUNCTION__))
;
144 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 144, __PRETTY_FUNCTION__))
;
145
146 addExprOperand(Inst, Imm);
147 }
148
149 void addMemOperands(MCInst &Inst, unsigned N) const {
150 assert(Kind == k_Mem && "Unexpected operand kind")((Kind == k_Mem && "Unexpected operand kind") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Mem && \"Unexpected operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 150, __PRETTY_FUNCTION__))
;
151 assert(N == 2 && "Invalid number of operands")((N == 2 && "Invalid number of operands") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 151, __PRETTY_FUNCTION__))
;
152
153 Inst.addOperand(MCOperand::createReg(Mem.Reg));
154 addExprOperand(Inst, Mem.Offset);
155 }
156
157 bool isReg() const { return Kind == k_Reg; }
158 bool isImm() const { return Kind == k_Imm; }
159 bool isToken() const { return Kind == k_Tok; }
160 bool isMem() const { return Kind == k_Mem; }
161 bool isIndReg() const { return Kind == k_IndReg; }
162 bool isPostIndReg() const { return Kind == k_PostIndReg; }
163
164 bool isCGImm() const {
165 if (Kind != k_Imm)
166 return false;
167
168 int64_t Val;
169 if (!Imm->evaluateAsAbsolute(Val))
170 return false;
171
172 if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)
173 return true;
174
175 return false;
176 }
177
178 StringRef getToken() const {
179 assert(Kind == k_Tok && "Invalid access!")((Kind == k_Tok && "Invalid access!") ? static_cast<
void> (0) : __assert_fail ("Kind == k_Tok && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 179, __PRETTY_FUNCTION__))
;
180 return Tok;
181 }
182
183 unsigned getReg() const {
184 assert(Kind == k_Reg && "Invalid access!")((Kind == k_Reg && "Invalid access!") ? static_cast<
void> (0) : __assert_fail ("Kind == k_Reg && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 184, __PRETTY_FUNCTION__))
;
185 return Reg;
186 }
187
188 void setReg(unsigned RegNo) {
189 assert(Kind == k_Reg && "Invalid access!")((Kind == k_Reg && "Invalid access!") ? static_cast<
void> (0) : __assert_fail ("Kind == k_Reg && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 189, __PRETTY_FUNCTION__))
;
190 Reg = RegNo;
191 }
192
193 static std::unique_ptr<MSP430Operand> CreateToken(StringRef Str, SMLoc S) {
194 return make_unique<MSP430Operand>(Str, S);
195 }
196
197 static std::unique_ptr<MSP430Operand> CreateReg(unsigned RegNum, SMLoc S,
198 SMLoc E) {
199 return make_unique<MSP430Operand>(k_Reg, RegNum, S, E);
200 }
201
202 static std::unique_ptr<MSP430Operand> CreateImm(const MCExpr *Val, SMLoc S,
203 SMLoc E) {
204 return make_unique<MSP430Operand>(Val, S, E);
205 }
206
207 static std::unique_ptr<MSP430Operand> CreateMem(unsigned RegNum,
208 const MCExpr *Val,
209 SMLoc S, SMLoc E) {
210 return make_unique<MSP430Operand>(RegNum, Val, S, E);
211 }
212
213 static std::unique_ptr<MSP430Operand> CreateIndReg(unsigned RegNum, SMLoc S,
214 SMLoc E) {
215 return make_unique<MSP430Operand>(k_IndReg, RegNum, S, E);
216 }
217
218 static std::unique_ptr<MSP430Operand> CreatePostIndReg(unsigned RegNum, SMLoc S,
219 SMLoc E) {
220 return make_unique<MSP430Operand>(k_PostIndReg, RegNum, S, E);
221 }
222
223 SMLoc getStartLoc() const { return Start; }
224 SMLoc getEndLoc() const { return End; }
225
226 virtual void print(raw_ostream &O) const {
227 switch (Kind) {
228 case k_Tok:
229 O << "Token " << Tok;
230 break;
231 case k_Reg:
232 O << "Register " << Reg;
233 break;
234 case k_Imm:
235 O << "Immediate " << *Imm;
236 break;
237 case k_Mem:
238 O << "Memory ";
239 O << *Mem.Offset << "(" << Reg << ")";
240 break;
241 case k_IndReg:
242 O << "RegInd " << Reg;
243 break;
244 case k_PostIndReg:
245 O << "PostInc " << Reg;
246 break;
247 }
248 }
249};
250} // end anonymous namespace
251
252bool MSP430AsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,
253 OperandVector &Operands,
254 MCStreamer &Out,
255 uint64_t &ErrorInfo,
256 bool MatchingInlineAsm) {
257 MCInst Inst;
258 unsigned MatchResult =
259 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
260
261 switch (MatchResult) {
262 case Match_Success:
263 Inst.setLoc(Loc);
264 Out.EmitInstruction(Inst, STI);
265 return false;
266 case Match_MnemonicFail:
267 return Error(Loc, "invalid instruction mnemonic");
268 case Match_InvalidOperand: {
269 SMLoc ErrorLoc = Loc;
270 if (ErrorInfo != ~0U) {
271 if (ErrorInfo >= Operands.size())
272 return Error(ErrorLoc, "too few operands for instruction");
273
274 ErrorLoc = ((MSP430Operand &)*Operands[ErrorInfo]).getStartLoc();
275 if (ErrorLoc == SMLoc())
276 ErrorLoc = Loc;
277 }
278 return Error(ErrorLoc, "invalid operand for instruction");
279 }
280 default:
281 return true;
282 }
283}
284
285// Auto-generated by TableGen
286static unsigned MatchRegisterName(StringRef Name);
287static unsigned MatchRegisterAltName(StringRef Name);
288
289bool MSP430AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
290 SMLoc &EndLoc) {
291 if (getLexer().getKind() == AsmToken::Identifier) {
10
Assuming the condition is false
11
Taking false branch
292 auto Name = getLexer().getTok().getIdentifier().lower();
293 RegNo = MatchRegisterName(Name);
294 if (RegNo == MSP430::NoRegister) {
295 RegNo = MatchRegisterAltName(Name);
296 if (RegNo == MSP430::NoRegister)
297 return true;
298 }
299
300 AsmToken const &T = getParser().getTok();
301 StartLoc = T.getLoc();
302 EndLoc = T.getEndLoc();
303 getLexer().Lex(); // eat register token
304
305 return false;
306 }
307
308 return Error(StartLoc, "invalid register name");
12
Returning without writing to 'RegNo'
309}
310
311bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info,
312 StringRef Name, SMLoc NameLoc,
313 OperandVector &Operands) {
314 if (!Name.startswith_lower("j"))
315 return true;
316
317 auto CC = Name.drop_front().lower();
318 unsigned CondCode;
319 if (CC == "ne" || CC == "nz")
320 CondCode = MSP430CC::COND_NE;
321 else if (CC == "eq" || CC == "z")
322 CondCode = MSP430CC::COND_E;
323 else if (CC == "lo" || CC == "nc")
324 CondCode = MSP430CC::COND_LO;
325 else if (CC == "hs" || CC == "c")
326 CondCode = MSP430CC::COND_HS;
327 else if (CC == "n")
328 CondCode = MSP430CC::COND_N;
329 else if (CC == "ge")
330 CondCode = MSP430CC::COND_GE;
331 else if (CC == "l")
332 CondCode = MSP430CC::COND_L;
333 else if (CC == "mp")
334 CondCode = MSP430CC::COND_NONE;
335 else
336 return Error(NameLoc, "unknown instruction");
337
338 if (CondCode == (unsigned)MSP430CC::COND_NONE)
339 Operands.push_back(MSP430Operand::CreateToken("jmp", NameLoc));
340 else {
341 Operands.push_back(MSP430Operand::CreateToken("j", NameLoc));
342 const MCExpr *CCode = MCConstantExpr::create(CondCode, getContext());
343 Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc()));
344 }
345
346 // Skip optional '$' sign.
347 if (getLexer().getKind() == AsmToken::Dollar)
348 getLexer().Lex(); // Eat '$'
349
350 const MCExpr *Val;
351 SMLoc ExprLoc = getLexer().getLoc();
352 if (getParser().parseExpression(Val))
353 return Error(ExprLoc, "expected expression operand");
354
355 int64_t Res;
356 if (Val->evaluateAsAbsolute(Res))
357 if (Res < -512 || Res > 511)
358 return Error(ExprLoc, "invalid jump offset");
359
360 Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc,
361 getLexer().getLoc()));
362
363 if (getLexer().isNot(AsmToken::EndOfStatement)) {
364 SMLoc Loc = getLexer().getLoc();
365 getParser().eatToEndOfStatement();
366 return Error(Loc, "unexpected token");
367 }
368
369 getParser().Lex(); // Consume the EndOfStatement.
370 return false;
371}
372
373bool MSP430AsmParser::ParseInstruction(ParseInstructionInfo &Info,
374 StringRef Name, SMLoc NameLoc,
375 OperandVector &Operands) {
376 // Drop .w suffix
377 if (Name.endswith_lower(".w"))
1
Assuming the condition is false
2
Taking false branch
378 Name = Name.drop_back(2);
379
380 if (!parseJccInstruction(Info, Name, NameLoc, Operands))
3
Assuming the condition is false
4
Taking false branch
381 return false;
382
383 // First operand is instruction mnemonic
384 Operands.push_back(MSP430Operand::CreateToken(Name, NameLoc));
385
386 // If there are no more operands, then finish
387 if (getLexer().is(AsmToken::EndOfStatement))
5
Taking false branch
388 return false;
389
390 // Parse first operand
391 if (ParseOperand(Operands))
6
Calling 'MSP430AsmParser::ParseOperand'
392 return true;
393
394 // Parse second operand if any
395 if (getLexer().is(AsmToken::Comma)) {
396 getLexer().Lex(); // Eat ','
397 if (ParseOperand(Operands))
398 return true;
399 }
400
401 if (getLexer().isNot(AsmToken::EndOfStatement)) {
402 SMLoc Loc = getLexer().getLoc();
403 getParser().eatToEndOfStatement();
404 return Error(Loc, "unexpected token");
405 }
406
407 getParser().Lex(); // Consume the EndOfStatement.
408 return false;
409}
410
411bool MSP430AsmParser::ParseDirectiveRefSym(AsmToken DirectiveID) {
412 StringRef Name;
413 if (getParser().parseIdentifier(Name))
414 return TokError("expected identifier in directive");
415
416 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
417 getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
418 return false;
419}
420
421bool MSP430AsmParser::ParseDirective(AsmToken DirectiveID) {
422 StringRef IDVal = DirectiveID.getIdentifier();
423 if (IDVal.lower() == ".long") {
424 ParseLiteralValues(4, DirectiveID.getLoc());
425 } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") {
426 ParseLiteralValues(2, DirectiveID.getLoc());
427 } else if (IDVal.lower() == ".byte") {
428 ParseLiteralValues(1, DirectiveID.getLoc());
429 } else if (IDVal.lower() == ".refsym") {
430 return ParseDirectiveRefSym(DirectiveID);
431 }
432 return true;
433}
434
435bool MSP430AsmParser::ParseOperand(OperandVector &Operands) {
436 switch (getLexer().getKind()) {
7
Control jumps to 'case At:' at line 487
437 default: return true;
438 case AsmToken::Identifier: {
439 // try rN
440 unsigned RegNo;
441 SMLoc StartLoc, EndLoc;
442 if (!ParseRegister(RegNo, StartLoc, EndLoc)) {
443 Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));
444 return false;
445 }
446 LLVM_FALLTHROUGH[[clang::fallthrough]];
447 }
448 case AsmToken::Integer:
449 case AsmToken::Plus:
450 case AsmToken::Minus: {
451 SMLoc StartLoc = getParser().getTok().getLoc();
452 const MCExpr *Val;
453 // Try constexpr[(rN)]
454 if (!getParser().parseExpression(Val)) {
455 unsigned RegNo = MSP430::PC;
456 SMLoc EndLoc = getParser().getTok().getLoc();
457 // Try (rN)
458 if (getLexer().getKind() == AsmToken::LParen) {
459 getLexer().Lex(); // Eat '('
460 SMLoc RegStartLoc;
461 if (ParseRegister(RegNo, RegStartLoc, EndLoc))
462 return true;
463 if (getLexer().getKind() != AsmToken::RParen)
464 return true;
465 EndLoc = getParser().getTok().getEndLoc();
466 getLexer().Lex(); // Eat ')'
467 }
468 Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,
469 EndLoc));
470 return false;
471 }
472 return true;
473 }
474 case AsmToken::Amp: {
475 // Try &constexpr
476 SMLoc StartLoc = getParser().getTok().getLoc();
477 getLexer().Lex(); // Eat '&'
478 const MCExpr *Val;
479 if (!getParser().parseExpression(Val)) {
480 SMLoc EndLoc = getParser().getTok().getLoc();
481 Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,
482 EndLoc));
483 return false;
484 }
485 return true;
486 }
487 case AsmToken::At: {
488 // Try @rN[+]
489 SMLoc StartLoc = getParser().getTok().getLoc();
490 getLexer().Lex(); // Eat '@'
491 unsigned RegNo;
8
'RegNo' declared without an initial value
492 SMLoc RegStartLoc, EndLoc;
493 if (ParseRegister(RegNo, RegStartLoc, EndLoc))
9
Calling 'MSP430AsmParser::ParseRegister'
13
Returning from 'MSP430AsmParser::ParseRegister'
14
Assuming the condition is false
15
Taking false branch
494 return true;
495 if (getLexer().getKind() == AsmToken::Plus) {
16
Assuming the condition is false
17
Taking false branch
496 Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));
497 getLexer().Lex(); // Eat '+'
498 return false;
499 }
500 Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
18
1st function call argument is an uninitialized value
501 return false;
502 }
503 case AsmToken::Hash:
504 // Try #constexpr
505 SMLoc StartLoc = getParser().getTok().getLoc();
506 getLexer().Lex(); // Eat '#'
507 const MCExpr *Val;
508 if (!getParser().parseExpression(Val)) {
509 SMLoc EndLoc = getParser().getTok().getLoc();
510 Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));
511 return false;
512 }
513 return true;
514 }
515}
516
517bool MSP430AsmParser::ParseLiteralValues(unsigned Size, SMLoc L) {
518 auto parseOne = [&]() -> bool {
519 const MCExpr *Value;
520 if (getParser().parseExpression(Value))
521 return true;
522 getParser().getStreamer().EmitValue(Value, Size, L);
523 return false;
524 };
525 return (parseMany(parseOne));
526}
527
528extern "C" void LLVMInitializeMSP430AsmParser() {
529 RegisterMCAsmParser<MSP430AsmParser> X(getTheMSP430Target());
530}
531
532#define GET_REGISTER_MATCHER
533#define GET_MATCHER_IMPLEMENTATION
534#include "MSP430GenAsmMatcher.inc"
535
536static unsigned convertGR16ToGR8(unsigned Reg) {
537 switch (Reg) {
538 default:
539 llvm_unreachable("Unknown GR16 register")::llvm::llvm_unreachable_internal("Unknown GR16 register", "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp"
, 539)
;
540 case MSP430::PC: return MSP430::PCB;
541 case MSP430::SP: return MSP430::SPB;
542 case MSP430::SR: return MSP430::SRB;
543 case MSP430::CG: return MSP430::CGB;
544 case MSP430::FP: return MSP430::FPB;
545 case MSP430::R5: return MSP430::R5B;
546 case MSP430::R6: return MSP430::R6B;
547 case MSP430::R7: return MSP430::R7B;
548 case MSP430::R8: return MSP430::R8B;
549 case MSP430::R9: return MSP430::R9B;
550 case MSP430::R10: return MSP430::R10B;
551 case MSP430::R11: return MSP430::R11B;
552 case MSP430::R12: return MSP430::R12B;
553 case MSP430::R13: return MSP430::R13B;
554 case MSP430::R14: return MSP430::R14B;
555 case MSP430::R15: return MSP430::R15B;
556 }
557}
558
559unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
560 unsigned Kind) {
561 MSP430Operand &Op = static_cast<MSP430Operand &>(AsmOp);
562
563 if (!Op.isReg())
564 return Match_InvalidOperand;
565
566 unsigned Reg = Op.getReg();
567 bool isGR16 =
568 MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg);
569
570 if (isGR16 && (Kind == MCK_GR8)) {
571 Op.setReg(convertGR16ToGR8(Reg));
572 return Match_Success;
573 }
574
575 return Match_InvalidOperand;
576}