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/MC/TargetRegistry.h" 28 #include "llvm/Support/Casting.h" 29 #include "llvm/Support/ErrorHandling.h" 30 #include "llvm/Support/MathExtras.h" 31 #include "llvm/Support/SMLoc.h" 32 #include "llvm/Support/raw_ostream.h" 33 #include <algorithm> 34 #include <cassert> 35 #include <cstddef> 36 #include <cstdint> 37 #include <memory> 38 #include <optional> 39 40 using namespace llvm; 41 42 // Auto-generated by TableGen 43 static unsigned MatchRegisterName(StringRef Name); 44 45 namespace { 46 47 struct LanaiOperand; 48 49 class LanaiAsmParser : public MCTargetAsmParser { 50 // Parse operands 51 std::unique_ptr<LanaiOperand> parseRegister(bool RestoreOnFailure = false); 52 53 std::unique_ptr<LanaiOperand> parseImmediate(); 54 55 std::unique_ptr<LanaiOperand> parseIdentifier(); 56 57 unsigned parseAluOperator(bool PreOp, bool PostOp); 58 59 // Split the mnemonic stripping conditional code and quantifiers 60 StringRef splitMnemonic(StringRef Name, SMLoc NameLoc, 61 OperandVector *Operands); 62 63 bool parsePrePost(StringRef Type, int *OffsetValue); 64 65 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 66 SMLoc NameLoc, OperandVector &Operands) override; 67 68 bool parseRegister(MCRegister &RegNum, SMLoc &StartLoc, 69 SMLoc &EndLoc) override; 70 OperandMatchResultTy tryParseRegister(MCRegister &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: 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 144 explicit LanaiOperand(KindTy Kind) : 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 151 SMLoc getStartLoc() const override { return StartLoc; } 152 153 // getEndLoc - Gets location of the last token of this operand 154 SMLoc getEndLoc() const override { return EndLoc; } 155 156 unsigned getReg() const override { 157 assert(isReg() && "Invalid type access!"); 158 return Reg.RegNum; 159 } 160 161 const MCExpr *getImm() const { 162 assert(isImm() && "Invalid type access!"); 163 return Imm.Value; 164 } 165 166 StringRef getToken() const { 167 assert(isToken() && "Invalid type access!"); 168 return StringRef(Tok.Data, Tok.Length); 169 } 170 171 unsigned getMemBaseReg() const { 172 assert(isMem() && "Invalid type access!"); 173 return Mem.BaseReg; 174 } 175 176 unsigned getMemOffsetReg() const { 177 assert(isMem() && "Invalid type access!"); 178 return Mem.OffsetReg; 179 } 180 181 const MCExpr *getMemOffset() const { 182 assert(isMem() && "Invalid type access!"); 183 return Mem.Offset; 184 } 185 186 unsigned getMemOp() const { 187 assert(isMem() && "Invalid type access!"); 188 return Mem.AluOp; 189 } 190 191 // Functions for testing operand type 192 bool isReg() const override { return Kind == REGISTER; } 193 194 bool isImm() const override { return Kind == IMMEDIATE; } 195 196 bool isMem() const override { 197 return isMemImm() || isMemRegImm() || isMemRegReg(); 198 } 199 200 bool isMemImm() const { return Kind == MEMORY_IMM; } 201 202 bool isMemRegImm() const { return Kind == MEMORY_REG_IMM; } 203 204 bool isMemRegReg() const { return Kind == MEMORY_REG_REG; } 205 206 bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); } 207 208 bool isToken() const override { return Kind == TOKEN; } 209 210 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 223 bool isBrTarget() { return isBrImm() || isToken(); } 224 225 bool isCallTarget() { return isImm() || isToken(); } 226 227 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 250 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 263 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 287 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 311 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 324 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 335 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 366 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 377 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 391 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 402 void addRegOperands(MCInst &Inst, unsigned N) const { 403 assert(N == 1 && "Invalid number of operands!"); 404 Inst.addOperand(MCOperand::createReg(getReg())); 405 } 406 407 void addImmOperands(MCInst &Inst, unsigned N) const { 408 assert(N == 1 && "Invalid number of operands!"); 409 addExpr(Inst, getImm()); 410 } 411 412 void addBrTargetOperands(MCInst &Inst, unsigned N) const { 413 assert(N == 1 && "Invalid number of operands!"); 414 addExpr(Inst, getImm()); 415 } 416 417 void addCallTargetOperands(MCInst &Inst, unsigned N) const { 418 assert(N == 1 && "Invalid number of operands!"); 419 addExpr(Inst, getImm()); 420 } 421 422 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 423 assert(N == 1 && "Invalid number of operands!"); 424 addExpr(Inst, getImm()); 425 } 426 427 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 433 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 441 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 449 void addMemSplsOperands(MCInst &Inst, unsigned N) const { 450 if (isMemRegImm()) 451 addMemRegImmOperands(Inst, N); 452 if (isMemRegReg()) 453 addMemRegRegOperands(Inst, N); 454 } 455 456 void addImmShiftOperands(MCInst &Inst, unsigned N) const { 457 assert(N == 1 && "Invalid number of operands!"); 458 addExpr(Inst, getImm()); 459 } 460 461 void addImm10Operands(MCInst &Inst, unsigned N) const { 462 assert(N == 1 && "Invalid number of operands!"); 463 addExpr(Inst, getImm()); 464 } 465 466 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 490 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 498 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 521 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 529 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 560 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 585 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 594 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 603 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> 613 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> 624 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> 636 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 650 bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode, 651 OperandVector &Operands, 652 MCStreamer &Out, 653 uint64_t &ErrorInfo, 654 bool MatchingInlineAsm) { 655 MCInst Inst; 656 SMLoc ErrorLoc; 657 658 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { 659 case Match_Success: 660 Out.emitInstruction(Inst, SubtargetInfo); 661 Opcode = Inst.getOpcode(); 662 return false; 663 case Match_MissingFeature: 664 return Error(IdLoc, "Instruction use requires option to be enabled"); 665 case Match_MnemonicFail: 666 return Error(IdLoc, "Unrecognized instruction mnemonic"); 667 case Match_InvalidOperand: { 668 ErrorLoc = IdLoc; 669 if (ErrorInfo != ~0U) { 670 if (ErrorInfo >= Operands.size()) 671 return Error(IdLoc, "Too few operands for instruction"); 672 673 ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc(); 674 if (ErrorLoc == SMLoc()) 675 ErrorLoc = IdLoc; 676 } 677 return Error(ErrorLoc, "Invalid operand for instruction"); 678 } 679 default: 680 break; 681 } 682 683 llvm_unreachable("Unknown match type detected!"); 684 } 685 686 // Both '%rN' and 'rN' are parsed as valid registers. This was done to remain 687 // backwards compatible with GCC and the different ways inline assembly is 688 // handled. 689 // TODO: see if there isn't a better way to do this. 690 std::unique_ptr<LanaiOperand> 691 LanaiAsmParser::parseRegister(bool RestoreOnFailure) { 692 SMLoc Start = Parser.getTok().getLoc(); 693 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 694 std::optional<AsmToken> PercentTok; 695 696 unsigned RegNum; 697 // Eat the '%'. 698 if (Lexer.getKind() == AsmToken::Percent) { 699 PercentTok = Parser.getTok(); 700 Parser.Lex(); 701 } 702 if (Lexer.getKind() == AsmToken::Identifier) { 703 RegNum = MatchRegisterName(Lexer.getTok().getIdentifier()); 704 if (RegNum == 0) { 705 if (PercentTok && RestoreOnFailure) 706 Lexer.UnLex(*PercentTok); 707 return nullptr; 708 } 709 Parser.Lex(); // Eat identifier token 710 return LanaiOperand::createReg(RegNum, Start, End); 711 } 712 if (PercentTok && RestoreOnFailure) 713 Lexer.UnLex(*PercentTok); 714 return nullptr; 715 } 716 717 bool LanaiAsmParser::parseRegister(MCRegister &RegNum, SMLoc &StartLoc, 718 SMLoc &EndLoc) { 719 const AsmToken &Tok = getParser().getTok(); 720 StartLoc = Tok.getLoc(); 721 EndLoc = Tok.getEndLoc(); 722 std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/false); 723 if (Op != nullptr) 724 RegNum = Op->getReg(); 725 return (Op == nullptr); 726 } 727 728 OperandMatchResultTy LanaiAsmParser::tryParseRegister(MCRegister &RegNum, 729 SMLoc &StartLoc, 730 SMLoc &EndLoc) { 731 const AsmToken &Tok = getParser().getTok(); 732 StartLoc = Tok.getLoc(); 733 EndLoc = Tok.getEndLoc(); 734 std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/true); 735 if (Op == nullptr) 736 return MatchOperand_NoMatch; 737 RegNum = Op->getReg(); 738 return MatchOperand_Success; 739 } 740 741 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() { 742 SMLoc Start = Parser.getTok().getLoc(); 743 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 744 const MCExpr *Res, *RHS = nullptr; 745 LanaiMCExpr::VariantKind Kind = LanaiMCExpr::VK_Lanai_None; 746 747 if (Lexer.getKind() != AsmToken::Identifier) 748 return nullptr; 749 750 StringRef Identifier; 751 if (Parser.parseIdentifier(Identifier)) 752 return nullptr; 753 754 // Check if identifier has a modifier 755 if (Identifier.equals_insensitive("hi")) 756 Kind = LanaiMCExpr::VK_Lanai_ABS_HI; 757 else if (Identifier.equals_insensitive("lo")) 758 Kind = LanaiMCExpr::VK_Lanai_ABS_LO; 759 760 // If the identifier corresponds to a variant then extract the real 761 // identifier. 762 if (Kind != LanaiMCExpr::VK_Lanai_None) { 763 if (Lexer.getKind() != AsmToken::LParen) { 764 Error(Lexer.getLoc(), "Expected '('"); 765 return nullptr; 766 } 767 Lexer.Lex(); // lex '(' 768 769 // Parse identifier 770 if (Parser.parseIdentifier(Identifier)) 771 return nullptr; 772 } 773 774 // If addition parse the RHS. 775 if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS)) 776 return nullptr; 777 778 // For variants parse the final ')' 779 if (Kind != LanaiMCExpr::VK_Lanai_None) { 780 if (Lexer.getKind() != AsmToken::RParen) { 781 Error(Lexer.getLoc(), "Expected ')'"); 782 return nullptr; 783 } 784 Lexer.Lex(); // lex ')' 785 } 786 787 End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 788 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 789 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext()); 790 Res = LanaiMCExpr::create(Kind, Expr, getContext()); 791 792 // Nest if this was an addition 793 if (RHS) 794 Res = MCBinaryExpr::createAdd(Res, RHS, getContext()); 795 796 return LanaiOperand::createImm(Res, Start, End); 797 } 798 799 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() { 800 SMLoc Start = Parser.getTok().getLoc(); 801 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 802 803 const MCExpr *ExprVal; 804 switch (Lexer.getKind()) { 805 case AsmToken::Identifier: 806 return parseIdentifier(); 807 case AsmToken::Plus: 808 case AsmToken::Minus: 809 case AsmToken::Integer: 810 case AsmToken::Dot: 811 if (!Parser.parseExpression(ExprVal)) 812 return LanaiOperand::createImm(ExprVal, Start, End); 813 [[fallthrough]]; 814 default: 815 return nullptr; 816 } 817 } 818 819 static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) { 820 if (PreOp) 821 return LPAC::makePreOp(AluCode); 822 if (PostOp) 823 return LPAC::makePostOp(AluCode); 824 return AluCode; 825 } 826 827 unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) { 828 StringRef IdString; 829 Parser.parseIdentifier(IdString); 830 unsigned AluCode = LPAC::stringToLanaiAluCode(IdString); 831 if (AluCode == LPAC::UNKNOWN) { 832 Error(Parser.getTok().getLoc(), "Can't parse ALU operator"); 833 return 0; 834 } 835 return AluCode; 836 } 837 838 static int SizeForSuffix(StringRef T) { 839 return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4); 840 } 841 842 bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) { 843 bool PreOrPost = false; 844 if (Lexer.getKind() == Lexer.peekTok(true).getKind()) { 845 PreOrPost = true; 846 if (Lexer.is(AsmToken::Minus)) 847 *OffsetValue = -SizeForSuffix(Type); 848 else if (Lexer.is(AsmToken::Plus)) 849 *OffsetValue = SizeForSuffix(Type); 850 else 851 return false; 852 853 // Eat the '-' '-' or '+' '+' 854 Parser.Lex(); 855 Parser.Lex(); 856 } else if (Lexer.is(AsmToken::Star)) { 857 Parser.Lex(); // Eat the '*' 858 PreOrPost = true; 859 } 860 861 return PreOrPost; 862 } 863 864 bool shouldBeSls(const LanaiOperand &Op) { 865 // The instruction should be encoded as an SLS if the constant is word 866 // aligned and will fit in 21 bits 867 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) { 868 int64_t Value = ConstExpr->getValue(); 869 return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff); 870 } 871 // The instruction should be encoded as an SLS if the operand is a symbolic 872 // reference with no variant. 873 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm())) 874 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None; 875 // The instruction should be encoded as an SLS if the operand is a binary 876 // expression with the left-hand side being a symbolic reference with no 877 // variant. 878 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) { 879 const LanaiMCExpr *LHSSymbolRefExpr = 880 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()); 881 return (LHSSymbolRefExpr && 882 LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None); 883 } 884 return false; 885 } 886 887 // Matches memory operand. Returns true if error encountered. 888 OperandMatchResultTy 889 LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) { 890 // Try to match a memory operand. 891 // The memory operands are of the form: 892 // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or 893 // ^ 894 // (2) '[' '*'? Register '*'? AluOperator Register ']' 895 // ^ 896 // (3) '[' '--'|'++' Register '--'|'++' ']' 897 // 898 // (4) '[' Immediate ']' (for SLS) 899 900 // Store the type for use in parsing pre/post increment/decrement operators 901 StringRef Type; 902 if (Operands[0]->isToken()) 903 Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken(); 904 905 // Use 0 if no offset given 906 int OffsetValue = 0; 907 unsigned BaseReg = 0; 908 unsigned AluOp = LPAC::ADD; 909 bool PostOp = false, PreOp = false; 910 911 // Try to parse the offset 912 std::unique_ptr<LanaiOperand> Op = parseRegister(); 913 if (!Op) 914 Op = parseImmediate(); 915 916 // Only continue if next token is '[' 917 if (Lexer.isNot(AsmToken::LBrac)) { 918 if (!Op) 919 return MatchOperand_NoMatch; 920 921 // The start of this custom parsing overlaps with register/immediate so 922 // consider this as a successful match of an operand of that type as the 923 // token stream can't be rewound to allow them to match separately. 924 Operands.push_back(std::move(Op)); 925 return MatchOperand_Success; 926 } 927 928 Parser.Lex(); // Eat the '['. 929 std::unique_ptr<LanaiOperand> Offset = nullptr; 930 if (Op) 931 Offset.swap(Op); 932 933 // Determine if a pre operation 934 PreOp = parsePrePost(Type, &OffsetValue); 935 936 Op = parseRegister(); 937 if (!Op) { 938 if (!Offset) { 939 if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) { 940 Parser.Lex(); // Eat the ']' 941 942 // Memory address operations aligned to word boundary are encoded as 943 // SLS, the rest as RM. 944 if (shouldBeSls(*Op)) { 945 Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op))); 946 } else { 947 if (!Op->isLoImm16Signed()) { 948 Error(Parser.getTok().getLoc(), 949 "Memory address is not word " 950 "aligned and larger than class RM can handle"); 951 return MatchOperand_ParseFail; 952 } 953 Operands.push_back(LanaiOperand::MorphToMemRegImm( 954 Lanai::R0, std::move(Op), LPAC::ADD)); 955 } 956 return MatchOperand_Success; 957 } 958 } 959 960 Error(Parser.getTok().getLoc(), 961 "Unknown operand, expected register or immediate"); 962 return MatchOperand_ParseFail; 963 } 964 BaseReg = Op->getReg(); 965 966 // Determine if a post operation 967 if (!PreOp) 968 PostOp = parsePrePost(Type, &OffsetValue); 969 970 // If ] match form (1) else match form (2) 971 if (Lexer.is(AsmToken::RBrac)) { 972 Parser.Lex(); // Eat the ']'. 973 if (!Offset) { 974 SMLoc Start = Parser.getTok().getLoc(); 975 SMLoc End = 976 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 977 const MCConstantExpr *OffsetConstExpr = 978 MCConstantExpr::create(OffsetValue, getContext()); 979 Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End); 980 } 981 } else { 982 if (Offset || OffsetValue != 0) { 983 Error(Parser.getTok().getLoc(), "Expected ']'"); 984 return MatchOperand_ParseFail; 985 } 986 987 // Parse operator 988 AluOp = parseAluOperator(PreOp, PostOp); 989 990 // Second form requires offset register 991 Offset = parseRegister(); 992 if (!BaseReg || Lexer.isNot(AsmToken::RBrac)) { 993 Error(Parser.getTok().getLoc(), "Expected ']'"); 994 return MatchOperand_ParseFail; 995 } 996 Parser.Lex(); // Eat the ']'. 997 } 998 999 // First form has addition as operator. Add pre- or post-op indicator as 1000 // needed. 1001 AluOp = AluWithPrePost(AluOp, PreOp, PostOp); 1002 1003 // Ensure immediate offset is not too large 1004 if (Offset->isImm() && !Offset->isLoImm16Signed()) { 1005 Error(Parser.getTok().getLoc(), 1006 "Memory address is not word " 1007 "aligned and larger than class RM can handle"); 1008 return MatchOperand_ParseFail; 1009 } 1010 1011 Operands.push_back( 1012 Offset->isImm() 1013 ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp) 1014 : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp)); 1015 1016 return MatchOperand_Success; 1017 } 1018 1019 // Looks at a token type and creates the relevant operand from this 1020 // information, adding to operands. 1021 // If operand was parsed, returns false, else true. 1022 OperandMatchResultTy 1023 LanaiAsmParser::parseOperand(OperandVector *Operands, StringRef Mnemonic) { 1024 // Check if the current operand has a custom associated parser, if so, try to 1025 // custom parse the operand, or fallback to the general approach. 1026 OperandMatchResultTy Result = MatchOperandParserImpl(*Operands, Mnemonic); 1027 1028 if (Result == MatchOperand_Success) 1029 return Result; 1030 if (Result == MatchOperand_ParseFail) { 1031 Parser.eatToEndOfStatement(); 1032 return Result; 1033 } 1034 1035 // Attempt to parse token as register 1036 std::unique_ptr<LanaiOperand> Op = parseRegister(); 1037 1038 // Attempt to parse token as immediate 1039 if (!Op) 1040 Op = parseImmediate(); 1041 1042 // If the token could not be parsed then fail 1043 if (!Op) { 1044 Error(Parser.getTok().getLoc(), "Unknown operand"); 1045 Parser.eatToEndOfStatement(); 1046 return MatchOperand_ParseFail; 1047 } 1048 1049 // Push back parsed operand into list of operands 1050 Operands->push_back(std::move(Op)); 1051 1052 return MatchOperand_Success; 1053 } 1054 1055 // Split the mnemonic into ASM operand, conditional code and instruction 1056 // qualifier (half-word, byte). 1057 StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc, 1058 OperandVector *Operands) { 1059 size_t Next = Name.find('.'); 1060 1061 StringRef Mnemonic = Name; 1062 1063 bool IsBRR = false; 1064 if (Name.endswith(".r")) { 1065 Mnemonic = Name.substr(0, Name.size() - 2); 1066 IsBRR = true; 1067 } 1068 1069 // Match b?? and s?? (BR, BRR, and SCC instruction classes). 1070 if (Mnemonic[0] == 'b' || 1071 (Mnemonic[0] == 's' && !Mnemonic.startswith("sel") && 1072 !Mnemonic.startswith("st"))) { 1073 // Parse instructions with a conditional code. For example, 'bne' is 1074 // converted into two operands 'b' and 'ne'. 1075 LPCC::CondCode CondCode = 1076 LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next)); 1077 if (CondCode != LPCC::UNKNOWN) { 1078 Mnemonic = Mnemonic.slice(0, 1); 1079 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc)); 1080 Operands->push_back(LanaiOperand::createImm( 1081 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc)); 1082 if (IsBRR) { 1083 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc)); 1084 } 1085 return Mnemonic; 1086 } 1087 } 1088 1089 // Parse other instructions with condition codes (RR instructions). 1090 // We ignore .f here and assume they are flag-setting operations, not 1091 // conditional codes (except for select instructions where flag-setting 1092 // variants are not yet implemented). 1093 if (Mnemonic.startswith("sel") || 1094 (!Mnemonic.endswith(".f") && !Mnemonic.startswith("st"))) { 1095 LPCC::CondCode CondCode = LPCC::suffixToLanaiCondCode(Mnemonic); 1096 if (CondCode != LPCC::UNKNOWN) { 1097 size_t Next = Mnemonic.rfind('.', Name.size()); 1098 // 'sel' doesn't use a predicate operand whose printer adds the period, 1099 // but instead has the period as part of the identifier (i.e., 'sel.' is 1100 // expected by the generated matcher). If the mnemonic starts with 'sel' 1101 // then include the period as part of the mnemonic, else don't include it 1102 // as part of the mnemonic. 1103 if (Mnemonic.startswith("sel")) { 1104 Mnemonic = Mnemonic.substr(0, Next + 1); 1105 } else { 1106 Mnemonic = Mnemonic.substr(0, Next); 1107 } 1108 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc)); 1109 Operands->push_back(LanaiOperand::createImm( 1110 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc)); 1111 return Mnemonic; 1112 } 1113 } 1114 1115 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc)); 1116 if (IsBRR) { 1117 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc)); 1118 } 1119 1120 return Mnemonic; 1121 } 1122 1123 static bool IsMemoryAssignmentError(const OperandVector &Operands) { 1124 // Detects if a memory operation has an erroneous base register modification. 1125 // Memory operations are detected by matching the types of operands. 1126 // 1127 // TODO: This test is focussed on one specific instance (ld/st). 1128 // Extend it to handle more cases or be more robust. 1129 bool Modifies = false; 1130 1131 int Offset = 0; 1132 1133 if (Operands.size() < 5) 1134 return false; 1135 else if (Operands[0]->isToken() && Operands[1]->isReg() && 1136 Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg()) 1137 Offset = 0; 1138 else if (Operands[0]->isToken() && Operands[1]->isToken() && 1139 Operands[2]->isReg() && Operands[3]->isImm() && 1140 Operands[4]->isImm() && Operands[5]->isReg()) 1141 Offset = 1; 1142 else 1143 return false; 1144 1145 int PossibleAluOpIdx = Offset + 3; 1146 int PossibleBaseIdx = Offset + 1; 1147 int PossibleDestIdx = Offset + 4; 1148 if (LanaiOperand *PossibleAluOp = 1149 static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get())) 1150 if (PossibleAluOp->isImm()) 1151 if (const MCConstantExpr *ConstExpr = 1152 dyn_cast<MCConstantExpr>(PossibleAluOp->getImm())) 1153 Modifies = LPAC::modifiesOp(ConstExpr->getValue()); 1154 return Modifies && Operands[PossibleBaseIdx]->isReg() && 1155 Operands[PossibleDestIdx]->isReg() && 1156 Operands[PossibleBaseIdx]->getReg() == 1157 Operands[PossibleDestIdx]->getReg(); 1158 } 1159 1160 static bool IsRegister(const MCParsedAsmOperand &op) { 1161 return static_cast<const LanaiOperand &>(op).isReg(); 1162 } 1163 1164 static bool MaybePredicatedInst(const OperandVector &Operands) { 1165 if (Operands.size() < 4 || !IsRegister(*Operands[1]) || 1166 !IsRegister(*Operands[2])) 1167 return false; 1168 return StringSwitch<bool>( 1169 static_cast<const LanaiOperand &>(*Operands[0]).getToken()) 1170 .StartsWith("addc", true) 1171 .StartsWith("add", true) 1172 .StartsWith("and", true) 1173 .StartsWith("sh", true) 1174 .StartsWith("subb", true) 1175 .StartsWith("sub", true) 1176 .StartsWith("or", true) 1177 .StartsWith("xor", true) 1178 .Default(false); 1179 } 1180 1181 bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo & /*Info*/, 1182 StringRef Name, SMLoc NameLoc, 1183 OperandVector &Operands) { 1184 // First operand is token for instruction 1185 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands); 1186 1187 // If there are no more operands, then finish 1188 if (Lexer.is(AsmToken::EndOfStatement)) 1189 return false; 1190 1191 // Parse first operand 1192 if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success) 1193 return true; 1194 1195 // If it is a st instruction with one 1 operand then it is a "store true". 1196 // Transform <"st"> to <"s">, <LPCC:ICC_T> 1197 if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" && 1198 Operands.size() == 2) { 1199 Operands.erase(Operands.begin(), Operands.begin() + 1); 1200 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc)); 1201 Operands.insert(Operands.begin() + 1, 1202 LanaiOperand::createImm( 1203 MCConstantExpr::create(LPCC::ICC_T, getContext()), 1204 NameLoc, NameLoc)); 1205 } 1206 1207 // If the instruction is a bt instruction with 1 operand (in assembly) then it 1208 // is an unconditional branch instruction and the first two elements of 1209 // operands need to be merged. 1210 if (Lexer.is(AsmToken::EndOfStatement) && Name.startswith("bt") && 1211 Operands.size() == 3) { 1212 Operands.erase(Operands.begin(), Operands.begin() + 2); 1213 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc)); 1214 } 1215 1216 // Parse until end of statement, consuming commas between operands 1217 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) { 1218 // Consume comma token 1219 Lex(); 1220 1221 // Parse next operand 1222 if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success) 1223 return true; 1224 } 1225 1226 if (IsMemoryAssignmentError(Operands)) { 1227 Error(Parser.getTok().getLoc(), 1228 "the destination register can't equal the base register in an " 1229 "instruction that modifies the base register."); 1230 return true; 1231 } 1232 1233 // Insert always true operand for instruction that may be predicated but 1234 // are not. Currently the autogenerated parser always expects a predicate. 1235 if (MaybePredicatedInst(Operands)) { 1236 Operands.insert(Operands.begin() + 1, 1237 LanaiOperand::createImm( 1238 MCConstantExpr::create(LPCC::ICC_T, getContext()), 1239 NameLoc, NameLoc)); 1240 } 1241 1242 return false; 1243 } 1244 1245 #define GET_REGISTER_MATCHER 1246 #define GET_MATCHER_IMPLEMENTATION 1247 #include "LanaiGenAsmMatcher.inc" 1248 1249 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiAsmParser() { 1250 RegisterMCAsmParser<LanaiAsmParser> x(getTheLanaiTarget()); 1251 } 1252