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