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