File: | llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp |
Warning: | line 170, column 52 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===---- AVRAsmParser.cpp - Parse AVR assembly to MCInst instructions ----===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | ||||
9 | #include "AVR.h" | |||
10 | #include "AVRRegisterInfo.h" | |||
11 | #include "MCTargetDesc/AVRMCELFStreamer.h" | |||
12 | #include "MCTargetDesc/AVRMCExpr.h" | |||
13 | #include "MCTargetDesc/AVRMCTargetDesc.h" | |||
14 | #include "TargetInfo/AVRTargetInfo.h" | |||
15 | ||||
16 | #include "llvm/ADT/APInt.h" | |||
17 | #include "llvm/ADT/StringSwitch.h" | |||
18 | #include "llvm/MC/MCContext.h" | |||
19 | #include "llvm/MC/MCExpr.h" | |||
20 | #include "llvm/MC/MCInst.h" | |||
21 | #include "llvm/MC/MCInstBuilder.h" | |||
22 | #include "llvm/MC/MCParser/MCAsmLexer.h" | |||
23 | #include "llvm/MC/MCParser/MCParsedAsmOperand.h" | |||
24 | #include "llvm/MC/MCParser/MCTargetAsmParser.h" | |||
25 | #include "llvm/MC/MCStreamer.h" | |||
26 | #include "llvm/MC/MCSubtargetInfo.h" | |||
27 | #include "llvm/MC/MCSymbol.h" | |||
28 | #include "llvm/MC/MCValue.h" | |||
29 | #include "llvm/Support/Debug.h" | |||
30 | #include "llvm/Support/MathExtras.h" | |||
31 | #include "llvm/Support/TargetRegistry.h" | |||
32 | ||||
33 | #include <sstream> | |||
34 | ||||
35 | #define DEBUG_TYPE"avr-asm-parser" "avr-asm-parser" | |||
36 | ||||
37 | using namespace llvm; | |||
38 | ||||
39 | namespace { | |||
40 | /// Parses AVR assembly from a stream. | |||
41 | class AVRAsmParser : public MCTargetAsmParser { | |||
42 | const MCSubtargetInfo &STI; | |||
43 | MCAsmParser &Parser; | |||
44 | const MCRegisterInfo *MRI; | |||
45 | const std::string GENERATE_STUBS = "gs"; | |||
46 | ||||
47 | #define GET_ASSEMBLER_HEADER | |||
48 | #include "AVRGenAsmMatcher.inc" | |||
49 | ||||
50 | bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, | |||
51 | OperandVector &Operands, MCStreamer &Out, | |||
52 | uint64_t &ErrorInfo, | |||
53 | bool MatchingInlineAsm) override; | |||
54 | ||||
55 | bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; | |||
56 | OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, | |||
57 | SMLoc &EndLoc) override; | |||
58 | ||||
59 | bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, | |||
60 | SMLoc NameLoc, OperandVector &Operands) override; | |||
61 | ||||
62 | bool ParseDirective(AsmToken DirectiveID) override; | |||
63 | ||||
64 | OperandMatchResultTy parseMemriOperand(OperandVector &Operands); | |||
65 | ||||
66 | bool parseOperand(OperandVector &Operands); | |||
67 | int parseRegisterName(unsigned (*matchFn)(StringRef)); | |||
68 | int parseRegisterName(); | |||
69 | int parseRegister(bool RestoreOnFailure = false); | |||
70 | bool tryParseRegisterOperand(OperandVector &Operands); | |||
71 | bool tryParseExpression(OperandVector &Operands); | |||
72 | bool tryParseRelocExpression(OperandVector &Operands); | |||
73 | void eatComma(); | |||
74 | ||||
75 | unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, | |||
76 | unsigned Kind) override; | |||
77 | ||||
78 | unsigned toDREG(unsigned Reg, unsigned From = AVR::sub_lo) { | |||
79 | MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID]; | |||
80 | return MRI->getMatchingSuperReg(Reg, From, Class); | |||
81 | } | |||
82 | ||||
83 | bool emit(MCInst &Instruction, SMLoc const &Loc, MCStreamer &Out) const; | |||
84 | bool invalidOperand(SMLoc const &Loc, OperandVector const &Operands, | |||
85 | uint64_t const &ErrorInfo); | |||
86 | bool missingFeature(SMLoc const &Loc, uint64_t const &ErrorInfo); | |||
87 | ||||
88 | bool parseLiteralValues(unsigned SizeInBytes, SMLoc L); | |||
89 | ||||
90 | public: | |||
91 | AVRAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, | |||
92 | const MCInstrInfo &MII, const MCTargetOptions &Options) | |||
93 | : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) { | |||
94 | MCAsmParserExtension::Initialize(Parser); | |||
95 | MRI = getContext().getRegisterInfo(); | |||
96 | ||||
97 | setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); | |||
98 | } | |||
99 | ||||
100 | MCAsmParser &getParser() const { return Parser; } | |||
101 | MCAsmLexer &getLexer() const { return Parser.getLexer(); } | |||
102 | }; | |||
103 | ||||
104 | /// An parsed AVR assembly operand. | |||
105 | class AVROperand : public MCParsedAsmOperand { | |||
106 | typedef MCParsedAsmOperand Base; | |||
107 | enum KindTy { k_Immediate, k_Register, k_Token, k_Memri } Kind; | |||
108 | ||||
109 | public: | |||
110 | AVROperand(StringRef Tok, SMLoc const &S) | |||
111 | : Base(), Kind(k_Token), Tok(Tok), Start(S), End(S) {} | |||
112 | AVROperand(unsigned Reg, SMLoc const &S, SMLoc const &E) | |||
113 | : Base(), Kind(k_Register), RegImm({Reg, nullptr}), Start(S), End(E) {} | |||
114 | AVROperand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E) | |||
115 | : Base(), Kind(k_Immediate), RegImm({0, Imm}), Start(S), End(E) {} | |||
116 | AVROperand(unsigned Reg, MCExpr const *Imm, SMLoc const &S, SMLoc const &E) | |||
117 | : Base(), Kind(k_Memri), RegImm({Reg, Imm}), Start(S), End(E) {} | |||
118 | ||||
119 | struct RegisterImmediate { | |||
120 | unsigned Reg; | |||
121 | MCExpr const *Imm; | |||
122 | }; | |||
123 | union { | |||
124 | StringRef Tok; | |||
125 | RegisterImmediate RegImm; | |||
126 | }; | |||
127 | ||||
128 | SMLoc Start, End; | |||
129 | ||||
130 | public: | |||
131 | void addRegOperands(MCInst &Inst, unsigned N) const { | |||
132 | assert(Kind == k_Register && "Unexpected operand kind")((Kind == k_Register && "Unexpected operand kind") ? static_cast <void> (0) : __assert_fail ("Kind == k_Register && \"Unexpected operand kind\"" , "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 132, __PRETTY_FUNCTION__)); | |||
133 | 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-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 133, __PRETTY_FUNCTION__)); | |||
134 | ||||
135 | Inst.addOperand(MCOperand::createReg(getReg())); | |||
136 | } | |||
137 | ||||
138 | void addExpr(MCInst &Inst, const MCExpr *Expr) const { | |||
139 | // Add as immediate when possible | |||
140 | if (!Expr) | |||
141 | Inst.addOperand(MCOperand::createImm(0)); | |||
142 | else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) | |||
143 | Inst.addOperand(MCOperand::createImm(CE->getValue())); | |||
144 | else | |||
145 | Inst.addOperand(MCOperand::createExpr(Expr)); | |||
146 | } | |||
147 | ||||
148 | void addImmOperands(MCInst &Inst, unsigned N) const { | |||
149 | assert(Kind == k_Immediate && "Unexpected operand kind")((Kind == k_Immediate && "Unexpected operand kind") ? static_cast<void> (0) : __assert_fail ("Kind == k_Immediate && \"Unexpected operand kind\"" , "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 149, __PRETTY_FUNCTION__)); | |||
150 | 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-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 150, __PRETTY_FUNCTION__)); | |||
151 | ||||
152 | const MCExpr *Expr = getImm(); | |||
153 | addExpr(Inst, Expr); | |||
154 | } | |||
155 | ||||
156 | /// Adds the contained reg+imm operand to an instruction. | |||
157 | void addMemriOperands(MCInst &Inst, unsigned N) const { | |||
158 | assert(Kind == k_Memri && "Unexpected operand kind")((Kind == k_Memri && "Unexpected operand kind") ? static_cast <void> (0) : __assert_fail ("Kind == k_Memri && \"Unexpected operand kind\"" , "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 158, __PRETTY_FUNCTION__)); | |||
159 | 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-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 159, __PRETTY_FUNCTION__)); | |||
160 | ||||
161 | Inst.addOperand(MCOperand::createReg(getReg())); | |||
162 | addExpr(Inst, getImm()); | |||
163 | } | |||
164 | ||||
165 | void addImmCom8Operands(MCInst &Inst, unsigned N) const { | |||
166 | 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-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 166, __PRETTY_FUNCTION__)); | |||
| ||||
167 | // The operand is actually a imm8, but we have its bitwise | |||
168 | // negation in the assembly source, so twiddle it here. | |||
169 | const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); | |||
170 | Inst.addOperand(MCOperand::createImm(~(uint8_t)CE->getValue())); | |||
| ||||
171 | } | |||
172 | ||||
173 | bool isImmCom8() const { | |||
174 | if (!isImm()) return false; | |||
175 | const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); | |||
176 | if (!CE) return false; | |||
177 | int64_t Value = CE->getValue(); | |||
178 | return isUInt<8>(Value); | |||
179 | } | |||
180 | ||||
181 | bool isReg() const override { return Kind == k_Register; } | |||
182 | bool isImm() const override { return Kind == k_Immediate; } | |||
183 | bool isToken() const override { return Kind == k_Token; } | |||
184 | bool isMem() const override { return Kind == k_Memri; } | |||
185 | bool isMemri() const { return Kind == k_Memri; } | |||
186 | ||||
187 | StringRef getToken() const { | |||
188 | assert(Kind == k_Token && "Invalid access!")((Kind == k_Token && "Invalid access!") ? static_cast <void> (0) : __assert_fail ("Kind == k_Token && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 188, __PRETTY_FUNCTION__)); | |||
189 | return Tok; | |||
190 | } | |||
191 | ||||
192 | unsigned getReg() const override { | |||
193 | assert((Kind == k_Register || Kind == k_Memri) && "Invalid access!")(((Kind == k_Register || Kind == k_Memri) && "Invalid access!" ) ? static_cast<void> (0) : __assert_fail ("(Kind == k_Register || Kind == k_Memri) && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 193, __PRETTY_FUNCTION__)); | |||
194 | ||||
195 | return RegImm.Reg; | |||
196 | } | |||
197 | ||||
198 | const MCExpr *getImm() const { | |||
199 | assert((Kind == k_Immediate || Kind == k_Memri) && "Invalid access!")(((Kind == k_Immediate || Kind == k_Memri) && "Invalid access!" ) ? static_cast<void> (0) : __assert_fail ("(Kind == k_Immediate || Kind == k_Memri) && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 199, __PRETTY_FUNCTION__)); | |||
200 | return RegImm.Imm; | |||
201 | } | |||
202 | ||||
203 | static std::unique_ptr<AVROperand> CreateToken(StringRef Str, SMLoc S) { | |||
204 | return std::make_unique<AVROperand>(Str, S); | |||
205 | } | |||
206 | ||||
207 | static std::unique_ptr<AVROperand> CreateReg(unsigned RegNum, SMLoc S, | |||
208 | SMLoc E) { | |||
209 | return std::make_unique<AVROperand>(RegNum, S, E); | |||
210 | } | |||
211 | ||||
212 | static std::unique_ptr<AVROperand> CreateImm(const MCExpr *Val, SMLoc S, | |||
213 | SMLoc E) { | |||
214 | return std::make_unique<AVROperand>(Val, S, E); | |||
215 | } | |||
216 | ||||
217 | static std::unique_ptr<AVROperand> | |||
218 | CreateMemri(unsigned RegNum, const MCExpr *Val, SMLoc S, SMLoc E) { | |||
219 | return std::make_unique<AVROperand>(RegNum, Val, S, E); | |||
220 | } | |||
221 | ||||
222 | void makeToken(StringRef Token) { | |||
223 | Kind = k_Token; | |||
224 | Tok = Token; | |||
225 | } | |||
226 | ||||
227 | void makeReg(unsigned RegNo) { | |||
228 | Kind = k_Register; | |||
229 | RegImm = {RegNo, nullptr}; | |||
230 | } | |||
231 | ||||
232 | void makeImm(MCExpr const *Ex) { | |||
233 | Kind = k_Immediate; | |||
234 | RegImm = {0, Ex}; | |||
235 | } | |||
236 | ||||
237 | void makeMemri(unsigned RegNo, MCExpr const *Imm) { | |||
238 | Kind = k_Memri; | |||
239 | RegImm = {RegNo, Imm}; | |||
240 | } | |||
241 | ||||
242 | SMLoc getStartLoc() const override { return Start; } | |||
243 | SMLoc getEndLoc() const override { return End; } | |||
244 | ||||
245 | void print(raw_ostream &O) const override { | |||
246 | switch (Kind) { | |||
247 | case k_Token: | |||
248 | O << "Token: \"" << getToken() << "\""; | |||
249 | break; | |||
250 | case k_Register: | |||
251 | O << "Register: " << getReg(); | |||
252 | break; | |||
253 | case k_Immediate: | |||
254 | O << "Immediate: \"" << *getImm() << "\""; | |||
255 | break; | |||
256 | case k_Memri: { | |||
257 | // only manually print the size for non-negative values, | |||
258 | // as the sign is inserted automatically. | |||
259 | O << "Memri: \"" << getReg() << '+' << *getImm() << "\""; | |||
260 | break; | |||
261 | } | |||
262 | } | |||
263 | O << "\n"; | |||
264 | } | |||
265 | }; | |||
266 | ||||
267 | } // end anonymous namespace. | |||
268 | ||||
269 | // Auto-generated Match Functions | |||
270 | ||||
271 | /// Maps from the set of all register names to a register number. | |||
272 | /// \note Generated by TableGen. | |||
273 | static unsigned MatchRegisterName(StringRef Name); | |||
274 | ||||
275 | /// Maps from the set of all alternative registernames to a register number. | |||
276 | /// \note Generated by TableGen. | |||
277 | static unsigned MatchRegisterAltName(StringRef Name); | |||
278 | ||||
279 | bool AVRAsmParser::invalidOperand(SMLoc const &Loc, | |||
280 | OperandVector const &Operands, | |||
281 | uint64_t const &ErrorInfo) { | |||
282 | SMLoc ErrorLoc = Loc; | |||
283 | char const *Diag = 0; | |||
284 | ||||
285 | if (ErrorInfo != ~0U) { | |||
286 | if (ErrorInfo >= Operands.size()) { | |||
287 | Diag = "too few operands for instruction."; | |||
288 | } else { | |||
289 | AVROperand const &Op = (AVROperand const &)*Operands[ErrorInfo]; | |||
290 | ||||
291 | // TODO: See if we can do a better error than just "invalid ...". | |||
292 | if (Op.getStartLoc() != SMLoc()) { | |||
293 | ErrorLoc = Op.getStartLoc(); | |||
294 | } | |||
295 | } | |||
296 | } | |||
297 | ||||
298 | if (!Diag) { | |||
299 | Diag = "invalid operand for instruction"; | |||
300 | } | |||
301 | ||||
302 | return Error(ErrorLoc, Diag); | |||
303 | } | |||
304 | ||||
305 | bool AVRAsmParser::missingFeature(llvm::SMLoc const &Loc, | |||
306 | uint64_t const &ErrorInfo) { | |||
307 | return Error(Loc, "instruction requires a CPU feature not currently enabled"); | |||
308 | } | |||
309 | ||||
310 | bool AVRAsmParser::emit(MCInst &Inst, SMLoc const &Loc, MCStreamer &Out) const { | |||
311 | Inst.setLoc(Loc); | |||
312 | Out.emitInstruction(Inst, STI); | |||
313 | ||||
314 | return false; | |||
315 | } | |||
316 | ||||
317 | bool AVRAsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode, | |||
318 | OperandVector &Operands, | |||
319 | MCStreamer &Out, uint64_t &ErrorInfo, | |||
320 | bool MatchingInlineAsm) { | |||
321 | MCInst Inst; | |||
322 | unsigned MatchResult = | |||
323 | MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); | |||
324 | ||||
325 | switch (MatchResult) { | |||
326 | case Match_Success: return emit(Inst, Loc, Out); | |||
327 | case Match_MissingFeature: return missingFeature(Loc, ErrorInfo); | |||
328 | case Match_InvalidOperand: return invalidOperand(Loc, Operands, ErrorInfo); | |||
329 | case Match_MnemonicFail: return Error(Loc, "invalid instruction"); | |||
330 | default: return true; | |||
331 | } | |||
332 | } | |||
333 | ||||
334 | /// Parses a register name using a given matching function. | |||
335 | /// Checks for lowercase or uppercase if necessary. | |||
336 | int AVRAsmParser::parseRegisterName(unsigned (*matchFn)(StringRef)) { | |||
337 | StringRef Name = Parser.getTok().getString(); | |||
338 | ||||
339 | int RegNum = matchFn(Name); | |||
340 | ||||
341 | // GCC supports case insensitive register names. Some of the AVR registers | |||
342 | // are all lower case, some are all upper case but non are mixed. We prefer | |||
343 | // to use the original names in the register definitions. That is why we | |||
344 | // have to test both upper and lower case here. | |||
345 | if (RegNum == AVR::NoRegister) { | |||
346 | RegNum = matchFn(Name.lower()); | |||
347 | } | |||
348 | if (RegNum == AVR::NoRegister) { | |||
349 | RegNum = matchFn(Name.upper()); | |||
350 | } | |||
351 | ||||
352 | return RegNum; | |||
353 | } | |||
354 | ||||
355 | int AVRAsmParser::parseRegisterName() { | |||
356 | int RegNum = parseRegisterName(&MatchRegisterName); | |||
357 | ||||
358 | if (RegNum == AVR::NoRegister) | |||
359 | RegNum = parseRegisterName(&MatchRegisterAltName); | |||
360 | ||||
361 | return RegNum; | |||
362 | } | |||
363 | ||||
364 | int AVRAsmParser::parseRegister(bool RestoreOnFailure) { | |||
365 | int RegNum = AVR::NoRegister; | |||
366 | ||||
367 | if (Parser.getTok().is(AsmToken::Identifier)) { | |||
368 | // Check for register pair syntax | |||
369 | if (Parser.getLexer().peekTok().is(AsmToken::Colon)) { | |||
370 | AsmToken HighTok = Parser.getTok(); | |||
371 | Parser.Lex(); | |||
372 | AsmToken ColonTok = Parser.getTok(); | |||
373 | Parser.Lex(); // Eat high (odd) register and colon | |||
374 | ||||
375 | if (Parser.getTok().is(AsmToken::Identifier)) { | |||
376 | // Convert lower (even) register to DREG | |||
377 | RegNum = toDREG(parseRegisterName()); | |||
378 | } | |||
379 | if (RegNum == AVR::NoRegister && RestoreOnFailure) { | |||
380 | getLexer().UnLex(std::move(ColonTok)); | |||
381 | getLexer().UnLex(std::move(HighTok)); | |||
382 | } | |||
383 | } else { | |||
384 | RegNum = parseRegisterName(); | |||
385 | } | |||
386 | } | |||
387 | return RegNum; | |||
388 | } | |||
389 | ||||
390 | bool AVRAsmParser::tryParseRegisterOperand(OperandVector &Operands) { | |||
391 | int RegNo = parseRegister(); | |||
392 | ||||
393 | if (RegNo == AVR::NoRegister) | |||
394 | return true; | |||
395 | ||||
396 | AsmToken const &T = Parser.getTok(); | |||
397 | Operands.push_back(AVROperand::CreateReg(RegNo, T.getLoc(), T.getEndLoc())); | |||
398 | Parser.Lex(); // Eat register token. | |||
399 | ||||
400 | return false; | |||
401 | } | |||
402 | ||||
403 | bool AVRAsmParser::tryParseExpression(OperandVector &Operands) { | |||
404 | SMLoc S = Parser.getTok().getLoc(); | |||
405 | ||||
406 | if (!tryParseRelocExpression(Operands)) | |||
407 | return false; | |||
408 | ||||
409 | if ((Parser.getTok().getKind() == AsmToken::Plus || | |||
410 | Parser.getTok().getKind() == AsmToken::Minus) && | |||
411 | Parser.getLexer().peekTok().getKind() == AsmToken::Identifier) { | |||
412 | // Don't handle this case - it should be split into two | |||
413 | // separate tokens. | |||
414 | return true; | |||
415 | } | |||
416 | ||||
417 | // Parse (potentially inner) expression | |||
418 | MCExpr const *Expression; | |||
419 | if (getParser().parseExpression(Expression)) | |||
420 | return true; | |||
421 | ||||
422 | SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); | |||
423 | Operands.push_back(AVROperand::CreateImm(Expression, S, E)); | |||
424 | return false; | |||
425 | } | |||
426 | ||||
427 | bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) { | |||
428 | bool isNegated = false; | |||
429 | AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None; | |||
430 | ||||
431 | SMLoc S = Parser.getTok().getLoc(); | |||
432 | ||||
433 | // Check for sign | |||
434 | AsmToken tokens[2]; | |||
435 | size_t ReadCount = Parser.getLexer().peekTokens(tokens); | |||
436 | ||||
437 | if (ReadCount == 2) { | |||
438 | if ((tokens[0].getKind() == AsmToken::Identifier && | |||
439 | tokens[1].getKind() == AsmToken::LParen) || | |||
440 | (tokens[0].getKind() == AsmToken::LParen && | |||
441 | tokens[1].getKind() == AsmToken::Minus)) { | |||
442 | ||||
443 | AsmToken::TokenKind CurTok = Parser.getLexer().getKind(); | |||
444 | if (CurTok == AsmToken::Minus || | |||
445 | tokens[1].getKind() == AsmToken::Minus) { | |||
446 | isNegated = true; | |||
447 | } else { | |||
448 | assert(CurTok == AsmToken::Plus)((CurTok == AsmToken::Plus) ? static_cast<void> (0) : __assert_fail ("CurTok == AsmToken::Plus", "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 448, __PRETTY_FUNCTION__)); | |||
449 | isNegated = false; | |||
450 | } | |||
451 | ||||
452 | // Eat the sign | |||
453 | if (CurTok == AsmToken::Minus || CurTok == AsmToken::Plus) | |||
454 | Parser.Lex(); | |||
455 | } | |||
456 | } | |||
457 | ||||
458 | // Check if we have a target specific modifier (lo8, hi8, &c) | |||
459 | if (Parser.getTok().getKind() != AsmToken::Identifier || | |||
460 | Parser.getLexer().peekTok().getKind() != AsmToken::LParen) { | |||
461 | // Not a reloc expr | |||
462 | return true; | |||
463 | } | |||
464 | StringRef ModifierName = Parser.getTok().getString(); | |||
465 | ModifierKind = AVRMCExpr::getKindByName(ModifierName.str().c_str()); | |||
466 | ||||
467 | if (ModifierKind != AVRMCExpr::VK_AVR_None) { | |||
468 | Parser.Lex(); | |||
469 | Parser.Lex(); // Eat modifier name and parenthesis | |||
470 | if (Parser.getTok().getString() == GENERATE_STUBS && | |||
471 | Parser.getTok().getKind() == AsmToken::Identifier) { | |||
472 | std::string GSModName = ModifierName.str() + "_" + GENERATE_STUBS; | |||
473 | ModifierKind = AVRMCExpr::getKindByName(GSModName.c_str()); | |||
474 | if (ModifierKind != AVRMCExpr::VK_AVR_None) | |||
475 | Parser.Lex(); // Eat gs modifier name | |||
476 | } | |||
477 | } else { | |||
478 | return Error(Parser.getTok().getLoc(), "unknown modifier"); | |||
479 | } | |||
480 | ||||
481 | if (tokens[1].getKind() == AsmToken::Minus || | |||
482 | tokens[1].getKind() == AsmToken::Plus) { | |||
483 | Parser.Lex(); | |||
484 | assert(Parser.getTok().getKind() == AsmToken::LParen)((Parser.getTok().getKind() == AsmToken::LParen) ? static_cast <void> (0) : __assert_fail ("Parser.getTok().getKind() == AsmToken::LParen" , "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 484, __PRETTY_FUNCTION__)); | |||
485 | Parser.Lex(); // Eat the sign and parenthesis | |||
486 | } | |||
487 | ||||
488 | MCExpr const *InnerExpression; | |||
489 | if (getParser().parseExpression(InnerExpression)) | |||
490 | return true; | |||
491 | ||||
492 | if (tokens[1].getKind() == AsmToken::Minus || | |||
493 | tokens[1].getKind() == AsmToken::Plus) { | |||
494 | assert(Parser.getTok().getKind() == AsmToken::RParen)((Parser.getTok().getKind() == AsmToken::RParen) ? static_cast <void> (0) : __assert_fail ("Parser.getTok().getKind() == AsmToken::RParen" , "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 494, __PRETTY_FUNCTION__)); | |||
495 | Parser.Lex(); // Eat closing parenthesis | |||
496 | } | |||
497 | ||||
498 | // If we have a modifier wrap the inner expression | |||
499 | assert(Parser.getTok().getKind() == AsmToken::RParen)((Parser.getTok().getKind() == AsmToken::RParen) ? static_cast <void> (0) : __assert_fail ("Parser.getTok().getKind() == AsmToken::RParen" , "/build/llvm-toolchain-snapshot-12~++20200911111112+c0825fa5fc3/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp" , 499, __PRETTY_FUNCTION__)); | |||
500 | Parser.Lex(); // Eat closing parenthesis | |||
501 | ||||
502 | MCExpr const *Expression = AVRMCExpr::create(ModifierKind, InnerExpression, | |||
503 | isNegated, getContext()); | |||
504 | ||||
505 | SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); | |||
506 | Operands.push_back(AVROperand::CreateImm(Expression, S, E)); | |||
507 | ||||
508 | return false; | |||
509 | } | |||
510 | ||||
511 | bool AVRAsmParser::parseOperand(OperandVector &Operands) { | |||
512 | LLVM_DEBUG(dbgs() << "parseOperand\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("avr-asm-parser")) { dbgs() << "parseOperand\n"; } } while (false); | |||
513 | ||||
514 | switch (getLexer().getKind()) { | |||
515 | default: | |||
516 | return Error(Parser.getTok().getLoc(), "unexpected token in operand"); | |||
517 | ||||
518 | case AsmToken::Identifier: | |||
519 | // Try to parse a register, if it fails, | |||
520 | // fall through to the next case. | |||
521 | if (!tryParseRegisterOperand(Operands)) { | |||
522 | return false; | |||
523 | } | |||
524 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | |||
525 | case AsmToken::LParen: | |||
526 | case AsmToken::Integer: | |||
527 | case AsmToken::Dot: | |||
528 | return tryParseExpression(Operands); | |||
529 | case AsmToken::Plus: | |||
530 | case AsmToken::Minus: { | |||
531 | // If the sign preceeds a number, parse the number, | |||
532 | // otherwise treat the sign a an independent token. | |||
533 | switch (getLexer().peekTok().getKind()) { | |||
534 | case AsmToken::Integer: | |||
535 | case AsmToken::BigNum: | |||
536 | case AsmToken::Identifier: | |||
537 | case AsmToken::Real: | |||
538 | if (!tryParseExpression(Operands)) | |||
539 | return false; | |||
540 | break; | |||
541 | default: | |||
542 | break; | |||
543 | } | |||
544 | // Treat the token as an independent token. | |||
545 | Operands.push_back(AVROperand::CreateToken(Parser.getTok().getString(), | |||
546 | Parser.getTok().getLoc())); | |||
547 | Parser.Lex(); // Eat the token. | |||
548 | return false; | |||
549 | } | |||
550 | } | |||
551 | ||||
552 | // Could not parse operand | |||
553 | return true; | |||
554 | } | |||
555 | ||||
556 | OperandMatchResultTy | |||
557 | AVRAsmParser::parseMemriOperand(OperandVector &Operands) { | |||
558 | LLVM_DEBUG(dbgs() << "parseMemriOperand()\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("avr-asm-parser")) { dbgs() << "parseMemriOperand()\n" ; } } while (false); | |||
559 | ||||
560 | SMLoc E, S; | |||
561 | MCExpr const *Expression; | |||
562 | int RegNo; | |||
563 | ||||
564 | // Parse register. | |||
565 | { | |||
566 | RegNo = parseRegister(); | |||
567 | ||||
568 | if (RegNo == AVR::NoRegister) | |||
569 | return MatchOperand_ParseFail; | |||
570 | ||||
571 | S = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); | |||
572 | Parser.Lex(); // Eat register token. | |||
573 | } | |||
574 | ||||
575 | // Parse immediate; | |||
576 | { | |||
577 | if (getParser().parseExpression(Expression)) | |||
578 | return MatchOperand_ParseFail; | |||
579 | ||||
580 | E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); | |||
581 | } | |||
582 | ||||
583 | Operands.push_back(AVROperand::CreateMemri(RegNo, Expression, S, E)); | |||
584 | ||||
585 | return MatchOperand_Success; | |||
586 | } | |||
587 | ||||
588 | bool AVRAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, | |||
589 | SMLoc &EndLoc) { | |||
590 | StartLoc = Parser.getTok().getLoc(); | |||
591 | RegNo = parseRegister(/*RestoreOnFailure=*/false); | |||
592 | EndLoc = Parser.getTok().getLoc(); | |||
593 | ||||
594 | return (RegNo == AVR::NoRegister); | |||
595 | } | |||
596 | ||||
597 | OperandMatchResultTy AVRAsmParser::tryParseRegister(unsigned &RegNo, | |||
598 | SMLoc &StartLoc, | |||
599 | SMLoc &EndLoc) { | |||
600 | StartLoc = Parser.getTok().getLoc(); | |||
601 | RegNo = parseRegister(/*RestoreOnFailure=*/true); | |||
602 | EndLoc = Parser.getTok().getLoc(); | |||
603 | ||||
604 | if (RegNo == AVR::NoRegister) | |||
605 | return MatchOperand_NoMatch; | |||
606 | return MatchOperand_Success; | |||
607 | } | |||
608 | ||||
609 | void AVRAsmParser::eatComma() { | |||
610 | if (getLexer().is(AsmToken::Comma)) { | |||
611 | Parser.Lex(); | |||
612 | } else { | |||
613 | // GCC allows commas to be omitted. | |||
614 | } | |||
615 | } | |||
616 | ||||
617 | bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info, | |||
618 | StringRef Mnemonic, SMLoc NameLoc, | |||
619 | OperandVector &Operands) { | |||
620 | Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc)); | |||
621 | ||||
622 | bool first = true; | |||
623 | while (getLexer().isNot(AsmToken::EndOfStatement)) { | |||
624 | if (!first) eatComma(); | |||
625 | ||||
626 | first = false; | |||
627 | ||||
628 | auto MatchResult = MatchOperandParserImpl(Operands, Mnemonic); | |||
629 | ||||
630 | if (MatchResult == MatchOperand_Success) { | |||
631 | continue; | |||
632 | } | |||
633 | ||||
634 | if (MatchResult == MatchOperand_ParseFail) { | |||
635 | SMLoc Loc = getLexer().getLoc(); | |||
636 | Parser.eatToEndOfStatement(); | |||
637 | ||||
638 | return Error(Loc, "failed to parse register and immediate pair"); | |||
639 | } | |||
640 | ||||
641 | if (parseOperand(Operands)) { | |||
642 | SMLoc Loc = getLexer().getLoc(); | |||
643 | Parser.eatToEndOfStatement(); | |||
644 | return Error(Loc, "unexpected token in argument list"); | |||
645 | } | |||
646 | } | |||
647 | Parser.Lex(); // Consume the EndOfStatement | |||
648 | return false; | |||
649 | } | |||
650 | ||||
651 | bool AVRAsmParser::ParseDirective(llvm::AsmToken DirectiveID) { | |||
652 | StringRef IDVal = DirectiveID.getIdentifier(); | |||
653 | if (IDVal.lower() == ".long") { | |||
654 | parseLiteralValues(SIZE_LONG, DirectiveID.getLoc()); | |||
655 | } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") { | |||
656 | parseLiteralValues(SIZE_WORD, DirectiveID.getLoc()); | |||
657 | } else if (IDVal.lower() == ".byte") { | |||
658 | parseLiteralValues(1, DirectiveID.getLoc()); | |||
659 | } | |||
660 | return true; | |||
661 | } | |||
662 | ||||
663 | bool AVRAsmParser::parseLiteralValues(unsigned SizeInBytes, SMLoc L) { | |||
664 | MCAsmParser &Parser = getParser(); | |||
665 | AVRMCELFStreamer &AVRStreamer = | |||
666 | static_cast<AVRMCELFStreamer &>(Parser.getStreamer()); | |||
667 | AsmToken Tokens[2]; | |||
668 | size_t ReadCount = Parser.getLexer().peekTokens(Tokens); | |||
669 | if (ReadCount == 2 && Parser.getTok().getKind() == AsmToken::Identifier && | |||
670 | Tokens[0].getKind() == AsmToken::Minus && | |||
671 | Tokens[1].getKind() == AsmToken::Identifier) { | |||
672 | MCSymbol *Symbol = getContext().getOrCreateSymbol(".text"); | |||
673 | AVRStreamer.emitValueForModiferKind(Symbol, SizeInBytes, L, | |||
674 | AVRMCExpr::VK_AVR_None); | |||
675 | return false; | |||
676 | } | |||
677 | ||||
678 | if (Parser.getTok().getKind() == AsmToken::Identifier && | |||
679 | Parser.getLexer().peekTok().getKind() == AsmToken::LParen) { | |||
680 | StringRef ModifierName = Parser.getTok().getString(); | |||
681 | AVRMCExpr::VariantKind ModifierKind = | |||
682 | AVRMCExpr::getKindByName(ModifierName.str().c_str()); | |||
683 | if (ModifierKind != AVRMCExpr::VK_AVR_None) { | |||
684 | Parser.Lex(); | |||
685 | Parser.Lex(); // Eat the modifier and parenthesis | |||
686 | } else { | |||
687 | return Error(Parser.getTok().getLoc(), "unknown modifier"); | |||
688 | } | |||
689 | MCSymbol *Symbol = | |||
690 | getContext().getOrCreateSymbol(Parser.getTok().getString()); | |||
691 | AVRStreamer.emitValueForModiferKind(Symbol, SizeInBytes, L, ModifierKind); | |||
692 | return false; | |||
693 | } | |||
694 | ||||
695 | auto parseOne = [&]() -> bool { | |||
696 | const MCExpr *Value; | |||
697 | if (Parser.parseExpression(Value)) | |||
698 | return true; | |||
699 | Parser.getStreamer().emitValue(Value, SizeInBytes, L); | |||
700 | return false; | |||
701 | }; | |||
702 | return (parseMany(parseOne)); | |||
703 | } | |||
704 | ||||
705 | extern "C" LLVM_EXTERNAL_VISIBILITY__attribute__ ((visibility("default"))) void LLVMInitializeAVRAsmParser() { | |||
706 | RegisterMCAsmParser<AVRAsmParser> X(getTheAVRTarget()); | |||
707 | } | |||
708 | ||||
709 | #define GET_REGISTER_MATCHER | |||
710 | #define GET_MATCHER_IMPLEMENTATION | |||
711 | #include "AVRGenAsmMatcher.inc" | |||
712 | ||||
713 | // Uses enums defined in AVRGenAsmMatcher.inc | |||
714 | unsigned AVRAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, | |||
715 | unsigned ExpectedKind) { | |||
716 | AVROperand &Op = static_cast<AVROperand &>(AsmOp); | |||
717 | MatchClassKind Expected = static_cast<MatchClassKind>(ExpectedKind); | |||
718 | ||||
719 | // If need be, GCC converts bare numbers to register names | |||
720 | // It's ugly, but GCC supports it. | |||
721 | if (Op.isImm()) { | |||
722 | if (MCConstantExpr const *Const = dyn_cast<MCConstantExpr>(Op.getImm())) { | |||
723 | int64_t RegNum = Const->getValue(); | |||
724 | std::ostringstream RegName; | |||
725 | RegName << "r" << RegNum; | |||
726 | RegNum = MatchRegisterName(RegName.str().c_str()); | |||
727 | if (RegNum != AVR::NoRegister) { | |||
728 | Op.makeReg(RegNum); | |||
729 | if (validateOperandClass(Op, Expected) == Match_Success) { | |||
730 | return Match_Success; | |||
731 | } | |||
732 | } | |||
733 | // Let the other quirks try their magic. | |||
734 | } | |||
735 | } | |||
736 | ||||
737 | if (Op.isReg()) { | |||
738 | // If the instruction uses a register pair but we got a single, lower | |||
739 | // register we perform a "class cast". | |||
740 | if (isSubclass(Expected, MCK_DREGS)) { | |||
741 | unsigned correspondingDREG = toDREG(Op.getReg()); | |||
742 | ||||
743 | if (correspondingDREG != AVR::NoRegister) { | |||
744 | Op.makeReg(correspondingDREG); | |||
745 | return validateOperandClass(Op, Expected); | |||
746 | } | |||
747 | } | |||
748 | } | |||
749 | return Match_InvalidOperand; | |||
750 | } |