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