blob: 799f587ff3f648b494c110037f92d232a9051d34 [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
137 SMLoc getEndLoc() const override { return EndLoc; }
138
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
360 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
361 // Add as immediates where possible. Null MCExpr = 0
362 if (Expr == nullptr)
363 Inst.addOperand(MCOperand::createImm(0));
364 else if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
365 Inst.addOperand(
366 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
367 else
368 Inst.addOperand(MCOperand::createExpr(Expr));
369 }
370
371 void addRegOperands(MCInst &Inst, unsigned N) const {
372 assert(N == 1 && "Invalid number of operands!");
373 Inst.addOperand(MCOperand::createReg(getReg()));
374 }
375
376 void addImmOperands(MCInst &Inst, unsigned N) const {
377 assert(N == 1 && "Invalid number of operands!");
378 addExpr(Inst, getImm());
379 }
380
381 void addBrTargetOperands(MCInst &Inst, unsigned N) const {
382 assert(N == 1 && "Invalid number of operands!");
383 addExpr(Inst, getImm());
384 }
385
386 void addCallTargetOperands(MCInst &Inst, unsigned N) const {
387 assert(N == 1 && "Invalid number of operands!");
388 addExpr(Inst, getImm());
389 }
390
391 void addMemImmOperands(MCInst &Inst, unsigned N) const {
392 assert(N == 1 && "Invalid number of operands!");
393 const MCExpr *Expr = getMemOffset();
394 addExpr(Inst, Expr);
395 }
396
397 void addMemRegImmOperands(MCInst &Inst, unsigned N) const {
398 assert(N == 3 && "Invalid number of operands!");
399 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
400 const MCExpr *Expr = getMemOffset();
401 addExpr(Inst, Expr);
402 Inst.addOperand(MCOperand::createImm(getMemOp()));
403 }
404
405 void addMemRegRegOperands(MCInst &Inst, unsigned N) const {
406 assert(N == 3 && "Invalid number of operands!");
407 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
408 assert(getMemOffsetReg() != 0 && "Invalid offset");
409 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
410 Inst.addOperand(MCOperand::createImm(getMemOp()));
411 }
412
413 void addMemSplsOperands(MCInst &Inst, unsigned N) const {
414 if (isMemRegImm())
415 addMemRegImmOperands(Inst, N);
416 if (isMemRegReg())
417 addMemRegRegOperands(Inst, N);
418 }
419
420 void addImmShiftOperands(MCInst &Inst, unsigned N) const {
421 assert(N == 1 && "Invalid number of operands!");
422 addExpr(Inst, getImm());
423 }
424
425 void addImm10Operands(MCInst &Inst, unsigned N) const {
426 assert(N == 1 && "Invalid number of operands!");
427 addExpr(Inst, getImm());
428 }
429
430 void addLoImm16Operands(MCInst &Inst, unsigned N) const {
431 assert(N == 1 && "Invalid number of operands!");
432 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
433 Inst.addOperand(
434 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
435 else if (isa<LanaiMCExpr>(getImm())) {
436#ifndef NDEBUG
437 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
438 assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO);
439#endif
440 Inst.addOperand(MCOperand::createExpr(getImm()));
441 } else if (isa<MCBinaryExpr>(getImm())) {
442#ifndef NDEBUG
443 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
444 assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
445 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
446 LanaiMCExpr::VK_Lanai_ABS_LO);
447#endif
448 Inst.addOperand(MCOperand::createExpr(getImm()));
449 } else
450 assert(false && "Operand type not supported.");
451 }
452
453 void addLoImm16AndOperands(MCInst &Inst, unsigned N) const {
454 assert(N == 1 && "Invalid number of operands!");
455 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
456 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0xffff));
457 else
458 assert(false && "Operand type not supported.");
459 }
460
461 void addHiImm16Operands(MCInst &Inst, unsigned N) const {
462 assert(N == 1 && "Invalid number of operands!");
463 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
464 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
465 else if (isa<LanaiMCExpr>(getImm())) {
466#ifndef NDEBUG
467 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
468 assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI);
469#endif
470 Inst.addOperand(MCOperand::createExpr(getImm()));
471 } else if (isa<MCBinaryExpr>(getImm())) {
472#ifndef NDEBUG
473 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
474 assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
475 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
476 LanaiMCExpr::VK_Lanai_ABS_HI);
477#endif
478 Inst.addOperand(MCOperand::createExpr(getImm()));
479 } else
480 assert(false && "Operand type not supported.");
481 }
482
483 void addHiImm16AndOperands(MCInst &Inst, unsigned N) const {
484 assert(N == 1 && "Invalid number of operands!");
485 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
486 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
487 else
488 assert(false && "Operand type not supported.");
489 }
490
491 void addLoImm21Operands(MCInst &Inst, unsigned N) const {
492 assert(N == 1 && "Invalid number of operands!");
493 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
494 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
495 else if (isa<LanaiMCExpr>(getImm())) {
496#ifndef NDEBUG
497 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
498 assert(SymbolRefExpr &&
499 SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
500#endif
501 Inst.addOperand(MCOperand::createExpr(getImm()));
502 } else if (isa<MCSymbolRefExpr>(getImm())) {
503#ifndef NDEBUG
504 const MCSymbolRefExpr *SymbolRefExpr =
505 dyn_cast<MCSymbolRefExpr>(getImm());
506 assert(SymbolRefExpr &&
507 SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None);
508#endif
509 Inst.addOperand(MCOperand::createExpr(getImm()));
510 } else if (isa<MCBinaryExpr>(getImm())) {
511#ifndef NDEBUG
512 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
513 const LanaiMCExpr *SymbolRefExpr =
514 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
515 assert(SymbolRefExpr &&
516 SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
517#endif
518 Inst.addOperand(MCOperand::createExpr(getImm()));
519 } else
520 assert(false && "Operand type not supported.");
521 }
522
523 void print(raw_ostream &OS) const override {
524 switch (Kind) {
525 case IMMEDIATE:
526 OS << "Imm: " << getImm() << "\n";
527 break;
528 case TOKEN:
529 OS << "Token: " << getToken() << "\n";
530 break;
531 case REGISTER:
532 OS << "Reg: %r" << getReg() << "\n";
533 break;
534 case MEMORY_IMM:
535 OS << "MemImm: " << *getMemOffset() << "\n";
536 break;
537 case MEMORY_REG_IMM:
538 OS << "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
539 break;
540 case MEMORY_REG_REG:
541 assert(getMemOffset() == nullptr);
542 OS << "MemRegReg: " << getMemBaseReg() << "+"
543 << "%r" << getMemOffsetReg() << "\n";
544 break;
545 }
546 }
547
548 static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
549 auto Op = make_unique<LanaiOperand>(TOKEN);
550 Op->Tok.Data = Str.data();
551 Op->Tok.Length = Str.size();
552 Op->StartLoc = Start;
553 Op->EndLoc = Start;
554 return Op;
555 }
556
557 static std::unique_ptr<LanaiOperand> createReg(unsigned RegNum, SMLoc Start,
558 SMLoc End) {
559 auto Op = make_unique<LanaiOperand>(REGISTER);
560 Op->Reg.RegNum = RegNum;
561 Op->StartLoc = Start;
562 Op->EndLoc = End;
563 return Op;
564 }
565
566 static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
567 SMLoc Start, SMLoc End) {
568 auto Op = make_unique<LanaiOperand>(IMMEDIATE);
569 Op->Imm.Value = Value;
570 Op->StartLoc = Start;
571 Op->EndLoc = End;
572 return Op;
573 }
574
575 static std::unique_ptr<LanaiOperand>
576 MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
577 const MCExpr *Imm = Op->getImm();
578 Op->Kind = MEMORY_IMM;
579 Op->Mem.BaseReg = 0;
580 Op->Mem.AluOp = LPAC::ADD;
581 Op->Mem.OffsetReg = 0;
582 Op->Mem.Offset = Imm;
583 return Op;
584 }
585
586 static std::unique_ptr<LanaiOperand>
587 MorphToMemRegReg(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
588 unsigned AluOp) {
589 unsigned OffsetReg = Op->getReg();
590 Op->Kind = MEMORY_REG_REG;
591 Op->Mem.BaseReg = BaseReg;
592 Op->Mem.AluOp = AluOp;
593 Op->Mem.OffsetReg = OffsetReg;
594 Op->Mem.Offset = nullptr;
595 return Op;
596 }
597
598 static std::unique_ptr<LanaiOperand>
599 MorphToMemRegImm(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
600 unsigned AluOp) {
601 const MCExpr *Imm = Op->getImm();
602 Op->Kind = MEMORY_REG_IMM;
603 Op->Mem.BaseReg = BaseReg;
604 Op->Mem.AluOp = AluOp;
605 Op->Mem.OffsetReg = 0;
606 Op->Mem.Offset = Imm;
607 return Op;
608 }
609};
610
611bool LanaiAsmParser::ParseDirective(AsmToken DirectiveId) { return true; }
612
613bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
614 OperandVector &Operands,
615 MCStreamer &Out,
616 uint64_t &ErrorInfo,
617 bool MatchingInlineAsm) {
618 MCInst Inst;
619 SMLoc ErrorLoc;
620
621 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
622 case Match_Success:
623 Out.EmitInstruction(Inst, SubtargetInfo);
624 return false;
625 case Match_MissingFeature:
626 return Error(IdLoc, "Instruction use requires option to be enabled");
627 case Match_MnemonicFail:
628 return Error(IdLoc, "Unrecognized instruction mnemonic");
629 case Match_InvalidOperand: {
630 ErrorLoc = IdLoc;
631 if (ErrorInfo != ~0U) {
632 if (ErrorInfo >= Operands.size())
633 return Error(IdLoc, "Too few operands for instruction");
634
635 ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
636 if (ErrorLoc == SMLoc())
637 ErrorLoc = IdLoc;
638 }
639 return Error(ErrorLoc, "Invalid operand for instruction");
640 }
641 default:
642 break;
643 }
644
645 llvm_unreachable("Unknown match type detected!");
646}
647
648// Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
649// backwards compatible with GCC and the different ways inline assembly is
650// handled.
651// TODO: see if there isn't a better way to do this.
652std::unique_ptr<LanaiOperand> LanaiAsmParser::parseRegister() {
653 SMLoc Start = Parser.getTok().getLoc();
654 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
655
656 unsigned RegNum;
657 // Eat the '%'.
658 if (Lexer.getKind() == AsmToken::Percent)
659 Parser.Lex();
660 if (Lexer.getKind() == AsmToken::Identifier) {
661 RegNum = MatchRegisterName(Lexer.getTok().getIdentifier());
662 if (RegNum == 0)
663 return 0;
664 Parser.Lex(); // Eat identifier token
665 return LanaiOperand::createReg(RegNum, Start, End);
666 }
667 return 0;
668}
669
670bool LanaiAsmParser::ParseRegister(unsigned &RegNum, SMLoc &StartLoc,
671 SMLoc &EndLoc) {
672 std::unique_ptr<LanaiOperand> Op = parseRegister();
673 if (Op != 0)
674 RegNum = Op->getReg();
675 return (Op == 0);
676}
677
678std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
679 SMLoc Start = Parser.getTok().getLoc();
680 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
681 const MCExpr *Res, *RHS = 0;
682 LanaiMCExpr::VariantKind Kind = LanaiMCExpr::VK_Lanai_None;
683
684 if (Lexer.getKind() != AsmToken::Identifier)
685 return 0;
686
687 StringRef Identifier;
688 if (Parser.parseIdentifier(Identifier))
689 return 0;
690
691 // Check if identifier has a modifier
692 if (Identifier.equals_lower("hi"))
693 Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
694 else if (Identifier.equals_lower("lo"))
695 Kind = LanaiMCExpr::VK_Lanai_ABS_LO;
696
697 // If the identifier corresponds to a variant then extract the real
698 // identifier.
699 if (Kind != LanaiMCExpr::VK_Lanai_None) {
700 if (Lexer.getKind() != AsmToken::LParen) {
701 Error(Lexer.getLoc(), "Expected '('");
702 return 0;
703 }
704 Lexer.Lex(); // lex '('
705
706 // Parse identifier
707 if (Parser.parseIdentifier(Identifier))
708 return 0;
709 }
710
711 // If addition parse the RHS.
712 if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS))
713 return 0;
714
715 // For variants parse the final ')'
716 if (Kind != LanaiMCExpr::VK_Lanai_None) {
717 if (Lexer.getKind() != AsmToken::RParen) {
718 Error(Lexer.getLoc(), "Expected ')'");
719 return 0;
720 }
721 Lexer.Lex(); // lex ')'
722 }
723
724 End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
725 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
726 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
727 Res = LanaiMCExpr::create(Kind, Expr, getContext());
728
729 // Nest if this was an addition
730 if (RHS)
731 Res = MCBinaryExpr::createAdd(Res, RHS, getContext());
732
733 return LanaiOperand::createImm(Res, Start, End);
734}
735
736std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
737 SMLoc Start = Parser.getTok().getLoc();
738 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
739
740 const MCExpr *ExprVal;
741 switch (Lexer.getKind()) {
742 case AsmToken::Identifier:
743 return parseIdentifier();
744 case AsmToken::Plus:
745 case AsmToken::Minus:
746 case AsmToken::Integer:
747 case AsmToken::Dot:
748 if (!Parser.parseExpression(ExprVal))
749 return LanaiOperand::createImm(ExprVal, Start, End);
750 default:
751 return 0;
752 }
753}
754
755static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
756 if (PreOp)
757 return LPAC::makePreOp(AluCode);
758 if (PostOp)
759 return LPAC::makePostOp(AluCode);
760 return AluCode;
761}
762
763unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
764 StringRef IdString;
765 Parser.parseIdentifier(IdString);
766 unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
767 if (AluCode == LPAC::UNKNOWN) {
768 Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
769 return 0;
770 }
771 return AluCode;
772}
773
774static int SizeForSuffix(StringRef T) {
775 return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
776}
777
778bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
779 bool PreOrPost = false;
780 if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
781 PreOrPost = true;
782 if (Lexer.is(AsmToken::Minus))
783 *OffsetValue = -SizeForSuffix(Type);
784 else if (Lexer.is(AsmToken::Plus))
785 *OffsetValue = SizeForSuffix(Type);
786 else
787 return false;
788
789 // Eat the '-' '-' or '+' '+'
790 Parser.Lex();
791 Parser.Lex();
792 } else if (Lexer.is(AsmToken::Star)) {
793 Parser.Lex(); // Eat the '*'
794 PreOrPost = true;
795 }
796
797 return PreOrPost;
798}
799
800bool shouldBeSls(const LanaiOperand &Op) {
801 // The instruction should be encoded as an SLS if the constant is word
802 // aligned and will fit in 21 bits
803 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
804 int64_t Value = ConstExpr->getValue();
805 return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
806 }
807 // The instruction should be encoded as an SLS if the operand is a symbolic
808 // reference with no variant.
809 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
810 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
811 // The instruction should be encoded as an SLS if the operand is a binary
812 // expression with the left-hand side being a symbolic reference with no
813 // variant.
814 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
815 const LanaiMCExpr *LHSSymbolRefExpr =
816 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
817 return (LHSSymbolRefExpr &&
818 LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
819 }
820 return false;
821}
822
823// Matches memory operand. Returns true if error encountered.
824LanaiAsmParser::OperandMatchResultTy
825LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
826 // Try to match a memory operand.
827 // The memory operands are of the form:
828 // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or
829 // ^
830 // (2) '[' '*'? Register '*'? AluOperator Register ']'
831 // ^
832 // (3) '[' '--'|'++' Register '--'|'++' ']'
833 //
834 // (4) '[' Immediate ']' (for SLS)
835
836 // Store the type for use in parsing pre/post increment/decrement operators
837 StringRef Type;
838 if (Operands[0]->isToken())
839 Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();
840
841 // Use 0 if no offset given
842 int OffsetValue = 0;
843 unsigned BaseReg = 0;
844 unsigned AluOp = LPAC::ADD;
845 bool PostOp = false, PreOp = false;
846
847 // Try to parse the offset
848 std::unique_ptr<LanaiOperand> Op = parseRegister();
849 if (!Op)
850 Op = parseImmediate();
851
852 // Only continue if next token is '['
853 if (Lexer.isNot(AsmToken::LBrac)) {
854 if (!Op)
855 return MatchOperand_NoMatch;
856
857 // The start of this custom parsing overlaps with register/immediate so
858 // consider this as a successful match of an operand of that type as the
859 // token stream can't be rewound to allow them to match separately.
860 Operands.push_back(std::move(Op));
861 return MatchOperand_Success;
862 }
863
864 Parser.Lex(); // Eat the '['.
865 std::unique_ptr<LanaiOperand> Offset = nullptr;
866 if (Op)
867 Offset.swap(Op);
868
869 // Determine if a pre operation
870 PreOp = parsePrePost(Type, &OffsetValue);
871
872 Op = parseRegister();
873 if (!Op) {
874 if (!Offset) {
875 if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
876 Parser.Lex(); // Eat the ']'
877
878 // Memory address operations aligned to word boundary are encoded as
879 // SLS, the rest as RM.
880 if (shouldBeSls(*Op)) {
881 Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
882 } else {
883 if (!Op->isLoImm16Signed()) {
884 Error(Parser.getTok().getLoc(),
885 "Memory address is not word "
886 "aligned and larger than class RM can handle");
887 return MatchOperand_ParseFail;
888 }
889 Operands.push_back(LanaiOperand::MorphToMemRegImm(
890 Lanai::R0, std::move(Op), LPAC::ADD));
891 }
892 return MatchOperand_Success;
893 }
894 }
895
896 Error(Parser.getTok().getLoc(),
897 "Unknown operand, expected register or immediate");
898 return MatchOperand_ParseFail;
899 }
900 BaseReg = Op->getReg();
901
902 // Determine if a post operation
903 if (!PreOp)
904 PostOp = parsePrePost(Type, &OffsetValue);
905
906 // If ] match form (1) else match form (2)
907 if (Lexer.is(AsmToken::RBrac)) {
908 Parser.Lex(); // Eat the ']'.
909 if (!Offset) {
910 SMLoc Start = Parser.getTok().getLoc();
911 SMLoc End =
912 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
913 const MCConstantExpr *OffsetConstExpr =
914 MCConstantExpr::create(OffsetValue, getContext());
915 Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
916 }
917 } else {
918 if (Offset || OffsetValue != 0) {
919 Error(Parser.getTok().getLoc(), "Expected ']'");
920 return MatchOperand_ParseFail;
921 }
922
923 // Parse operator
924 AluOp = parseAluOperator(PreOp, PostOp);
925
926 // Second form requires offset register
927 Offset = parseRegister();
928 if (!BaseReg || Lexer.isNot(AsmToken::RBrac)) {
929 Error(Parser.getTok().getLoc(), "Expected ']'");
930 return MatchOperand_ParseFail;
931 }
932 Parser.Lex(); // Eat the ']'.
933 }
934
935 // First form has addition as operator. Add pre- or post-op indicator as
936 // needed.
937 AluOp = AluWithPrePost(AluOp, PreOp, PostOp);
938
939 // Ensure immediate offset is not too large
940 if (Offset->isImm() && !Offset->isLoImm16Signed()) {
941 Error(Parser.getTok().getLoc(),
942 "Memory address is not word "
943 "aligned and larger than class RM can handle");
944 return MatchOperand_ParseFail;
945 }
946
947 Operands.push_back(
948 Offset->isImm()
949 ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
950 : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));
951
952 return MatchOperand_Success;
953}
954
955// Looks at a token type and creates the relevant operand from this
956// information, adding to operands.
957// If operand was parsed, returns false, else true.
958LanaiAsmParser::OperandMatchResultTy
959LanaiAsmParser::parseOperand(OperandVector *Operands, StringRef Mnemonic) {
960 // Check if the current operand has a custom associated parser, if so, try to
961 // custom parse the operand, or fallback to the general approach.
962 OperandMatchResultTy Result = MatchOperandParserImpl(*Operands, Mnemonic);
963
964 if (Result == MatchOperand_Success)
965 return Result;
966 if (Result == MatchOperand_ParseFail) {
967 Parser.eatToEndOfStatement();
968 return Result;
969 }
970
971 // Attempt to parse token as register
972 std::unique_ptr<LanaiOperand> Op = parseRegister();
973
974 // Attempt to parse token as immediate
975 if (!Op)
976 Op = parseImmediate();
977
978 // If the token could not be parsed then fail
979 if (!Op) {
980 Error(Parser.getTok().getLoc(), "Unknown operand");
981 Parser.eatToEndOfStatement();
982 return MatchOperand_ParseFail;
983 }
984
985 // Push back parsed operand into list of operands
986 Operands->push_back(std::move(Op));
987
988 return MatchOperand_Success;
989}
990
991// Split the mnemonic into ASM operand, conditional code and instruction
992// qualifier (half-word, byte).
993StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
994 OperandVector *Operands) {
995 size_t Next = Name.find('.');
996
997 StringRef Mnemonic = Name;
998
999 bool IsBRR = false;
1000 if (Name.endswith(".r")) {
1001 Mnemonic = Name.substr(0, Name.size() - 2);
1002 IsBRR = true;
1003 }
1004
1005 // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1006 if (Mnemonic[0] == 'b' ||
1007 (Mnemonic[0] == 's' && !Mnemonic.startswith("sel") &&
1008 !Mnemonic.startswith("st"))) {
1009 // Parse instructions with a conditional code. For example, 'bne' is
1010 // converted into two operands 'b' and 'ne'.
1011 LPCC::CondCode CondCode =
1012 LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
1013 if (CondCode != LPCC::UNKNOWN) {
1014 Mnemonic = Mnemonic.slice(0, 1);
1015 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1016 Operands->push_back(LanaiOperand::createImm(
1017 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1018 if (IsBRR) {
1019 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1020 }
1021 return Mnemonic;
1022 }
1023 }
1024
1025 // Parse other instructions with condition codes (RR instructions).
1026 // We ignore .f here and assume they are flag-setting operations, not
1027 // conditional codes (except for select instructions where flag-setting
1028 // variants are not yet implemented).
1029 if (Mnemonic.startswith("sel") ||
1030 (!Mnemonic.endswith(".f") && !Mnemonic.startswith("st"))) {
1031 LPCC::CondCode CondCode = LPCC::suffixToLanaiCondCode(Mnemonic);
1032 if (CondCode != LPCC::UNKNOWN) {
1033 size_t Next = Mnemonic.rfind('.', Name.size());
1034 Mnemonic = Mnemonic.substr(0, Next + 1);
1035 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1036 Operands->push_back(LanaiOperand::createImm(
1037 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1038 return Mnemonic;
1039 }
1040 }
1041
1042 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1043 if (IsBRR) {
1044 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1045 }
1046
1047 return Mnemonic;
1048}
1049
1050bool IsMemoryAssignmentError(const OperandVector &Operands) {
1051 // Detects if a memory operation has an erroneous base register modification.
1052 // Memory operations are detected by matching the types of operands.
1053 //
1054 // TODO: This test is focussed on one specific instance (ld/st).
1055 // Extend it to handle more cases or be more robust.
1056 bool Modifies = false;
1057
1058 int Offset = 0;
1059
1060 if (Operands.size() < 5)
1061 return false;
1062 else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1063 Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
1064 Offset = 0;
1065 else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1066 Operands[2]->isReg() && Operands[3]->isImm() &&
1067 Operands[4]->isImm() && Operands[5]->isReg())
1068 Offset = 1;
1069 else
1070 return false;
1071
1072 int PossibleAluOpIdx = Offset + 3;
1073 int PossibleBaseIdx = Offset + 1;
1074 int PossibleDestIdx = Offset + 4;
1075 if (LanaiOperand *PossibleAluOp =
1076 static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
1077 if (PossibleAluOp->isImm())
1078 if (const MCConstantExpr *ConstExpr =
1079 dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1080 Modifies = LPAC::modifiesOp(ConstExpr->getValue());
1081 return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1082 Operands[PossibleDestIdx]->isReg() &&
1083 Operands[PossibleBaseIdx]->getReg() ==
1084 Operands[PossibleDestIdx]->getReg();
1085}
1086
1087bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1088 StringRef Name, SMLoc NameLoc,
1089 OperandVector &Operands) {
1090 // First operand is token for instruction
1091 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1092
1093 // If there are no more operands, then finish
1094 if (Lexer.is(AsmToken::EndOfStatement))
1095 return false;
1096
1097 // Parse first operand
1098 if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1099 return true;
1100
1101 // If it is a st instruction with one 1 operand then it is a "store true".
1102 // Transform <"st"> to <"s">, <LPCC:ICC_T>
1103 if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" &&
1104 Operands.size() == 2) {
1105 Operands.erase(Operands.begin(), Operands.begin() + 1);
1106 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
1107 Operands.insert(Operands.begin() + 1,
1108 LanaiOperand::createImm(
1109 MCConstantExpr::create(LPCC::ICC_T, getContext()),
1110 NameLoc, NameLoc));
1111 }
1112
1113 // If the instruction is a bt instruction with 1 operand (in assembly) then it
1114 // is an unconditional branch instruction and the first two elements of
1115 // operands need to be merged.
1116 if (Lexer.is(AsmToken::EndOfStatement) && Name.startswith("bt") &&
1117 Operands.size() == 3) {
1118 Operands.erase(Operands.begin(), Operands.begin() + 2);
1119 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
1120 }
1121
1122 // Parse until end of statement, consuming commas between operands
1123 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) {
1124 // Consume comma token
Nirav Davefd910412016-06-17 16:06:17 +00001125 Lex();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +00001126
1127 // Parse next operand
1128 if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1129 return true;
1130 }
1131
1132 if (IsMemoryAssignmentError(Operands)) {
1133 Error(Parser.getTok().getLoc(),
1134 "the destination register can't equal the base register in an "
1135 "instruction that modifies the base register.");
1136 return true;
1137 }
1138
1139 return false;
1140}
1141
1142#define GET_REGISTER_MATCHER
1143#define GET_MATCHER_IMPLEMENTATION
1144#include "LanaiGenAsmMatcher.inc"
1145} // namespace
1146
1147extern "C" void LLVMInitializeLanaiAsmParser() {
1148 RegisterMCAsmParser<LanaiAsmParser> x(TheLanaiTarget);
1149}
1150
1151} // namespace llvm