blob: bad187cf047879ffd2d739afc6e612a2acf71a2f [file] [log] [blame]
Jacques Pienaarfcef3e42016-03-28 13:09:54 +00001//===-- LanaiAsmParser.cpp - Parse Lanai 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 "Lanai.h"
11#include "MCTargetDesc/LanaiMCExpr.h"
12#include "MCTargetDesc/LanaiMCTargetDesc.h"
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCParser/MCAsmLexer.h"
18#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
19#include "llvm/MC/MCParser/MCTargetAsmParser.h"
20#include "llvm/MC/MCStreamer.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/MC/MCSymbol.h"
23#include "llvm/Support/MathExtras.h"
24#include "llvm/Support/TargetRegistry.h"
25
26namespace llvm {
27namespace {
28struct LanaiOperand;
29
30class LanaiAsmParser : public MCTargetAsmParser {
31 // Parse operands
32 std::unique_ptr<LanaiOperand> parseRegister();
33
34 std::unique_ptr<LanaiOperand> parseImmediate();
35
36 std::unique_ptr<LanaiOperand> parseIdentifier();
37
38 unsigned parseAluOperator(bool PreOp, bool PostOp);
39
40 // Split the mnemonic stripping conditional code and quantifiers
41 StringRef splitMnemonic(StringRef Name, SMLoc NameLoc,
42 OperandVector *Operands);
43
44 bool parsePrePost(StringRef Type, int *OffsetValue);
45
46 bool ParseDirective(AsmToken DirectiveID) override;
47
48 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
49 SMLoc NameLoc, OperandVector &Operands) override;
50
51 bool ParseRegister(unsigned &RegNum, SMLoc &StartLoc, SMLoc &EndLoc) override;
52
53 bool MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
54 OperandVector &Operands, MCStreamer &Out,
55 uint64_t &ErrorInfo,
56 bool MatchingInlineAsm) override;
57
58// Auto-generated instruction matching functions
59#define GET_ASSEMBLER_HEADER
60#include "LanaiGenAsmMatcher.inc"
61
62 OperandMatchResultTy parseOperand(OperandVector *Operands,
63 StringRef Mnemonic);
64
65 OperandMatchResultTy parseMemoryOperand(OperandVector &Operands);
66
67public:
68 LanaiAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
69 const MCInstrInfo &MII, const MCTargetOptions &Options)
70 : MCTargetAsmParser(Options, STI), Parser(Parser),
71 Lexer(Parser.getLexer()), SubtargetInfo(STI) {
72 setAvailableFeatures(
73 ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
74 }
75
76private:
77 MCAsmParser &Parser;
78 MCAsmLexer &Lexer;
79
80 const MCSubtargetInfo &SubtargetInfo;
81};
82
83// Auto-generated by TableGen
84static unsigned MatchRegisterName(llvm::StringRef Name);
85
86// LanaiOperand - Instances of this class represented a parsed machine
87// instruction
88struct LanaiOperand : public MCParsedAsmOperand {
89 enum KindTy {
90 TOKEN,
91 REGISTER,
92 IMMEDIATE,
93 MEMORY_IMM,
94 MEMORY_REG_IMM,
95 MEMORY_REG_REG,
96 } Kind;
97
98 SMLoc StartLoc, EndLoc;
99
100 struct Token {
101 const char *Data;
102 unsigned Length;
103 };
104
105 struct RegOp {
106 unsigned RegNum;
107 };
108
109 struct ImmOp {
110 const MCExpr *Value;
111 };
112
113 struct MemOp {
114 unsigned BaseReg;
115 unsigned OffsetReg;
116 unsigned AluOp;
117 const MCExpr *Offset;
118 };
119
120 union {
121 struct Token Tok;
122 struct RegOp Reg;
123 struct ImmOp Imm;
124 struct MemOp Mem;
125 };
126
127 explicit LanaiOperand(KindTy Kind) : MCParsedAsmOperand(), Kind(Kind) {}
128
129public:
130 // The functions below are used by the autogenerated ASM matcher and hence to
131 // be of the form expected.
132
133 // getStartLoc - Gets location of the first token of this operand
134 SMLoc getStartLoc() const override { return StartLoc; }
135
136 // getEndLoc - Gets location of the last token of this operand
Peter Collingbournecc723cc2016-10-09 04:39:13 +0000137 SMLoc getEndLoc() const { return EndLoc; }
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000138
139 unsigned getReg() const override {
140 assert(isReg() && "Invalid type access!");
141 return Reg.RegNum;
142 }
143
144 const MCExpr *getImm() const {
145 assert(isImm() && "Invalid type access!");
146 return Imm.Value;
147 }
148
149 StringRef getToken() const {
150 assert(isToken() && "Invalid type access!");
151 return StringRef(Tok.Data, Tok.Length);
152 }
153
154 unsigned getMemBaseReg() const {
155 assert(isMem() && "Invalid type access!");
156 return Mem.BaseReg;
157 }
158
159 unsigned getMemOffsetReg() const {
160 assert(isMem() && "Invalid type access!");
161 return Mem.OffsetReg;
162 }
163
164 const MCExpr *getMemOffset() const {
165 assert(isMem() && "Invalid type access!");
166 return Mem.Offset;
167 }
168
169 unsigned getMemOp() const {
170 assert(isMem() && "Invalid type access!");
171 return Mem.AluOp;
172 }
173
174 // Functions for testing operand type
175 bool isReg() const override { return Kind == REGISTER; }
176
177 bool isImm() const override { return Kind == IMMEDIATE; }
178
179 bool isMem() const override {
180 return isMemImm() || isMemRegImm() || isMemRegReg();
181 }
182
183 bool isMemImm() const { return Kind == MEMORY_IMM; }
184
185 bool isMemRegImm() const { return Kind == MEMORY_REG_IMM; }
186
187 bool isMemRegReg() const { return Kind == MEMORY_REG_REG; }
188
189 bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }
190
191 bool isToken() const override { return Kind == TOKEN; }
192
193 bool isBrImm() {
194 if (!isImm())
195 return false;
196
197 // Constant case
Jacques Pienaar4badd6a2016-03-31 17:58:55 +0000198 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm.Value);
199 if (!MCE)
200 return true;
201 int64_t Value = MCE->getValue();
202 // Check if value fits in 25 bits with 2 least significant bits 0.
203 return isShiftedUInt<23, 2>(static_cast<int32_t>(Value));
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000204 }
205
206 bool isBrTarget() { return isBrImm() || isToken(); }
207
208 bool isCallTarget() { return isImm() || isToken(); }
209
210 bool isHiImm16() {
211 if (!isImm())
212 return false;
213
214 // Constant case
215 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
216 int64_t Value = ConstExpr->getValue();
217 return Value != 0 && isShiftedUInt<16, 16>(Value);
218 }
219
220 // Symbolic reference expression
221 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
222 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;
223
224 // Binary expression
225 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
226 if (const LanaiMCExpr *SymbolRefExpr =
227 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
228 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;
229
230 return false;
231 }
232
233 bool isHiImm16And() {
234 if (!isImm())
235 return false;
236
237 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
238 if (ConstExpr) {
239 int64_t Value = ConstExpr->getValue();
240 // Check if in the form 0xXYZWffff
241 return (Value != 0) && ((Value & ~0xffff0000) == 0xffff);
242 }
243 return false;
244 }
245
246 bool isLoImm16() {
247 if (!isImm())
248 return false;
249
250 // Constant case
251 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
252 int64_t Value = ConstExpr->getValue();
253 // Check if value fits in 16 bits
254 return isUInt<16>(static_cast<int32_t>(Value));
255 }
256
257 // Symbolic reference expression
258 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
259 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
260
261 // Binary expression
262 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
263 if (const LanaiMCExpr *SymbolRefExpr =
264 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
265 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
266
267 return false;
268 }
269
270 bool isLoImm16Signed() {
271 if (!isImm())
272 return false;
273
274 // Constant case
275 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
276 int64_t Value = ConstExpr->getValue();
277 // Check if value fits in 16 bits or value of the form 0xffffxyzw
278 return isInt<16>(static_cast<int32_t>(Value));
279 }
280
281 // Symbolic reference expression
282 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
283 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
284
285 // Binary expression
286 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
287 if (const LanaiMCExpr *SymbolRefExpr =
288 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
289 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
290
291 return false;
292 }
293
294 bool isLoImm16And() {
295 if (!isImm())
296 return false;
297
298 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
299 if (ConstExpr) {
300 int64_t Value = ConstExpr->getValue();
301 // Check if in the form 0xffffXYZW
302 return ((Value & ~0xffff) == 0xffff0000);
303 }
304 return false;
305 }
306
307 bool isImmShift() {
308 if (!isImm())
309 return false;
310
311 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
312 if (!ConstExpr)
313 return false;
314 int64_t Value = ConstExpr->getValue();
315 return (Value >= -31) && (Value <= 31);
316 }
317
318 bool isLoImm21() {
319 if (!isImm())
320 return false;
321
322 // Constant case
323 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
324 int64_t Value = ConstExpr->getValue();
325 return isUInt<21>(Value);
326 }
327
328 // Symbolic reference expression
329 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
330 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
331 if (const MCSymbolRefExpr *SymbolRefExpr =
332 dyn_cast<MCSymbolRefExpr>(Imm.Value)) {
333 return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
334 }
335
336 // Binary expression
337 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value)) {
338 if (const LanaiMCExpr *SymbolRefExpr =
339 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
340 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
341 if (const MCSymbolRefExpr *SymbolRefExpr =
342 dyn_cast<MCSymbolRefExpr>(BinaryExpr->getLHS()))
343 return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
344 }
345
346 return false;
347 }
348
349 bool isImm10() {
350 if (!isImm())
351 return false;
352
353 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
354 if (!ConstExpr)
355 return false;
356 int64_t Value = ConstExpr->getValue();
357 return isInt<10>(Value);
358 }
359
Jacques Pienaar6d3eecc2016-07-07 23:36:04 +0000360 bool isCondCode() {
361 if (!isImm())
362 return false;
363
364 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
365 if (!ConstExpr)
366 return false;
367 uint64_t Value = ConstExpr->getValue();
368 // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
369 // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
370 // value corresponds to a valid condition code.
371 return Value < LPCC::UNKNOWN;
372 }
373
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000374 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
375 // Add as immediates where possible. Null MCExpr = 0
376 if (Expr == nullptr)
377 Inst.addOperand(MCOperand::createImm(0));
378 else if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
379 Inst.addOperand(
380 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
381 else
382 Inst.addOperand(MCOperand::createExpr(Expr));
383 }
384
385 void addRegOperands(MCInst &Inst, unsigned N) const {
386 assert(N == 1 && "Invalid number of operands!");
387 Inst.addOperand(MCOperand::createReg(getReg()));
388 }
389
390 void addImmOperands(MCInst &Inst, unsigned N) const {
391 assert(N == 1 && "Invalid number of operands!");
392 addExpr(Inst, getImm());
393 }
394
395 void addBrTargetOperands(MCInst &Inst, unsigned N) const {
396 assert(N == 1 && "Invalid number of operands!");
397 addExpr(Inst, getImm());
398 }
399
400 void addCallTargetOperands(MCInst &Inst, unsigned N) const {
401 assert(N == 1 && "Invalid number of operands!");
402 addExpr(Inst, getImm());
403 }
404
Jacques Pienaar6d3eecc2016-07-07 23:36:04 +0000405 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
406 assert(N == 1 && "Invalid number of operands!");
407 addExpr(Inst, getImm());
408 }
409
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000410 void addMemImmOperands(MCInst &Inst, unsigned N) const {
411 assert(N == 1 && "Invalid number of operands!");
412 const MCExpr *Expr = getMemOffset();
413 addExpr(Inst, Expr);
414 }
415
416 void addMemRegImmOperands(MCInst &Inst, unsigned N) const {
417 assert(N == 3 && "Invalid number of operands!");
418 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
419 const MCExpr *Expr = getMemOffset();
420 addExpr(Inst, Expr);
421 Inst.addOperand(MCOperand::createImm(getMemOp()));
422 }
423
424 void addMemRegRegOperands(MCInst &Inst, unsigned N) const {
425 assert(N == 3 && "Invalid number of operands!");
426 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
427 assert(getMemOffsetReg() != 0 && "Invalid offset");
428 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
429 Inst.addOperand(MCOperand::createImm(getMemOp()));
430 }
431
432 void addMemSplsOperands(MCInst &Inst, unsigned N) const {
433 if (isMemRegImm())
434 addMemRegImmOperands(Inst, N);
435 if (isMemRegReg())
436 addMemRegRegOperands(Inst, N);
437 }
438
439 void addImmShiftOperands(MCInst &Inst, unsigned N) const {
440 assert(N == 1 && "Invalid number of operands!");
441 addExpr(Inst, getImm());
442 }
443
444 void addImm10Operands(MCInst &Inst, unsigned N) const {
445 assert(N == 1 && "Invalid number of operands!");
446 addExpr(Inst, getImm());
447 }
448
449 void addLoImm16Operands(MCInst &Inst, unsigned N) const {
450 assert(N == 1 && "Invalid number of operands!");
451 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
452 Inst.addOperand(
453 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
454 else if (isa<LanaiMCExpr>(getImm())) {
455#ifndef NDEBUG
456 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
457 assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO);
458#endif
459 Inst.addOperand(MCOperand::createExpr(getImm()));
460 } else if (isa<MCBinaryExpr>(getImm())) {
461#ifndef NDEBUG
462 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
463 assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
464 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
465 LanaiMCExpr::VK_Lanai_ABS_LO);
466#endif
467 Inst.addOperand(MCOperand::createExpr(getImm()));
468 } else
469 assert(false && "Operand type not supported.");
470 }
471
472 void addLoImm16AndOperands(MCInst &Inst, unsigned N) const {
473 assert(N == 1 && "Invalid number of operands!");
474 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
475 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0xffff));
476 else
477 assert(false && "Operand type not supported.");
478 }
479
480 void addHiImm16Operands(MCInst &Inst, unsigned N) const {
481 assert(N == 1 && "Invalid number of operands!");
482 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
483 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
484 else if (isa<LanaiMCExpr>(getImm())) {
485#ifndef NDEBUG
486 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
487 assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI);
488#endif
489 Inst.addOperand(MCOperand::createExpr(getImm()));
490 } else if (isa<MCBinaryExpr>(getImm())) {
491#ifndef NDEBUG
492 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
493 assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
494 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
495 LanaiMCExpr::VK_Lanai_ABS_HI);
496#endif
497 Inst.addOperand(MCOperand::createExpr(getImm()));
498 } else
499 assert(false && "Operand type not supported.");
500 }
501
502 void addHiImm16AndOperands(MCInst &Inst, unsigned N) const {
503 assert(N == 1 && "Invalid number of operands!");
504 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
505 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
506 else
507 assert(false && "Operand type not supported.");
508 }
509
510 void addLoImm21Operands(MCInst &Inst, unsigned N) const {
511 assert(N == 1 && "Invalid number of operands!");
512 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
513 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
514 else if (isa<LanaiMCExpr>(getImm())) {
515#ifndef NDEBUG
516 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
517 assert(SymbolRefExpr &&
518 SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
519#endif
520 Inst.addOperand(MCOperand::createExpr(getImm()));
521 } else if (isa<MCSymbolRefExpr>(getImm())) {
522#ifndef NDEBUG
523 const MCSymbolRefExpr *SymbolRefExpr =
524 dyn_cast<MCSymbolRefExpr>(getImm());
525 assert(SymbolRefExpr &&
526 SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None);
527#endif
528 Inst.addOperand(MCOperand::createExpr(getImm()));
529 } else if (isa<MCBinaryExpr>(getImm())) {
530#ifndef NDEBUG
531 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
532 const LanaiMCExpr *SymbolRefExpr =
533 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
534 assert(SymbolRefExpr &&
535 SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
536#endif
537 Inst.addOperand(MCOperand::createExpr(getImm()));
538 } else
539 assert(false && "Operand type not supported.");
540 }
541
542 void print(raw_ostream &OS) const override {
543 switch (Kind) {
544 case IMMEDIATE:
545 OS << "Imm: " << getImm() << "\n";
546 break;
547 case TOKEN:
548 OS << "Token: " << getToken() << "\n";
549 break;
550 case REGISTER:
551 OS << "Reg: %r" << getReg() << "\n";
552 break;
553 case MEMORY_IMM:
554 OS << "MemImm: " << *getMemOffset() << "\n";
555 break;
556 case MEMORY_REG_IMM:
557 OS << "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
558 break;
559 case MEMORY_REG_REG:
560 assert(getMemOffset() == nullptr);
561 OS << "MemRegReg: " << getMemBaseReg() << "+"
562 << "%r" << getMemOffsetReg() << "\n";
563 break;
564 }
565 }
566
567 static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
568 auto Op = make_unique<LanaiOperand>(TOKEN);
569 Op->Tok.Data = Str.data();
570 Op->Tok.Length = Str.size();
571 Op->StartLoc = Start;
572 Op->EndLoc = Start;
573 return Op;
574 }
575
576 static std::unique_ptr<LanaiOperand> createReg(unsigned RegNum, SMLoc Start,
577 SMLoc End) {
578 auto Op = make_unique<LanaiOperand>(REGISTER);
579 Op->Reg.RegNum = RegNum;
580 Op->StartLoc = Start;
581 Op->EndLoc = End;
582 return Op;
583 }
584
585 static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
586 SMLoc Start, SMLoc End) {
587 auto Op = make_unique<LanaiOperand>(IMMEDIATE);
588 Op->Imm.Value = Value;
589 Op->StartLoc = Start;
590 Op->EndLoc = End;
591 return Op;
592 }
593
594 static std::unique_ptr<LanaiOperand>
595 MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
596 const MCExpr *Imm = Op->getImm();
597 Op->Kind = MEMORY_IMM;
598 Op->Mem.BaseReg = 0;
599 Op->Mem.AluOp = LPAC::ADD;
600 Op->Mem.OffsetReg = 0;
601 Op->Mem.Offset = Imm;
602 return Op;
603 }
604
605 static std::unique_ptr<LanaiOperand>
606 MorphToMemRegReg(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
607 unsigned AluOp) {
608 unsigned OffsetReg = Op->getReg();
609 Op->Kind = MEMORY_REG_REG;
610 Op->Mem.BaseReg = BaseReg;
611 Op->Mem.AluOp = AluOp;
612 Op->Mem.OffsetReg = OffsetReg;
613 Op->Mem.Offset = nullptr;
614 return Op;
615 }
616
617 static std::unique_ptr<LanaiOperand>
618 MorphToMemRegImm(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
619 unsigned AluOp) {
620 const MCExpr *Imm = Op->getImm();
621 Op->Kind = MEMORY_REG_IMM;
622 Op->Mem.BaseReg = BaseReg;
623 Op->Mem.AluOp = AluOp;
624 Op->Mem.OffsetReg = 0;
625 Op->Mem.Offset = Imm;
626 return Op;
627 }
628};
629
Jacques Pienaare2f06992016-07-15 22:38:32 +0000630bool LanaiAsmParser::ParseDirective(AsmToken /*DirectiveId*/) { return true; }
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000631
632bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
633 OperandVector &Operands,
634 MCStreamer &Out,
635 uint64_t &ErrorInfo,
636 bool MatchingInlineAsm) {
637 MCInst Inst;
638 SMLoc ErrorLoc;
639
640 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
641 case Match_Success:
642 Out.EmitInstruction(Inst, SubtargetInfo);
Jacques Pienaare2f06992016-07-15 22:38:32 +0000643 Opcode = Inst.getOpcode();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000644 return false;
645 case Match_MissingFeature:
646 return Error(IdLoc, "Instruction use requires option to be enabled");
647 case Match_MnemonicFail:
648 return Error(IdLoc, "Unrecognized instruction mnemonic");
649 case Match_InvalidOperand: {
650 ErrorLoc = IdLoc;
651 if (ErrorInfo != ~0U) {
652 if (ErrorInfo >= Operands.size())
653 return Error(IdLoc, "Too few operands for instruction");
654
655 ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
656 if (ErrorLoc == SMLoc())
657 ErrorLoc = IdLoc;
658 }
659 return Error(ErrorLoc, "Invalid operand for instruction");
660 }
661 default:
662 break;
663 }
664
665 llvm_unreachable("Unknown match type detected!");
666}
667
668// Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
669// backwards compatible with GCC and the different ways inline assembly is
670// handled.
671// TODO: see if there isn't a better way to do this.
672std::unique_ptr<LanaiOperand> LanaiAsmParser::parseRegister() {
673 SMLoc Start = Parser.getTok().getLoc();
674 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
675
676 unsigned RegNum;
677 // Eat the '%'.
678 if (Lexer.getKind() == AsmToken::Percent)
679 Parser.Lex();
680 if (Lexer.getKind() == AsmToken::Identifier) {
681 RegNum = MatchRegisterName(Lexer.getTok().getIdentifier());
682 if (RegNum == 0)
683 return 0;
684 Parser.Lex(); // Eat identifier token
685 return LanaiOperand::createReg(RegNum, Start, End);
686 }
687 return 0;
688}
689
690bool LanaiAsmParser::ParseRegister(unsigned &RegNum, SMLoc &StartLoc,
691 SMLoc &EndLoc) {
Jacques Pienaare2f06992016-07-15 22:38:32 +0000692 const AsmToken &Tok = getParser().getTok();
693 StartLoc = Tok.getLoc();
694 EndLoc = Tok.getEndLoc();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000695 std::unique_ptr<LanaiOperand> Op = parseRegister();
Jacques Pienaare2f06992016-07-15 22:38:32 +0000696 if (Op != nullptr)
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000697 RegNum = Op->getReg();
Jacques Pienaare2f06992016-07-15 22:38:32 +0000698 return (Op == nullptr);
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000699}
700
701std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
702 SMLoc Start = Parser.getTok().getLoc();
703 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
704 const MCExpr *Res, *RHS = 0;
705 LanaiMCExpr::VariantKind Kind = LanaiMCExpr::VK_Lanai_None;
706
707 if (Lexer.getKind() != AsmToken::Identifier)
708 return 0;
709
710 StringRef Identifier;
711 if (Parser.parseIdentifier(Identifier))
712 return 0;
713
714 // Check if identifier has a modifier
715 if (Identifier.equals_lower("hi"))
716 Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
717 else if (Identifier.equals_lower("lo"))
718 Kind = LanaiMCExpr::VK_Lanai_ABS_LO;
719
720 // If the identifier corresponds to a variant then extract the real
721 // identifier.
722 if (Kind != LanaiMCExpr::VK_Lanai_None) {
723 if (Lexer.getKind() != AsmToken::LParen) {
724 Error(Lexer.getLoc(), "Expected '('");
725 return 0;
726 }
727 Lexer.Lex(); // lex '('
728
729 // Parse identifier
730 if (Parser.parseIdentifier(Identifier))
731 return 0;
732 }
733
734 // If addition parse the RHS.
735 if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS))
736 return 0;
737
738 // For variants parse the final ')'
739 if (Kind != LanaiMCExpr::VK_Lanai_None) {
740 if (Lexer.getKind() != AsmToken::RParen) {
741 Error(Lexer.getLoc(), "Expected ')'");
742 return 0;
743 }
744 Lexer.Lex(); // lex ')'
745 }
746
747 End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
748 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
749 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
750 Res = LanaiMCExpr::create(Kind, Expr, getContext());
751
752 // Nest if this was an addition
753 if (RHS)
754 Res = MCBinaryExpr::createAdd(Res, RHS, getContext());
755
756 return LanaiOperand::createImm(Res, Start, End);
757}
758
759std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
760 SMLoc Start = Parser.getTok().getLoc();
761 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
762
763 const MCExpr *ExprVal;
764 switch (Lexer.getKind()) {
765 case AsmToken::Identifier:
766 return parseIdentifier();
767 case AsmToken::Plus:
768 case AsmToken::Minus:
769 case AsmToken::Integer:
770 case AsmToken::Dot:
771 if (!Parser.parseExpression(ExprVal))
772 return LanaiOperand::createImm(ExprVal, Start, End);
773 default:
774 return 0;
775 }
776}
777
778static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
779 if (PreOp)
780 return LPAC::makePreOp(AluCode);
781 if (PostOp)
782 return LPAC::makePostOp(AluCode);
783 return AluCode;
784}
785
786unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
787 StringRef IdString;
788 Parser.parseIdentifier(IdString);
789 unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
790 if (AluCode == LPAC::UNKNOWN) {
791 Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
792 return 0;
793 }
794 return AluCode;
795}
796
797static int SizeForSuffix(StringRef T) {
798 return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
799}
800
801bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
802 bool PreOrPost = false;
803 if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
804 PreOrPost = true;
805 if (Lexer.is(AsmToken::Minus))
806 *OffsetValue = -SizeForSuffix(Type);
807 else if (Lexer.is(AsmToken::Plus))
808 *OffsetValue = SizeForSuffix(Type);
809 else
810 return false;
811
812 // Eat the '-' '-' or '+' '+'
813 Parser.Lex();
814 Parser.Lex();
815 } else if (Lexer.is(AsmToken::Star)) {
816 Parser.Lex(); // Eat the '*'
817 PreOrPost = true;
818 }
819
820 return PreOrPost;
821}
822
823bool shouldBeSls(const LanaiOperand &Op) {
824 // The instruction should be encoded as an SLS if the constant is word
825 // aligned and will fit in 21 bits
826 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
827 int64_t Value = ConstExpr->getValue();
828 return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
829 }
830 // The instruction should be encoded as an SLS if the operand is a symbolic
831 // reference with no variant.
832 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
833 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
834 // The instruction should be encoded as an SLS if the operand is a binary
835 // expression with the left-hand side being a symbolic reference with no
836 // variant.
837 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
838 const LanaiMCExpr *LHSSymbolRefExpr =
839 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
840 return (LHSSymbolRefExpr &&
841 LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
842 }
843 return false;
844}
845
846// Matches memory operand. Returns true if error encountered.
847LanaiAsmParser::OperandMatchResultTy
848LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
849 // Try to match a memory operand.
850 // The memory operands are of the form:
851 // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or
852 // ^
853 // (2) '[' '*'? Register '*'? AluOperator Register ']'
854 // ^
855 // (3) '[' '--'|'++' Register '--'|'++' ']'
856 //
857 // (4) '[' Immediate ']' (for SLS)
858
859 // Store the type for use in parsing pre/post increment/decrement operators
860 StringRef Type;
861 if (Operands[0]->isToken())
862 Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();
863
864 // Use 0 if no offset given
865 int OffsetValue = 0;
866 unsigned BaseReg = 0;
867 unsigned AluOp = LPAC::ADD;
868 bool PostOp = false, PreOp = false;
869
870 // Try to parse the offset
871 std::unique_ptr<LanaiOperand> Op = parseRegister();
872 if (!Op)
873 Op = parseImmediate();
874
875 // Only continue if next token is '['
876 if (Lexer.isNot(AsmToken::LBrac)) {
877 if (!Op)
878 return MatchOperand_NoMatch;
879
880 // The start of this custom parsing overlaps with register/immediate so
881 // consider this as a successful match of an operand of that type as the
882 // token stream can't be rewound to allow them to match separately.
883 Operands.push_back(std::move(Op));
884 return MatchOperand_Success;
885 }
886
887 Parser.Lex(); // Eat the '['.
888 std::unique_ptr<LanaiOperand> Offset = nullptr;
889 if (Op)
890 Offset.swap(Op);
891
892 // Determine if a pre operation
893 PreOp = parsePrePost(Type, &OffsetValue);
894
895 Op = parseRegister();
896 if (!Op) {
897 if (!Offset) {
898 if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
899 Parser.Lex(); // Eat the ']'
900
901 // Memory address operations aligned to word boundary are encoded as
902 // SLS, the rest as RM.
903 if (shouldBeSls(*Op)) {
904 Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
905 } else {
906 if (!Op->isLoImm16Signed()) {
907 Error(Parser.getTok().getLoc(),
908 "Memory address is not word "
909 "aligned and larger than class RM can handle");
910 return MatchOperand_ParseFail;
911 }
912 Operands.push_back(LanaiOperand::MorphToMemRegImm(
913 Lanai::R0, std::move(Op), LPAC::ADD));
914 }
915 return MatchOperand_Success;
916 }
917 }
918
919 Error(Parser.getTok().getLoc(),
920 "Unknown operand, expected register or immediate");
921 return MatchOperand_ParseFail;
922 }
923 BaseReg = Op->getReg();
924
925 // Determine if a post operation
926 if (!PreOp)
927 PostOp = parsePrePost(Type, &OffsetValue);
928
929 // If ] match form (1) else match form (2)
930 if (Lexer.is(AsmToken::RBrac)) {
931 Parser.Lex(); // Eat the ']'.
932 if (!Offset) {
933 SMLoc Start = Parser.getTok().getLoc();
934 SMLoc End =
935 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
936 const MCConstantExpr *OffsetConstExpr =
937 MCConstantExpr::create(OffsetValue, getContext());
938 Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
939 }
940 } else {
941 if (Offset || OffsetValue != 0) {
942 Error(Parser.getTok().getLoc(), "Expected ']'");
943 return MatchOperand_ParseFail;
944 }
945
946 // Parse operator
947 AluOp = parseAluOperator(PreOp, PostOp);
948
949 // Second form requires offset register
950 Offset = parseRegister();
951 if (!BaseReg || Lexer.isNot(AsmToken::RBrac)) {
952 Error(Parser.getTok().getLoc(), "Expected ']'");
953 return MatchOperand_ParseFail;
954 }
955 Parser.Lex(); // Eat the ']'.
956 }
957
958 // First form has addition as operator. Add pre- or post-op indicator as
959 // needed.
960 AluOp = AluWithPrePost(AluOp, PreOp, PostOp);
961
962 // Ensure immediate offset is not too large
963 if (Offset->isImm() && !Offset->isLoImm16Signed()) {
964 Error(Parser.getTok().getLoc(),
965 "Memory address is not word "
966 "aligned and larger than class RM can handle");
967 return MatchOperand_ParseFail;
968 }
969
970 Operands.push_back(
971 Offset->isImm()
972 ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
973 : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));
974
975 return MatchOperand_Success;
976}
977
978// Looks at a token type and creates the relevant operand from this
979// information, adding to operands.
980// If operand was parsed, returns false, else true.
981LanaiAsmParser::OperandMatchResultTy
982LanaiAsmParser::parseOperand(OperandVector *Operands, StringRef Mnemonic) {
983 // Check if the current operand has a custom associated parser, if so, try to
984 // custom parse the operand, or fallback to the general approach.
985 OperandMatchResultTy Result = MatchOperandParserImpl(*Operands, Mnemonic);
986
987 if (Result == MatchOperand_Success)
988 return Result;
989 if (Result == MatchOperand_ParseFail) {
990 Parser.eatToEndOfStatement();
991 return Result;
992 }
993
994 // Attempt to parse token as register
995 std::unique_ptr<LanaiOperand> Op = parseRegister();
996
997 // Attempt to parse token as immediate
998 if (!Op)
999 Op = parseImmediate();
1000
1001 // If the token could not be parsed then fail
1002 if (!Op) {
1003 Error(Parser.getTok().getLoc(), "Unknown operand");
1004 Parser.eatToEndOfStatement();
1005 return MatchOperand_ParseFail;
1006 }
1007
1008 // Push back parsed operand into list of operands
1009 Operands->push_back(std::move(Op));
1010
1011 return MatchOperand_Success;
1012}
1013
1014// Split the mnemonic into ASM operand, conditional code and instruction
1015// qualifier (half-word, byte).
1016StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1017 OperandVector *Operands) {
1018 size_t Next = Name.find('.');
1019
1020 StringRef Mnemonic = Name;
1021
1022 bool IsBRR = false;
1023 if (Name.endswith(".r")) {
1024 Mnemonic = Name.substr(0, Name.size() - 2);
1025 IsBRR = true;
1026 }
1027
1028 // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1029 if (Mnemonic[0] == 'b' ||
1030 (Mnemonic[0] == 's' && !Mnemonic.startswith("sel") &&
1031 !Mnemonic.startswith("st"))) {
1032 // Parse instructions with a conditional code. For example, 'bne' is
1033 // converted into two operands 'b' and 'ne'.
1034 LPCC::CondCode CondCode =
1035 LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
1036 if (CondCode != LPCC::UNKNOWN) {
1037 Mnemonic = Mnemonic.slice(0, 1);
1038 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1039 Operands->push_back(LanaiOperand::createImm(
1040 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1041 if (IsBRR) {
1042 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1043 }
1044 return Mnemonic;
1045 }
1046 }
1047
1048 // Parse other instructions with condition codes (RR instructions).
1049 // We ignore .f here and assume they are flag-setting operations, not
1050 // conditional codes (except for select instructions where flag-setting
1051 // variants are not yet implemented).
1052 if (Mnemonic.startswith("sel") ||
1053 (!Mnemonic.endswith(".f") && !Mnemonic.startswith("st"))) {
1054 LPCC::CondCode CondCode = LPCC::suffixToLanaiCondCode(Mnemonic);
1055 if (CondCode != LPCC::UNKNOWN) {
1056 size_t Next = Mnemonic.rfind('.', Name.size());
Jacques Pienaar6d3eecc2016-07-07 23:36:04 +00001057 // 'sel' doesn't use a predicate operand whose printer adds the period,
1058 // but instead has the period as part of the identifier (i.e., 'sel.' is
1059 // expected by the generated matcher). If the mnemonic starts with 'sel'
1060 // then include the period as part of the mnemonic, else don't include it
1061 // as part of the mnemonic.
1062 if (Mnemonic.startswith("sel")) {
1063 Mnemonic = Mnemonic.substr(0, Next + 1);
1064 } else {
1065 Mnemonic = Mnemonic.substr(0, Next);
1066 }
Jacques Pienaarfcef3e42016-03-28 13:09:54 +00001067 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1068 Operands->push_back(LanaiOperand::createImm(
1069 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1070 return Mnemonic;
1071 }
1072 }
1073
1074 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1075 if (IsBRR) {
1076 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1077 }
1078
1079 return Mnemonic;
1080}
1081
1082bool IsMemoryAssignmentError(const OperandVector &Operands) {
1083 // Detects if a memory operation has an erroneous base register modification.
1084 // Memory operations are detected by matching the types of operands.
1085 //
1086 // TODO: This test is focussed on one specific instance (ld/st).
1087 // Extend it to handle more cases or be more robust.
1088 bool Modifies = false;
1089
1090 int Offset = 0;
1091
1092 if (Operands.size() < 5)
1093 return false;
1094 else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1095 Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
1096 Offset = 0;
1097 else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1098 Operands[2]->isReg() && Operands[3]->isImm() &&
1099 Operands[4]->isImm() && Operands[5]->isReg())
1100 Offset = 1;
1101 else
1102 return false;
1103
1104 int PossibleAluOpIdx = Offset + 3;
1105 int PossibleBaseIdx = Offset + 1;
1106 int PossibleDestIdx = Offset + 4;
1107 if (LanaiOperand *PossibleAluOp =
1108 static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
1109 if (PossibleAluOp->isImm())
1110 if (const MCConstantExpr *ConstExpr =
1111 dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1112 Modifies = LPAC::modifiesOp(ConstExpr->getValue());
1113 return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1114 Operands[PossibleDestIdx]->isReg() &&
1115 Operands[PossibleBaseIdx]->getReg() ==
1116 Operands[PossibleDestIdx]->getReg();
1117}
1118
Jacques Pienaarb32a9122016-07-09 18:26:04 +00001119static bool IsRegister(const MCParsedAsmOperand &op) {
1120 return static_cast<const LanaiOperand &>(op).isReg();
1121}
1122
1123static bool MaybePredicatedInst(const OperandVector &Operands) {
1124 if (Operands.size() < 4 || !IsRegister(*Operands[1]) ||
1125 !IsRegister(*Operands[2]))
1126 return false;
1127 return StringSwitch<bool>(
1128 static_cast<const LanaiOperand &>(*Operands[0]).getToken())
1129 .StartsWith("addc", true)
1130 .StartsWith("add", true)
1131 .StartsWith("and", true)
1132 .StartsWith("sh", true)
1133 .StartsWith("subb", true)
1134 .StartsWith("sub", true)
1135 .StartsWith("or", true)
1136 .StartsWith("xor", true)
1137 .Default(false);
1138}
1139
Jacques Pienaare2f06992016-07-15 22:38:32 +00001140bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo & /*Info*/,
Jacques Pienaarfcef3e42016-03-28 13:09:54 +00001141 StringRef Name, SMLoc NameLoc,
1142 OperandVector &Operands) {
1143 // First operand is token for instruction
1144 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1145
1146 // If there are no more operands, then finish
1147 if (Lexer.is(AsmToken::EndOfStatement))
1148 return false;
1149
1150 // Parse first operand
1151 if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1152 return true;
1153
1154 // If it is a st instruction with one 1 operand then it is a "store true".
1155 // Transform <"st"> to <"s">, <LPCC:ICC_T>
1156 if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" &&
1157 Operands.size() == 2) {
1158 Operands.erase(Operands.begin(), Operands.begin() + 1);
1159 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
1160 Operands.insert(Operands.begin() + 1,
1161 LanaiOperand::createImm(
1162 MCConstantExpr::create(LPCC::ICC_T, getContext()),
1163 NameLoc, NameLoc));
1164 }
1165
1166 // If the instruction is a bt instruction with 1 operand (in assembly) then it
1167 // is an unconditional branch instruction and the first two elements of
1168 // operands need to be merged.
1169 if (Lexer.is(AsmToken::EndOfStatement) && Name.startswith("bt") &&
1170 Operands.size() == 3) {
1171 Operands.erase(Operands.begin(), Operands.begin() + 2);
1172 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
1173 }
1174
1175 // Parse until end of statement, consuming commas between operands
1176 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) {
1177 // Consume comma token
Nirav Davefd910412016-06-17 16:06:17 +00001178 Lex();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +00001179
1180 // Parse next operand
1181 if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1182 return true;
1183 }
1184
1185 if (IsMemoryAssignmentError(Operands)) {
1186 Error(Parser.getTok().getLoc(),
1187 "the destination register can't equal the base register in an "
1188 "instruction that modifies the base register.");
1189 return true;
1190 }
1191
Jacques Pienaarb32a9122016-07-09 18:26:04 +00001192 // Insert always true operand for instruction that may be predicated but
1193 // are not. Currently the autogenerated parser always expects a predicate.
1194 if (MaybePredicatedInst(Operands)) {
1195 Operands.insert(Operands.begin() + 1,
1196 LanaiOperand::createImm(
1197 MCConstantExpr::create(LPCC::ICC_T, getContext()),
1198 NameLoc, NameLoc));
1199 }
1200
Jacques Pienaarfcef3e42016-03-28 13:09:54 +00001201 return false;
1202}
1203
1204#define GET_REGISTER_MATCHER
1205#define GET_MATCHER_IMPLEMENTATION
1206#include "LanaiGenAsmMatcher.inc"
1207} // namespace
1208
1209extern "C" void LLVMInitializeLanaiAsmParser() {
1210 RegisterMCAsmParser<LanaiAsmParser> x(TheLanaiTarget);
1211}
1212
1213} // namespace llvm