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