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