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