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