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