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