10
10
#include " AVR.h"
11
11
#include " MCTargetDesc/AVRMCTargetDesc.h"
12
12
#include " AVRRegisterInfo.h"
13
+ #include " MCTargetDesc/AVRMCExpr.h"
13
14
#include " llvm/ADT/APInt.h"
14
15
#include " llvm/ADT/StringSwitch.h"
15
16
#include " llvm/MC/MCContext.h"
@@ -56,23 +57,16 @@ class AVRAsmParser : public MCTargetAsmParser {
56
57
bool ParseDirective (AsmToken directiveID) override { return true ; }
57
58
58
59
59
- // ! Parses an assembly operand.
60
- // ! \param Operands A list to add the successfully parsed operand to.
61
- // ! \param Mnemonic The mnemonic of the instruction.
62
- // ! \return `false` if parsing succeeds, `true` otherwise.
63
60
bool parseOperand (OperandVector &Operands, StringRef Mnemonic);
64
-
65
- // ! Attempts to parse a register.
66
- // ! \return The register number, or `-1` if the token is not a register.
67
- int parseRegister ();
61
+ int parseRegister ();
68
62
bool tryParseRegisterOperand (OperandVector &Operands);
69
63
bool tryParseExpression (OperandVector & Operands);
70
64
void appendToken (OperandVector & Operands);
71
65
72
- // ! Handles target specific special cases. See definition for notes.
66
+ // Handles target specific special cases. See definition for notes.
73
67
unsigned validateTargetOperandClass (MCParsedAsmOperand &Op, unsigned Kind);
74
68
75
- // ! Given a register returns the corresponding DREG
69
+ // Given a register returns the corresponding DREG
76
70
unsigned toDREG (unsigned Reg, unsigned From = AVR::sub_lo) {
77
71
return MRI->getMatchingSuperReg (Reg, From, &AVRMCRegisterClasses[AVR::DREGSRegClassID]);
78
72
}
@@ -91,18 +85,6 @@ class AVRAsmParser : public MCTargetAsmParser {
91
85
MCAsmLexer &getLexer () const { return Parser.getLexer (); }
92
86
93
87
};
94
- } // end of anonymous namespace
95
-
96
- // / @name Auto-generated Match Functions
97
- // / {
98
-
99
- // ! Matches a register name to a register number.
100
- // ! \return The register number, or -1 if the register is invalid.
101
- static unsigned MatchRegisterName (StringRef Name);
102
-
103
- // / }
104
-
105
- namespace {
106
88
107
89
/* !
108
90
* Represents a parsed AVR machine instruction.
@@ -116,25 +98,15 @@ class AVROperand : public MCParsedAsmOperand {
116
98
} Kind;
117
99
118
100
public:
119
- AVROperand (KindTy K) : MCParsedAsmOperand(), Kind(K) {}
120
-
121
- struct Token {
122
- const char *Data;
123
- unsigned Length;
124
- };
125
-
126
- struct Register {
127
- unsigned RegNum;
128
- };
129
-
130
- struct Immediate {
131
- const MCExpr *Val;
132
- };
101
+ explicit AVROperand (KindTy K) : MCParsedAsmOperand(), Kind(K) {}
102
+ explicit AVROperand (StringRef Tok) : MCParsedAsmOperand(), Kind(k_Token), Tok(Tok) {}
103
+ explicit AVROperand (unsigned Reg) : MCParsedAsmOperand(), Kind(k_Register), Reg(Reg) {}
104
+ explicit AVROperand (MCExpr const * Imm) : MCParsedAsmOperand(), Kind(k_Immediate), Imm(Imm) {}
133
105
134
106
union {
135
- Token Tok;
136
- Register Reg;
137
- Immediate Imm;
107
+ StringRef Tok;
108
+ unsigned Reg;
109
+ MCExpr const * Imm;
138
110
};
139
111
140
112
SMLoc StartLoc, EndLoc;
@@ -161,30 +133,28 @@ class AVROperand : public MCParsedAsmOperand {
161
133
addExpr (Inst,Expr);
162
134
}
163
135
164
- bool isReg () const { return Kind == k_Register; }
165
- bool isImm () const { return Kind == k_Immediate; }
136
+ bool isReg () const { return Kind == k_Register; }
137
+ bool isImm () const { return Kind == k_Immediate; }
166
138
bool isToken () const { return Kind == k_Token; }
167
- bool isMem () const { return false ; }
139
+ bool isMem () const { return false ; }
168
140
169
141
StringRef getToken () const {
170
142
assert (Kind == k_Token && " Invalid access!" );
171
- return StringRef ( Tok. Data , Tok. Length ) ;
143
+ return Tok;
172
144
}
173
145
174
146
unsigned getReg () const {
175
147
assert ((Kind == k_Register) && " Invalid access!" );
176
- return Reg. RegNum ;
148
+ return Reg;
177
149
}
178
150
179
151
const MCExpr *getImm () const {
180
152
assert ((Kind == k_Immediate) && " Invalid access!" );
181
- return Imm. Val ;
153
+ return Imm;
182
154
}
183
155
184
156
static std::unique_ptr<AVROperand> CreateToken (StringRef Str, SMLoc S) {
185
- auto Op = make_unique<AVROperand>(k_Token);
186
- Op->Tok .Data = Str.data ();
187
- Op->Tok .Length = Str.size ();
157
+ auto Op = make_unique<AVROperand>(Str);
188
158
Op->StartLoc = S;
189
159
Op->EndLoc = S;
190
160
return Op;
@@ -193,54 +163,38 @@ class AVROperand : public MCParsedAsmOperand {
193
163
// / Internal constructor for register kinds
194
164
static std::unique_ptr<AVROperand> CreateReg (unsigned RegNum, SMLoc S,
195
165
SMLoc E) {
196
- auto Op = make_unique<AVROperand>(k_Register);
197
- Op->Reg .RegNum = RegNum;
166
+ auto Op = make_unique<AVROperand>(RegNum);
198
167
Op->StartLoc = S;
199
168
Op->EndLoc = E;
200
169
return Op;
201
170
}
202
171
203
172
static std::unique_ptr<AVROperand> CreateImm (const MCExpr *Val, SMLoc S, SMLoc E) {
204
- auto Op = make_unique<AVROperand>(k_Immediate);
205
- Op->Imm .Val = Val;
173
+ auto Op = make_unique<AVROperand>(Val);
206
174
Op->StartLoc = S;
207
175
Op->EndLoc = E;
208
176
return Op;
209
177
}
210
178
211
- /* !
212
- * Gets the location of the first token of this operand.
213
- */
214
179
SMLoc getStartLoc () const { return StartLoc; }
215
- /* !
216
- * Gets the location of the last token of this operand.
217
- */
218
- SMLoc getEndLoc () const { return EndLoc; }
180
+ SMLoc getEndLoc () const { return EndLoc; }
219
181
220
182
virtual void print (raw_ostream &OS) const {
221
- OS << " AVROperand = " ;
222
-
223
183
switch (Kind) {
224
- case k_Token:
225
- OS << " Token(\" " << std::string (Tok.Data , Tok.Length ) << " \" )" ;
226
- break ;
227
- case k_Register:
228
- OS << " Register(Num = " << Reg.RegNum << " )" ;
229
- break ;
230
- case k_Immediate:
231
- OS << " Immediate(Expr = " ;
232
-
233
- Imm.Val ->print (OS);
234
-
235
- OS << " )" ;
236
-
237
- break ;
184
+ case k_Token: OS << " Token: \" " << Tok << " \" " ; break ;
185
+ case k_Register: OS << " Register: " << Reg; break ;
186
+ case k_Immediate: OS << " Immediate: \" " ; Imm->print (OS); OS << " \" " ; break ;
238
187
}
239
-
240
188
OS << " \n " ;
241
189
}
242
190
};
243
- }
191
+
192
+ } // end of anonymous namespace
193
+
194
+ // Auto-generated Match Functions
195
+
196
+ // Returns the register number, or 0 if the register is invalid.
197
+ static unsigned MatchRegisterName (StringRef Name);
244
198
245
199
bool AVRAsmParser::
246
200
MatchAndEmitInstruction (SMLoc IDLoc, unsigned &Opcode,
@@ -281,7 +235,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
281
235
282
236
int AVRAsmParser::parseRegister () {
283
237
const AsmToken &Tok = Parser.getTok ();
284
- int RegNum = - 1 ;
238
+ int RegNum = 0 ;
285
239
if (Tok.is (AsmToken::Identifier)) {
286
240
// check for register pair syntax
287
241
if (Parser.getLexer ().peekTok ().is (AsmToken::Colon)) {
@@ -301,8 +255,7 @@ bool AVRAsmParser::
301
255
tryParseRegisterOperand (OperandVector &Operands){
302
256
303
257
int RegNo = parseRegister ();
304
- if (RegNo == -1 )
305
- return true ;
258
+ if (RegNo == 0 ) return true ;
306
259
307
260
AsmToken const & T = Parser.getTok ();
308
261
Operands.push_back (AVROperand::CreateReg (RegNo, T.getLoc (), T.getEndLoc ()));
@@ -318,10 +271,31 @@ tryParseRegisterOperand(OperandVector &Operands){
318
271
319
272
bool
320
273
AVRAsmParser::tryParseExpression (OperandVector & Operands) {
274
+ AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None;
321
275
SMLoc S = Parser.getTok ().getLoc ();
276
+
277
+ // check if we have a target specific modifier (lo8, hi8, &c)
278
+ if (Parser.getTok ().getKind () == AsmToken::Identifier &&
279
+ Parser.getLexer ().peekTok ().getKind () == AsmToken::LParen)
280
+ {
281
+
282
+ StringRef ModifierName = Parser.getTok ().getString ();
283
+ ModifierKind = AVRMCExpr::getKindByName (ModifierName.str ().c_str ());
284
+ if (ModifierKind != AVRMCExpr::VK_AVR_None) {
285
+ Parser.Lex (); Parser.Lex (); // eat modifier name and parenthesis
286
+ }
287
+ }
288
+
289
+ // parse (potentially inner) expression
322
290
MCExpr const * Expression;
323
- if (getParser ().parseExpression (Expression))
324
- return true ;
291
+ if (getParser ().parseExpression (Expression)) return true ;
292
+
293
+ // if we have a modifier wrap the inner expression
294
+ if (ModifierKind != AVRMCExpr::VK_AVR_None) {
295
+ assert (Parser.getTok ().getKind () == AsmToken::RParen);
296
+ Parser.Lex (); // eat closing parenthesis
297
+ Expression = AVRMCExpr::create (ModifierKind, Expression, getContext ());
298
+ }
325
299
326
300
SMLoc E = SMLoc::getFromPointer (Parser.getTok ().getLoc ().getPointer () - 1 );
327
301
Operands.push_back (AVROperand::CreateImm (Expression, S, E));
@@ -367,7 +341,7 @@ bool AVRAsmParser::parseOperand(OperandVector &Operands,
367
341
appendToken (Operands);
368
342
return false ;
369
343
}
370
- } // switch(getLexer().getKind())
344
+ }
371
345
372
346
// could not parse operand
373
347
return true ;
@@ -419,12 +393,12 @@ AVRAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, unsigned Exp
419
393
if (Op.isReg ()) {
420
394
MatchClassKind Expected (static_cast <MatchClassKind>(ExpectedKind));
421
395
422
- // If the instructions uses a register pair but we got a single, lower
396
+ // If the instruction uses a register pair but we got a single, lower
423
397
// register we perform a "class cast".
424
398
if (isSubclass (Expected, MCK_DREGS)) {
425
399
unsigned correspondingDREG = toDREG (Op.getReg ());
426
400
if (correspondingDREG) {
427
- Op.Reg . RegNum = correspondingDREG;
401
+ Op.Reg = correspondingDREG;
428
402
return Match_Success;
429
403
}
430
404
}
0 commit comments