1 //===-- X86AsmParser.cpp - Parse X86 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 "MCTargetDesc/X86BaseInfo.h" 11 #include "llvm/MC/MCTargetAsmParser.h" 12 #include "llvm/MC/MCStreamer.h" 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/MC/MCInst.h" 15 #include "llvm/MC/MCRegisterInfo.h" 16 #include "llvm/MC/MCSubtargetInfo.h" 17 #include "llvm/MC/MCParser/MCAsmLexer.h" 18 #include "llvm/MC/MCParser/MCAsmParser.h" 19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 20 #include "llvm/ADT/SmallString.h" 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/ADT/StringSwitch.h" 23 #include "llvm/ADT/Twine.h" 24 #include "llvm/Support/SourceMgr.h" 25 #include "llvm/Support/TargetRegistry.h" 26 #include "llvm/Support/raw_ostream.h" 27 28 using namespace llvm; 29 30 namespace { 31 struct X86Operand; 32 33 class X86AsmParser : public MCTargetAsmParser { 34 MCSubtargetInfo &STI; 35 MCAsmParser &Parser; 36 private: 37 MCAsmParser &getParser() const { return Parser; } 38 39 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 40 41 bool Error(SMLoc L, const Twine &Msg, 42 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) { 43 return Parser.Error(L, Msg, Ranges); 44 } 45 46 X86Operand *ErrorOperand(SMLoc Loc, StringRef Msg) { 47 Error(Loc, Msg); 48 return 0; 49 } 50 51 X86Operand *ParseOperand(); 52 X86Operand *ParseATTOperand(); 53 X86Operand *ParseIntelOperand(); 54 X86Operand *ParseIntelMemOperand(); 55 X86Operand *ParseIntelBracExpression(unsigned SegReg, unsigned Size); 56 X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc); 57 58 bool ParseDirectiveWord(unsigned Size, SMLoc L); 59 bool ParseDirectiveCode(StringRef IDVal, SMLoc L); 60 61 bool processInstruction(MCInst &Inst, 62 const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 63 64 bool MatchAndEmitInstruction(SMLoc IDLoc, 65 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 66 MCStreamer &Out); 67 68 bool MatchInstruction(SMLoc IDLoc, 69 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 70 SmallVectorImpl<MCInst> &MCInsts); 71 72 /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi) 73 /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode. 74 bool isSrcOp(X86Operand &Op); 75 76 /// isDstOp - Returns true if operand is either (%rdi) or %es:(%rdi) 77 /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode. 78 bool isDstOp(X86Operand &Op); 79 80 bool is64BitMode() const { 81 // FIXME: Can tablegen auto-generate this? 82 return (STI.getFeatureBits() & X86::Mode64Bit) != 0; 83 } 84 void SwitchMode() { 85 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit)); 86 setAvailableFeatures(FB); 87 } 88 89 /// @name Auto-generated Matcher Functions 90 /// { 91 92 #define GET_ASSEMBLER_HEADER 93 #include "X86GenAsmMatcher.inc" 94 95 /// } 96 97 public: 98 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 99 : MCTargetAsmParser(), STI(sti), Parser(parser) { 100 101 // Initialize the set of available features. 102 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 103 } 104 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 105 106 virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 107 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 108 109 virtual bool ParseDirective(AsmToken DirectiveID); 110 111 bool isParsingIntelSyntax() { 112 return getParser().getAssemblerDialect(); 113 } 114 }; 115 } // end anonymous namespace 116 117 /// @name Auto-generated Match Functions 118 /// { 119 120 static unsigned MatchRegisterName(StringRef Name); 121 122 /// } 123 124 static bool isImmSExti16i8Value(uint64_t Value) { 125 return (( Value <= 0x000000000000007FULL)|| 126 (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)|| 127 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 128 } 129 130 static bool isImmSExti32i8Value(uint64_t Value) { 131 return (( Value <= 0x000000000000007FULL)|| 132 (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)|| 133 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 134 } 135 136 static bool isImmZExtu32u8Value(uint64_t Value) { 137 return (Value <= 0x00000000000000FFULL); 138 } 139 140 static bool isImmSExti64i8Value(uint64_t Value) { 141 return (( Value <= 0x000000000000007FULL)|| 142 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 143 } 144 145 static bool isImmSExti64i32Value(uint64_t Value) { 146 return (( Value <= 0x000000007FFFFFFFULL)|| 147 (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 148 } 149 namespace { 150 151 /// X86Operand - Instances of this class represent a parsed X86 machine 152 /// instruction. 153 struct X86Operand : public MCParsedAsmOperand { 154 enum KindTy { 155 Token, 156 Register, 157 Immediate, 158 Memory 159 } Kind; 160 161 SMLoc StartLoc, EndLoc; 162 163 union { 164 struct { 165 const char *Data; 166 unsigned Length; 167 } Tok; 168 169 struct { 170 unsigned RegNo; 171 } Reg; 172 173 struct { 174 const MCExpr *Val; 175 } Imm; 176 177 struct { 178 unsigned SegReg; 179 const MCExpr *Disp; 180 unsigned BaseReg; 181 unsigned IndexReg; 182 unsigned Scale; 183 unsigned Size; 184 } Mem; 185 }; 186 187 X86Operand(KindTy K, SMLoc Start, SMLoc End) 188 : Kind(K), StartLoc(Start), EndLoc(End) {} 189 190 /// getStartLoc - Get the location of the first token of this operand. 191 SMLoc getStartLoc() const { return StartLoc; } 192 /// getEndLoc - Get the location of the last token of this operand. 193 SMLoc getEndLoc() const { return EndLoc; } 194 195 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 196 197 virtual void print(raw_ostream &OS) const {} 198 199 StringRef getToken() const { 200 assert(Kind == Token && "Invalid access!"); 201 return StringRef(Tok.Data, Tok.Length); 202 } 203 void setTokenValue(StringRef Value) { 204 assert(Kind == Token && "Invalid access!"); 205 Tok.Data = Value.data(); 206 Tok.Length = Value.size(); 207 } 208 209 unsigned getReg() const { 210 assert(Kind == Register && "Invalid access!"); 211 return Reg.RegNo; 212 } 213 214 const MCExpr *getImm() const { 215 assert(Kind == Immediate && "Invalid access!"); 216 return Imm.Val; 217 } 218 219 const MCExpr *getMemDisp() const { 220 assert(Kind == Memory && "Invalid access!"); 221 return Mem.Disp; 222 } 223 unsigned getMemSegReg() const { 224 assert(Kind == Memory && "Invalid access!"); 225 return Mem.SegReg; 226 } 227 unsigned getMemBaseReg() const { 228 assert(Kind == Memory && "Invalid access!"); 229 return Mem.BaseReg; 230 } 231 unsigned getMemIndexReg() const { 232 assert(Kind == Memory && "Invalid access!"); 233 return Mem.IndexReg; 234 } 235 unsigned getMemScale() const { 236 assert(Kind == Memory && "Invalid access!"); 237 return Mem.Scale; 238 } 239 240 bool isToken() const {return Kind == Token; } 241 242 bool isImm() const { return Kind == Immediate; } 243 244 bool isImmSExti16i8() const { 245 if (!isImm()) 246 return false; 247 248 // If this isn't a constant expr, just assume it fits and let relaxation 249 // handle it. 250 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 251 if (!CE) 252 return true; 253 254 // Otherwise, check the value is in a range that makes sense for this 255 // extension. 256 return isImmSExti16i8Value(CE->getValue()); 257 } 258 bool isImmSExti32i8() const { 259 if (!isImm()) 260 return false; 261 262 // If this isn't a constant expr, just assume it fits and let relaxation 263 // handle it. 264 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 265 if (!CE) 266 return true; 267 268 // Otherwise, check the value is in a range that makes sense for this 269 // extension. 270 return isImmSExti32i8Value(CE->getValue()); 271 } 272 bool isImmZExtu32u8() const { 273 if (!isImm()) 274 return false; 275 276 // If this isn't a constant expr, just assume it fits and let relaxation 277 // handle it. 278 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 279 if (!CE) 280 return true; 281 282 // Otherwise, check the value is in a range that makes sense for this 283 // extension. 284 return isImmZExtu32u8Value(CE->getValue()); 285 } 286 bool isImmSExti64i8() const { 287 if (!isImm()) 288 return false; 289 290 // If this isn't a constant expr, just assume it fits and let relaxation 291 // handle it. 292 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 293 if (!CE) 294 return true; 295 296 // Otherwise, check the value is in a range that makes sense for this 297 // extension. 298 return isImmSExti64i8Value(CE->getValue()); 299 } 300 bool isImmSExti64i32() const { 301 if (!isImm()) 302 return false; 303 304 // If this isn't a constant expr, just assume it fits and let relaxation 305 // handle it. 306 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 307 if (!CE) 308 return true; 309 310 // Otherwise, check the value is in a range that makes sense for this 311 // extension. 312 return isImmSExti64i32Value(CE->getValue()); 313 } 314 315 bool isMem() const { return Kind == Memory; } 316 bool isMem8() const { 317 return Kind == Memory && (!Mem.Size || Mem.Size == 8); 318 } 319 bool isMem16() const { 320 return Kind == Memory && (!Mem.Size || Mem.Size == 16); 321 } 322 bool isMem32() const { 323 return Kind == Memory && (!Mem.Size || Mem.Size == 32); 324 } 325 bool isMem64() const { 326 return Kind == Memory && (!Mem.Size || Mem.Size == 64); 327 } 328 bool isMem80() const { 329 return Kind == Memory && (!Mem.Size || Mem.Size == 80); 330 } 331 bool isMem128() const { 332 return Kind == Memory && (!Mem.Size || Mem.Size == 128); 333 } 334 bool isMem256() const { 335 return Kind == Memory && (!Mem.Size || Mem.Size == 256); 336 } 337 338 bool isMemVX32() const { 339 return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 340 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15; 341 } 342 bool isMemVY32() const { 343 return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 344 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15; 345 } 346 bool isMemVX64() const { 347 return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 348 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15; 349 } 350 bool isMemVY64() const { 351 return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 352 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15; 353 } 354 355 bool isAbsMem() const { 356 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 357 !getMemIndexReg() && getMemScale() == 1; 358 } 359 360 bool isReg() const { return Kind == Register; } 361 362 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 363 // Add as immediates when possible. 364 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 365 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 366 else 367 Inst.addOperand(MCOperand::CreateExpr(Expr)); 368 } 369 370 void addRegOperands(MCInst &Inst, unsigned N) const { 371 assert(N == 1 && "Invalid number of operands!"); 372 Inst.addOperand(MCOperand::CreateReg(getReg())); 373 } 374 375 void addImmOperands(MCInst &Inst, unsigned N) const { 376 assert(N == 1 && "Invalid number of operands!"); 377 addExpr(Inst, getImm()); 378 } 379 380 void addMem8Operands(MCInst &Inst, unsigned N) const { 381 addMemOperands(Inst, N); 382 } 383 void addMem16Operands(MCInst &Inst, unsigned N) const { 384 addMemOperands(Inst, N); 385 } 386 void addMem32Operands(MCInst &Inst, unsigned N) const { 387 addMemOperands(Inst, N); 388 } 389 void addMem64Operands(MCInst &Inst, unsigned N) const { 390 addMemOperands(Inst, N); 391 } 392 void addMem80Operands(MCInst &Inst, unsigned N) const { 393 addMemOperands(Inst, N); 394 } 395 void addMem128Operands(MCInst &Inst, unsigned N) const { 396 addMemOperands(Inst, N); 397 } 398 void addMem256Operands(MCInst &Inst, unsigned N) const { 399 addMemOperands(Inst, N); 400 } 401 void addMemVX32Operands(MCInst &Inst, unsigned N) const { 402 addMemOperands(Inst, N); 403 } 404 void addMemVY32Operands(MCInst &Inst, unsigned N) const { 405 addMemOperands(Inst, N); 406 } 407 void addMemVX64Operands(MCInst &Inst, unsigned N) const { 408 addMemOperands(Inst, N); 409 } 410 void addMemVY64Operands(MCInst &Inst, unsigned N) const { 411 addMemOperands(Inst, N); 412 } 413 414 void addMemOperands(MCInst &Inst, unsigned N) const { 415 assert((N == 5) && "Invalid number of operands!"); 416 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 417 Inst.addOperand(MCOperand::CreateImm(getMemScale())); 418 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); 419 addExpr(Inst, getMemDisp()); 420 Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 421 } 422 423 void addAbsMemOperands(MCInst &Inst, unsigned N) const { 424 assert((N == 1) && "Invalid number of operands!"); 425 // Add as immediates when possible. 426 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 427 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 428 else 429 Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); 430 } 431 432 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) { 433 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size() - 1); 434 X86Operand *Res = new X86Operand(Token, Loc, EndLoc); 435 Res->Tok.Data = Str.data(); 436 Res->Tok.Length = Str.size(); 437 return Res; 438 } 439 440 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) { 441 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc); 442 Res->Reg.RegNo = RegNo; 443 return Res; 444 } 445 446 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){ 447 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc); 448 Res->Imm.Val = Val; 449 return Res; 450 } 451 452 /// Create an absolute memory operand. 453 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, 454 SMLoc EndLoc, unsigned Size = 0) { 455 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 456 Res->Mem.SegReg = 0; 457 Res->Mem.Disp = Disp; 458 Res->Mem.BaseReg = 0; 459 Res->Mem.IndexReg = 0; 460 Res->Mem.Scale = 1; 461 Res->Mem.Size = Size; 462 return Res; 463 } 464 465 /// Create a generalized memory operand. 466 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp, 467 unsigned BaseReg, unsigned IndexReg, 468 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc, 469 unsigned Size = 0) { 470 // We should never just have a displacement, that should be parsed as an 471 // absolute memory operand. 472 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 473 474 // The scale should always be one of {1,2,4,8}. 475 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 476 "Invalid scale!"); 477 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 478 Res->Mem.SegReg = SegReg; 479 Res->Mem.Disp = Disp; 480 Res->Mem.BaseReg = BaseReg; 481 Res->Mem.IndexReg = IndexReg; 482 Res->Mem.Scale = Scale; 483 Res->Mem.Size = Size; 484 return Res; 485 } 486 }; 487 488 } // end anonymous namespace. 489 490 bool X86AsmParser::isSrcOp(X86Operand &Op) { 491 unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI; 492 493 return (Op.isMem() && 494 (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) && 495 isa<MCConstantExpr>(Op.Mem.Disp) && 496 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 497 Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0); 498 } 499 500 bool X86AsmParser::isDstOp(X86Operand &Op) { 501 unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI; 502 503 return Op.isMem() && 504 (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) && 505 isa<MCConstantExpr>(Op.Mem.Disp) && 506 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 507 Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0; 508 } 509 510 bool X86AsmParser::ParseRegister(unsigned &RegNo, 511 SMLoc &StartLoc, SMLoc &EndLoc) { 512 RegNo = 0; 513 if (!isParsingIntelSyntax()) { 514 const AsmToken &TokPercent = Parser.getTok(); 515 assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!"); 516 StartLoc = TokPercent.getLoc(); 517 Parser.Lex(); // Eat percent token. 518 } 519 520 const AsmToken &Tok = Parser.getTok(); 521 if (Tok.isNot(AsmToken::Identifier)) { 522 if (isParsingIntelSyntax()) return true; 523 return Error(StartLoc, "invalid register name", 524 SMRange(StartLoc, Tok.getEndLoc())); 525 } 526 527 RegNo = MatchRegisterName(Tok.getString()); 528 529 // If the match failed, try the register name as lowercase. 530 if (RegNo == 0) 531 RegNo = MatchRegisterName(Tok.getString().lower()); 532 533 if (!is64BitMode()) { 534 // FIXME: This should be done using Requires<In32BitMode> and 535 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also 536 // checked. 537 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a 538 // REX prefix. 539 if (RegNo == X86::RIZ || 540 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) || 541 X86II::isX86_64NonExtLowByteReg(RegNo) || 542 X86II::isX86_64ExtendedReg(RegNo)) 543 return Error(StartLoc, "register %" 544 + Tok.getString() + " is only available in 64-bit mode", 545 SMRange(StartLoc, Tok.getEndLoc())); 546 } 547 548 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. 549 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) { 550 RegNo = X86::ST0; 551 EndLoc = Tok.getLoc(); 552 Parser.Lex(); // Eat 'st' 553 554 // Check to see if we have '(4)' after %st. 555 if (getLexer().isNot(AsmToken::LParen)) 556 return false; 557 // Lex the paren. 558 getParser().Lex(); 559 560 const AsmToken &IntTok = Parser.getTok(); 561 if (IntTok.isNot(AsmToken::Integer)) 562 return Error(IntTok.getLoc(), "expected stack index"); 563 switch (IntTok.getIntVal()) { 564 case 0: RegNo = X86::ST0; break; 565 case 1: RegNo = X86::ST1; break; 566 case 2: RegNo = X86::ST2; break; 567 case 3: RegNo = X86::ST3; break; 568 case 4: RegNo = X86::ST4; break; 569 case 5: RegNo = X86::ST5; break; 570 case 6: RegNo = X86::ST6; break; 571 case 7: RegNo = X86::ST7; break; 572 default: return Error(IntTok.getLoc(), "invalid stack index"); 573 } 574 575 if (getParser().Lex().isNot(AsmToken::RParen)) 576 return Error(Parser.getTok().getLoc(), "expected ')'"); 577 578 EndLoc = Tok.getLoc(); 579 Parser.Lex(); // Eat ')' 580 return false; 581 } 582 583 // If this is "db[0-7]", match it as an alias 584 // for dr[0-7]. 585 if (RegNo == 0 && Tok.getString().size() == 3 && 586 Tok.getString().startswith("db")) { 587 switch (Tok.getString()[2]) { 588 case '0': RegNo = X86::DR0; break; 589 case '1': RegNo = X86::DR1; break; 590 case '2': RegNo = X86::DR2; break; 591 case '3': RegNo = X86::DR3; break; 592 case '4': RegNo = X86::DR4; break; 593 case '5': RegNo = X86::DR5; break; 594 case '6': RegNo = X86::DR6; break; 595 case '7': RegNo = X86::DR7; break; 596 } 597 598 if (RegNo != 0) { 599 EndLoc = Tok.getLoc(); 600 Parser.Lex(); // Eat it. 601 return false; 602 } 603 } 604 605 if (RegNo == 0) { 606 if (isParsingIntelSyntax()) return true; 607 return Error(StartLoc, "invalid register name", 608 SMRange(StartLoc, Tok.getEndLoc())); 609 } 610 611 EndLoc = Tok.getEndLoc(); 612 Parser.Lex(); // Eat identifier token. 613 return false; 614 } 615 616 X86Operand *X86AsmParser::ParseOperand() { 617 if (isParsingIntelSyntax()) 618 return ParseIntelOperand(); 619 return ParseATTOperand(); 620 } 621 622 /// getIntelMemOperandSize - Return intel memory operand size. 623 static unsigned getIntelMemOperandSize(StringRef OpStr) { 624 unsigned Size = 0; 625 if (OpStr == "BYTE") Size = 8; 626 if (OpStr == "WORD") Size = 16; 627 if (OpStr == "DWORD") Size = 32; 628 if (OpStr == "QWORD") Size = 64; 629 if (OpStr == "XWORD") Size = 80; 630 if (OpStr == "XMMWORD") Size = 128; 631 if (OpStr == "YMMWORD") Size = 256; 632 return Size; 633 } 634 635 X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, 636 unsigned Size) { 637 unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 638 SMLoc Start = Parser.getTok().getLoc(), End; 639 640 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); 641 // Parse [ BaseReg + Scale*IndexReg + Disp ] or [ symbol ] 642 643 // Eat '[' 644 if (getLexer().isNot(AsmToken::LBrac)) 645 return ErrorOperand(Start, "Expected '[' token!"); 646 Parser.Lex(); 647 648 if (getLexer().is(AsmToken::Identifier)) { 649 // Parse BaseReg 650 if (ParseRegister(BaseReg, Start, End)) { 651 // Handle '[' 'symbol' ']' 652 if (getParser().ParseExpression(Disp, End)) return 0; 653 if (getLexer().isNot(AsmToken::RBrac)) 654 return ErrorOperand(Start, "Expected ']' token!"); 655 Parser.Lex(); 656 return X86Operand::CreateMem(Disp, Start, End, Size); 657 } 658 } else if (getLexer().is(AsmToken::Integer)) { 659 int64_t Val = Parser.getTok().getIntVal(); 660 Parser.Lex(); 661 SMLoc Loc = Parser.getTok().getLoc(); 662 if (getLexer().is(AsmToken::RBrac)) { 663 // Handle '[' number ']' 664 Parser.Lex(); 665 const MCExpr *Disp = MCConstantExpr::Create(Val, getContext()); 666 if (SegReg) 667 return X86Operand::CreateMem(SegReg, Disp, 0, 0, Scale, 668 Start, End, Size); 669 return X86Operand::CreateMem(Disp, Start, End, Size); 670 } else if (getLexer().is(AsmToken::Star)) { 671 // Handle '[' Scale*IndexReg ']' 672 Parser.Lex(); 673 SMLoc IdxRegLoc = Parser.getTok().getLoc(); 674 if (ParseRegister(IndexReg, IdxRegLoc, End)) 675 return ErrorOperand(IdxRegLoc, "Expected register"); 676 Scale = Val; 677 } else 678 return ErrorOperand(Loc, "Unexpected token"); 679 } 680 681 if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus)) { 682 bool isPlus = getLexer().is(AsmToken::Plus); 683 Parser.Lex(); 684 SMLoc PlusLoc = Parser.getTok().getLoc(); 685 if (getLexer().is(AsmToken::Integer)) { 686 int64_t Val = Parser.getTok().getIntVal(); 687 Parser.Lex(); 688 if (getLexer().is(AsmToken::Star)) { 689 Parser.Lex(); 690 SMLoc IdxRegLoc = Parser.getTok().getLoc(); 691 if (ParseRegister(IndexReg, IdxRegLoc, End)) 692 return ErrorOperand(IdxRegLoc, "Expected register"); 693 Scale = Val; 694 } else if (getLexer().is(AsmToken::RBrac)) { 695 const MCExpr *ValExpr = MCConstantExpr::Create(Val, getContext()); 696 Disp = isPlus ? ValExpr : MCConstantExpr::Create(0-Val, getContext()); 697 } else 698 return ErrorOperand(PlusLoc, "unexpected token after +"); 699 } else if (getLexer().is(AsmToken::Identifier)) { 700 // This could be an index register or a displacement expression. 701 End = Parser.getTok().getLoc(); 702 if (!IndexReg) 703 ParseRegister(IndexReg, Start, End); 704 else if (getParser().ParseExpression(Disp, End)) return 0; 705 } 706 } 707 708 if (getLexer().isNot(AsmToken::RBrac)) 709 if (getParser().ParseExpression(Disp, End)) return 0; 710 711 End = Parser.getTok().getLoc(); 712 if (getLexer().isNot(AsmToken::RBrac)) 713 return ErrorOperand(End, "expected ']' token!"); 714 Parser.Lex(); 715 End = Parser.getTok().getLoc(); 716 717 // handle [-42] 718 if (!BaseReg && !IndexReg) 719 return X86Operand::CreateMem(Disp, Start, End, Size); 720 721 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, 722 Start, End, Size); 723 } 724 725 /// ParseIntelMemOperand - Parse intel style memory operand. 726 X86Operand *X86AsmParser::ParseIntelMemOperand() { 727 const AsmToken &Tok = Parser.getTok(); 728 SMLoc Start = Parser.getTok().getLoc(), End; 729 unsigned SegReg = 0; 730 731 unsigned Size = getIntelMemOperandSize(Tok.getString()); 732 if (Size) { 733 Parser.Lex(); 734 assert (Tok.getString() == "PTR" && "Unexpected token!"); 735 Parser.Lex(); 736 } 737 738 if (getLexer().is(AsmToken::LBrac)) 739 return ParseIntelBracExpression(SegReg, Size); 740 741 if (!ParseRegister(SegReg, Start, End)) { 742 // Handel SegReg : [ ... ] 743 if (getLexer().isNot(AsmToken::Colon)) 744 return ErrorOperand(Start, "Expected ':' token!"); 745 Parser.Lex(); // Eat : 746 if (getLexer().isNot(AsmToken::LBrac)) 747 return ErrorOperand(Start, "Expected '[' token!"); 748 return ParseIntelBracExpression(SegReg, Size); 749 } 750 751 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); 752 if (getParser().ParseExpression(Disp, End)) return 0; 753 return X86Operand::CreateMem(Disp, Start, End, Size); 754 } 755 756 X86Operand *X86AsmParser::ParseIntelOperand() { 757 SMLoc Start = Parser.getTok().getLoc(), End; 758 759 // immediate. 760 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Real) || 761 getLexer().is(AsmToken::Minus)) { 762 const MCExpr *Val; 763 if (!getParser().ParseExpression(Val, End)) { 764 End = Parser.getTok().getLoc(); 765 return X86Operand::CreateImm(Val, Start, End); 766 } 767 } 768 769 // register 770 unsigned RegNo = 0; 771 if (!ParseRegister(RegNo, Start, End)) { 772 End = Parser.getTok().getLoc(); 773 return X86Operand::CreateReg(RegNo, Start, End); 774 } 775 776 // mem operand 777 return ParseIntelMemOperand(); 778 } 779 780 X86Operand *X86AsmParser::ParseATTOperand() { 781 switch (getLexer().getKind()) { 782 default: 783 // Parse a memory operand with no segment register. 784 return ParseMemOperand(0, Parser.getTok().getLoc()); 785 case AsmToken::Percent: { 786 // Read the register. 787 unsigned RegNo; 788 SMLoc Start, End; 789 if (ParseRegister(RegNo, Start, End)) return 0; 790 if (RegNo == X86::EIZ || RegNo == X86::RIZ) { 791 Error(Start, "%eiz and %riz can only be used as index registers", 792 SMRange(Start, End)); 793 return 0; 794 } 795 796 // If this is a segment register followed by a ':', then this is the start 797 // of a memory reference, otherwise this is a normal register reference. 798 if (getLexer().isNot(AsmToken::Colon)) 799 return X86Operand::CreateReg(RegNo, Start, End); 800 801 802 getParser().Lex(); // Eat the colon. 803 return ParseMemOperand(RegNo, Start); 804 } 805 case AsmToken::Dollar: { 806 // $42 -> immediate. 807 SMLoc Start = Parser.getTok().getLoc(), End; 808 Parser.Lex(); 809 const MCExpr *Val; 810 if (getParser().ParseExpression(Val, End)) 811 return 0; 812 return X86Operand::CreateImm(Val, Start, End); 813 } 814 } 815 } 816 817 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix 818 /// has already been parsed if present. 819 X86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) { 820 821 // We have to disambiguate a parenthesized expression "(4+5)" from the start 822 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 823 // only way to do this without lookahead is to eat the '(' and see what is 824 // after it. 825 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); 826 if (getLexer().isNot(AsmToken::LParen)) { 827 SMLoc ExprEnd; 828 if (getParser().ParseExpression(Disp, ExprEnd)) return 0; 829 830 // After parsing the base expression we could either have a parenthesized 831 // memory address or not. If not, return now. If so, eat the (. 832 if (getLexer().isNot(AsmToken::LParen)) { 833 // Unless we have a segment register, treat this as an immediate. 834 if (SegReg == 0) 835 return X86Operand::CreateMem(Disp, MemStart, ExprEnd); 836 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 837 } 838 839 // Eat the '('. 840 Parser.Lex(); 841 } else { 842 // Okay, we have a '('. We don't know if this is an expression or not, but 843 // so we have to eat the ( to see beyond it. 844 SMLoc LParenLoc = Parser.getTok().getLoc(); 845 Parser.Lex(); // Eat the '('. 846 847 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { 848 // Nothing to do here, fall into the code below with the '(' part of the 849 // memory operand consumed. 850 } else { 851 SMLoc ExprEnd; 852 853 // It must be an parenthesized expression, parse it now. 854 if (getParser().ParseParenExpression(Disp, ExprEnd)) 855 return 0; 856 857 // After parsing the base expression we could either have a parenthesized 858 // memory address or not. If not, return now. If so, eat the (. 859 if (getLexer().isNot(AsmToken::LParen)) { 860 // Unless we have a segment register, treat this as an immediate. 861 if (SegReg == 0) 862 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd); 863 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 864 } 865 866 // Eat the '('. 867 Parser.Lex(); 868 } 869 } 870 871 // If we reached here, then we just ate the ( of the memory operand. Process 872 // the rest of the memory operand. 873 unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 874 SMLoc IndexLoc; 875 876 if (getLexer().is(AsmToken::Percent)) { 877 SMLoc StartLoc, EndLoc; 878 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return 0; 879 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) { 880 Error(StartLoc, "eiz and riz can only be used as index registers", 881 SMRange(StartLoc, EndLoc)); 882 return 0; 883 } 884 } 885 886 if (getLexer().is(AsmToken::Comma)) { 887 Parser.Lex(); // Eat the comma. 888 IndexLoc = Parser.getTok().getLoc(); 889 890 // Following the comma we should have either an index register, or a scale 891 // value. We don't support the later form, but we want to parse it 892 // correctly. 893 // 894 // Not that even though it would be completely consistent to support syntax 895 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. 896 if (getLexer().is(AsmToken::Percent)) { 897 SMLoc L; 898 if (ParseRegister(IndexReg, L, L)) return 0; 899 900 if (getLexer().isNot(AsmToken::RParen)) { 901 // Parse the scale amount: 902 // ::= ',' [scale-expression] 903 if (getLexer().isNot(AsmToken::Comma)) { 904 Error(Parser.getTok().getLoc(), 905 "expected comma in scale expression"); 906 return 0; 907 } 908 Parser.Lex(); // Eat the comma. 909 910 if (getLexer().isNot(AsmToken::RParen)) { 911 SMLoc Loc = Parser.getTok().getLoc(); 912 913 int64_t ScaleVal; 914 if (getParser().ParseAbsoluteExpression(ScaleVal)){ 915 Error(Loc, "expected scale expression"); 916 return 0; 917 } 918 919 // Validate the scale amount. 920 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){ 921 Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 922 return 0; 923 } 924 Scale = (unsigned)ScaleVal; 925 } 926 } 927 } else if (getLexer().isNot(AsmToken::RParen)) { 928 // A scale amount without an index is ignored. 929 // index. 930 SMLoc Loc = Parser.getTok().getLoc(); 931 932 int64_t Value; 933 if (getParser().ParseAbsoluteExpression(Value)) 934 return 0; 935 936 if (Value != 1) 937 Warning(Loc, "scale factor without index register is ignored"); 938 Scale = 1; 939 } 940 } 941 942 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 943 if (getLexer().isNot(AsmToken::RParen)) { 944 Error(Parser.getTok().getLoc(), "unexpected token in memory operand"); 945 return 0; 946 } 947 SMLoc MemEnd = Parser.getTok().getLoc(); 948 Parser.Lex(); // Eat the ')'. 949 950 // If we have both a base register and an index register make sure they are 951 // both 64-bit or 32-bit registers. 952 // To support VSIB, IndexReg can be 128-bit or 256-bit registers. 953 if (BaseReg != 0 && IndexReg != 0) { 954 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) && 955 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 956 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) && 957 IndexReg != X86::RIZ) { 958 Error(IndexLoc, "index register is 32-bit, but base register is 64-bit"); 959 return 0; 960 } 961 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) && 962 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 963 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) && 964 IndexReg != X86::EIZ){ 965 Error(IndexLoc, "index register is 64-bit, but base register is 32-bit"); 966 return 0; 967 } 968 } 969 970 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, 971 MemStart, MemEnd); 972 } 973 974 bool X86AsmParser:: 975 ParseInstruction(StringRef Name, SMLoc NameLoc, 976 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 977 StringRef PatchedName = Name; 978 979 // FIXME: Hack to recognize setneb as setne. 980 if (PatchedName.startswith("set") && PatchedName.endswith("b") && 981 PatchedName != "setb" && PatchedName != "setnb") 982 PatchedName = PatchedName.substr(0, Name.size()-1); 983 984 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}. 985 const MCExpr *ExtraImmOp = 0; 986 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) && 987 (PatchedName.endswith("ss") || PatchedName.endswith("sd") || 988 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { 989 bool IsVCMP = PatchedName[0] == 'v'; 990 unsigned SSECCIdx = IsVCMP ? 4 : 3; 991 unsigned SSEComparisonCode = StringSwitch<unsigned>( 992 PatchedName.slice(SSECCIdx, PatchedName.size() - 2)) 993 .Case("eq", 0x00) 994 .Case("lt", 0x01) 995 .Case("le", 0x02) 996 .Case("unord", 0x03) 997 .Case("neq", 0x04) 998 .Case("nlt", 0x05) 999 .Case("nle", 0x06) 1000 .Case("ord", 0x07) 1001 /* AVX only from here */ 1002 .Case("eq_uq", 0x08) 1003 .Case("nge", 0x09) 1004 .Case("ngt", 0x0A) 1005 .Case("false", 0x0B) 1006 .Case("neq_oq", 0x0C) 1007 .Case("ge", 0x0D) 1008 .Case("gt", 0x0E) 1009 .Case("true", 0x0F) 1010 .Case("eq_os", 0x10) 1011 .Case("lt_oq", 0x11) 1012 .Case("le_oq", 0x12) 1013 .Case("unord_s", 0x13) 1014 .Case("neq_us", 0x14) 1015 .Case("nlt_uq", 0x15) 1016 .Case("nle_uq", 0x16) 1017 .Case("ord_s", 0x17) 1018 .Case("eq_us", 0x18) 1019 .Case("nge_uq", 0x19) 1020 .Case("ngt_uq", 0x1A) 1021 .Case("false_os", 0x1B) 1022 .Case("neq_os", 0x1C) 1023 .Case("ge_oq", 0x1D) 1024 .Case("gt_oq", 0x1E) 1025 .Case("true_us", 0x1F) 1026 .Default(~0U); 1027 if (SSEComparisonCode != ~0U && (IsVCMP || SSEComparisonCode < 8)) { 1028 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode, 1029 getParser().getContext()); 1030 if (PatchedName.endswith("ss")) { 1031 PatchedName = IsVCMP ? "vcmpss" : "cmpss"; 1032 } else if (PatchedName.endswith("sd")) { 1033 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd"; 1034 } else if (PatchedName.endswith("ps")) { 1035 PatchedName = IsVCMP ? "vcmpps" : "cmpps"; 1036 } else { 1037 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!"); 1038 PatchedName = IsVCMP ? "vcmppd" : "cmppd"; 1039 } 1040 } 1041 } 1042 1043 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); 1044 1045 if (ExtraImmOp && !isParsingIntelSyntax()) 1046 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); 1047 1048 // Determine whether this is an instruction prefix. 1049 bool isPrefix = 1050 Name == "lock" || Name == "rep" || 1051 Name == "repe" || Name == "repz" || 1052 Name == "repne" || Name == "repnz" || 1053 Name == "rex64" || Name == "data16"; 1054 1055 1056 // This does the actual operand parsing. Don't parse any more if we have a 1057 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we 1058 // just want to parse the "lock" as the first instruction and the "incl" as 1059 // the next one. 1060 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) { 1061 1062 // Parse '*' modifier. 1063 if (getLexer().is(AsmToken::Star)) { 1064 SMLoc Loc = Parser.getTok().getLoc(); 1065 Operands.push_back(X86Operand::CreateToken("*", Loc)); 1066 Parser.Lex(); // Eat the star. 1067 } 1068 1069 // Read the first operand. 1070 if (X86Operand *Op = ParseOperand()) 1071 Operands.push_back(Op); 1072 else { 1073 Parser.EatToEndOfStatement(); 1074 return true; 1075 } 1076 1077 while (getLexer().is(AsmToken::Comma)) { 1078 Parser.Lex(); // Eat the comma. 1079 1080 // Parse and remember the operand. 1081 if (X86Operand *Op = ParseOperand()) 1082 Operands.push_back(Op); 1083 else { 1084 Parser.EatToEndOfStatement(); 1085 return true; 1086 } 1087 } 1088 1089 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1090 SMLoc Loc = getLexer().getLoc(); 1091 Parser.EatToEndOfStatement(); 1092 return Error(Loc, "unexpected token in argument list"); 1093 } 1094 } 1095 1096 if (getLexer().is(AsmToken::EndOfStatement)) 1097 Parser.Lex(); // Consume the EndOfStatement 1098 else if (isPrefix && getLexer().is(AsmToken::Slash)) 1099 Parser.Lex(); // Consume the prefix separator Slash 1100 1101 if (ExtraImmOp && isParsingIntelSyntax()) 1102 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); 1103 1104 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" -> 1105 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely 1106 // documented form in various unofficial manuals, so a lot of code uses it. 1107 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") && 1108 Operands.size() == 3) { 1109 X86Operand &Op = *(X86Operand*)Operands.back(); 1110 if (Op.isMem() && Op.Mem.SegReg == 0 && 1111 isa<MCConstantExpr>(Op.Mem.Disp) && 1112 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 1113 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 1114 SMLoc Loc = Op.getEndLoc(); 1115 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 1116 delete &Op; 1117 } 1118 } 1119 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al". 1120 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") && 1121 Operands.size() == 3) { 1122 X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 1123 if (Op.isMem() && Op.Mem.SegReg == 0 && 1124 isa<MCConstantExpr>(Op.Mem.Disp) && 1125 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 1126 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 1127 SMLoc Loc = Op.getEndLoc(); 1128 Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 1129 delete &Op; 1130 } 1131 } 1132 // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]" 1133 if (Name.startswith("ins") && Operands.size() == 3 && 1134 (Name == "insb" || Name == "insw" || Name == "insl")) { 1135 X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 1136 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 1137 if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) { 1138 Operands.pop_back(); 1139 Operands.pop_back(); 1140 delete &Op; 1141 delete &Op2; 1142 } 1143 } 1144 1145 // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]" 1146 if (Name.startswith("outs") && Operands.size() == 3 && 1147 (Name == "outsb" || Name == "outsw" || Name == "outsl")) { 1148 X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 1149 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 1150 if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) { 1151 Operands.pop_back(); 1152 Operands.pop_back(); 1153 delete &Op; 1154 delete &Op2; 1155 } 1156 } 1157 1158 // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]" 1159 if (Name.startswith("movs") && Operands.size() == 3 && 1160 (Name == "movsb" || Name == "movsw" || Name == "movsl" || 1161 (is64BitMode() && Name == "movsq"))) { 1162 X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 1163 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 1164 if (isSrcOp(Op) && isDstOp(Op2)) { 1165 Operands.pop_back(); 1166 Operands.pop_back(); 1167 delete &Op; 1168 delete &Op2; 1169 } 1170 } 1171 // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]" 1172 if (Name.startswith("lods") && Operands.size() == 3 && 1173 (Name == "lods" || Name == "lodsb" || Name == "lodsw" || 1174 Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) { 1175 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 1176 X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]); 1177 if (isSrcOp(*Op1) && Op2->isReg()) { 1178 const char *ins; 1179 unsigned reg = Op2->getReg(); 1180 bool isLods = Name == "lods"; 1181 if (reg == X86::AL && (isLods || Name == "lodsb")) 1182 ins = "lodsb"; 1183 else if (reg == X86::AX && (isLods || Name == "lodsw")) 1184 ins = "lodsw"; 1185 else if (reg == X86::EAX && (isLods || Name == "lodsl")) 1186 ins = "lodsl"; 1187 else if (reg == X86::RAX && (isLods || Name == "lodsq")) 1188 ins = "lodsq"; 1189 else 1190 ins = NULL; 1191 if (ins != NULL) { 1192 Operands.pop_back(); 1193 Operands.pop_back(); 1194 delete Op1; 1195 delete Op2; 1196 if (Name != ins) 1197 static_cast<X86Operand*>(Operands[0])->setTokenValue(ins); 1198 } 1199 } 1200 } 1201 // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]" 1202 if (Name.startswith("stos") && Operands.size() == 3 && 1203 (Name == "stos" || Name == "stosb" || Name == "stosw" || 1204 Name == "stosl" || (is64BitMode() && Name == "stosq"))) { 1205 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 1206 X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]); 1207 if (isDstOp(*Op2) && Op1->isReg()) { 1208 const char *ins; 1209 unsigned reg = Op1->getReg(); 1210 bool isStos = Name == "stos"; 1211 if (reg == X86::AL && (isStos || Name == "stosb")) 1212 ins = "stosb"; 1213 else if (reg == X86::AX && (isStos || Name == "stosw")) 1214 ins = "stosw"; 1215 else if (reg == X86::EAX && (isStos || Name == "stosl")) 1216 ins = "stosl"; 1217 else if (reg == X86::RAX && (isStos || Name == "stosq")) 1218 ins = "stosq"; 1219 else 1220 ins = NULL; 1221 if (ins != NULL) { 1222 Operands.pop_back(); 1223 Operands.pop_back(); 1224 delete Op1; 1225 delete Op2; 1226 if (Name != ins) 1227 static_cast<X86Operand*>(Operands[0])->setTokenValue(ins); 1228 } 1229 } 1230 } 1231 1232 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to 1233 // "shift <op>". 1234 if ((Name.startswith("shr") || Name.startswith("sar") || 1235 Name.startswith("shl") || Name.startswith("sal") || 1236 Name.startswith("rcl") || Name.startswith("rcr") || 1237 Name.startswith("rol") || Name.startswith("ror")) && 1238 Operands.size() == 3) { 1239 if (isParsingIntelSyntax()) { 1240 // Intel syntax 1241 X86Operand *Op1 = static_cast<X86Operand*>(Operands[2]); 1242 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 1243 cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) { 1244 delete Operands[2]; 1245 Operands.pop_back(); 1246 } 1247 } else { 1248 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 1249 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 1250 cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) { 1251 delete Operands[1]; 1252 Operands.erase(Operands.begin() + 1); 1253 } 1254 } 1255 } 1256 1257 // Transforms "int $3" into "int3" as a size optimization. We can't write an 1258 // instalias with an immediate operand yet. 1259 if (Name == "int" && Operands.size() == 2) { 1260 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 1261 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 1262 cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) { 1263 delete Operands[1]; 1264 Operands.erase(Operands.begin() + 1); 1265 static_cast<X86Operand*>(Operands[0])->setTokenValue("int3"); 1266 } 1267 } 1268 1269 return false; 1270 } 1271 1272 bool X86AsmParser:: 1273 processInstruction(MCInst &Inst, 1274 const SmallVectorImpl<MCParsedAsmOperand*> &Ops) { 1275 switch (Inst.getOpcode()) { 1276 default: return false; 1277 case X86::AND16i16: { 1278 if (!Inst.getOperand(0).isImm() || 1279 !isImmSExti16i8Value(Inst.getOperand(0).getImm())) 1280 return false; 1281 1282 MCInst TmpInst; 1283 TmpInst.setOpcode(X86::AND16ri8); 1284 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1285 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1286 TmpInst.addOperand(Inst.getOperand(0)); 1287 Inst = TmpInst; 1288 return true; 1289 } 1290 case X86::AND32i32: { 1291 if (!Inst.getOperand(0).isImm() || 1292 !isImmSExti32i8Value(Inst.getOperand(0).getImm())) 1293 return false; 1294 1295 MCInst TmpInst; 1296 TmpInst.setOpcode(X86::AND32ri8); 1297 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1298 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1299 TmpInst.addOperand(Inst.getOperand(0)); 1300 Inst = TmpInst; 1301 return true; 1302 } 1303 case X86::AND64i32: { 1304 if (!Inst.getOperand(0).isImm() || 1305 !isImmSExti64i8Value(Inst.getOperand(0).getImm())) 1306 return false; 1307 1308 MCInst TmpInst; 1309 TmpInst.setOpcode(X86::AND64ri8); 1310 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1311 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1312 TmpInst.addOperand(Inst.getOperand(0)); 1313 Inst = TmpInst; 1314 return true; 1315 } 1316 case X86::XOR16i16: { 1317 if (!Inst.getOperand(0).isImm() || 1318 !isImmSExti16i8Value(Inst.getOperand(0).getImm())) 1319 return false; 1320 1321 MCInst TmpInst; 1322 TmpInst.setOpcode(X86::XOR16ri8); 1323 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1324 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1325 TmpInst.addOperand(Inst.getOperand(0)); 1326 Inst = TmpInst; 1327 return true; 1328 } 1329 case X86::XOR32i32: { 1330 if (!Inst.getOperand(0).isImm() || 1331 !isImmSExti32i8Value(Inst.getOperand(0).getImm())) 1332 return false; 1333 1334 MCInst TmpInst; 1335 TmpInst.setOpcode(X86::XOR32ri8); 1336 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1337 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1338 TmpInst.addOperand(Inst.getOperand(0)); 1339 Inst = TmpInst; 1340 return true; 1341 } 1342 case X86::XOR64i32: { 1343 if (!Inst.getOperand(0).isImm() || 1344 !isImmSExti64i8Value(Inst.getOperand(0).getImm())) 1345 return false; 1346 1347 MCInst TmpInst; 1348 TmpInst.setOpcode(X86::XOR64ri8); 1349 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1350 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1351 TmpInst.addOperand(Inst.getOperand(0)); 1352 Inst = TmpInst; 1353 return true; 1354 } 1355 case X86::OR16i16: { 1356 if (!Inst.getOperand(0).isImm() || 1357 !isImmSExti16i8Value(Inst.getOperand(0).getImm())) 1358 return false; 1359 1360 MCInst TmpInst; 1361 TmpInst.setOpcode(X86::OR16ri8); 1362 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1363 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1364 TmpInst.addOperand(Inst.getOperand(0)); 1365 Inst = TmpInst; 1366 return true; 1367 } 1368 case X86::OR32i32: { 1369 if (!Inst.getOperand(0).isImm() || 1370 !isImmSExti32i8Value(Inst.getOperand(0).getImm())) 1371 return false; 1372 1373 MCInst TmpInst; 1374 TmpInst.setOpcode(X86::OR32ri8); 1375 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1376 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1377 TmpInst.addOperand(Inst.getOperand(0)); 1378 Inst = TmpInst; 1379 return true; 1380 } 1381 case X86::OR64i32: { 1382 if (!Inst.getOperand(0).isImm() || 1383 !isImmSExti64i8Value(Inst.getOperand(0).getImm())) 1384 return false; 1385 1386 MCInst TmpInst; 1387 TmpInst.setOpcode(X86::OR64ri8); 1388 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1389 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1390 TmpInst.addOperand(Inst.getOperand(0)); 1391 Inst = TmpInst; 1392 return true; 1393 } 1394 case X86::CMP16i16: { 1395 if (!Inst.getOperand(0).isImm() || 1396 !isImmSExti16i8Value(Inst.getOperand(0).getImm())) 1397 return false; 1398 1399 MCInst TmpInst; 1400 TmpInst.setOpcode(X86::CMP16ri8); 1401 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1402 TmpInst.addOperand(Inst.getOperand(0)); 1403 Inst = TmpInst; 1404 return true; 1405 } 1406 case X86::CMP32i32: { 1407 if (!Inst.getOperand(0).isImm() || 1408 !isImmSExti32i8Value(Inst.getOperand(0).getImm())) 1409 return false; 1410 1411 MCInst TmpInst; 1412 TmpInst.setOpcode(X86::CMP32ri8); 1413 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1414 TmpInst.addOperand(Inst.getOperand(0)); 1415 Inst = TmpInst; 1416 return true; 1417 } 1418 case X86::CMP64i32: { 1419 if (!Inst.getOperand(0).isImm() || 1420 !isImmSExti64i8Value(Inst.getOperand(0).getImm())) 1421 return false; 1422 1423 MCInst TmpInst; 1424 TmpInst.setOpcode(X86::CMP64ri8); 1425 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1426 TmpInst.addOperand(Inst.getOperand(0)); 1427 Inst = TmpInst; 1428 return true; 1429 } 1430 case X86::ADD16i16: { 1431 if (!Inst.getOperand(0).isImm() || 1432 !isImmSExti16i8Value(Inst.getOperand(0).getImm())) 1433 return false; 1434 1435 MCInst TmpInst; 1436 TmpInst.setOpcode(X86::ADD16ri8); 1437 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1438 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1439 TmpInst.addOperand(Inst.getOperand(0)); 1440 Inst = TmpInst; 1441 return true; 1442 } 1443 case X86::ADD32i32: { 1444 if (!Inst.getOperand(0).isImm() || 1445 !isImmSExti32i8Value(Inst.getOperand(0).getImm())) 1446 return false; 1447 1448 MCInst TmpInst; 1449 TmpInst.setOpcode(X86::ADD32ri8); 1450 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1451 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1452 TmpInst.addOperand(Inst.getOperand(0)); 1453 Inst = TmpInst; 1454 return true; 1455 } 1456 case X86::ADD64i32: { 1457 if (!Inst.getOperand(0).isImm() || 1458 !isImmSExti64i8Value(Inst.getOperand(0).getImm())) 1459 return false; 1460 1461 MCInst TmpInst; 1462 TmpInst.setOpcode(X86::ADD64ri8); 1463 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1464 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1465 TmpInst.addOperand(Inst.getOperand(0)); 1466 Inst = TmpInst; 1467 return true; 1468 } 1469 case X86::SUB16i16: { 1470 if (!Inst.getOperand(0).isImm() || 1471 !isImmSExti16i8Value(Inst.getOperand(0).getImm())) 1472 return false; 1473 1474 MCInst TmpInst; 1475 TmpInst.setOpcode(X86::SUB16ri8); 1476 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1477 TmpInst.addOperand(MCOperand::CreateReg(X86::AX)); 1478 TmpInst.addOperand(Inst.getOperand(0)); 1479 Inst = TmpInst; 1480 return true; 1481 } 1482 case X86::SUB32i32: { 1483 if (!Inst.getOperand(0).isImm() || 1484 !isImmSExti32i8Value(Inst.getOperand(0).getImm())) 1485 return false; 1486 1487 MCInst TmpInst; 1488 TmpInst.setOpcode(X86::SUB32ri8); 1489 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1490 TmpInst.addOperand(MCOperand::CreateReg(X86::EAX)); 1491 TmpInst.addOperand(Inst.getOperand(0)); 1492 Inst = TmpInst; 1493 return true; 1494 } 1495 case X86::SUB64i32: { 1496 if (!Inst.getOperand(0).isImm() || 1497 !isImmSExti64i8Value(Inst.getOperand(0).getImm())) 1498 return false; 1499 1500 MCInst TmpInst; 1501 TmpInst.setOpcode(X86::SUB64ri8); 1502 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1503 TmpInst.addOperand(MCOperand::CreateReg(X86::RAX)); 1504 TmpInst.addOperand(Inst.getOperand(0)); 1505 Inst = TmpInst; 1506 return true; 1507 } 1508 } 1509 } 1510 1511 bool X86AsmParser:: 1512 MatchAndEmitInstruction(SMLoc IDLoc, 1513 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1514 MCStreamer &Out) { 1515 SmallVector<MCInst, 2> Insts; 1516 bool Error = MatchInstruction(IDLoc, Operands, Insts); 1517 if (!Error) 1518 for (unsigned i = 0, e = Insts.size(); i != e; ++i) 1519 Out.EmitInstruction(Insts[i]); 1520 return Error; 1521 } 1522 1523 bool X86AsmParser:: 1524 MatchInstruction(SMLoc IDLoc, 1525 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1526 SmallVectorImpl<MCInst> &MCInsts) { 1527 assert(!Operands.empty() && "Unexpect empty operand list!"); 1528 X86Operand *Op = static_cast<X86Operand*>(Operands[0]); 1529 assert(Op->isToken() && "Leading operand should always be a mnemonic!"); 1530 1531 // First, handle aliases that expand to multiple instructions. 1532 // FIXME: This should be replaced with a real .td file alias mechanism. 1533 // Also, MatchInstructionImpl should do actually *do* the EmitInstruction 1534 // call. 1535 if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" || 1536 Op->getToken() == "fstsww" || Op->getToken() == "fstcww" || 1537 Op->getToken() == "finit" || Op->getToken() == "fsave" || 1538 Op->getToken() == "fstenv" || Op->getToken() == "fclex") { 1539 MCInst Inst; 1540 Inst.setOpcode(X86::WAIT); 1541 Inst.setLoc(IDLoc); 1542 MCInsts.push_back(Inst); 1543 1544 const char *Repl = 1545 StringSwitch<const char*>(Op->getToken()) 1546 .Case("finit", "fninit") 1547 .Case("fsave", "fnsave") 1548 .Case("fstcw", "fnstcw") 1549 .Case("fstcww", "fnstcw") 1550 .Case("fstenv", "fnstenv") 1551 .Case("fstsw", "fnstsw") 1552 .Case("fstsww", "fnstsw") 1553 .Case("fclex", "fnclex") 1554 .Default(0); 1555 assert(Repl && "Unknown wait-prefixed instruction"); 1556 delete Operands[0]; 1557 Operands[0] = X86Operand::CreateToken(Repl, IDLoc); 1558 } 1559 1560 bool WasOriginallyInvalidOperand = false; 1561 unsigned OrigErrorInfo; 1562 MCInst Inst; 1563 1564 // First, try a direct match. 1565 switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo, 1566 isParsingIntelSyntax())) { 1567 default: break; 1568 case Match_Success: 1569 // Some instructions need post-processing to, for example, tweak which 1570 // encoding is selected. Loop on it while changes happen so the 1571 // individual transformations can chain off each other. 1572 while (processInstruction(Inst, Operands)) 1573 ; 1574 1575 Inst.setLoc(IDLoc); 1576 MCInsts.push_back(Inst); 1577 return false; 1578 case Match_MissingFeature: 1579 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1580 return true; 1581 case Match_ConversionFail: 1582 return Error(IDLoc, "unable to convert operands to instruction"); 1583 case Match_InvalidOperand: 1584 WasOriginallyInvalidOperand = true; 1585 break; 1586 case Match_MnemonicFail: 1587 break; 1588 } 1589 1590 // FIXME: Ideally, we would only attempt suffix matches for things which are 1591 // valid prefixes, and we could just infer the right unambiguous 1592 // type. However, that requires substantially more matcher support than the 1593 // following hack. 1594 1595 // Change the operand to point to a temporary token. 1596 StringRef Base = Op->getToken(); 1597 SmallString<16> Tmp; 1598 Tmp += Base; 1599 Tmp += ' '; 1600 Op->setTokenValue(Tmp.str()); 1601 1602 // If this instruction starts with an 'f', then it is a floating point stack 1603 // instruction. These come in up to three forms for 32-bit, 64-bit, and 1604 // 80-bit floating point, which use the suffixes s,l,t respectively. 1605 // 1606 // Otherwise, we assume that this may be an integer instruction, which comes 1607 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively. 1608 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0"; 1609 1610 // Check for the various suffix matches. 1611 Tmp[Base.size()] = Suffixes[0]; 1612 unsigned ErrorInfoIgnore; 1613 unsigned Match1, Match2, Match3, Match4; 1614 1615 Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1616 Tmp[Base.size()] = Suffixes[1]; 1617 Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1618 Tmp[Base.size()] = Suffixes[2]; 1619 Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1620 Tmp[Base.size()] = Suffixes[3]; 1621 Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1622 1623 // Restore the old token. 1624 Op->setTokenValue(Base); 1625 1626 // If exactly one matched, then we treat that as a successful match (and the 1627 // instruction will already have been filled in correctly, since the failing 1628 // matches won't have modified it). 1629 unsigned NumSuccessfulMatches = 1630 (Match1 == Match_Success) + (Match2 == Match_Success) + 1631 (Match3 == Match_Success) + (Match4 == Match_Success); 1632 if (NumSuccessfulMatches == 1) { 1633 Inst.setLoc(IDLoc); 1634 MCInsts.push_back(Inst); 1635 return false; 1636 } 1637 1638 // Otherwise, the match failed, try to produce a decent error message. 1639 1640 // If we had multiple suffix matches, then identify this as an ambiguous 1641 // match. 1642 if (NumSuccessfulMatches > 1) { 1643 char MatchChars[4]; 1644 unsigned NumMatches = 0; 1645 if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0]; 1646 if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1]; 1647 if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2]; 1648 if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3]; 1649 1650 SmallString<126> Msg; 1651 raw_svector_ostream OS(Msg); 1652 OS << "ambiguous instructions require an explicit suffix (could be "; 1653 for (unsigned i = 0; i != NumMatches; ++i) { 1654 if (i != 0) 1655 OS << ", "; 1656 if (i + 1 == NumMatches) 1657 OS << "or "; 1658 OS << "'" << Base << MatchChars[i] << "'"; 1659 } 1660 OS << ")"; 1661 Error(IDLoc, OS.str()); 1662 return true; 1663 } 1664 1665 // Okay, we know that none of the variants matched successfully. 1666 1667 // If all of the instructions reported an invalid mnemonic, then the original 1668 // mnemonic was invalid. 1669 if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) && 1670 (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) { 1671 if (!WasOriginallyInvalidOperand) { 1672 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'", 1673 Op->getLocRange()); 1674 } 1675 1676 // Recover location info for the operand if we know which was the problem. 1677 if (OrigErrorInfo != ~0U) { 1678 if (OrigErrorInfo >= Operands.size()) 1679 return Error(IDLoc, "too few operands for instruction"); 1680 1681 X86Operand *Operand = (X86Operand*)Operands[OrigErrorInfo]; 1682 if (Operand->getStartLoc().isValid()) { 1683 SMRange OperandRange = Operand->getLocRange(); 1684 return Error(Operand->getStartLoc(), "invalid operand for instruction", 1685 OperandRange); 1686 } 1687 } 1688 1689 return Error(IDLoc, "invalid operand for instruction"); 1690 } 1691 1692 // If one instruction matched with a missing feature, report this as a 1693 // missing feature. 1694 if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) + 1695 (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){ 1696 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1697 return true; 1698 } 1699 1700 // If one instruction matched with an invalid operand, report this as an 1701 // operand failure. 1702 if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) + 1703 (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){ 1704 Error(IDLoc, "invalid operand for instruction"); 1705 return true; 1706 } 1707 1708 // If all of these were an outright failure, report it in a useless way. 1709 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix"); 1710 return true; 1711 } 1712 1713 1714 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) { 1715 StringRef IDVal = DirectiveID.getIdentifier(); 1716 if (IDVal == ".word") 1717 return ParseDirectiveWord(2, DirectiveID.getLoc()); 1718 else if (IDVal.startswith(".code")) 1719 return ParseDirectiveCode(IDVal, DirectiveID.getLoc()); 1720 else if (IDVal.startswith(".intel_syntax")) { 1721 getParser().setAssemblerDialect(1); 1722 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1723 if(Parser.getTok().getString() == "noprefix") { 1724 // FIXME : Handle noprefix 1725 Parser.Lex(); 1726 } else 1727 return true; 1728 } 1729 return false; 1730 } 1731 return true; 1732 } 1733 1734 /// ParseDirectiveWord 1735 /// ::= .word [ expression (, expression)* ] 1736 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 1737 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1738 for (;;) { 1739 const MCExpr *Value; 1740 if (getParser().ParseExpression(Value)) 1741 return true; 1742 1743 getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/); 1744 1745 if (getLexer().is(AsmToken::EndOfStatement)) 1746 break; 1747 1748 // FIXME: Improve diagnostic. 1749 if (getLexer().isNot(AsmToken::Comma)) 1750 return Error(L, "unexpected token in directive"); 1751 Parser.Lex(); 1752 } 1753 } 1754 1755 Parser.Lex(); 1756 return false; 1757 } 1758 1759 /// ParseDirectiveCode 1760 /// ::= .code32 | .code64 1761 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { 1762 if (IDVal == ".code32") { 1763 Parser.Lex(); 1764 if (is64BitMode()) { 1765 SwitchMode(); 1766 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 1767 } 1768 } else if (IDVal == ".code64") { 1769 Parser.Lex(); 1770 if (!is64BitMode()) { 1771 SwitchMode(); 1772 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64); 1773 } 1774 } else { 1775 return Error(L, "unexpected directive " + IDVal); 1776 } 1777 1778 return false; 1779 } 1780 1781 1782 extern "C" void LLVMInitializeX86AsmLexer(); 1783 1784 // Force static initialization. 1785 extern "C" void LLVMInitializeX86AsmParser() { 1786 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target); 1787 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target); 1788 LLVMInitializeX86AsmLexer(); 1789 } 1790 1791 #define GET_REGISTER_MATCHER 1792 #define GET_MATCHER_IMPLEMENTATION 1793 #include "X86GenAsmMatcher.inc" 1794