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