1 //===-- 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
26 namespace llvm {
27 namespace {
28 struct LanaiOperand;
29
30 class 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
67 public:
LanaiAsmParser(const MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)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
76 private:
77 MCAsmParser &Parser;
78 MCAsmLexer &Lexer;
79
80 const MCSubtargetInfo &SubtargetInfo;
81 };
82
83 // Auto-generated by TableGen
84 static unsigned MatchRegisterName(llvm::StringRef Name);
85
86 // LanaiOperand - Instances of this class represented a parsed machine
87 // instruction
88 struct 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
LanaiOperandllvm::__anon737eca8c0111::LanaiOperand127 explicit LanaiOperand(KindTy Kind) : MCParsedAsmOperand(), Kind(Kind) {}
128
129 public:
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
getStartLocllvm::__anon737eca8c0111::LanaiOperand134 SMLoc getStartLoc() const override { return StartLoc; }
135
136 // getEndLoc - Gets location of the last token of this operand
getEndLocllvm::__anon737eca8c0111::LanaiOperand137 SMLoc getEndLoc() const override { return EndLoc; }
138
getRegllvm::__anon737eca8c0111::LanaiOperand139 unsigned getReg() const override {
140 assert(isReg() && "Invalid type access!");
141 return Reg.RegNum;
142 }
143
getImmllvm::__anon737eca8c0111::LanaiOperand144 const MCExpr *getImm() const {
145 assert(isImm() && "Invalid type access!");
146 return Imm.Value;
147 }
148
getTokenllvm::__anon737eca8c0111::LanaiOperand149 StringRef getToken() const {
150 assert(isToken() && "Invalid type access!");
151 return StringRef(Tok.Data, Tok.Length);
152 }
153
getMemBaseRegllvm::__anon737eca8c0111::LanaiOperand154 unsigned getMemBaseReg() const {
155 assert(isMem() && "Invalid type access!");
156 return Mem.BaseReg;
157 }
158
getMemOffsetRegllvm::__anon737eca8c0111::LanaiOperand159 unsigned getMemOffsetReg() const {
160 assert(isMem() && "Invalid type access!");
161 return Mem.OffsetReg;
162 }
163
getMemOffsetllvm::__anon737eca8c0111::LanaiOperand164 const MCExpr *getMemOffset() const {
165 assert(isMem() && "Invalid type access!");
166 return Mem.Offset;
167 }
168
getMemOpllvm::__anon737eca8c0111::LanaiOperand169 unsigned getMemOp() const {
170 assert(isMem() && "Invalid type access!");
171 return Mem.AluOp;
172 }
173
174 // Functions for testing operand type
isRegllvm::__anon737eca8c0111::LanaiOperand175 bool isReg() const override { return Kind == REGISTER; }
176
isImmllvm::__anon737eca8c0111::LanaiOperand177 bool isImm() const override { return Kind == IMMEDIATE; }
178
isMemllvm::__anon737eca8c0111::LanaiOperand179 bool isMem() const override {
180 return isMemImm() || isMemRegImm() || isMemRegReg();
181 }
182
isMemImmllvm::__anon737eca8c0111::LanaiOperand183 bool isMemImm() const { return Kind == MEMORY_IMM; }
184
isMemRegImmllvm::__anon737eca8c0111::LanaiOperand185 bool isMemRegImm() const { return Kind == MEMORY_REG_IMM; }
186
isMemRegRegllvm::__anon737eca8c0111::LanaiOperand187 bool isMemRegReg() const { return Kind == MEMORY_REG_REG; }
188
isMemSplsllvm::__anon737eca8c0111::LanaiOperand189 bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }
190
isTokenllvm::__anon737eca8c0111::LanaiOperand191 bool isToken() const override { return Kind == TOKEN; }
192
isBrImmllvm::__anon737eca8c0111::LanaiOperand193 bool isBrImm() {
194 if (!isImm())
195 return false;
196
197 // Constant case
198 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));
204 }
205
isBrTargetllvm::__anon737eca8c0111::LanaiOperand206 bool isBrTarget() { return isBrImm() || isToken(); }
207
isCallTargetllvm::__anon737eca8c0111::LanaiOperand208 bool isCallTarget() { return isImm() || isToken(); }
209
isHiImm16llvm::__anon737eca8c0111::LanaiOperand210 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
isHiImm16Andllvm::__anon737eca8c0111::LanaiOperand233 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
isLoImm16llvm::__anon737eca8c0111::LanaiOperand246 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
isLoImm16Signedllvm::__anon737eca8c0111::LanaiOperand270 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
isLoImm16Andllvm::__anon737eca8c0111::LanaiOperand294 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
isImmShiftllvm::__anon737eca8c0111::LanaiOperand307 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
isLoImm21llvm::__anon737eca8c0111::LanaiOperand318 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
isImm10llvm::__anon737eca8c0111::LanaiOperand349 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
isCondCodellvm::__anon737eca8c0111::LanaiOperand360 bool isCondCode() {
361 if (!isImm())
362 return false;
363
364 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
365 if (!ConstExpr)
366 return false;
367 uint64_t Value = ConstExpr->getValue();
368 // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
369 // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
370 // value corresponds to a valid condition code.
371 return Value < LPCC::UNKNOWN;
372 }
373
addExprllvm::__anon737eca8c0111::LanaiOperand374 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
375 // Add as immediates where possible. Null MCExpr = 0
376 if (Expr == nullptr)
377 Inst.addOperand(MCOperand::createImm(0));
378 else if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
379 Inst.addOperand(
380 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
381 else
382 Inst.addOperand(MCOperand::createExpr(Expr));
383 }
384
addRegOperandsllvm::__anon737eca8c0111::LanaiOperand385 void addRegOperands(MCInst &Inst, unsigned N) const {
386 assert(N == 1 && "Invalid number of operands!");
387 Inst.addOperand(MCOperand::createReg(getReg()));
388 }
389
addImmOperandsllvm::__anon737eca8c0111::LanaiOperand390 void addImmOperands(MCInst &Inst, unsigned N) const {
391 assert(N == 1 && "Invalid number of operands!");
392 addExpr(Inst, getImm());
393 }
394
addBrTargetOperandsllvm::__anon737eca8c0111::LanaiOperand395 void addBrTargetOperands(MCInst &Inst, unsigned N) const {
396 assert(N == 1 && "Invalid number of operands!");
397 addExpr(Inst, getImm());
398 }
399
addCallTargetOperandsllvm::__anon737eca8c0111::LanaiOperand400 void addCallTargetOperands(MCInst &Inst, unsigned N) const {
401 assert(N == 1 && "Invalid number of operands!");
402 addExpr(Inst, getImm());
403 }
404
addCondCodeOperandsllvm::__anon737eca8c0111::LanaiOperand405 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
406 assert(N == 1 && "Invalid number of operands!");
407 addExpr(Inst, getImm());
408 }
409
addMemImmOperandsllvm::__anon737eca8c0111::LanaiOperand410 void addMemImmOperands(MCInst &Inst, unsigned N) const {
411 assert(N == 1 && "Invalid number of operands!");
412 const MCExpr *Expr = getMemOffset();
413 addExpr(Inst, Expr);
414 }
415
addMemRegImmOperandsllvm::__anon737eca8c0111::LanaiOperand416 void addMemRegImmOperands(MCInst &Inst, unsigned N) const {
417 assert(N == 3 && "Invalid number of operands!");
418 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
419 const MCExpr *Expr = getMemOffset();
420 addExpr(Inst, Expr);
421 Inst.addOperand(MCOperand::createImm(getMemOp()));
422 }
423
addMemRegRegOperandsllvm::__anon737eca8c0111::LanaiOperand424 void addMemRegRegOperands(MCInst &Inst, unsigned N) const {
425 assert(N == 3 && "Invalid number of operands!");
426 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
427 assert(getMemOffsetReg() != 0 && "Invalid offset");
428 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
429 Inst.addOperand(MCOperand::createImm(getMemOp()));
430 }
431
addMemSplsOperandsllvm::__anon737eca8c0111::LanaiOperand432 void addMemSplsOperands(MCInst &Inst, unsigned N) const {
433 if (isMemRegImm())
434 addMemRegImmOperands(Inst, N);
435 if (isMemRegReg())
436 addMemRegRegOperands(Inst, N);
437 }
438
addImmShiftOperandsllvm::__anon737eca8c0111::LanaiOperand439 void addImmShiftOperands(MCInst &Inst, unsigned N) const {
440 assert(N == 1 && "Invalid number of operands!");
441 addExpr(Inst, getImm());
442 }
443
addImm10Operandsllvm::__anon737eca8c0111::LanaiOperand444 void addImm10Operands(MCInst &Inst, unsigned N) const {
445 assert(N == 1 && "Invalid number of operands!");
446 addExpr(Inst, getImm());
447 }
448
addLoImm16Operandsllvm::__anon737eca8c0111::LanaiOperand449 void addLoImm16Operands(MCInst &Inst, unsigned N) const {
450 assert(N == 1 && "Invalid number of operands!");
451 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
452 Inst.addOperand(
453 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
454 else if (isa<LanaiMCExpr>(getImm())) {
455 #ifndef NDEBUG
456 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
457 assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO);
458 #endif
459 Inst.addOperand(MCOperand::createExpr(getImm()));
460 } else if (isa<MCBinaryExpr>(getImm())) {
461 #ifndef NDEBUG
462 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
463 assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
464 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
465 LanaiMCExpr::VK_Lanai_ABS_LO);
466 #endif
467 Inst.addOperand(MCOperand::createExpr(getImm()));
468 } else
469 assert(false && "Operand type not supported.");
470 }
471
addLoImm16AndOperandsllvm::__anon737eca8c0111::LanaiOperand472 void addLoImm16AndOperands(MCInst &Inst, unsigned N) const {
473 assert(N == 1 && "Invalid number of operands!");
474 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
475 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0xffff));
476 else
477 assert(false && "Operand type not supported.");
478 }
479
addHiImm16Operandsllvm::__anon737eca8c0111::LanaiOperand480 void addHiImm16Operands(MCInst &Inst, unsigned N) const {
481 assert(N == 1 && "Invalid number of operands!");
482 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
483 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
484 else if (isa<LanaiMCExpr>(getImm())) {
485 #ifndef NDEBUG
486 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
487 assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI);
488 #endif
489 Inst.addOperand(MCOperand::createExpr(getImm()));
490 } else if (isa<MCBinaryExpr>(getImm())) {
491 #ifndef NDEBUG
492 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
493 assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
494 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
495 LanaiMCExpr::VK_Lanai_ABS_HI);
496 #endif
497 Inst.addOperand(MCOperand::createExpr(getImm()));
498 } else
499 assert(false && "Operand type not supported.");
500 }
501
addHiImm16AndOperandsllvm::__anon737eca8c0111::LanaiOperand502 void addHiImm16AndOperands(MCInst &Inst, unsigned N) const {
503 assert(N == 1 && "Invalid number of operands!");
504 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
505 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
506 else
507 assert(false && "Operand type not supported.");
508 }
509
addLoImm21Operandsllvm::__anon737eca8c0111::LanaiOperand510 void addLoImm21Operands(MCInst &Inst, unsigned N) const {
511 assert(N == 1 && "Invalid number of operands!");
512 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
513 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
514 else if (isa<LanaiMCExpr>(getImm())) {
515 #ifndef NDEBUG
516 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
517 assert(SymbolRefExpr &&
518 SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
519 #endif
520 Inst.addOperand(MCOperand::createExpr(getImm()));
521 } else if (isa<MCSymbolRefExpr>(getImm())) {
522 #ifndef NDEBUG
523 const MCSymbolRefExpr *SymbolRefExpr =
524 dyn_cast<MCSymbolRefExpr>(getImm());
525 assert(SymbolRefExpr &&
526 SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None);
527 #endif
528 Inst.addOperand(MCOperand::createExpr(getImm()));
529 } else if (isa<MCBinaryExpr>(getImm())) {
530 #ifndef NDEBUG
531 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
532 const LanaiMCExpr *SymbolRefExpr =
533 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
534 assert(SymbolRefExpr &&
535 SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
536 #endif
537 Inst.addOperand(MCOperand::createExpr(getImm()));
538 } else
539 assert(false && "Operand type not supported.");
540 }
541
printllvm::__anon737eca8c0111::LanaiOperand542 void print(raw_ostream &OS) const override {
543 switch (Kind) {
544 case IMMEDIATE:
545 OS << "Imm: " << getImm() << "\n";
546 break;
547 case TOKEN:
548 OS << "Token: " << getToken() << "\n";
549 break;
550 case REGISTER:
551 OS << "Reg: %r" << getReg() << "\n";
552 break;
553 case MEMORY_IMM:
554 OS << "MemImm: " << *getMemOffset() << "\n";
555 break;
556 case MEMORY_REG_IMM:
557 OS << "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
558 break;
559 case MEMORY_REG_REG:
560 assert(getMemOffset() == nullptr);
561 OS << "MemRegReg: " << getMemBaseReg() << "+"
562 << "%r" << getMemOffsetReg() << "\n";
563 break;
564 }
565 }
566
CreateTokenllvm::__anon737eca8c0111::LanaiOperand567 static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
568 auto Op = make_unique<LanaiOperand>(TOKEN);
569 Op->Tok.Data = Str.data();
570 Op->Tok.Length = Str.size();
571 Op->StartLoc = Start;
572 Op->EndLoc = Start;
573 return Op;
574 }
575
createRegllvm::__anon737eca8c0111::LanaiOperand576 static std::unique_ptr<LanaiOperand> createReg(unsigned RegNum, SMLoc Start,
577 SMLoc End) {
578 auto Op = make_unique<LanaiOperand>(REGISTER);
579 Op->Reg.RegNum = RegNum;
580 Op->StartLoc = Start;
581 Op->EndLoc = End;
582 return Op;
583 }
584
createImmllvm::__anon737eca8c0111::LanaiOperand585 static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
586 SMLoc Start, SMLoc End) {
587 auto Op = make_unique<LanaiOperand>(IMMEDIATE);
588 Op->Imm.Value = Value;
589 Op->StartLoc = Start;
590 Op->EndLoc = End;
591 return Op;
592 }
593
594 static std::unique_ptr<LanaiOperand>
MorphToMemImmllvm::__anon737eca8c0111::LanaiOperand595 MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
596 const MCExpr *Imm = Op->getImm();
597 Op->Kind = MEMORY_IMM;
598 Op->Mem.BaseReg = 0;
599 Op->Mem.AluOp = LPAC::ADD;
600 Op->Mem.OffsetReg = 0;
601 Op->Mem.Offset = Imm;
602 return Op;
603 }
604
605 static std::unique_ptr<LanaiOperand>
MorphToMemRegRegllvm::__anon737eca8c0111::LanaiOperand606 MorphToMemRegReg(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
607 unsigned AluOp) {
608 unsigned OffsetReg = Op->getReg();
609 Op->Kind = MEMORY_REG_REG;
610 Op->Mem.BaseReg = BaseReg;
611 Op->Mem.AluOp = AluOp;
612 Op->Mem.OffsetReg = OffsetReg;
613 Op->Mem.Offset = nullptr;
614 return Op;
615 }
616
617 static std::unique_ptr<LanaiOperand>
MorphToMemRegImmllvm::__anon737eca8c0111::LanaiOperand618 MorphToMemRegImm(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
619 unsigned AluOp) {
620 const MCExpr *Imm = Op->getImm();
621 Op->Kind = MEMORY_REG_IMM;
622 Op->Mem.BaseReg = BaseReg;
623 Op->Mem.AluOp = AluOp;
624 Op->Mem.OffsetReg = 0;
625 Op->Mem.Offset = Imm;
626 return Op;
627 }
628 };
629
ParseDirective(AsmToken DirectiveId)630 bool LanaiAsmParser::ParseDirective(AsmToken DirectiveId) { return true; }
631
MatchAndEmitInstruction(SMLoc IdLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)632 bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
633 OperandVector &Operands,
634 MCStreamer &Out,
635 uint64_t &ErrorInfo,
636 bool MatchingInlineAsm) {
637 MCInst Inst;
638 SMLoc ErrorLoc;
639
640 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
641 case Match_Success:
642 Out.EmitInstruction(Inst, SubtargetInfo);
643 return false;
644 case Match_MissingFeature:
645 return Error(IdLoc, "Instruction use requires option to be enabled");
646 case Match_MnemonicFail:
647 return Error(IdLoc, "Unrecognized instruction mnemonic");
648 case Match_InvalidOperand: {
649 ErrorLoc = IdLoc;
650 if (ErrorInfo != ~0U) {
651 if (ErrorInfo >= Operands.size())
652 return Error(IdLoc, "Too few operands for instruction");
653
654 ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
655 if (ErrorLoc == SMLoc())
656 ErrorLoc = IdLoc;
657 }
658 return Error(ErrorLoc, "Invalid operand for instruction");
659 }
660 default:
661 break;
662 }
663
664 llvm_unreachable("Unknown match type detected!");
665 }
666
667 // Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
668 // backwards compatible with GCC and the different ways inline assembly is
669 // handled.
670 // TODO: see if there isn't a better way to do this.
parseRegister()671 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseRegister() {
672 SMLoc Start = Parser.getTok().getLoc();
673 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
674
675 unsigned RegNum;
676 // Eat the '%'.
677 if (Lexer.getKind() == AsmToken::Percent)
678 Parser.Lex();
679 if (Lexer.getKind() == AsmToken::Identifier) {
680 RegNum = MatchRegisterName(Lexer.getTok().getIdentifier());
681 if (RegNum == 0)
682 return 0;
683 Parser.Lex(); // Eat identifier token
684 return LanaiOperand::createReg(RegNum, Start, End);
685 }
686 return 0;
687 }
688
ParseRegister(unsigned & RegNum,SMLoc & StartLoc,SMLoc & EndLoc)689 bool LanaiAsmParser::ParseRegister(unsigned &RegNum, SMLoc &StartLoc,
690 SMLoc &EndLoc) {
691 std::unique_ptr<LanaiOperand> Op = parseRegister();
692 if (Op != 0)
693 RegNum = Op->getReg();
694 return (Op == 0);
695 }
696
parseIdentifier()697 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
698 SMLoc Start = Parser.getTok().getLoc();
699 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
700 const MCExpr *Res, *RHS = 0;
701 LanaiMCExpr::VariantKind Kind = LanaiMCExpr::VK_Lanai_None;
702
703 if (Lexer.getKind() != AsmToken::Identifier)
704 return 0;
705
706 StringRef Identifier;
707 if (Parser.parseIdentifier(Identifier))
708 return 0;
709
710 // Check if identifier has a modifier
711 if (Identifier.equals_lower("hi"))
712 Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
713 else if (Identifier.equals_lower("lo"))
714 Kind = LanaiMCExpr::VK_Lanai_ABS_LO;
715
716 // If the identifier corresponds to a variant then extract the real
717 // identifier.
718 if (Kind != LanaiMCExpr::VK_Lanai_None) {
719 if (Lexer.getKind() != AsmToken::LParen) {
720 Error(Lexer.getLoc(), "Expected '('");
721 return 0;
722 }
723 Lexer.Lex(); // lex '('
724
725 // Parse identifier
726 if (Parser.parseIdentifier(Identifier))
727 return 0;
728 }
729
730 // If addition parse the RHS.
731 if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS))
732 return 0;
733
734 // For variants parse the final ')'
735 if (Kind != LanaiMCExpr::VK_Lanai_None) {
736 if (Lexer.getKind() != AsmToken::RParen) {
737 Error(Lexer.getLoc(), "Expected ')'");
738 return 0;
739 }
740 Lexer.Lex(); // lex ')'
741 }
742
743 End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
744 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
745 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
746 Res = LanaiMCExpr::create(Kind, Expr, getContext());
747
748 // Nest if this was an addition
749 if (RHS)
750 Res = MCBinaryExpr::createAdd(Res, RHS, getContext());
751
752 return LanaiOperand::createImm(Res, Start, End);
753 }
754
parseImmediate()755 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
756 SMLoc Start = Parser.getTok().getLoc();
757 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
758
759 const MCExpr *ExprVal;
760 switch (Lexer.getKind()) {
761 case AsmToken::Identifier:
762 return parseIdentifier();
763 case AsmToken::Plus:
764 case AsmToken::Minus:
765 case AsmToken::Integer:
766 case AsmToken::Dot:
767 if (!Parser.parseExpression(ExprVal))
768 return LanaiOperand::createImm(ExprVal, Start, End);
769 default:
770 return 0;
771 }
772 }
773
AluWithPrePost(unsigned AluCode,bool PreOp,bool PostOp)774 static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
775 if (PreOp)
776 return LPAC::makePreOp(AluCode);
777 if (PostOp)
778 return LPAC::makePostOp(AluCode);
779 return AluCode;
780 }
781
parseAluOperator(bool PreOp,bool PostOp)782 unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
783 StringRef IdString;
784 Parser.parseIdentifier(IdString);
785 unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
786 if (AluCode == LPAC::UNKNOWN) {
787 Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
788 return 0;
789 }
790 return AluCode;
791 }
792
SizeForSuffix(StringRef T)793 static int SizeForSuffix(StringRef T) {
794 return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
795 }
796
parsePrePost(StringRef Type,int * OffsetValue)797 bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
798 bool PreOrPost = false;
799 if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
800 PreOrPost = true;
801 if (Lexer.is(AsmToken::Minus))
802 *OffsetValue = -SizeForSuffix(Type);
803 else if (Lexer.is(AsmToken::Plus))
804 *OffsetValue = SizeForSuffix(Type);
805 else
806 return false;
807
808 // Eat the '-' '-' or '+' '+'
809 Parser.Lex();
810 Parser.Lex();
811 } else if (Lexer.is(AsmToken::Star)) {
812 Parser.Lex(); // Eat the '*'
813 PreOrPost = true;
814 }
815
816 return PreOrPost;
817 }
818
shouldBeSls(const LanaiOperand & Op)819 bool shouldBeSls(const LanaiOperand &Op) {
820 // The instruction should be encoded as an SLS if the constant is word
821 // aligned and will fit in 21 bits
822 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
823 int64_t Value = ConstExpr->getValue();
824 return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
825 }
826 // The instruction should be encoded as an SLS if the operand is a symbolic
827 // reference with no variant.
828 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
829 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
830 // The instruction should be encoded as an SLS if the operand is a binary
831 // expression with the left-hand side being a symbolic reference with no
832 // variant.
833 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
834 const LanaiMCExpr *LHSSymbolRefExpr =
835 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
836 return (LHSSymbolRefExpr &&
837 LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
838 }
839 return false;
840 }
841
842 // Matches memory operand. Returns true if error encountered.
843 LanaiAsmParser::OperandMatchResultTy
parseMemoryOperand(OperandVector & Operands)844 LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
845 // Try to match a memory operand.
846 // The memory operands are of the form:
847 // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or
848 // ^
849 // (2) '[' '*'? Register '*'? AluOperator Register ']'
850 // ^
851 // (3) '[' '--'|'++' Register '--'|'++' ']'
852 //
853 // (4) '[' Immediate ']' (for SLS)
854
855 // Store the type for use in parsing pre/post increment/decrement operators
856 StringRef Type;
857 if (Operands[0]->isToken())
858 Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();
859
860 // Use 0 if no offset given
861 int OffsetValue = 0;
862 unsigned BaseReg = 0;
863 unsigned AluOp = LPAC::ADD;
864 bool PostOp = false, PreOp = false;
865
866 // Try to parse the offset
867 std::unique_ptr<LanaiOperand> Op = parseRegister();
868 if (!Op)
869 Op = parseImmediate();
870
871 // Only continue if next token is '['
872 if (Lexer.isNot(AsmToken::LBrac)) {
873 if (!Op)
874 return MatchOperand_NoMatch;
875
876 // The start of this custom parsing overlaps with register/immediate so
877 // consider this as a successful match of an operand of that type as the
878 // token stream can't be rewound to allow them to match separately.
879 Operands.push_back(std::move(Op));
880 return MatchOperand_Success;
881 }
882
883 Parser.Lex(); // Eat the '['.
884 std::unique_ptr<LanaiOperand> Offset = nullptr;
885 if (Op)
886 Offset.swap(Op);
887
888 // Determine if a pre operation
889 PreOp = parsePrePost(Type, &OffsetValue);
890
891 Op = parseRegister();
892 if (!Op) {
893 if (!Offset) {
894 if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
895 Parser.Lex(); // Eat the ']'
896
897 // Memory address operations aligned to word boundary are encoded as
898 // SLS, the rest as RM.
899 if (shouldBeSls(*Op)) {
900 Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
901 } else {
902 if (!Op->isLoImm16Signed()) {
903 Error(Parser.getTok().getLoc(),
904 "Memory address is not word "
905 "aligned and larger than class RM can handle");
906 return MatchOperand_ParseFail;
907 }
908 Operands.push_back(LanaiOperand::MorphToMemRegImm(
909 Lanai::R0, std::move(Op), LPAC::ADD));
910 }
911 return MatchOperand_Success;
912 }
913 }
914
915 Error(Parser.getTok().getLoc(),
916 "Unknown operand, expected register or immediate");
917 return MatchOperand_ParseFail;
918 }
919 BaseReg = Op->getReg();
920
921 // Determine if a post operation
922 if (!PreOp)
923 PostOp = parsePrePost(Type, &OffsetValue);
924
925 // If ] match form (1) else match form (2)
926 if (Lexer.is(AsmToken::RBrac)) {
927 Parser.Lex(); // Eat the ']'.
928 if (!Offset) {
929 SMLoc Start = Parser.getTok().getLoc();
930 SMLoc End =
931 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
932 const MCConstantExpr *OffsetConstExpr =
933 MCConstantExpr::create(OffsetValue, getContext());
934 Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
935 }
936 } else {
937 if (Offset || OffsetValue != 0) {
938 Error(Parser.getTok().getLoc(), "Expected ']'");
939 return MatchOperand_ParseFail;
940 }
941
942 // Parse operator
943 AluOp = parseAluOperator(PreOp, PostOp);
944
945 // Second form requires offset register
946 Offset = parseRegister();
947 if (!BaseReg || Lexer.isNot(AsmToken::RBrac)) {
948 Error(Parser.getTok().getLoc(), "Expected ']'");
949 return MatchOperand_ParseFail;
950 }
951 Parser.Lex(); // Eat the ']'.
952 }
953
954 // First form has addition as operator. Add pre- or post-op indicator as
955 // needed.
956 AluOp = AluWithPrePost(AluOp, PreOp, PostOp);
957
958 // Ensure immediate offset is not too large
959 if (Offset->isImm() && !Offset->isLoImm16Signed()) {
960 Error(Parser.getTok().getLoc(),
961 "Memory address is not word "
962 "aligned and larger than class RM can handle");
963 return MatchOperand_ParseFail;
964 }
965
966 Operands.push_back(
967 Offset->isImm()
968 ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
969 : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));
970
971 return MatchOperand_Success;
972 }
973
974 // Looks at a token type and creates the relevant operand from this
975 // information, adding to operands.
976 // If operand was parsed, returns false, else true.
977 LanaiAsmParser::OperandMatchResultTy
parseOperand(OperandVector * Operands,StringRef Mnemonic)978 LanaiAsmParser::parseOperand(OperandVector *Operands, StringRef Mnemonic) {
979 // Check if the current operand has a custom associated parser, if so, try to
980 // custom parse the operand, or fallback to the general approach.
981 OperandMatchResultTy Result = MatchOperandParserImpl(*Operands, Mnemonic);
982
983 if (Result == MatchOperand_Success)
984 return Result;
985 if (Result == MatchOperand_ParseFail) {
986 Parser.eatToEndOfStatement();
987 return Result;
988 }
989
990 // Attempt to parse token as register
991 std::unique_ptr<LanaiOperand> Op = parseRegister();
992
993 // Attempt to parse token as immediate
994 if (!Op)
995 Op = parseImmediate();
996
997 // If the token could not be parsed then fail
998 if (!Op) {
999 Error(Parser.getTok().getLoc(), "Unknown operand");
1000 Parser.eatToEndOfStatement();
1001 return MatchOperand_ParseFail;
1002 }
1003
1004 // Push back parsed operand into list of operands
1005 Operands->push_back(std::move(Op));
1006
1007 return MatchOperand_Success;
1008 }
1009
1010 // Split the mnemonic into ASM operand, conditional code and instruction
1011 // qualifier (half-word, byte).
splitMnemonic(StringRef Name,SMLoc NameLoc,OperandVector * Operands)1012 StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1013 OperandVector *Operands) {
1014 size_t Next = Name.find('.');
1015
1016 StringRef Mnemonic = Name;
1017
1018 bool IsBRR = false;
1019 if (Name.endswith(".r")) {
1020 Mnemonic = Name.substr(0, Name.size() - 2);
1021 IsBRR = true;
1022 }
1023
1024 // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1025 if (Mnemonic[0] == 'b' ||
1026 (Mnemonic[0] == 's' && !Mnemonic.startswith("sel") &&
1027 !Mnemonic.startswith("st"))) {
1028 // Parse instructions with a conditional code. For example, 'bne' is
1029 // converted into two operands 'b' and 'ne'.
1030 LPCC::CondCode CondCode =
1031 LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
1032 if (CondCode != LPCC::UNKNOWN) {
1033 Mnemonic = Mnemonic.slice(0, 1);
1034 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1035 Operands->push_back(LanaiOperand::createImm(
1036 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1037 if (IsBRR) {
1038 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1039 }
1040 return Mnemonic;
1041 }
1042 }
1043
1044 // Parse other instructions with condition codes (RR instructions).
1045 // We ignore .f here and assume they are flag-setting operations, not
1046 // conditional codes (except for select instructions where flag-setting
1047 // variants are not yet implemented).
1048 if (Mnemonic.startswith("sel") ||
1049 (!Mnemonic.endswith(".f") && !Mnemonic.startswith("st"))) {
1050 LPCC::CondCode CondCode = LPCC::suffixToLanaiCondCode(Mnemonic);
1051 if (CondCode != LPCC::UNKNOWN) {
1052 size_t Next = Mnemonic.rfind('.', Name.size());
1053 // 'sel' doesn't use a predicate operand whose printer adds the period,
1054 // but instead has the period as part of the identifier (i.e., 'sel.' is
1055 // expected by the generated matcher). If the mnemonic starts with 'sel'
1056 // then include the period as part of the mnemonic, else don't include it
1057 // as part of the mnemonic.
1058 if (Mnemonic.startswith("sel")) {
1059 Mnemonic = Mnemonic.substr(0, Next + 1);
1060 } else {
1061 Mnemonic = Mnemonic.substr(0, Next);
1062 }
1063 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1064 Operands->push_back(LanaiOperand::createImm(
1065 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1066 return Mnemonic;
1067 }
1068 }
1069
1070 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1071 if (IsBRR) {
1072 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1073 }
1074
1075 return Mnemonic;
1076 }
1077
IsMemoryAssignmentError(const OperandVector & Operands)1078 bool IsMemoryAssignmentError(const OperandVector &Operands) {
1079 // Detects if a memory operation has an erroneous base register modification.
1080 // Memory operations are detected by matching the types of operands.
1081 //
1082 // TODO: This test is focussed on one specific instance (ld/st).
1083 // Extend it to handle more cases or be more robust.
1084 bool Modifies = false;
1085
1086 int Offset = 0;
1087
1088 if (Operands.size() < 5)
1089 return false;
1090 else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1091 Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
1092 Offset = 0;
1093 else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1094 Operands[2]->isReg() && Operands[3]->isImm() &&
1095 Operands[4]->isImm() && Operands[5]->isReg())
1096 Offset = 1;
1097 else
1098 return false;
1099
1100 int PossibleAluOpIdx = Offset + 3;
1101 int PossibleBaseIdx = Offset + 1;
1102 int PossibleDestIdx = Offset + 4;
1103 if (LanaiOperand *PossibleAluOp =
1104 static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
1105 if (PossibleAluOp->isImm())
1106 if (const MCConstantExpr *ConstExpr =
1107 dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1108 Modifies = LPAC::modifiesOp(ConstExpr->getValue());
1109 return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1110 Operands[PossibleDestIdx]->isReg() &&
1111 Operands[PossibleBaseIdx]->getReg() ==
1112 Operands[PossibleDestIdx]->getReg();
1113 }
1114
IsRegister(const MCParsedAsmOperand & op)1115 static bool IsRegister(const MCParsedAsmOperand &op) {
1116 return static_cast<const LanaiOperand &>(op).isReg();
1117 }
1118
MaybePredicatedInst(const OperandVector & Operands)1119 static bool MaybePredicatedInst(const OperandVector &Operands) {
1120 if (Operands.size() < 4 || !IsRegister(*Operands[1]) ||
1121 !IsRegister(*Operands[2]))
1122 return false;
1123 return StringSwitch<bool>(
1124 static_cast<const LanaiOperand &>(*Operands[0]).getToken())
1125 .StartsWith("addc", true)
1126 .StartsWith("add", true)
1127 .StartsWith("and", true)
1128 .StartsWith("sh", true)
1129 .StartsWith("subb", true)
1130 .StartsWith("sub", true)
1131 .StartsWith("or", true)
1132 .StartsWith("xor", true)
1133 .Default(false);
1134 }
1135
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)1136 bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1137 StringRef Name, SMLoc NameLoc,
1138 OperandVector &Operands) {
1139 // First operand is token for instruction
1140 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1141
1142 // If there are no more operands, then finish
1143 if (Lexer.is(AsmToken::EndOfStatement))
1144 return false;
1145
1146 // Parse first operand
1147 if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1148 return true;
1149
1150 // If it is a st instruction with one 1 operand then it is a "store true".
1151 // Transform <"st"> to <"s">, <LPCC:ICC_T>
1152 if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" &&
1153 Operands.size() == 2) {
1154 Operands.erase(Operands.begin(), Operands.begin() + 1);
1155 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
1156 Operands.insert(Operands.begin() + 1,
1157 LanaiOperand::createImm(
1158 MCConstantExpr::create(LPCC::ICC_T, getContext()),
1159 NameLoc, NameLoc));
1160 }
1161
1162 // If the instruction is a bt instruction with 1 operand (in assembly) then it
1163 // is an unconditional branch instruction and the first two elements of
1164 // operands need to be merged.
1165 if (Lexer.is(AsmToken::EndOfStatement) && Name.startswith("bt") &&
1166 Operands.size() == 3) {
1167 Operands.erase(Operands.begin(), Operands.begin() + 2);
1168 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
1169 }
1170
1171 // Parse until end of statement, consuming commas between operands
1172 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) {
1173 // Consume comma token
1174 Lex();
1175
1176 // Parse next operand
1177 if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1178 return true;
1179 }
1180
1181 if (IsMemoryAssignmentError(Operands)) {
1182 Error(Parser.getTok().getLoc(),
1183 "the destination register can't equal the base register in an "
1184 "instruction that modifies the base register.");
1185 return true;
1186 }
1187
1188 // Insert always true operand for instruction that may be predicated but
1189 // are not. Currently the autogenerated parser always expects a predicate.
1190 if (MaybePredicatedInst(Operands)) {
1191 Operands.insert(Operands.begin() + 1,
1192 LanaiOperand::createImm(
1193 MCConstantExpr::create(LPCC::ICC_T, getContext()),
1194 NameLoc, NameLoc));
1195 }
1196
1197 return false;
1198 }
1199
1200 #define GET_REGISTER_MATCHER
1201 #define GET_MATCHER_IMPLEMENTATION
1202 #include "LanaiGenAsmMatcher.inc"
1203 } // namespace
1204
LLVMInitializeLanaiAsmParser()1205 extern "C" void LLVMInitializeLanaiAsmParser() {
1206 RegisterMCAsmParser<LanaiAsmParser> x(TheLanaiTarget);
1207 }
1208
1209 } // namespace llvm
1210