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