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