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