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