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/OwningPtr.h" 21 #include "llvm/ADT/SmallString.h" 22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/ADT/StringExtras.h" 24 #include "llvm/ADT/StringSwitch.h" 25 #include "llvm/ADT/Twine.h" 26 #include "llvm/Support/SourceMgr.h" 27 #include "llvm/Support/TargetRegistry.h" 28 #include "llvm/Support/raw_ostream.h" 29 30 using namespace llvm; 31 32 namespace { 33 struct X86Operand; 34 35 class X86ATTAsmParser : public MCTargetAsmParser { 36 MCSubtargetInfo &STI; 37 MCAsmParser &Parser; 38 39 private: 40 MCAsmParser &getParser() const { return Parser; } 41 42 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 43 44 bool Error(SMLoc L, const Twine &Msg, 45 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) { 46 return Parser.Error(L, Msg, Ranges); 47 } 48 49 X86Operand *ParseOperand(); 50 X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc); 51 52 bool ParseDirectiveWord(unsigned Size, SMLoc L); 53 bool ParseDirectiveCode(StringRef IDVal, SMLoc L); 54 55 bool MatchAndEmitInstruction(SMLoc IDLoc, 56 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 57 MCStreamer &Out); 58 59 /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi) 60 /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode. 61 bool isSrcOp(X86Operand &Op); 62 63 /// isDstOp - Returns true if operand is either %es:(%rdi) in 64bit mode 64 /// or %es:(%edi) in 32bit mode. 65 bool isDstOp(X86Operand &Op); 66 67 bool is64BitMode() const { 68 // FIXME: Can tablegen auto-generate this? 69 return (STI.getFeatureBits() & X86::Mode64Bit) != 0; 70 } 71 void SwitchMode() { 72 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit)); 73 setAvailableFeatures(FB); 74 } 75 76 /// @name Auto-generated Matcher Functions 77 /// { 78 79 #define GET_ASSEMBLER_HEADER 80 #include "X86GenAsmMatcher.inc" 81 82 /// } 83 84 public: 85 X86ATTAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 86 : MCTargetAsmParser(), STI(sti), Parser(parser) { 87 88 // Initialize the set of available features. 89 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 90 } 91 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 92 93 virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 94 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 95 96 virtual bool ParseDirective(AsmToken DirectiveID); 97 }; 98 } // end anonymous namespace 99 100 /// @name Auto-generated Match Functions 101 /// { 102 103 static unsigned MatchRegisterName(StringRef Name); 104 105 /// } 106 107 namespace { 108 109 /// X86Operand - Instances of this class represent a parsed X86 machine 110 /// instruction. 111 struct X86Operand : public MCParsedAsmOperand { 112 enum KindTy { 113 Token, 114 Register, 115 Immediate, 116 Memory 117 } Kind; 118 119 SMLoc StartLoc, EndLoc; 120 121 union { 122 struct { 123 const char *Data; 124 unsigned Length; 125 } Tok; 126 127 struct { 128 unsigned RegNo; 129 } Reg; 130 131 struct { 132 const MCExpr *Val; 133 } Imm; 134 135 struct { 136 unsigned SegReg; 137 const MCExpr *Disp; 138 unsigned BaseReg; 139 unsigned IndexReg; 140 unsigned Scale; 141 } Mem; 142 }; 143 144 X86Operand(KindTy K, SMLoc Start, SMLoc End) 145 : Kind(K), StartLoc(Start), EndLoc(End) {} 146 147 /// getStartLoc - Get the location of the first token of this operand. 148 SMLoc getStartLoc() const { return StartLoc; } 149 /// getEndLoc - Get the location of the last token of this operand. 150 SMLoc getEndLoc() const { return EndLoc; } 151 152 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 153 154 virtual void print(raw_ostream &OS) const {} 155 156 StringRef getToken() const { 157 assert(Kind == Token && "Invalid access!"); 158 return StringRef(Tok.Data, Tok.Length); 159 } 160 void setTokenValue(StringRef Value) { 161 assert(Kind == Token && "Invalid access!"); 162 Tok.Data = Value.data(); 163 Tok.Length = Value.size(); 164 } 165 166 unsigned getReg() const { 167 assert(Kind == Register && "Invalid access!"); 168 return Reg.RegNo; 169 } 170 171 const MCExpr *getImm() const { 172 assert(Kind == Immediate && "Invalid access!"); 173 return Imm.Val; 174 } 175 176 const MCExpr *getMemDisp() const { 177 assert(Kind == Memory && "Invalid access!"); 178 return Mem.Disp; 179 } 180 unsigned getMemSegReg() const { 181 assert(Kind == Memory && "Invalid access!"); 182 return Mem.SegReg; 183 } 184 unsigned getMemBaseReg() const { 185 assert(Kind == Memory && "Invalid access!"); 186 return Mem.BaseReg; 187 } 188 unsigned getMemIndexReg() const { 189 assert(Kind == Memory && "Invalid access!"); 190 return Mem.IndexReg; 191 } 192 unsigned getMemScale() const { 193 assert(Kind == Memory && "Invalid access!"); 194 return Mem.Scale; 195 } 196 197 bool isToken() const {return Kind == Token; } 198 199 bool isImm() const { return Kind == Immediate; } 200 201 bool isImmSExti16i8() const { 202 if (!isImm()) 203 return false; 204 205 // If this isn't a constant expr, just assume it fits and let relaxation 206 // handle it. 207 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 208 if (!CE) 209 return true; 210 211 // Otherwise, check the value is in a range that makes sense for this 212 // extension. 213 uint64_t Value = CE->getValue(); 214 return (( Value <= 0x000000000000007FULL)|| 215 (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)|| 216 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 217 } 218 bool isImmSExti32i8() const { 219 if (!isImm()) 220 return false; 221 222 // If this isn't a constant expr, just assume it fits and let relaxation 223 // handle it. 224 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 225 if (!CE) 226 return true; 227 228 // Otherwise, check the value is in a range that makes sense for this 229 // extension. 230 uint64_t Value = CE->getValue(); 231 return (( Value <= 0x000000000000007FULL)|| 232 (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)|| 233 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 234 } 235 bool isImmZExtu32u8() const { 236 if (!isImm()) 237 return false; 238 239 // If this isn't a constant expr, just assume it fits and let relaxation 240 // handle it. 241 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 242 if (!CE) 243 return true; 244 245 // Otherwise, check the value is in a range that makes sense for this 246 // extension. 247 uint64_t Value = CE->getValue(); 248 return (Value <= 0x00000000000000FFULL); 249 } 250 bool isImmSExti64i8() 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 uint64_t Value = CE->getValue(); 263 return (( Value <= 0x000000000000007FULL)|| 264 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 265 } 266 bool isImmSExti64i32() const { 267 if (!isImm()) 268 return false; 269 270 // If this isn't a constant expr, just assume it fits and let relaxation 271 // handle it. 272 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 273 if (!CE) 274 return true; 275 276 // Otherwise, check the value is in a range that makes sense for this 277 // extension. 278 uint64_t Value = CE->getValue(); 279 return (( Value <= 0x000000007FFFFFFFULL)|| 280 (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 281 } 282 283 bool isMem() const { return Kind == Memory; } 284 285 bool isAbsMem() const { 286 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 287 !getMemIndexReg() && getMemScale() == 1; 288 } 289 290 bool isReg() const { return Kind == Register; } 291 292 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 293 // Add as immediates when possible. 294 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 295 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 296 else 297 Inst.addOperand(MCOperand::CreateExpr(Expr)); 298 } 299 300 void addRegOperands(MCInst &Inst, unsigned N) const { 301 assert(N == 1 && "Invalid number of operands!"); 302 Inst.addOperand(MCOperand::CreateReg(getReg())); 303 } 304 305 void addImmOperands(MCInst &Inst, unsigned N) const { 306 assert(N == 1 && "Invalid number of operands!"); 307 addExpr(Inst, getImm()); 308 } 309 310 void addMemOperands(MCInst &Inst, unsigned N) const { 311 assert((N == 5) && "Invalid number of operands!"); 312 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 313 Inst.addOperand(MCOperand::CreateImm(getMemScale())); 314 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); 315 addExpr(Inst, getMemDisp()); 316 Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 317 } 318 319 void addAbsMemOperands(MCInst &Inst, unsigned N) const { 320 assert((N == 1) && "Invalid number of operands!"); 321 Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); 322 } 323 324 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) { 325 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size() - 1); 326 X86Operand *Res = new X86Operand(Token, Loc, EndLoc); 327 Res->Tok.Data = Str.data(); 328 Res->Tok.Length = Str.size(); 329 return Res; 330 } 331 332 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) { 333 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc); 334 Res->Reg.RegNo = RegNo; 335 return Res; 336 } 337 338 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){ 339 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc); 340 Res->Imm.Val = Val; 341 return Res; 342 } 343 344 /// Create an absolute memory operand. 345 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, 346 SMLoc EndLoc) { 347 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 348 Res->Mem.SegReg = 0; 349 Res->Mem.Disp = Disp; 350 Res->Mem.BaseReg = 0; 351 Res->Mem.IndexReg = 0; 352 Res->Mem.Scale = 1; 353 return Res; 354 } 355 356 /// Create a generalized memory operand. 357 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp, 358 unsigned BaseReg, unsigned IndexReg, 359 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) { 360 // We should never just have a displacement, that should be parsed as an 361 // absolute memory operand. 362 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 363 364 // The scale should always be one of {1,2,4,8}. 365 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 366 "Invalid scale!"); 367 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 368 Res->Mem.SegReg = SegReg; 369 Res->Mem.Disp = Disp; 370 Res->Mem.BaseReg = BaseReg; 371 Res->Mem.IndexReg = IndexReg; 372 Res->Mem.Scale = Scale; 373 return Res; 374 } 375 }; 376 377 } // end anonymous namespace. 378 379 bool X86ATTAsmParser::isSrcOp(X86Operand &Op) { 380 unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI; 381 382 return (Op.isMem() && 383 (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) && 384 isa<MCConstantExpr>(Op.Mem.Disp) && 385 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 386 Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0); 387 } 388 389 bool X86ATTAsmParser::isDstOp(X86Operand &Op) { 390 unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI; 391 392 return Op.isMem() && Op.Mem.SegReg == X86::ES && 393 isa<MCConstantExpr>(Op.Mem.Disp) && 394 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 395 Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0; 396 } 397 398 bool X86ATTAsmParser::ParseRegister(unsigned &RegNo, 399 SMLoc &StartLoc, SMLoc &EndLoc) { 400 RegNo = 0; 401 const AsmToken &TokPercent = Parser.getTok(); 402 assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!"); 403 StartLoc = TokPercent.getLoc(); 404 Parser.Lex(); // Eat percent token. 405 406 const AsmToken &Tok = Parser.getTok(); 407 if (Tok.isNot(AsmToken::Identifier)) 408 return Error(StartLoc, "invalid register name", 409 SMRange(StartLoc, Tok.getEndLoc())); 410 411 RegNo = MatchRegisterName(Tok.getString()); 412 413 // If the match failed, try the register name as lowercase. 414 if (RegNo == 0) 415 RegNo = MatchRegisterName(LowercaseString(Tok.getString())); 416 417 if (!is64BitMode()) { 418 // FIXME: This should be done using Requires<In32BitMode> and 419 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also 420 // checked. 421 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a 422 // REX prefix. 423 if (RegNo == X86::RIZ || 424 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) || 425 X86II::isX86_64NonExtLowByteReg(RegNo) || 426 X86II::isX86_64ExtendedReg(RegNo)) 427 return Error(StartLoc, "register %" 428 + Tok.getString() + " is only available in 64-bit mode", 429 SMRange(StartLoc, Tok.getEndLoc())); 430 } 431 432 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. 433 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) { 434 RegNo = X86::ST0; 435 EndLoc = Tok.getLoc(); 436 Parser.Lex(); // Eat 'st' 437 438 // Check to see if we have '(4)' after %st. 439 if (getLexer().isNot(AsmToken::LParen)) 440 return false; 441 // Lex the paren. 442 getParser().Lex(); 443 444 const AsmToken &IntTok = Parser.getTok(); 445 if (IntTok.isNot(AsmToken::Integer)) 446 return Error(IntTok.getLoc(), "expected stack index"); 447 switch (IntTok.getIntVal()) { 448 case 0: RegNo = X86::ST0; break; 449 case 1: RegNo = X86::ST1; break; 450 case 2: RegNo = X86::ST2; break; 451 case 3: RegNo = X86::ST3; break; 452 case 4: RegNo = X86::ST4; break; 453 case 5: RegNo = X86::ST5; break; 454 case 6: RegNo = X86::ST6; break; 455 case 7: RegNo = X86::ST7; break; 456 default: return Error(IntTok.getLoc(), "invalid stack index"); 457 } 458 459 if (getParser().Lex().isNot(AsmToken::RParen)) 460 return Error(Parser.getTok().getLoc(), "expected ')'"); 461 462 EndLoc = Tok.getLoc(); 463 Parser.Lex(); // Eat ')' 464 return false; 465 } 466 467 // If this is "db[0-7]", match it as an alias 468 // for dr[0-7]. 469 if (RegNo == 0 && Tok.getString().size() == 3 && 470 Tok.getString().startswith("db")) { 471 switch (Tok.getString()[2]) { 472 case '0': RegNo = X86::DR0; break; 473 case '1': RegNo = X86::DR1; break; 474 case '2': RegNo = X86::DR2; break; 475 case '3': RegNo = X86::DR3; break; 476 case '4': RegNo = X86::DR4; break; 477 case '5': RegNo = X86::DR5; break; 478 case '6': RegNo = X86::DR6; break; 479 case '7': RegNo = X86::DR7; break; 480 } 481 482 if (RegNo != 0) { 483 EndLoc = Tok.getLoc(); 484 Parser.Lex(); // Eat it. 485 return false; 486 } 487 } 488 489 if (RegNo == 0) 490 return Error(StartLoc, "invalid register name", 491 SMRange(StartLoc, Tok.getEndLoc())); 492 493 EndLoc = Tok.getEndLoc(); 494 Parser.Lex(); // Eat identifier token. 495 return false; 496 } 497 498 X86Operand *X86ATTAsmParser::ParseOperand() { 499 switch (getLexer().getKind()) { 500 default: 501 // Parse a memory operand with no segment register. 502 return ParseMemOperand(0, Parser.getTok().getLoc()); 503 case AsmToken::Percent: { 504 // Read the register. 505 unsigned RegNo; 506 SMLoc Start, End; 507 if (ParseRegister(RegNo, Start, End)) return 0; 508 if (RegNo == X86::EIZ || RegNo == X86::RIZ) { 509 Error(Start, "%eiz and %riz can only be used as index registers", 510 SMRange(Start, End)); 511 return 0; 512 } 513 514 // If this is a segment register followed by a ':', then this is the start 515 // of a memory reference, otherwise this is a normal register reference. 516 if (getLexer().isNot(AsmToken::Colon)) 517 return X86Operand::CreateReg(RegNo, Start, End); 518 519 520 getParser().Lex(); // Eat the colon. 521 return ParseMemOperand(RegNo, Start); 522 } 523 case AsmToken::Dollar: { 524 // $42 -> immediate. 525 SMLoc Start = Parser.getTok().getLoc(), End; 526 Parser.Lex(); 527 const MCExpr *Val; 528 if (getParser().ParseExpression(Val, End)) 529 return 0; 530 return X86Operand::CreateImm(Val, Start, End); 531 } 532 } 533 } 534 535 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix 536 /// has already been parsed if present. 537 X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) { 538 539 // We have to disambiguate a parenthesized expression "(4+5)" from the start 540 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 541 // only way to do this without lookahead is to eat the '(' and see what is 542 // after it. 543 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); 544 if (getLexer().isNot(AsmToken::LParen)) { 545 SMLoc ExprEnd; 546 if (getParser().ParseExpression(Disp, ExprEnd)) return 0; 547 548 // After parsing the base expression we could either have a parenthesized 549 // memory address or not. If not, return now. If so, eat the (. 550 if (getLexer().isNot(AsmToken::LParen)) { 551 // Unless we have a segment register, treat this as an immediate. 552 if (SegReg == 0) 553 return X86Operand::CreateMem(Disp, MemStart, ExprEnd); 554 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 555 } 556 557 // Eat the '('. 558 Parser.Lex(); 559 } else { 560 // Okay, we have a '('. We don't know if this is an expression or not, but 561 // so we have to eat the ( to see beyond it. 562 SMLoc LParenLoc = Parser.getTok().getLoc(); 563 Parser.Lex(); // Eat the '('. 564 565 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { 566 // Nothing to do here, fall into the code below with the '(' part of the 567 // memory operand consumed. 568 } else { 569 SMLoc ExprEnd; 570 571 // It must be an parenthesized expression, parse it now. 572 if (getParser().ParseParenExpression(Disp, ExprEnd)) 573 return 0; 574 575 // After parsing the base expression we could either have a parenthesized 576 // memory address or not. If not, return now. If so, eat the (. 577 if (getLexer().isNot(AsmToken::LParen)) { 578 // Unless we have a segment register, treat this as an immediate. 579 if (SegReg == 0) 580 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd); 581 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 582 } 583 584 // Eat the '('. 585 Parser.Lex(); 586 } 587 } 588 589 // If we reached here, then we just ate the ( of the memory operand. Process 590 // the rest of the memory operand. 591 unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 592 593 if (getLexer().is(AsmToken::Percent)) { 594 SMLoc StartLoc, EndLoc; 595 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return 0; 596 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) { 597 Error(StartLoc, "eiz and riz can only be used as index registers", 598 SMRange(StartLoc, EndLoc)); 599 return 0; 600 } 601 } 602 603 if (getLexer().is(AsmToken::Comma)) { 604 Parser.Lex(); // Eat the comma. 605 606 // Following the comma we should have either an index register, or a scale 607 // value. We don't support the later form, but we want to parse it 608 // correctly. 609 // 610 // Not that even though it would be completely consistent to support syntax 611 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. 612 if (getLexer().is(AsmToken::Percent)) { 613 SMLoc L; 614 if (ParseRegister(IndexReg, L, L)) return 0; 615 616 if (getLexer().isNot(AsmToken::RParen)) { 617 // Parse the scale amount: 618 // ::= ',' [scale-expression] 619 if (getLexer().isNot(AsmToken::Comma)) { 620 Error(Parser.getTok().getLoc(), 621 "expected comma in scale expression"); 622 return 0; 623 } 624 Parser.Lex(); // Eat the comma. 625 626 if (getLexer().isNot(AsmToken::RParen)) { 627 SMLoc Loc = Parser.getTok().getLoc(); 628 629 int64_t ScaleVal; 630 if (getParser().ParseAbsoluteExpression(ScaleVal)) 631 return 0; 632 633 // Validate the scale amount. 634 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){ 635 Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 636 return 0; 637 } 638 Scale = (unsigned)ScaleVal; 639 } 640 } 641 } else if (getLexer().isNot(AsmToken::RParen)) { 642 // A scale amount without an index is ignored. 643 // index. 644 SMLoc Loc = Parser.getTok().getLoc(); 645 646 int64_t Value; 647 if (getParser().ParseAbsoluteExpression(Value)) 648 return 0; 649 650 if (Value != 1) 651 Warning(Loc, "scale factor without index register is ignored"); 652 Scale = 1; 653 } 654 } 655 656 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 657 if (getLexer().isNot(AsmToken::RParen)) { 658 Error(Parser.getTok().getLoc(), "unexpected token in memory operand"); 659 return 0; 660 } 661 SMLoc MemEnd = Parser.getTok().getLoc(); 662 Parser.Lex(); // Eat the ')'. 663 664 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, 665 MemStart, MemEnd); 666 } 667 668 bool X86ATTAsmParser:: 669 ParseInstruction(StringRef Name, SMLoc NameLoc, 670 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 671 StringRef PatchedName = Name; 672 673 // FIXME: Hack to recognize setneb as setne. 674 if (PatchedName.startswith("set") && PatchedName.endswith("b") && 675 PatchedName != "setb" && PatchedName != "setnb") 676 PatchedName = PatchedName.substr(0, Name.size()-1); 677 678 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}. 679 const MCExpr *ExtraImmOp = 0; 680 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) && 681 (PatchedName.endswith("ss") || PatchedName.endswith("sd") || 682 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { 683 bool IsVCMP = PatchedName.startswith("vcmp"); 684 unsigned SSECCIdx = IsVCMP ? 4 : 3; 685 unsigned SSEComparisonCode = StringSwitch<unsigned>( 686 PatchedName.slice(SSECCIdx, PatchedName.size() - 2)) 687 .Case("eq", 0) 688 .Case("lt", 1) 689 .Case("le", 2) 690 .Case("unord", 3) 691 .Case("neq", 4) 692 .Case("nlt", 5) 693 .Case("nle", 6) 694 .Case("ord", 7) 695 .Case("eq_uq", 8) 696 .Case("nge", 9) 697 .Case("ngt", 0x0A) 698 .Case("false", 0x0B) 699 .Case("neq_oq", 0x0C) 700 .Case("ge", 0x0D) 701 .Case("gt", 0x0E) 702 .Case("true", 0x0F) 703 .Case("eq_os", 0x10) 704 .Case("lt_oq", 0x11) 705 .Case("le_oq", 0x12) 706 .Case("unord_s", 0x13) 707 .Case("neq_us", 0x14) 708 .Case("nlt_uq", 0x15) 709 .Case("nle_uq", 0x16) 710 .Case("ord_s", 0x17) 711 .Case("eq_us", 0x18) 712 .Case("nge_uq", 0x19) 713 .Case("ngt_uq", 0x1A) 714 .Case("false_os", 0x1B) 715 .Case("neq_os", 0x1C) 716 .Case("ge_oq", 0x1D) 717 .Case("gt_oq", 0x1E) 718 .Case("true_us", 0x1F) 719 .Default(~0U); 720 if (SSEComparisonCode != ~0U) { 721 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode, 722 getParser().getContext()); 723 if (PatchedName.endswith("ss")) { 724 PatchedName = IsVCMP ? "vcmpss" : "cmpss"; 725 } else if (PatchedName.endswith("sd")) { 726 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd"; 727 } else if (PatchedName.endswith("ps")) { 728 PatchedName = IsVCMP ? "vcmpps" : "cmpps"; 729 } else { 730 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!"); 731 PatchedName = IsVCMP ? "vcmppd" : "cmppd"; 732 } 733 } 734 } 735 736 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); 737 738 if (ExtraImmOp) 739 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); 740 741 742 // Determine whether this is an instruction prefix. 743 bool isPrefix = 744 Name == "lock" || Name == "rep" || 745 Name == "repe" || Name == "repz" || 746 Name == "repne" || Name == "repnz" || 747 Name == "rex64" || Name == "data16"; 748 749 750 // This does the actual operand parsing. Don't parse any more if we have a 751 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we 752 // just want to parse the "lock" as the first instruction and the "incl" as 753 // the next one. 754 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) { 755 756 // Parse '*' modifier. 757 if (getLexer().is(AsmToken::Star)) { 758 SMLoc Loc = Parser.getTok().getLoc(); 759 Operands.push_back(X86Operand::CreateToken("*", Loc)); 760 Parser.Lex(); // Eat the star. 761 } 762 763 // Read the first operand. 764 if (X86Operand *Op = ParseOperand()) 765 Operands.push_back(Op); 766 else { 767 Parser.EatToEndOfStatement(); 768 return true; 769 } 770 771 while (getLexer().is(AsmToken::Comma)) { 772 Parser.Lex(); // Eat the comma. 773 774 // Parse and remember the operand. 775 if (X86Operand *Op = ParseOperand()) 776 Operands.push_back(Op); 777 else { 778 Parser.EatToEndOfStatement(); 779 return true; 780 } 781 } 782 783 if (getLexer().isNot(AsmToken::EndOfStatement)) { 784 SMLoc Loc = getLexer().getLoc(); 785 Parser.EatToEndOfStatement(); 786 return Error(Loc, "unexpected token in argument list"); 787 } 788 } 789 790 if (getLexer().is(AsmToken::EndOfStatement)) 791 Parser.Lex(); // Consume the EndOfStatement 792 else if (isPrefix && getLexer().is(AsmToken::Slash)) 793 Parser.Lex(); // Consume the prefix separator Slash 794 795 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" -> 796 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely 797 // documented form in various unofficial manuals, so a lot of code uses it. 798 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") && 799 Operands.size() == 3) { 800 X86Operand &Op = *(X86Operand*)Operands.back(); 801 if (Op.isMem() && Op.Mem.SegReg == 0 && 802 isa<MCConstantExpr>(Op.Mem.Disp) && 803 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 804 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 805 SMLoc Loc = Op.getEndLoc(); 806 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 807 delete &Op; 808 } 809 } 810 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al". 811 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") && 812 Operands.size() == 3) { 813 X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 814 if (Op.isMem() && Op.Mem.SegReg == 0 && 815 isa<MCConstantExpr>(Op.Mem.Disp) && 816 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 817 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 818 SMLoc Loc = Op.getEndLoc(); 819 Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 820 delete &Op; 821 } 822 } 823 // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]" 824 if (Name.startswith("ins") && Operands.size() == 3 && 825 (Name == "insb" || Name == "insw" || Name == "insl")) { 826 X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 827 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 828 if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) { 829 Operands.pop_back(); 830 Operands.pop_back(); 831 delete &Op; 832 delete &Op2; 833 } 834 } 835 836 // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]" 837 if (Name.startswith("outs") && Operands.size() == 3 && 838 (Name == "outsb" || Name == "outsw" || Name == "outsl")) { 839 X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 840 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 841 if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) { 842 Operands.pop_back(); 843 Operands.pop_back(); 844 delete &Op; 845 delete &Op2; 846 } 847 } 848 849 // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]" 850 if (Name.startswith("movs") && Operands.size() == 3 && 851 (Name == "movsb" || Name == "movsw" || Name == "movsl" || 852 (is64BitMode() && Name == "movsq"))) { 853 X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 854 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 855 if (isSrcOp(Op) && isDstOp(Op2)) { 856 Operands.pop_back(); 857 Operands.pop_back(); 858 delete &Op; 859 delete &Op2; 860 } 861 } 862 // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]" 863 if (Name.startswith("lods") && Operands.size() == 3 && 864 (Name == "lods" || Name == "lodsb" || Name == "lodsw" || 865 Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) { 866 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 867 X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]); 868 if (isSrcOp(*Op1) && Op2->isReg()) { 869 const char *ins; 870 unsigned reg = Op2->getReg(); 871 bool isLods = Name == "lods"; 872 if (reg == X86::AL && (isLods || Name == "lodsb")) 873 ins = "lodsb"; 874 else if (reg == X86::AX && (isLods || Name == "lodsw")) 875 ins = "lodsw"; 876 else if (reg == X86::EAX && (isLods || Name == "lodsl")) 877 ins = "lodsl"; 878 else if (reg == X86::RAX && (isLods || Name == "lodsq")) 879 ins = "lodsq"; 880 else 881 ins = NULL; 882 if (ins != NULL) { 883 Operands.pop_back(); 884 Operands.pop_back(); 885 delete Op1; 886 delete Op2; 887 if (Name != ins) 888 static_cast<X86Operand*>(Operands[0])->setTokenValue(ins); 889 } 890 } 891 } 892 // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]" 893 if (Name.startswith("stos") && Operands.size() == 3 && 894 (Name == "stos" || Name == "stosb" || Name == "stosw" || 895 Name == "stosl" || (is64BitMode() && Name == "stosq"))) { 896 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 897 X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]); 898 if (isDstOp(*Op2) && Op1->isReg()) { 899 const char *ins; 900 unsigned reg = Op1->getReg(); 901 bool isStos = Name == "stos"; 902 if (reg == X86::AL && (isStos || Name == "stosb")) 903 ins = "stosb"; 904 else if (reg == X86::AX && (isStos || Name == "stosw")) 905 ins = "stosw"; 906 else if (reg == X86::EAX && (isStos || Name == "stosl")) 907 ins = "stosl"; 908 else if (reg == X86::RAX && (isStos || Name == "stosq")) 909 ins = "stosq"; 910 else 911 ins = NULL; 912 if (ins != NULL) { 913 Operands.pop_back(); 914 Operands.pop_back(); 915 delete Op1; 916 delete Op2; 917 if (Name != ins) 918 static_cast<X86Operand*>(Operands[0])->setTokenValue(ins); 919 } 920 } 921 } 922 923 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to 924 // "shift <op>". 925 if ((Name.startswith("shr") || Name.startswith("sar") || 926 Name.startswith("shl") || Name.startswith("sal") || 927 Name.startswith("rcl") || Name.startswith("rcr") || 928 Name.startswith("rol") || Name.startswith("ror")) && 929 Operands.size() == 3) { 930 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 931 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 932 cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) { 933 delete Operands[1]; 934 Operands.erase(Operands.begin() + 1); 935 } 936 } 937 938 // Transforms "int $3" into "int3" as a size optimization. We can't write an 939 // instalias with an immediate operand yet. 940 if (Name == "int" && Operands.size() == 2) { 941 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 942 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 943 cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) { 944 delete Operands[1]; 945 Operands.erase(Operands.begin() + 1); 946 static_cast<X86Operand*>(Operands[0])->setTokenValue("int3"); 947 } 948 } 949 950 return false; 951 } 952 953 bool X86ATTAsmParser:: 954 MatchAndEmitInstruction(SMLoc IDLoc, 955 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 956 MCStreamer &Out) { 957 assert(!Operands.empty() && "Unexpect empty operand list!"); 958 X86Operand *Op = static_cast<X86Operand*>(Operands[0]); 959 assert(Op->isToken() && "Leading operand should always be a mnemonic!"); 960 961 // First, handle aliases that expand to multiple instructions. 962 // FIXME: This should be replaced with a real .td file alias mechanism. 963 // Also, MatchInstructionImpl should do actually *do* the EmitInstruction 964 // call. 965 if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" || 966 Op->getToken() == "fstsww" || Op->getToken() == "fstcww" || 967 Op->getToken() == "finit" || Op->getToken() == "fsave" || 968 Op->getToken() == "fstenv" || Op->getToken() == "fclex") { 969 MCInst Inst; 970 Inst.setOpcode(X86::WAIT); 971 Out.EmitInstruction(Inst); 972 973 const char *Repl = 974 StringSwitch<const char*>(Op->getToken()) 975 .Case("finit", "fninit") 976 .Case("fsave", "fnsave") 977 .Case("fstcw", "fnstcw") 978 .Case("fstcww", "fnstcw") 979 .Case("fstenv", "fnstenv") 980 .Case("fstsw", "fnstsw") 981 .Case("fstsww", "fnstsw") 982 .Case("fclex", "fnclex") 983 .Default(0); 984 assert(Repl && "Unknown wait-prefixed instruction"); 985 delete Operands[0]; 986 Operands[0] = X86Operand::CreateToken(Repl, IDLoc); 987 } 988 989 bool WasOriginallyInvalidOperand = false; 990 unsigned OrigErrorInfo; 991 MCInst Inst; 992 993 // First, try a direct match. 994 switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) { 995 default: break; 996 case Match_Success: 997 Out.EmitInstruction(Inst); 998 return false; 999 case Match_MissingFeature: 1000 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1001 return true; 1002 case Match_ConversionFail: 1003 return Error(IDLoc, "unable to convert operands to instruction"); 1004 case Match_InvalidOperand: 1005 WasOriginallyInvalidOperand = true; 1006 break; 1007 case Match_MnemonicFail: 1008 break; 1009 } 1010 1011 // FIXME: Ideally, we would only attempt suffix matches for things which are 1012 // valid prefixes, and we could just infer the right unambiguous 1013 // type. However, that requires substantially more matcher support than the 1014 // following hack. 1015 1016 // Change the operand to point to a temporary token. 1017 StringRef Base = Op->getToken(); 1018 SmallString<16> Tmp; 1019 Tmp += Base; 1020 Tmp += ' '; 1021 Op->setTokenValue(Tmp.str()); 1022 1023 // If this instruction starts with an 'f', then it is a floating point stack 1024 // instruction. These come in up to three forms for 32-bit, 64-bit, and 1025 // 80-bit floating point, which use the suffixes s,l,t respectively. 1026 // 1027 // Otherwise, we assume that this may be an integer instruction, which comes 1028 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively. 1029 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0"; 1030 1031 // Check for the various suffix matches. 1032 Tmp[Base.size()] = Suffixes[0]; 1033 unsigned ErrorInfoIgnore; 1034 unsigned Match1, Match2, Match3, Match4; 1035 1036 Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1037 Tmp[Base.size()] = Suffixes[1]; 1038 Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1039 Tmp[Base.size()] = Suffixes[2]; 1040 Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1041 Tmp[Base.size()] = Suffixes[3]; 1042 Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1043 1044 // Restore the old token. 1045 Op->setTokenValue(Base); 1046 1047 // If exactly one matched, then we treat that as a successful match (and the 1048 // instruction will already have been filled in correctly, since the failing 1049 // matches won't have modified it). 1050 unsigned NumSuccessfulMatches = 1051 (Match1 == Match_Success) + (Match2 == Match_Success) + 1052 (Match3 == Match_Success) + (Match4 == Match_Success); 1053 if (NumSuccessfulMatches == 1) { 1054 Out.EmitInstruction(Inst); 1055 return false; 1056 } 1057 1058 // Otherwise, the match failed, try to produce a decent error message. 1059 1060 // If we had multiple suffix matches, then identify this as an ambiguous 1061 // match. 1062 if (NumSuccessfulMatches > 1) { 1063 char MatchChars[4]; 1064 unsigned NumMatches = 0; 1065 if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0]; 1066 if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1]; 1067 if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2]; 1068 if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3]; 1069 1070 SmallString<126> Msg; 1071 raw_svector_ostream OS(Msg); 1072 OS << "ambiguous instructions require an explicit suffix (could be "; 1073 for (unsigned i = 0; i != NumMatches; ++i) { 1074 if (i != 0) 1075 OS << ", "; 1076 if (i + 1 == NumMatches) 1077 OS << "or "; 1078 OS << "'" << Base << MatchChars[i] << "'"; 1079 } 1080 OS << ")"; 1081 Error(IDLoc, OS.str()); 1082 return true; 1083 } 1084 1085 // Okay, we know that none of the variants matched successfully. 1086 1087 // If all of the instructions reported an invalid mnemonic, then the original 1088 // mnemonic was invalid. 1089 if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) && 1090 (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) { 1091 if (!WasOriginallyInvalidOperand) { 1092 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'", 1093 Op->getLocRange()); 1094 } 1095 1096 // Recover location info for the operand if we know which was the problem. 1097 if (OrigErrorInfo != ~0U) { 1098 if (OrigErrorInfo >= Operands.size()) 1099 return Error(IDLoc, "too few operands for instruction"); 1100 1101 X86Operand *Operand = (X86Operand*)Operands[OrigErrorInfo]; 1102 if (Operand->getStartLoc().isValid()) { 1103 SMRange OperandRange = Operand->getLocRange(); 1104 return Error(Operand->getStartLoc(), "invalid operand for instruction", 1105 OperandRange); 1106 } 1107 } 1108 1109 return Error(IDLoc, "invalid operand for instruction"); 1110 } 1111 1112 // If one instruction matched with a missing feature, report this as a 1113 // missing feature. 1114 if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) + 1115 (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){ 1116 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1117 return true; 1118 } 1119 1120 // If one instruction matched with an invalid operand, report this as an 1121 // operand failure. 1122 if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) + 1123 (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){ 1124 Error(IDLoc, "invalid operand for instruction"); 1125 return true; 1126 } 1127 1128 // If all of these were an outright failure, report it in a useless way. 1129 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix"); 1130 return true; 1131 } 1132 1133 1134 bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) { 1135 StringRef IDVal = DirectiveID.getIdentifier(); 1136 if (IDVal == ".word") 1137 return ParseDirectiveWord(2, DirectiveID.getLoc()); 1138 else if (IDVal.startswith(".code")) 1139 return ParseDirectiveCode(IDVal, DirectiveID.getLoc()); 1140 return true; 1141 } 1142 1143 /// ParseDirectiveWord 1144 /// ::= .word [ expression (, expression)* ] 1145 bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 1146 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1147 for (;;) { 1148 const MCExpr *Value; 1149 if (getParser().ParseExpression(Value)) 1150 return true; 1151 1152 getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/); 1153 1154 if (getLexer().is(AsmToken::EndOfStatement)) 1155 break; 1156 1157 // FIXME: Improve diagnostic. 1158 if (getLexer().isNot(AsmToken::Comma)) 1159 return Error(L, "unexpected token in directive"); 1160 Parser.Lex(); 1161 } 1162 } 1163 1164 Parser.Lex(); 1165 return false; 1166 } 1167 1168 /// ParseDirectiveCode 1169 /// ::= .code32 | .code64 1170 bool X86ATTAsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { 1171 if (IDVal == ".code32") { 1172 Parser.Lex(); 1173 if (is64BitMode()) { 1174 SwitchMode(); 1175 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 1176 } 1177 } else if (IDVal == ".code64") { 1178 Parser.Lex(); 1179 if (!is64BitMode()) { 1180 SwitchMode(); 1181 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64); 1182 } 1183 } else { 1184 return Error(L, "unexpected directive " + IDVal); 1185 } 1186 1187 return false; 1188 } 1189 1190 1191 extern "C" void LLVMInitializeX86AsmLexer(); 1192 1193 // Force static initialization. 1194 extern "C" void LLVMInitializeX86AsmParser() { 1195 RegisterMCAsmParser<X86ATTAsmParser> X(TheX86_32Target); 1196 RegisterMCAsmParser<X86ATTAsmParser> Y(TheX86_64Target); 1197 LLVMInitializeX86AsmLexer(); 1198 } 1199 1200 #define GET_REGISTER_MATCHER 1201 #define GET_MATCHER_IMPLEMENTATION 1202 #include "X86GenAsmMatcher.inc" 1203