LLVM API Documentation
00001 //===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "MCTargetDesc/X86BaseInfo.h" 00011 #include "X86AsmInstrumentation.h" 00012 #include "X86AsmParserCommon.h" 00013 #include "X86Operand.h" 00014 #include "llvm/ADT/APFloat.h" 00015 #include "llvm/ADT/STLExtras.h" 00016 #include "llvm/ADT/SmallString.h" 00017 #include "llvm/ADT/SmallVector.h" 00018 #include "llvm/ADT/StringSwitch.h" 00019 #include "llvm/ADT/Twine.h" 00020 #include "llvm/MC/MCContext.h" 00021 #include "llvm/MC/MCExpr.h" 00022 #include "llvm/MC/MCInst.h" 00023 #include "llvm/MC/MCInstrInfo.h" 00024 #include "llvm/MC/MCParser/MCAsmLexer.h" 00025 #include "llvm/MC/MCParser/MCAsmParser.h" 00026 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 00027 #include "llvm/MC/MCRegisterInfo.h" 00028 #include "llvm/MC/MCStreamer.h" 00029 #include "llvm/MC/MCSubtargetInfo.h" 00030 #include "llvm/MC/MCSymbol.h" 00031 #include "llvm/MC/MCTargetAsmParser.h" 00032 #include "llvm/Support/SourceMgr.h" 00033 #include "llvm/Support/TargetRegistry.h" 00034 #include "llvm/Support/raw_ostream.h" 00035 #include <algorithm> 00036 #include <memory> 00037 00038 using namespace llvm; 00039 00040 namespace { 00041 00042 static const char OpPrecedence[] = { 00043 0, // IC_OR 00044 1, // IC_AND 00045 2, // IC_LSHIFT 00046 2, // IC_RSHIFT 00047 3, // IC_PLUS 00048 3, // IC_MINUS 00049 4, // IC_MULTIPLY 00050 4, // IC_DIVIDE 00051 5, // IC_RPAREN 00052 6, // IC_LPAREN 00053 0, // IC_IMM 00054 0 // IC_REGISTER 00055 }; 00056 00057 class X86AsmParser : public MCTargetAsmParser { 00058 MCSubtargetInfo &STI; 00059 MCAsmParser &Parser; 00060 const MCInstrInfo &MII; 00061 ParseInstructionInfo *InstInfo; 00062 std::unique_ptr<X86AsmInstrumentation> Instrumentation; 00063 private: 00064 SMLoc consumeToken() { 00065 SMLoc Result = Parser.getTok().getLoc(); 00066 Parser.Lex(); 00067 return Result; 00068 } 00069 00070 enum InfixCalculatorTok { 00071 IC_OR = 0, 00072 IC_AND, 00073 IC_LSHIFT, 00074 IC_RSHIFT, 00075 IC_PLUS, 00076 IC_MINUS, 00077 IC_MULTIPLY, 00078 IC_DIVIDE, 00079 IC_RPAREN, 00080 IC_LPAREN, 00081 IC_IMM, 00082 IC_REGISTER 00083 }; 00084 00085 class InfixCalculator { 00086 typedef std::pair< InfixCalculatorTok, int64_t > ICToken; 00087 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack; 00088 SmallVector<ICToken, 4> PostfixStack; 00089 00090 public: 00091 int64_t popOperand() { 00092 assert (!PostfixStack.empty() && "Poped an empty stack!"); 00093 ICToken Op = PostfixStack.pop_back_val(); 00094 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER) 00095 && "Expected and immediate or register!"); 00096 return Op.second; 00097 } 00098 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) { 00099 assert ((Op == IC_IMM || Op == IC_REGISTER) && 00100 "Unexpected operand!"); 00101 PostfixStack.push_back(std::make_pair(Op, Val)); 00102 } 00103 00104 void popOperator() { InfixOperatorStack.pop_back(); } 00105 void pushOperator(InfixCalculatorTok Op) { 00106 // Push the new operator if the stack is empty. 00107 if (InfixOperatorStack.empty()) { 00108 InfixOperatorStack.push_back(Op); 00109 return; 00110 } 00111 00112 // Push the new operator if it has a higher precedence than the operator 00113 // on the top of the stack or the operator on the top of the stack is a 00114 // left parentheses. 00115 unsigned Idx = InfixOperatorStack.size() - 1; 00116 InfixCalculatorTok StackOp = InfixOperatorStack[Idx]; 00117 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) { 00118 InfixOperatorStack.push_back(Op); 00119 return; 00120 } 00121 00122 // The operator on the top of the stack has higher precedence than the 00123 // new operator. 00124 unsigned ParenCount = 0; 00125 while (1) { 00126 // Nothing to process. 00127 if (InfixOperatorStack.empty()) 00128 break; 00129 00130 Idx = InfixOperatorStack.size() - 1; 00131 StackOp = InfixOperatorStack[Idx]; 00132 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount)) 00133 break; 00134 00135 // If we have an even parentheses count and we see a left parentheses, 00136 // then stop processing. 00137 if (!ParenCount && StackOp == IC_LPAREN) 00138 break; 00139 00140 if (StackOp == IC_RPAREN) { 00141 ++ParenCount; 00142 InfixOperatorStack.pop_back(); 00143 } else if (StackOp == IC_LPAREN) { 00144 --ParenCount; 00145 InfixOperatorStack.pop_back(); 00146 } else { 00147 InfixOperatorStack.pop_back(); 00148 PostfixStack.push_back(std::make_pair(StackOp, 0)); 00149 } 00150 } 00151 // Push the new operator. 00152 InfixOperatorStack.push_back(Op); 00153 } 00154 int64_t execute() { 00155 // Push any remaining operators onto the postfix stack. 00156 while (!InfixOperatorStack.empty()) { 00157 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val(); 00158 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN) 00159 PostfixStack.push_back(std::make_pair(StackOp, 0)); 00160 } 00161 00162 if (PostfixStack.empty()) 00163 return 0; 00164 00165 SmallVector<ICToken, 16> OperandStack; 00166 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) { 00167 ICToken Op = PostfixStack[i]; 00168 if (Op.first == IC_IMM || Op.first == IC_REGISTER) { 00169 OperandStack.push_back(Op); 00170 } else { 00171 assert (OperandStack.size() > 1 && "Too few operands."); 00172 int64_t Val; 00173 ICToken Op2 = OperandStack.pop_back_val(); 00174 ICToken Op1 = OperandStack.pop_back_val(); 00175 switch (Op.first) { 00176 default: 00177 report_fatal_error("Unexpected operator!"); 00178 break; 00179 case IC_PLUS: 00180 Val = Op1.second + Op2.second; 00181 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 00182 break; 00183 case IC_MINUS: 00184 Val = Op1.second - Op2.second; 00185 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 00186 break; 00187 case IC_MULTIPLY: 00188 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 00189 "Multiply operation with an immediate and a register!"); 00190 Val = Op1.second * Op2.second; 00191 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 00192 break; 00193 case IC_DIVIDE: 00194 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 00195 "Divide operation with an immediate and a register!"); 00196 assert (Op2.second != 0 && "Division by zero!"); 00197 Val = Op1.second / Op2.second; 00198 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 00199 break; 00200 case IC_OR: 00201 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 00202 "Or operation with an immediate and a register!"); 00203 Val = Op1.second | Op2.second; 00204 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 00205 break; 00206 case IC_AND: 00207 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 00208 "And operation with an immediate and a register!"); 00209 Val = Op1.second & Op2.second; 00210 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 00211 break; 00212 case IC_LSHIFT: 00213 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 00214 "Left shift operation with an immediate and a register!"); 00215 Val = Op1.second << Op2.second; 00216 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 00217 break; 00218 case IC_RSHIFT: 00219 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 00220 "Right shift operation with an immediate and a register!"); 00221 Val = Op1.second >> Op2.second; 00222 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 00223 break; 00224 } 00225 } 00226 } 00227 assert (OperandStack.size() == 1 && "Expected a single result."); 00228 return OperandStack.pop_back_val().second; 00229 } 00230 }; 00231 00232 enum IntelExprState { 00233 IES_OR, 00234 IES_AND, 00235 IES_LSHIFT, 00236 IES_RSHIFT, 00237 IES_PLUS, 00238 IES_MINUS, 00239 IES_NOT, 00240 IES_MULTIPLY, 00241 IES_DIVIDE, 00242 IES_LBRAC, 00243 IES_RBRAC, 00244 IES_LPAREN, 00245 IES_RPAREN, 00246 IES_REGISTER, 00247 IES_INTEGER, 00248 IES_IDENTIFIER, 00249 IES_ERROR 00250 }; 00251 00252 class IntelExprStateMachine { 00253 IntelExprState State, PrevState; 00254 unsigned BaseReg, IndexReg, TmpReg, Scale; 00255 int64_t Imm; 00256 const MCExpr *Sym; 00257 StringRef SymName; 00258 bool StopOnLBrac, AddImmPrefix; 00259 InfixCalculator IC; 00260 InlineAsmIdentifierInfo Info; 00261 public: 00262 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) : 00263 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0), 00264 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac), 00265 AddImmPrefix(addimmprefix) { Info.clear(); } 00266 00267 unsigned getBaseReg() { return BaseReg; } 00268 unsigned getIndexReg() { return IndexReg; } 00269 unsigned getScale() { return Scale; } 00270 const MCExpr *getSym() { return Sym; } 00271 StringRef getSymName() { return SymName; } 00272 int64_t getImm() { return Imm + IC.execute(); } 00273 bool isValidEndState() { 00274 return State == IES_RBRAC || State == IES_INTEGER; 00275 } 00276 bool getStopOnLBrac() { return StopOnLBrac; } 00277 bool getAddImmPrefix() { return AddImmPrefix; } 00278 bool hadError() { return State == IES_ERROR; } 00279 00280 InlineAsmIdentifierInfo &getIdentifierInfo() { 00281 return Info; 00282 } 00283 00284 void onOr() { 00285 IntelExprState CurrState = State; 00286 switch (State) { 00287 default: 00288 State = IES_ERROR; 00289 break; 00290 case IES_INTEGER: 00291 case IES_RPAREN: 00292 case IES_REGISTER: 00293 State = IES_OR; 00294 IC.pushOperator(IC_OR); 00295 break; 00296 } 00297 PrevState = CurrState; 00298 } 00299 void onAnd() { 00300 IntelExprState CurrState = State; 00301 switch (State) { 00302 default: 00303 State = IES_ERROR; 00304 break; 00305 case IES_INTEGER: 00306 case IES_RPAREN: 00307 case IES_REGISTER: 00308 State = IES_AND; 00309 IC.pushOperator(IC_AND); 00310 break; 00311 } 00312 PrevState = CurrState; 00313 } 00314 void onLShift() { 00315 IntelExprState CurrState = State; 00316 switch (State) { 00317 default: 00318 State = IES_ERROR; 00319 break; 00320 case IES_INTEGER: 00321 case IES_RPAREN: 00322 case IES_REGISTER: 00323 State = IES_LSHIFT; 00324 IC.pushOperator(IC_LSHIFT); 00325 break; 00326 } 00327 PrevState = CurrState; 00328 } 00329 void onRShift() { 00330 IntelExprState CurrState = State; 00331 switch (State) { 00332 default: 00333 State = IES_ERROR; 00334 break; 00335 case IES_INTEGER: 00336 case IES_RPAREN: 00337 case IES_REGISTER: 00338 State = IES_RSHIFT; 00339 IC.pushOperator(IC_RSHIFT); 00340 break; 00341 } 00342 PrevState = CurrState; 00343 } 00344 void onPlus() { 00345 IntelExprState CurrState = State; 00346 switch (State) { 00347 default: 00348 State = IES_ERROR; 00349 break; 00350 case IES_INTEGER: 00351 case IES_RPAREN: 00352 case IES_REGISTER: 00353 State = IES_PLUS; 00354 IC.pushOperator(IC_PLUS); 00355 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 00356 // If we already have a BaseReg, then assume this is the IndexReg with 00357 // a scale of 1. 00358 if (!BaseReg) { 00359 BaseReg = TmpReg; 00360 } else { 00361 assert (!IndexReg && "BaseReg/IndexReg already set!"); 00362 IndexReg = TmpReg; 00363 Scale = 1; 00364 } 00365 } 00366 break; 00367 } 00368 PrevState = CurrState; 00369 } 00370 void onMinus() { 00371 IntelExprState CurrState = State; 00372 switch (State) { 00373 default: 00374 State = IES_ERROR; 00375 break; 00376 case IES_PLUS: 00377 case IES_NOT: 00378 case IES_MULTIPLY: 00379 case IES_DIVIDE: 00380 case IES_LPAREN: 00381 case IES_RPAREN: 00382 case IES_LBRAC: 00383 case IES_RBRAC: 00384 case IES_INTEGER: 00385 case IES_REGISTER: 00386 State = IES_MINUS; 00387 // Only push the minus operator if it is not a unary operator. 00388 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS || 00389 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE || 00390 CurrState == IES_LPAREN || CurrState == IES_LBRAC)) 00391 IC.pushOperator(IC_MINUS); 00392 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 00393 // If we already have a BaseReg, then assume this is the IndexReg with 00394 // a scale of 1. 00395 if (!BaseReg) { 00396 BaseReg = TmpReg; 00397 } else { 00398 assert (!IndexReg && "BaseReg/IndexReg already set!"); 00399 IndexReg = TmpReg; 00400 Scale = 1; 00401 } 00402 } 00403 break; 00404 } 00405 PrevState = CurrState; 00406 } 00407 void onNot() { 00408 IntelExprState CurrState = State; 00409 switch (State) { 00410 default: 00411 State = IES_ERROR; 00412 break; 00413 case IES_PLUS: 00414 case IES_NOT: 00415 State = IES_NOT; 00416 break; 00417 } 00418 PrevState = CurrState; 00419 } 00420 void onRegister(unsigned Reg) { 00421 IntelExprState CurrState = State; 00422 switch (State) { 00423 default: 00424 State = IES_ERROR; 00425 break; 00426 case IES_PLUS: 00427 case IES_LPAREN: 00428 State = IES_REGISTER; 00429 TmpReg = Reg; 00430 IC.pushOperand(IC_REGISTER); 00431 break; 00432 case IES_MULTIPLY: 00433 // Index Register - Scale * Register 00434 if (PrevState == IES_INTEGER) { 00435 assert (!IndexReg && "IndexReg already set!"); 00436 State = IES_REGISTER; 00437 IndexReg = Reg; 00438 // Get the scale and replace the 'Scale * Register' with '0'. 00439 Scale = IC.popOperand(); 00440 IC.pushOperand(IC_IMM); 00441 IC.popOperator(); 00442 } else { 00443 State = IES_ERROR; 00444 } 00445 break; 00446 } 00447 PrevState = CurrState; 00448 } 00449 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) { 00450 PrevState = State; 00451 switch (State) { 00452 default: 00453 State = IES_ERROR; 00454 break; 00455 case IES_PLUS: 00456 case IES_MINUS: 00457 case IES_NOT: 00458 State = IES_INTEGER; 00459 Sym = SymRef; 00460 SymName = SymRefName; 00461 IC.pushOperand(IC_IMM); 00462 break; 00463 } 00464 } 00465 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) { 00466 IntelExprState CurrState = State; 00467 switch (State) { 00468 default: 00469 State = IES_ERROR; 00470 break; 00471 case IES_PLUS: 00472 case IES_MINUS: 00473 case IES_NOT: 00474 case IES_OR: 00475 case IES_AND: 00476 case IES_LSHIFT: 00477 case IES_RSHIFT: 00478 case IES_DIVIDE: 00479 case IES_MULTIPLY: 00480 case IES_LPAREN: 00481 State = IES_INTEGER; 00482 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) { 00483 // Index Register - Register * Scale 00484 assert (!IndexReg && "IndexReg already set!"); 00485 IndexReg = TmpReg; 00486 Scale = TmpInt; 00487 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) { 00488 ErrMsg = "scale factor in address must be 1, 2, 4 or 8"; 00489 return true; 00490 } 00491 // Get the scale and replace the 'Register * Scale' with '0'. 00492 IC.popOperator(); 00493 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS || 00494 PrevState == IES_OR || PrevState == IES_AND || 00495 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT || 00496 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || 00497 PrevState == IES_LPAREN || PrevState == IES_LBRAC || 00498 PrevState == IES_NOT) && 00499 CurrState == IES_MINUS) { 00500 // Unary minus. No need to pop the minus operand because it was never 00501 // pushed. 00502 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm. 00503 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS || 00504 PrevState == IES_OR || PrevState == IES_AND || 00505 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT || 00506 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || 00507 PrevState == IES_LPAREN || PrevState == IES_LBRAC || 00508 PrevState == IES_NOT) && 00509 CurrState == IES_NOT) { 00510 // Unary not. No need to pop the not operand because it was never 00511 // pushed. 00512 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm. 00513 } else { 00514 IC.pushOperand(IC_IMM, TmpInt); 00515 } 00516 break; 00517 } 00518 PrevState = CurrState; 00519 return false; 00520 } 00521 void onStar() { 00522 PrevState = State; 00523 switch (State) { 00524 default: 00525 State = IES_ERROR; 00526 break; 00527 case IES_INTEGER: 00528 case IES_REGISTER: 00529 case IES_RPAREN: 00530 State = IES_MULTIPLY; 00531 IC.pushOperator(IC_MULTIPLY); 00532 break; 00533 } 00534 } 00535 void onDivide() { 00536 PrevState = State; 00537 switch (State) { 00538 default: 00539 State = IES_ERROR; 00540 break; 00541 case IES_INTEGER: 00542 case IES_RPAREN: 00543 State = IES_DIVIDE; 00544 IC.pushOperator(IC_DIVIDE); 00545 break; 00546 } 00547 } 00548 void onLBrac() { 00549 PrevState = State; 00550 switch (State) { 00551 default: 00552 State = IES_ERROR; 00553 break; 00554 case IES_RBRAC: 00555 State = IES_PLUS; 00556 IC.pushOperator(IC_PLUS); 00557 break; 00558 } 00559 } 00560 void onRBrac() { 00561 IntelExprState CurrState = State; 00562 switch (State) { 00563 default: 00564 State = IES_ERROR; 00565 break; 00566 case IES_INTEGER: 00567 case IES_REGISTER: 00568 case IES_RPAREN: 00569 State = IES_RBRAC; 00570 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 00571 // If we already have a BaseReg, then assume this is the IndexReg with 00572 // a scale of 1. 00573 if (!BaseReg) { 00574 BaseReg = TmpReg; 00575 } else { 00576 assert (!IndexReg && "BaseReg/IndexReg already set!"); 00577 IndexReg = TmpReg; 00578 Scale = 1; 00579 } 00580 } 00581 break; 00582 } 00583 PrevState = CurrState; 00584 } 00585 void onLParen() { 00586 IntelExprState CurrState = State; 00587 switch (State) { 00588 default: 00589 State = IES_ERROR; 00590 break; 00591 case IES_PLUS: 00592 case IES_MINUS: 00593 case IES_NOT: 00594 case IES_OR: 00595 case IES_AND: 00596 case IES_LSHIFT: 00597 case IES_RSHIFT: 00598 case IES_MULTIPLY: 00599 case IES_DIVIDE: 00600 case IES_LPAREN: 00601 // FIXME: We don't handle this type of unary minus or not, yet. 00602 if ((PrevState == IES_PLUS || PrevState == IES_MINUS || 00603 PrevState == IES_OR || PrevState == IES_AND || 00604 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT || 00605 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || 00606 PrevState == IES_LPAREN || PrevState == IES_LBRAC || 00607 PrevState == IES_NOT) && 00608 (CurrState == IES_MINUS || CurrState == IES_NOT)) { 00609 State = IES_ERROR; 00610 break; 00611 } 00612 State = IES_LPAREN; 00613 IC.pushOperator(IC_LPAREN); 00614 break; 00615 } 00616 PrevState = CurrState; 00617 } 00618 void onRParen() { 00619 PrevState = State; 00620 switch (State) { 00621 default: 00622 State = IES_ERROR; 00623 break; 00624 case IES_INTEGER: 00625 case IES_REGISTER: 00626 case IES_RPAREN: 00627 State = IES_RPAREN; 00628 IC.pushOperator(IC_RPAREN); 00629 break; 00630 } 00631 } 00632 }; 00633 00634 MCAsmParser &getParser() const { return Parser; } 00635 00636 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 00637 00638 bool Error(SMLoc L, const Twine &Msg, 00639 ArrayRef<SMRange> Ranges = None, 00640 bool MatchingInlineAsm = false) { 00641 if (MatchingInlineAsm) return true; 00642 return Parser.Error(L, Msg, Ranges); 00643 } 00644 00645 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg, 00646 ArrayRef<SMRange> Ranges = None, 00647 bool MatchingInlineAsm = false) { 00648 Parser.eatToEndOfStatement(); 00649 return Error(L, Msg, Ranges, MatchingInlineAsm); 00650 } 00651 00652 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) { 00653 Error(Loc, Msg); 00654 return nullptr; 00655 } 00656 00657 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc); 00658 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc); 00659 std::unique_ptr<X86Operand> ParseOperand(); 00660 std::unique_ptr<X86Operand> ParseATTOperand(); 00661 std::unique_ptr<X86Operand> ParseIntelOperand(); 00662 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator(); 00663 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp); 00664 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind); 00665 std::unique_ptr<X86Operand> 00666 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size); 00667 std::unique_ptr<X86Operand> 00668 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size); 00669 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End); 00670 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg, 00671 SMLoc Start, 00672 int64_t ImmDisp, 00673 unsigned Size); 00674 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier, 00675 InlineAsmIdentifierInfo &Info, 00676 bool IsUnevaluatedOperand, SMLoc &End); 00677 00678 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc); 00679 00680 std::unique_ptr<X86Operand> 00681 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, 00682 unsigned IndexReg, unsigned Scale, SMLoc Start, 00683 SMLoc End, unsigned Size, StringRef Identifier, 00684 InlineAsmIdentifierInfo &Info); 00685 00686 bool ParseDirectiveWord(unsigned Size, SMLoc L); 00687 bool ParseDirectiveCode(StringRef IDVal, SMLoc L); 00688 00689 bool processInstruction(MCInst &Inst, const OperandVector &Ops); 00690 00691 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds 00692 /// instrumentation around Inst. 00693 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out); 00694 00695 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 00696 OperandVector &Operands, MCStreamer &Out, 00697 uint64_t &ErrorInfo, 00698 bool MatchingInlineAsm) override; 00699 00700 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands, 00701 MCStreamer &Out, bool MatchingInlineAsm); 00702 00703 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo, 00704 bool MatchingInlineAsm); 00705 00706 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, 00707 OperandVector &Operands, MCStreamer &Out, 00708 uint64_t &ErrorInfo, 00709 bool MatchingInlineAsm); 00710 00711 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, 00712 OperandVector &Operands, MCStreamer &Out, 00713 uint64_t &ErrorInfo, 00714 bool MatchingInlineAsm); 00715 00716 unsigned getPointerSize() { 00717 if (is16BitMode()) return 16; 00718 if (is32BitMode()) return 32; 00719 if (is64BitMode()) return 64; 00720 llvm_unreachable("invalid mode"); 00721 } 00722 00723 bool OmitRegisterFromClobberLists(unsigned RegNo) override; 00724 00725 /// doSrcDstMatch - Returns true if operands are matching in their 00726 /// word size (%si and %di, %esi and %edi, etc.). Order depends on 00727 /// the parsing mode (Intel vs. AT&T). 00728 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2); 00729 00730 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z}) 00731 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required. 00732 /// \return \c true if no parsing errors occurred, \c false otherwise. 00733 bool HandleAVX512Operand(OperandVector &Operands, 00734 const MCParsedAsmOperand &Op); 00735 00736 bool is64BitMode() const { 00737 // FIXME: Can tablegen auto-generate this? 00738 return (STI.getFeatureBits() & X86::Mode64Bit) != 0; 00739 } 00740 bool is32BitMode() const { 00741 // FIXME: Can tablegen auto-generate this? 00742 return (STI.getFeatureBits() & X86::Mode32Bit) != 0; 00743 } 00744 bool is16BitMode() const { 00745 // FIXME: Can tablegen auto-generate this? 00746 return (STI.getFeatureBits() & X86::Mode16Bit) != 0; 00747 } 00748 void SwitchMode(uint64_t mode) { 00749 uint64_t oldMode = STI.getFeatureBits() & 00750 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit); 00751 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(oldMode | mode)); 00752 setAvailableFeatures(FB); 00753 assert(mode == (STI.getFeatureBits() & 00754 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit))); 00755 } 00756 00757 unsigned getPointerWidth() { 00758 if (is16BitMode()) return 16; 00759 if (is32BitMode()) return 32; 00760 if (is64BitMode()) return 64; 00761 llvm_unreachable("invalid mode"); 00762 } 00763 00764 bool isParsingIntelSyntax() { 00765 return getParser().getAssemblerDialect(); 00766 } 00767 00768 /// @name Auto-generated Matcher Functions 00769 /// { 00770 00771 #define GET_ASSEMBLER_HEADER 00772 #include "X86GenAsmMatcher.inc" 00773 00774 /// } 00775 00776 public: 00777 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 00778 const MCInstrInfo &mii, 00779 const MCTargetOptions &Options) 00780 : MCTargetAsmParser(), STI(sti), Parser(parser), MII(mii), 00781 InstInfo(nullptr) { 00782 00783 // Initialize the set of available features. 00784 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 00785 Instrumentation.reset( 00786 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI)); 00787 } 00788 00789 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 00790 00791 void SetFrameRegister(unsigned RegNo) override; 00792 00793 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 00794 SMLoc NameLoc, OperandVector &Operands) override; 00795 00796 bool ParseDirective(AsmToken DirectiveID) override; 00797 }; 00798 } // end anonymous namespace 00799 00800 /// @name Auto-generated Match Functions 00801 /// { 00802 00803 static unsigned MatchRegisterName(StringRef Name); 00804 00805 /// } 00806 00807 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg, 00808 StringRef &ErrMsg) { 00809 // If we have both a base register and an index register make sure they are 00810 // both 64-bit or 32-bit registers. 00811 // To support VSIB, IndexReg can be 128-bit or 256-bit registers. 00812 if (BaseReg != 0 && IndexReg != 0) { 00813 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) && 00814 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 00815 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) && 00816 IndexReg != X86::RIZ) { 00817 ErrMsg = "base register is 64-bit, but index register is not"; 00818 return true; 00819 } 00820 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) && 00821 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 00822 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) && 00823 IndexReg != X86::EIZ){ 00824 ErrMsg = "base register is 32-bit, but index register is not"; 00825 return true; 00826 } 00827 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) { 00828 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) || 00829 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) { 00830 ErrMsg = "base register is 16-bit, but index register is not"; 00831 return true; 00832 } 00833 if (((BaseReg == X86::BX || BaseReg == X86::BP) && 00834 IndexReg != X86::SI && IndexReg != X86::DI) || 00835 ((BaseReg == X86::SI || BaseReg == X86::DI) && 00836 IndexReg != X86::BX && IndexReg != X86::BP)) { 00837 ErrMsg = "invalid 16-bit base/index register combination"; 00838 return true; 00839 } 00840 } 00841 } 00842 return false; 00843 } 00844 00845 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2) 00846 { 00847 // Return true and let a normal complaint about bogus operands happen. 00848 if (!Op1.isMem() || !Op2.isMem()) 00849 return true; 00850 00851 // Actually these might be the other way round if Intel syntax is 00852 // being used. It doesn't matter. 00853 unsigned diReg = Op1.Mem.BaseReg; 00854 unsigned siReg = Op2.Mem.BaseReg; 00855 00856 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg)) 00857 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg); 00858 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg)) 00859 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg); 00860 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg)) 00861 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg); 00862 // Again, return true and let another error happen. 00863 return true; 00864 } 00865 00866 bool X86AsmParser::ParseRegister(unsigned &RegNo, 00867 SMLoc &StartLoc, SMLoc &EndLoc) { 00868 RegNo = 0; 00869 const AsmToken &PercentTok = Parser.getTok(); 00870 StartLoc = PercentTok.getLoc(); 00871 00872 // If we encounter a %, ignore it. This code handles registers with and 00873 // without the prefix, unprefixed registers can occur in cfi directives. 00874 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent)) 00875 Parser.Lex(); // Eat percent token. 00876 00877 const AsmToken &Tok = Parser.getTok(); 00878 EndLoc = Tok.getEndLoc(); 00879 00880 if (Tok.isNot(AsmToken::Identifier)) { 00881 if (isParsingIntelSyntax()) return true; 00882 return Error(StartLoc, "invalid register name", 00883 SMRange(StartLoc, EndLoc)); 00884 } 00885 00886 RegNo = MatchRegisterName(Tok.getString()); 00887 00888 // If the match failed, try the register name as lowercase. 00889 if (RegNo == 0) 00890 RegNo = MatchRegisterName(Tok.getString().lower()); 00891 00892 if (!is64BitMode()) { 00893 // FIXME: This should be done using Requires<Not64BitMode> and 00894 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also 00895 // checked. 00896 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a 00897 // REX prefix. 00898 if (RegNo == X86::RIZ || 00899 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) || 00900 X86II::isX86_64NonExtLowByteReg(RegNo) || 00901 X86II::isX86_64ExtendedReg(RegNo)) 00902 return Error(StartLoc, "register %" 00903 + Tok.getString() + " is only available in 64-bit mode", 00904 SMRange(StartLoc, EndLoc)); 00905 } 00906 00907 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. 00908 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) { 00909 RegNo = X86::ST0; 00910 Parser.Lex(); // Eat 'st' 00911 00912 // Check to see if we have '(4)' after %st. 00913 if (getLexer().isNot(AsmToken::LParen)) 00914 return false; 00915 // Lex the paren. 00916 getParser().Lex(); 00917 00918 const AsmToken &IntTok = Parser.getTok(); 00919 if (IntTok.isNot(AsmToken::Integer)) 00920 return Error(IntTok.getLoc(), "expected stack index"); 00921 switch (IntTok.getIntVal()) { 00922 case 0: RegNo = X86::ST0; break; 00923 case 1: RegNo = X86::ST1; break; 00924 case 2: RegNo = X86::ST2; break; 00925 case 3: RegNo = X86::ST3; break; 00926 case 4: RegNo = X86::ST4; break; 00927 case 5: RegNo = X86::ST5; break; 00928 case 6: RegNo = X86::ST6; break; 00929 case 7: RegNo = X86::ST7; break; 00930 default: return Error(IntTok.getLoc(), "invalid stack index"); 00931 } 00932 00933 if (getParser().Lex().isNot(AsmToken::RParen)) 00934 return Error(Parser.getTok().getLoc(), "expected ')'"); 00935 00936 EndLoc = Parser.getTok().getEndLoc(); 00937 Parser.Lex(); // Eat ')' 00938 return false; 00939 } 00940 00941 EndLoc = Parser.getTok().getEndLoc(); 00942 00943 // If this is "db[0-7]", match it as an alias 00944 // for dr[0-7]. 00945 if (RegNo == 0 && Tok.getString().size() == 3 && 00946 Tok.getString().startswith("db")) { 00947 switch (Tok.getString()[2]) { 00948 case '0': RegNo = X86::DR0; break; 00949 case '1': RegNo = X86::DR1; break; 00950 case '2': RegNo = X86::DR2; break; 00951 case '3': RegNo = X86::DR3; break; 00952 case '4': RegNo = X86::DR4; break; 00953 case '5': RegNo = X86::DR5; break; 00954 case '6': RegNo = X86::DR6; break; 00955 case '7': RegNo = X86::DR7; break; 00956 } 00957 00958 if (RegNo != 0) { 00959 EndLoc = Parser.getTok().getEndLoc(); 00960 Parser.Lex(); // Eat it. 00961 return false; 00962 } 00963 } 00964 00965 if (RegNo == 0) { 00966 if (isParsingIntelSyntax()) return true; 00967 return Error(StartLoc, "invalid register name", 00968 SMRange(StartLoc, EndLoc)); 00969 } 00970 00971 Parser.Lex(); // Eat identifier token. 00972 return false; 00973 } 00974 00975 void X86AsmParser::SetFrameRegister(unsigned RegNo) { 00976 Instrumentation->SetFrameRegister(RegNo); 00977 } 00978 00979 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) { 00980 unsigned basereg = 00981 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI); 00982 const MCExpr *Disp = MCConstantExpr::Create(0, getContext()); 00983 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg, 00984 /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0); 00985 } 00986 00987 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) { 00988 unsigned basereg = 00989 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI); 00990 const MCExpr *Disp = MCConstantExpr::Create(0, getContext()); 00991 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg, 00992 /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0); 00993 } 00994 00995 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() { 00996 if (isParsingIntelSyntax()) 00997 return ParseIntelOperand(); 00998 return ParseATTOperand(); 00999 } 01000 01001 /// getIntelMemOperandSize - Return intel memory operand size. 01002 static unsigned getIntelMemOperandSize(StringRef OpStr) { 01003 unsigned Size = StringSwitch<unsigned>(OpStr) 01004 .Cases("BYTE", "byte", 8) 01005 .Cases("WORD", "word", 16) 01006 .Cases("DWORD", "dword", 32) 01007 .Cases("QWORD", "qword", 64) 01008 .Cases("XWORD", "xword", 80) 01009 .Cases("XMMWORD", "xmmword", 128) 01010 .Cases("YMMWORD", "ymmword", 256) 01011 .Cases("ZMMWORD", "zmmword", 512) 01012 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter 01013 .Default(0); 01014 return Size; 01015 } 01016 01017 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm( 01018 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg, 01019 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier, 01020 InlineAsmIdentifierInfo &Info) { 01021 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or 01022 // some other label reference. 01023 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) { 01024 // Insert an explicit size if the user didn't have one. 01025 if (!Size) { 01026 Size = getPointerWidth(); 01027 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start, 01028 /*Len=*/0, Size)); 01029 } 01030 01031 // Create an absolute memory reference in order to match against 01032 // instructions taking a PC relative operand. 01033 return X86Operand::CreateMem(Disp, Start, End, Size, Identifier, 01034 Info.OpDecl); 01035 } 01036 01037 // We either have a direct symbol reference, or an offset from a symbol. The 01038 // parser always puts the symbol on the LHS, so look there for size 01039 // calculation purposes. 01040 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp); 01041 bool IsSymRef = 01042 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp); 01043 if (IsSymRef) { 01044 if (!Size) { 01045 Size = Info.Type * 8; // Size is in terms of bits in this context. 01046 if (Size) 01047 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start, 01048 /*Len=*/0, Size)); 01049 } 01050 } 01051 01052 // When parsing inline assembly we set the base register to a non-zero value 01053 // if we don't know the actual value at this time. This is necessary to 01054 // get the matching correct in some cases. 01055 BaseReg = BaseReg ? BaseReg : 1; 01056 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start, 01057 End, Size, Identifier, Info.OpDecl); 01058 } 01059 01060 static void 01061 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites, 01062 StringRef SymName, int64_t ImmDisp, 01063 int64_t FinalImmDisp, SMLoc &BracLoc, 01064 SMLoc &StartInBrac, SMLoc &End) { 01065 // Remove the '[' and ']' from the IR string. 01066 AsmRewrites->push_back(AsmRewrite(AOK_Skip, BracLoc, 1)); 01067 AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1)); 01068 01069 // If ImmDisp is non-zero, then we parsed a displacement before the 01070 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp]) 01071 // If ImmDisp doesn't match the displacement computed by the state machine 01072 // then we have an additional displacement in the bracketed expression. 01073 if (ImmDisp != FinalImmDisp) { 01074 if (ImmDisp) { 01075 // We have an immediate displacement before the bracketed expression. 01076 // Adjust this to match the final immediate displacement. 01077 bool Found = false; 01078 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(), 01079 E = AsmRewrites->end(); I != E; ++I) { 01080 if ((*I).Loc.getPointer() > BracLoc.getPointer()) 01081 continue; 01082 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) { 01083 assert (!Found && "ImmDisp already rewritten."); 01084 (*I).Kind = AOK_Imm; 01085 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer(); 01086 (*I).Val = FinalImmDisp; 01087 Found = true; 01088 break; 01089 } 01090 } 01091 assert (Found && "Unable to rewrite ImmDisp."); 01092 (void)Found; 01093 } else { 01094 // We have a symbolic and an immediate displacement, but no displacement 01095 // before the bracketed expression. Put the immediate displacement 01096 // before the bracketed expression. 01097 AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp)); 01098 } 01099 } 01100 // Remove all the ImmPrefix rewrites within the brackets. 01101 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(), 01102 E = AsmRewrites->end(); I != E; ++I) { 01103 if ((*I).Loc.getPointer() < StartInBrac.getPointer()) 01104 continue; 01105 if ((*I).Kind == AOK_ImmPrefix) 01106 (*I).Kind = AOK_Delete; 01107 } 01108 const char *SymLocPtr = SymName.data(); 01109 // Skip everything before the symbol. 01110 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) { 01111 assert(Len > 0 && "Expected a non-negative length."); 01112 AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len)); 01113 } 01114 // Skip everything after the symbol. 01115 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) { 01116 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size()); 01117 assert(Len > 0 && "Expected a non-negative length."); 01118 AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len)); 01119 } 01120 } 01121 01122 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) { 01123 const AsmToken &Tok = Parser.getTok(); 01124 01125 bool Done = false; 01126 while (!Done) { 01127 bool UpdateLocLex = true; 01128 01129 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an 01130 // identifier. Don't try an parse it as a register. 01131 if (Tok.getString().startswith(".")) 01132 break; 01133 01134 // If we're parsing an immediate expression, we don't expect a '['. 01135 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac) 01136 break; 01137 01138 AsmToken::TokenKind TK = getLexer().getKind(); 01139 switch (TK) { 01140 default: { 01141 if (SM.isValidEndState()) { 01142 Done = true; 01143 break; 01144 } 01145 return Error(Tok.getLoc(), "unknown token in expression"); 01146 } 01147 case AsmToken::EndOfStatement: { 01148 Done = true; 01149 break; 01150 } 01151 case AsmToken::String: 01152 case AsmToken::Identifier: { 01153 // This could be a register or a symbolic displacement. 01154 unsigned TmpReg; 01155 const MCExpr *Val; 01156 SMLoc IdentLoc = Tok.getLoc(); 01157 StringRef Identifier = Tok.getString(); 01158 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) { 01159 SM.onRegister(TmpReg); 01160 UpdateLocLex = false; 01161 break; 01162 } else { 01163 if (!isParsingInlineAsm()) { 01164 if (getParser().parsePrimaryExpr(Val, End)) 01165 return Error(Tok.getLoc(), "Unexpected identifier!"); 01166 } else { 01167 // This is a dot operator, not an adjacent identifier. 01168 if (Identifier.find('.') != StringRef::npos) { 01169 return false; 01170 } else { 01171 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo(); 01172 if (ParseIntelIdentifier(Val, Identifier, Info, 01173 /*Unevaluated=*/false, End)) 01174 return true; 01175 } 01176 } 01177 SM.onIdentifierExpr(Val, Identifier); 01178 UpdateLocLex = false; 01179 break; 01180 } 01181 return Error(Tok.getLoc(), "Unexpected identifier!"); 01182 } 01183 case AsmToken::Integer: { 01184 StringRef ErrMsg; 01185 if (isParsingInlineAsm() && SM.getAddImmPrefix()) 01186 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, 01187 Tok.getLoc())); 01188 // Look for 'b' or 'f' following an Integer as a directional label 01189 SMLoc Loc = getTok().getLoc(); 01190 int64_t IntVal = getTok().getIntVal(); 01191 End = consumeToken(); 01192 UpdateLocLex = false; 01193 if (getLexer().getKind() == AsmToken::Identifier) { 01194 StringRef IDVal = getTok().getString(); 01195 if (IDVal == "f" || IDVal == "b") { 01196 MCSymbol *Sym = 01197 getContext().GetDirectionalLocalSymbol(IntVal, IDVal == "b"); 01198 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 01199 const MCExpr *Val = 01200 MCSymbolRefExpr::Create(Sym, Variant, getContext()); 01201 if (IDVal == "b" && Sym->isUndefined()) 01202 return Error(Loc, "invalid reference to undefined symbol"); 01203 StringRef Identifier = Sym->getName(); 01204 SM.onIdentifierExpr(Val, Identifier); 01205 End = consumeToken(); 01206 } else { 01207 if (SM.onInteger(IntVal, ErrMsg)) 01208 return Error(Loc, ErrMsg); 01209 } 01210 } else { 01211 if (SM.onInteger(IntVal, ErrMsg)) 01212 return Error(Loc, ErrMsg); 01213 } 01214 break; 01215 } 01216 case AsmToken::Plus: SM.onPlus(); break; 01217 case AsmToken::Minus: SM.onMinus(); break; 01218 case AsmToken::Tilde: SM.onNot(); break; 01219 case AsmToken::Star: SM.onStar(); break; 01220 case AsmToken::Slash: SM.onDivide(); break; 01221 case AsmToken::Pipe: SM.onOr(); break; 01222 case AsmToken::Amp: SM.onAnd(); break; 01223 case AsmToken::LessLess: 01224 SM.onLShift(); break; 01225 case AsmToken::GreaterGreater: 01226 SM.onRShift(); break; 01227 case AsmToken::LBrac: SM.onLBrac(); break; 01228 case AsmToken::RBrac: SM.onRBrac(); break; 01229 case AsmToken::LParen: SM.onLParen(); break; 01230 case AsmToken::RParen: SM.onRParen(); break; 01231 } 01232 if (SM.hadError()) 01233 return Error(Tok.getLoc(), "unknown token in expression"); 01234 01235 if (!Done && UpdateLocLex) 01236 End = consumeToken(); 01237 } 01238 return false; 01239 } 01240 01241 std::unique_ptr<X86Operand> 01242 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start, 01243 int64_t ImmDisp, unsigned Size) { 01244 const AsmToken &Tok = Parser.getTok(); 01245 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc(); 01246 if (getLexer().isNot(AsmToken::LBrac)) 01247 return ErrorOperand(BracLoc, "Expected '[' token!"); 01248 Parser.Lex(); // Eat '[' 01249 01250 SMLoc StartInBrac = Tok.getLoc(); 01251 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We 01252 // may have already parsed an immediate displacement before the bracketed 01253 // expression. 01254 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true); 01255 if (ParseIntelExpression(SM, End)) 01256 return nullptr; 01257 01258 const MCExpr *Disp = nullptr; 01259 if (const MCExpr *Sym = SM.getSym()) { 01260 // A symbolic displacement. 01261 Disp = Sym; 01262 if (isParsingInlineAsm()) 01263 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(), 01264 ImmDisp, SM.getImm(), BracLoc, StartInBrac, 01265 End); 01266 } 01267 01268 if (SM.getImm() || !Disp) { 01269 const MCExpr *Imm = MCConstantExpr::Create(SM.getImm(), getContext()); 01270 if (Disp) 01271 Disp = MCBinaryExpr::CreateAdd(Disp, Imm, getContext()); 01272 else 01273 Disp = Imm; // An immediate displacement only. 01274 } 01275 01276 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC 01277 // will in fact do global lookup the field name inside all global typedefs, 01278 // but we don't emulate that. 01279 if (Tok.getString().find('.') != StringRef::npos) { 01280 const MCExpr *NewDisp; 01281 if (ParseIntelDotOperator(Disp, NewDisp)) 01282 return nullptr; 01283 01284 End = Tok.getEndLoc(); 01285 Parser.Lex(); // Eat the field. 01286 Disp = NewDisp; 01287 } 01288 01289 int BaseReg = SM.getBaseReg(); 01290 int IndexReg = SM.getIndexReg(); 01291 int Scale = SM.getScale(); 01292 if (!isParsingInlineAsm()) { 01293 // handle [-42] 01294 if (!BaseReg && !IndexReg) { 01295 if (!SegReg) 01296 return X86Operand::CreateMem(Disp, Start, End, Size); 01297 else 01298 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size); 01299 } 01300 StringRef ErrMsg; 01301 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) { 01302 Error(StartInBrac, ErrMsg); 01303 return nullptr; 01304 } 01305 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start, 01306 End, Size); 01307 } 01308 01309 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo(); 01310 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start, 01311 End, Size, SM.getSymName(), Info); 01312 } 01313 01314 // Inline assembly may use variable names with namespace alias qualifiers. 01315 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val, 01316 StringRef &Identifier, 01317 InlineAsmIdentifierInfo &Info, 01318 bool IsUnevaluatedOperand, SMLoc &End) { 01319 assert (isParsingInlineAsm() && "Expected to be parsing inline assembly."); 01320 Val = nullptr; 01321 01322 StringRef LineBuf(Identifier.data()); 01323 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand); 01324 01325 const AsmToken &Tok = Parser.getTok(); 01326 01327 // Advance the token stream until the end of the current token is 01328 // after the end of what the frontend claimed. 01329 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size(); 01330 while (true) { 01331 End = Tok.getEndLoc(); 01332 getLexer().Lex(); 01333 01334 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?"); 01335 if (End.getPointer() == EndPtr) break; 01336 } 01337 01338 // Create the symbol reference. 01339 Identifier = LineBuf; 01340 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier); 01341 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 01342 Val = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext()); 01343 return false; 01344 } 01345 01346 /// \brief Parse intel style segment override. 01347 std::unique_ptr<X86Operand> 01348 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, 01349 unsigned Size) { 01350 assert(SegReg != 0 && "Tried to parse a segment override without a segment!"); 01351 const AsmToken &Tok = Parser.getTok(); // Eat colon. 01352 if (Tok.isNot(AsmToken::Colon)) 01353 return ErrorOperand(Tok.getLoc(), "Expected ':' token!"); 01354 Parser.Lex(); // Eat ':' 01355 01356 int64_t ImmDisp = 0; 01357 if (getLexer().is(AsmToken::Integer)) { 01358 ImmDisp = Tok.getIntVal(); 01359 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer. 01360 01361 if (isParsingInlineAsm()) 01362 InstInfo->AsmRewrites->push_back( 01363 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc())); 01364 01365 if (getLexer().isNot(AsmToken::LBrac)) { 01366 // An immediate following a 'segment register', 'colon' token sequence can 01367 // be followed by a bracketed expression. If it isn't we know we have our 01368 // final segment override. 01369 const MCExpr *Disp = MCConstantExpr::Create(ImmDisp, getContext()); 01370 return X86Operand::CreateMem(SegReg, Disp, /*BaseReg=*/0, /*IndexReg=*/0, 01371 /*Scale=*/1, Start, ImmDispToken.getEndLoc(), 01372 Size); 01373 } 01374 } 01375 01376 if (getLexer().is(AsmToken::LBrac)) 01377 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size); 01378 01379 const MCExpr *Val; 01380 SMLoc End; 01381 if (!isParsingInlineAsm()) { 01382 if (getParser().parsePrimaryExpr(Val, End)) 01383 return ErrorOperand(Tok.getLoc(), "unknown token in expression"); 01384 01385 return X86Operand::CreateMem(Val, Start, End, Size); 01386 } 01387 01388 InlineAsmIdentifierInfo Info; 01389 StringRef Identifier = Tok.getString(); 01390 if (ParseIntelIdentifier(Val, Identifier, Info, 01391 /*Unevaluated=*/false, End)) 01392 return nullptr; 01393 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0, 01394 /*Scale=*/1, Start, End, Size, Identifier, Info); 01395 } 01396 01397 /// ParseIntelMemOperand - Parse intel style memory operand. 01398 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp, 01399 SMLoc Start, 01400 unsigned Size) { 01401 const AsmToken &Tok = Parser.getTok(); 01402 SMLoc End; 01403 01404 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ]. 01405 if (getLexer().is(AsmToken::LBrac)) 01406 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size); 01407 assert(ImmDisp == 0); 01408 01409 const MCExpr *Val; 01410 if (!isParsingInlineAsm()) { 01411 if (getParser().parsePrimaryExpr(Val, End)) 01412 return ErrorOperand(Tok.getLoc(), "unknown token in expression"); 01413 01414 return X86Operand::CreateMem(Val, Start, End, Size); 01415 } 01416 01417 InlineAsmIdentifierInfo Info; 01418 StringRef Identifier = Tok.getString(); 01419 if (ParseIntelIdentifier(Val, Identifier, Info, 01420 /*Unevaluated=*/false, End)) 01421 return nullptr; 01422 01423 if (!getLexer().is(AsmToken::LBrac)) 01424 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0, 01425 /*Scale=*/1, Start, End, Size, Identifier, Info); 01426 01427 Parser.Lex(); // Eat '[' 01428 01429 // Parse Identifier [ ImmDisp ] 01430 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true, 01431 /*AddImmPrefix=*/false); 01432 if (ParseIntelExpression(SM, End)) 01433 return nullptr; 01434 01435 if (SM.getSym()) { 01436 Error(Start, "cannot use more than one symbol in memory operand"); 01437 return nullptr; 01438 } 01439 if (SM.getBaseReg()) { 01440 Error(Start, "cannot use base register with variable reference"); 01441 return nullptr; 01442 } 01443 if (SM.getIndexReg()) { 01444 Error(Start, "cannot use index register with variable reference"); 01445 return nullptr; 01446 } 01447 01448 const MCExpr *Disp = MCConstantExpr::Create(SM.getImm(), getContext()); 01449 // BaseReg is non-zero to avoid assertions. In the context of inline asm, 01450 // we're pointing to a local variable in memory, so the base register is 01451 // really the frame or stack pointer. 01452 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/1, /*IndexReg=*/0, 01453 /*Scale=*/1, Start, End, Size, Identifier, 01454 Info.OpDecl); 01455 } 01456 01457 /// Parse the '.' operator. 01458 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp, 01459 const MCExpr *&NewDisp) { 01460 const AsmToken &Tok = Parser.getTok(); 01461 int64_t OrigDispVal, DotDispVal; 01462 01463 // FIXME: Handle non-constant expressions. 01464 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp)) 01465 OrigDispVal = OrigDisp->getValue(); 01466 else 01467 return Error(Tok.getLoc(), "Non-constant offsets are not supported!"); 01468 01469 // Drop the optional '.'. 01470 StringRef DotDispStr = Tok.getString(); 01471 if (DotDispStr.startswith(".")) 01472 DotDispStr = DotDispStr.drop_front(1); 01473 01474 // .Imm gets lexed as a real. 01475 if (Tok.is(AsmToken::Real)) { 01476 APInt DotDisp; 01477 DotDispStr.getAsInteger(10, DotDisp); 01478 DotDispVal = DotDisp.getZExtValue(); 01479 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) { 01480 unsigned DotDisp; 01481 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.'); 01482 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second, 01483 DotDisp)) 01484 return Error(Tok.getLoc(), "Unable to lookup field reference!"); 01485 DotDispVal = DotDisp; 01486 } else 01487 return Error(Tok.getLoc(), "Unexpected token type!"); 01488 01489 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) { 01490 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data()); 01491 unsigned Len = DotDispStr.size(); 01492 unsigned Val = OrigDispVal + DotDispVal; 01493 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len, 01494 Val)); 01495 } 01496 01497 NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext()); 01498 return false; 01499 } 01500 01501 /// Parse the 'offset' operator. This operator is used to specify the 01502 /// location rather then the content of a variable. 01503 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() { 01504 const AsmToken &Tok = Parser.getTok(); 01505 SMLoc OffsetOfLoc = Tok.getLoc(); 01506 Parser.Lex(); // Eat offset. 01507 01508 const MCExpr *Val; 01509 InlineAsmIdentifierInfo Info; 01510 SMLoc Start = Tok.getLoc(), End; 01511 StringRef Identifier = Tok.getString(); 01512 if (ParseIntelIdentifier(Val, Identifier, Info, 01513 /*Unevaluated=*/false, End)) 01514 return nullptr; 01515 01516 // Don't emit the offset operator. 01517 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7)); 01518 01519 // The offset operator will have an 'r' constraint, thus we need to create 01520 // register operand to ensure proper matching. Just pick a GPR based on 01521 // the size of a pointer. 01522 unsigned RegNo = 01523 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX); 01524 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true, 01525 OffsetOfLoc, Identifier, Info.OpDecl); 01526 } 01527 01528 enum IntelOperatorKind { 01529 IOK_LENGTH, 01530 IOK_SIZE, 01531 IOK_TYPE 01532 }; 01533 01534 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator 01535 /// returns the number of elements in an array. It returns the value 1 for 01536 /// non-array variables. The SIZE operator returns the size of a C or C++ 01537 /// variable. A variable's size is the product of its LENGTH and TYPE. The 01538 /// TYPE operator returns the size of a C or C++ type or variable. If the 01539 /// variable is an array, TYPE returns the size of a single element. 01540 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) { 01541 const AsmToken &Tok = Parser.getTok(); 01542 SMLoc TypeLoc = Tok.getLoc(); 01543 Parser.Lex(); // Eat operator. 01544 01545 const MCExpr *Val = nullptr; 01546 InlineAsmIdentifierInfo Info; 01547 SMLoc Start = Tok.getLoc(), End; 01548 StringRef Identifier = Tok.getString(); 01549 if (ParseIntelIdentifier(Val, Identifier, Info, 01550 /*Unevaluated=*/true, End)) 01551 return nullptr; 01552 01553 if (!Info.OpDecl) 01554 return ErrorOperand(Start, "unable to lookup expression"); 01555 01556 unsigned CVal = 0; 01557 switch(OpKind) { 01558 default: llvm_unreachable("Unexpected operand kind!"); 01559 case IOK_LENGTH: CVal = Info.Length; break; 01560 case IOK_SIZE: CVal = Info.Size; break; 01561 case IOK_TYPE: CVal = Info.Type; break; 01562 } 01563 01564 // Rewrite the type operator and the C or C++ type or variable in terms of an 01565 // immediate. E.g. TYPE foo -> $$4 01566 unsigned Len = End.getPointer() - TypeLoc.getPointer(); 01567 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal)); 01568 01569 const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext()); 01570 return X86Operand::CreateImm(Imm, Start, End); 01571 } 01572 01573 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() { 01574 const AsmToken &Tok = Parser.getTok(); 01575 SMLoc Start, End; 01576 01577 // Offset, length, type and size operators. 01578 if (isParsingInlineAsm()) { 01579 StringRef AsmTokStr = Tok.getString(); 01580 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET") 01581 return ParseIntelOffsetOfOperator(); 01582 if (AsmTokStr == "length" || AsmTokStr == "LENGTH") 01583 return ParseIntelOperator(IOK_LENGTH); 01584 if (AsmTokStr == "size" || AsmTokStr == "SIZE") 01585 return ParseIntelOperator(IOK_SIZE); 01586 if (AsmTokStr == "type" || AsmTokStr == "TYPE") 01587 return ParseIntelOperator(IOK_TYPE); 01588 } 01589 01590 unsigned Size = getIntelMemOperandSize(Tok.getString()); 01591 if (Size) { 01592 Parser.Lex(); // Eat operand size (e.g., byte, word). 01593 if (Tok.getString() != "PTR" && Tok.getString() != "ptr") 01594 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!"); 01595 Parser.Lex(); // Eat ptr. 01596 } 01597 Start = Tok.getLoc(); 01598 01599 // Immediate. 01600 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) || 01601 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) { 01602 AsmToken StartTok = Tok; 01603 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true, 01604 /*AddImmPrefix=*/false); 01605 if (ParseIntelExpression(SM, End)) 01606 return nullptr; 01607 01608 int64_t Imm = SM.getImm(); 01609 if (isParsingInlineAsm()) { 01610 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer(); 01611 if (StartTok.getString().size() == Len) 01612 // Just add a prefix if this wasn't a complex immediate expression. 01613 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start)); 01614 else 01615 // Otherwise, rewrite the complex expression as a single immediate. 01616 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm)); 01617 } 01618 01619 if (getLexer().isNot(AsmToken::LBrac)) { 01620 // If a directional label (ie. 1f or 2b) was parsed above from 01621 // ParseIntelExpression() then SM.getSym() was set to a pointer to 01622 // to the MCExpr with the directional local symbol and this is a 01623 // memory operand not an immediate operand. 01624 if (SM.getSym()) 01625 return X86Operand::CreateMem(SM.getSym(), Start, End, Size); 01626 01627 const MCExpr *ImmExpr = MCConstantExpr::Create(Imm, getContext()); 01628 return X86Operand::CreateImm(ImmExpr, Start, End); 01629 } 01630 01631 // Only positive immediates are valid. 01632 if (Imm < 0) 01633 return ErrorOperand(Start, "expected a positive immediate displacement " 01634 "before bracketed expr."); 01635 01636 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ]. 01637 return ParseIntelMemOperand(Imm, Start, Size); 01638 } 01639 01640 // Register. 01641 unsigned RegNo = 0; 01642 if (!ParseRegister(RegNo, Start, End)) { 01643 // If this is a segment register followed by a ':', then this is the start 01644 // of a segment override, otherwise this is a normal register reference. 01645 if (getLexer().isNot(AsmToken::Colon)) 01646 return X86Operand::CreateReg(RegNo, Start, End); 01647 01648 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size); 01649 } 01650 01651 // Memory operand. 01652 return ParseIntelMemOperand(/*Disp=*/0, Start, Size); 01653 } 01654 01655 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() { 01656 switch (getLexer().getKind()) { 01657 default: 01658 // Parse a memory operand with no segment register. 01659 return ParseMemOperand(0, Parser.getTok().getLoc()); 01660 case AsmToken::Percent: { 01661 // Read the register. 01662 unsigned RegNo; 01663 SMLoc Start, End; 01664 if (ParseRegister(RegNo, Start, End)) return nullptr; 01665 if (RegNo == X86::EIZ || RegNo == X86::RIZ) { 01666 Error(Start, "%eiz and %riz can only be used as index registers", 01667 SMRange(Start, End)); 01668 return nullptr; 01669 } 01670 01671 // If this is a segment register followed by a ':', then this is the start 01672 // of a memory reference, otherwise this is a normal register reference. 01673 if (getLexer().isNot(AsmToken::Colon)) 01674 return X86Operand::CreateReg(RegNo, Start, End); 01675 01676 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo)) 01677 return ErrorOperand(Start, "invalid segment register"); 01678 01679 getParser().Lex(); // Eat the colon. 01680 return ParseMemOperand(RegNo, Start); 01681 } 01682 case AsmToken::Dollar: { 01683 // $42 -> immediate. 01684 SMLoc Start = Parser.getTok().getLoc(), End; 01685 Parser.Lex(); 01686 const MCExpr *Val; 01687 if (getParser().parseExpression(Val, End)) 01688 return nullptr; 01689 return X86Operand::CreateImm(Val, Start, End); 01690 } 01691 } 01692 } 01693 01694 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands, 01695 const MCParsedAsmOperand &Op) { 01696 if(STI.getFeatureBits() & X86::FeatureAVX512) { 01697 if (getLexer().is(AsmToken::LCurly)) { 01698 // Eat "{" and mark the current place. 01699 const SMLoc consumedToken = consumeToken(); 01700 // Distinguish {1to<NUM>} from {%k<NUM>}. 01701 if(getLexer().is(AsmToken::Integer)) { 01702 // Parse memory broadcasting ({1to<NUM>}). 01703 if (getLexer().getTok().getIntVal() != 1) 01704 return !ErrorAndEatStatement(getLexer().getLoc(), 01705 "Expected 1to<NUM> at this point"); 01706 Parser.Lex(); // Eat "1" of 1to8 01707 if (!getLexer().is(AsmToken::Identifier) || 01708 !getLexer().getTok().getIdentifier().startswith("to")) 01709 return !ErrorAndEatStatement(getLexer().getLoc(), 01710 "Expected 1to<NUM> at this point"); 01711 // Recognize only reasonable suffixes. 01712 const char *BroadcastPrimitive = 01713 StringSwitch<const char*>(getLexer().getTok().getIdentifier()) 01714 .Case("to2", "{1to2}") 01715 .Case("to4", "{1to4}") 01716 .Case("to8", "{1to8}") 01717 .Case("to16", "{1to16}") 01718 .Default(nullptr); 01719 if (!BroadcastPrimitive) 01720 return !ErrorAndEatStatement(getLexer().getLoc(), 01721 "Invalid memory broadcast primitive."); 01722 Parser.Lex(); // Eat "toN" of 1toN 01723 if (!getLexer().is(AsmToken::RCurly)) 01724 return !ErrorAndEatStatement(getLexer().getLoc(), 01725 "Expected } at this point"); 01726 Parser.Lex(); // Eat "}" 01727 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive, 01728 consumedToken)); 01729 // No AVX512 specific primitives can pass 01730 // after memory broadcasting, so return. 01731 return true; 01732 } else { 01733 // Parse mask register {%k1} 01734 Operands.push_back(X86Operand::CreateToken("{", consumedToken)); 01735 if (std::unique_ptr<X86Operand> Op = ParseOperand()) { 01736 Operands.push_back(std::move(Op)); 01737 if (!getLexer().is(AsmToken::RCurly)) 01738 return !ErrorAndEatStatement(getLexer().getLoc(), 01739 "Expected } at this point"); 01740 Operands.push_back(X86Operand::CreateToken("}", consumeToken())); 01741 01742 // Parse "zeroing non-masked" semantic {z} 01743 if (getLexer().is(AsmToken::LCurly)) { 01744 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken())); 01745 if (!getLexer().is(AsmToken::Identifier) || 01746 getLexer().getTok().getIdentifier() != "z") 01747 return !ErrorAndEatStatement(getLexer().getLoc(), 01748 "Expected z at this point"); 01749 Parser.Lex(); // Eat the z 01750 if (!getLexer().is(AsmToken::RCurly)) 01751 return !ErrorAndEatStatement(getLexer().getLoc(), 01752 "Expected } at this point"); 01753 Parser.Lex(); // Eat the } 01754 } 01755 } 01756 } 01757 } 01758 } 01759 return true; 01760 } 01761 01762 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix 01763 /// has already been parsed if present. 01764 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg, 01765 SMLoc MemStart) { 01766 01767 // We have to disambiguate a parenthesized expression "(4+5)" from the start 01768 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 01769 // only way to do this without lookahead is to eat the '(' and see what is 01770 // after it. 01771 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); 01772 if (getLexer().isNot(AsmToken::LParen)) { 01773 SMLoc ExprEnd; 01774 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr; 01775 01776 // After parsing the base expression we could either have a parenthesized 01777 // memory address or not. If not, return now. If so, eat the (. 01778 if (getLexer().isNot(AsmToken::LParen)) { 01779 // Unless we have a segment register, treat this as an immediate. 01780 if (SegReg == 0) 01781 return X86Operand::CreateMem(Disp, MemStart, ExprEnd); 01782 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 01783 } 01784 01785 // Eat the '('. 01786 Parser.Lex(); 01787 } else { 01788 // Okay, we have a '('. We don't know if this is an expression or not, but 01789 // so we have to eat the ( to see beyond it. 01790 SMLoc LParenLoc = Parser.getTok().getLoc(); 01791 Parser.Lex(); // Eat the '('. 01792 01793 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { 01794 // Nothing to do here, fall into the code below with the '(' part of the 01795 // memory operand consumed. 01796 } else { 01797 SMLoc ExprEnd; 01798 01799 // It must be an parenthesized expression, parse it now. 01800 if (getParser().parseParenExpression(Disp, ExprEnd)) 01801 return nullptr; 01802 01803 // After parsing the base expression we could either have a parenthesized 01804 // memory address or not. If not, return now. If so, eat the (. 01805 if (getLexer().isNot(AsmToken::LParen)) { 01806 // Unless we have a segment register, treat this as an immediate. 01807 if (SegReg == 0) 01808 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd); 01809 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 01810 } 01811 01812 // Eat the '('. 01813 Parser.Lex(); 01814 } 01815 } 01816 01817 // If we reached here, then we just ate the ( of the memory operand. Process 01818 // the rest of the memory operand. 01819 unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 01820 SMLoc IndexLoc, BaseLoc; 01821 01822 if (getLexer().is(AsmToken::Percent)) { 01823 SMLoc StartLoc, EndLoc; 01824 BaseLoc = Parser.getTok().getLoc(); 01825 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr; 01826 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) { 01827 Error(StartLoc, "eiz and riz can only be used as index registers", 01828 SMRange(StartLoc, EndLoc)); 01829 return nullptr; 01830 } 01831 } 01832 01833 if (getLexer().is(AsmToken::Comma)) { 01834 Parser.Lex(); // Eat the comma. 01835 IndexLoc = Parser.getTok().getLoc(); 01836 01837 // Following the comma we should have either an index register, or a scale 01838 // value. We don't support the later form, but we want to parse it 01839 // correctly. 01840 // 01841 // Not that even though it would be completely consistent to support syntax 01842 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. 01843 if (getLexer().is(AsmToken::Percent)) { 01844 SMLoc L; 01845 if (ParseRegister(IndexReg, L, L)) return nullptr; 01846 01847 if (getLexer().isNot(AsmToken::RParen)) { 01848 // Parse the scale amount: 01849 // ::= ',' [scale-expression] 01850 if (getLexer().isNot(AsmToken::Comma)) { 01851 Error(Parser.getTok().getLoc(), 01852 "expected comma in scale expression"); 01853 return nullptr; 01854 } 01855 Parser.Lex(); // Eat the comma. 01856 01857 if (getLexer().isNot(AsmToken::RParen)) { 01858 SMLoc Loc = Parser.getTok().getLoc(); 01859 01860 int64_t ScaleVal; 01861 if (getParser().parseAbsoluteExpression(ScaleVal)){ 01862 Error(Loc, "expected scale expression"); 01863 return nullptr; 01864 } 01865 01866 // Validate the scale amount. 01867 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && 01868 ScaleVal != 1) { 01869 Error(Loc, "scale factor in 16-bit address must be 1"); 01870 return nullptr; 01871 } 01872 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){ 01873 Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 01874 return nullptr; 01875 } 01876 Scale = (unsigned)ScaleVal; 01877 } 01878 } 01879 } else if (getLexer().isNot(AsmToken::RParen)) { 01880 // A scale amount without an index is ignored. 01881 // index. 01882 SMLoc Loc = Parser.getTok().getLoc(); 01883 01884 int64_t Value; 01885 if (getParser().parseAbsoluteExpression(Value)) 01886 return nullptr; 01887 01888 if (Value != 1) 01889 Warning(Loc, "scale factor without index register is ignored"); 01890 Scale = 1; 01891 } 01892 } 01893 01894 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 01895 if (getLexer().isNot(AsmToken::RParen)) { 01896 Error(Parser.getTok().getLoc(), "unexpected token in memory operand"); 01897 return nullptr; 01898 } 01899 SMLoc MemEnd = Parser.getTok().getEndLoc(); 01900 Parser.Lex(); // Eat the ')'. 01901 01902 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed, 01903 // and then only in non-64-bit modes. Except for DX, which is a special case 01904 // because an unofficial form of in/out instructions uses it. 01905 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && 01906 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP && 01907 BaseReg != X86::SI && BaseReg != X86::DI)) && 01908 BaseReg != X86::DX) { 01909 Error(BaseLoc, "invalid 16-bit base register"); 01910 return nullptr; 01911 } 01912 if (BaseReg == 0 && 01913 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) { 01914 Error(IndexLoc, "16-bit memory operand may not include only index register"); 01915 return nullptr; 01916 } 01917 01918 StringRef ErrMsg; 01919 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) { 01920 Error(BaseLoc, ErrMsg); 01921 return nullptr; 01922 } 01923 01924 if (SegReg || BaseReg || IndexReg) 01925 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, 01926 MemStart, MemEnd); 01927 return X86Operand::CreateMem(Disp, MemStart, MemEnd); 01928 } 01929 01930 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 01931 SMLoc NameLoc, OperandVector &Operands) { 01932 InstInfo = &Info; 01933 StringRef PatchedName = Name; 01934 01935 // FIXME: Hack to recognize setneb as setne. 01936 if (PatchedName.startswith("set") && PatchedName.endswith("b") && 01937 PatchedName != "setb" && PatchedName != "setnb") 01938 PatchedName = PatchedName.substr(0, Name.size()-1); 01939 01940 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}. 01941 const MCExpr *ExtraImmOp = nullptr; 01942 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) && 01943 (PatchedName.endswith("ss") || PatchedName.endswith("sd") || 01944 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { 01945 bool IsVCMP = PatchedName[0] == 'v'; 01946 unsigned SSECCIdx = IsVCMP ? 4 : 3; 01947 unsigned SSEComparisonCode = StringSwitch<unsigned>( 01948 PatchedName.slice(SSECCIdx, PatchedName.size() - 2)) 01949 .Case("eq", 0x00) 01950 .Case("lt", 0x01) 01951 .Case("le", 0x02) 01952 .Case("unord", 0x03) 01953 .Case("neq", 0x04) 01954 .Case("nlt", 0x05) 01955 .Case("nle", 0x06) 01956 .Case("ord", 0x07) 01957 /* AVX only from here */ 01958 .Case("eq_uq", 0x08) 01959 .Case("nge", 0x09) 01960 .Case("ngt", 0x0A) 01961 .Case("false", 0x0B) 01962 .Case("neq_oq", 0x0C) 01963 .Case("ge", 0x0D) 01964 .Case("gt", 0x0E) 01965 .Case("true", 0x0F) 01966 .Case("eq_os", 0x10) 01967 .Case("lt_oq", 0x11) 01968 .Case("le_oq", 0x12) 01969 .Case("unord_s", 0x13) 01970 .Case("neq_us", 0x14) 01971 .Case("nlt_uq", 0x15) 01972 .Case("nle_uq", 0x16) 01973 .Case("ord_s", 0x17) 01974 .Case("eq_us", 0x18) 01975 .Case("nge_uq", 0x19) 01976 .Case("ngt_uq", 0x1A) 01977 .Case("false_os", 0x1B) 01978 .Case("neq_os", 0x1C) 01979 .Case("ge_oq", 0x1D) 01980 .Case("gt_oq", 0x1E) 01981 .Case("true_us", 0x1F) 01982 .Default(~0U); 01983 if (SSEComparisonCode != ~0U && (IsVCMP || SSEComparisonCode < 8)) { 01984 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode, 01985 getParser().getContext()); 01986 if (PatchedName.endswith("ss")) { 01987 PatchedName = IsVCMP ? "vcmpss" : "cmpss"; 01988 } else if (PatchedName.endswith("sd")) { 01989 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd"; 01990 } else if (PatchedName.endswith("ps")) { 01991 PatchedName = IsVCMP ? "vcmpps" : "cmpps"; 01992 } else { 01993 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!"); 01994 PatchedName = IsVCMP ? "vcmppd" : "cmppd"; 01995 } 01996 } 01997 } 01998 01999 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); 02000 02001 if (ExtraImmOp && !isParsingIntelSyntax()) 02002 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); 02003 02004 // Determine whether this is an instruction prefix. 02005 bool isPrefix = 02006 Name == "lock" || Name == "rep" || 02007 Name == "repe" || Name == "repz" || 02008 Name == "repne" || Name == "repnz" || 02009 Name == "rex64" || Name == "data16"; 02010 02011 02012 // This does the actual operand parsing. Don't parse any more if we have a 02013 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we 02014 // just want to parse the "lock" as the first instruction and the "incl" as 02015 // the next one. 02016 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) { 02017 02018 // Parse '*' modifier. 02019 if (getLexer().is(AsmToken::Star)) 02020 Operands.push_back(X86Operand::CreateToken("*", consumeToken())); 02021 02022 // Read the operands. 02023 while(1) { 02024 if (std::unique_ptr<X86Operand> Op = ParseOperand()) { 02025 Operands.push_back(std::move(Op)); 02026 if (!HandleAVX512Operand(Operands, *Operands.back())) 02027 return true; 02028 } else { 02029 Parser.eatToEndOfStatement(); 02030 return true; 02031 } 02032 // check for comma and eat it 02033 if (getLexer().is(AsmToken::Comma)) 02034 Parser.Lex(); 02035 else 02036 break; 02037 } 02038 02039 if (getLexer().isNot(AsmToken::EndOfStatement)) 02040 return ErrorAndEatStatement(getLexer().getLoc(), 02041 "unexpected token in argument list"); 02042 } 02043 02044 // Consume the EndOfStatement or the prefix separator Slash 02045 if (getLexer().is(AsmToken::EndOfStatement) || 02046 (isPrefix && getLexer().is(AsmToken::Slash))) 02047 Parser.Lex(); 02048 02049 if (ExtraImmOp && isParsingIntelSyntax()) 02050 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); 02051 02052 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" -> 02053 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely 02054 // documented form in various unofficial manuals, so a lot of code uses it. 02055 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") && 02056 Operands.size() == 3) { 02057 X86Operand &Op = (X86Operand &)*Operands.back(); 02058 if (Op.isMem() && Op.Mem.SegReg == 0 && 02059 isa<MCConstantExpr>(Op.Mem.Disp) && 02060 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 02061 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 02062 SMLoc Loc = Op.getEndLoc(); 02063 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 02064 } 02065 } 02066 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al". 02067 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") && 02068 Operands.size() == 3) { 02069 X86Operand &Op = (X86Operand &)*Operands[1]; 02070 if (Op.isMem() && Op.Mem.SegReg == 0 && 02071 isa<MCConstantExpr>(Op.Mem.Disp) && 02072 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 02073 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 02074 SMLoc Loc = Op.getEndLoc(); 02075 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 02076 } 02077 } 02078 02079 // Append default arguments to "ins[bwld]" 02080 if (Name.startswith("ins") && Operands.size() == 1 && 02081 (Name == "insb" || Name == "insw" || Name == "insl" || 02082 Name == "insd" )) { 02083 if (isParsingIntelSyntax()) { 02084 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc)); 02085 Operands.push_back(DefaultMemDIOperand(NameLoc)); 02086 } else { 02087 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc)); 02088 Operands.push_back(DefaultMemDIOperand(NameLoc)); 02089 } 02090 } 02091 02092 // Append default arguments to "outs[bwld]" 02093 if (Name.startswith("outs") && Operands.size() == 1 && 02094 (Name == "outsb" || Name == "outsw" || Name == "outsl" || 02095 Name == "outsd" )) { 02096 if (isParsingIntelSyntax()) { 02097 Operands.push_back(DefaultMemSIOperand(NameLoc)); 02098 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc)); 02099 } else { 02100 Operands.push_back(DefaultMemSIOperand(NameLoc)); 02101 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc)); 02102 } 02103 } 02104 02105 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate 02106 // values of $SIREG according to the mode. It would be nice if this 02107 // could be achieved with InstAlias in the tables. 02108 if (Name.startswith("lods") && Operands.size() == 1 && 02109 (Name == "lods" || Name == "lodsb" || Name == "lodsw" || 02110 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) 02111 Operands.push_back(DefaultMemSIOperand(NameLoc)); 02112 02113 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate 02114 // values of $DIREG according to the mode. It would be nice if this 02115 // could be achieved with InstAlias in the tables. 02116 if (Name.startswith("stos") && Operands.size() == 1 && 02117 (Name == "stos" || Name == "stosb" || Name == "stosw" || 02118 Name == "stosl" || Name == "stosd" || Name == "stosq")) 02119 Operands.push_back(DefaultMemDIOperand(NameLoc)); 02120 02121 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate 02122 // values of $DIREG according to the mode. It would be nice if this 02123 // could be achieved with InstAlias in the tables. 02124 if (Name.startswith("scas") && Operands.size() == 1 && 02125 (Name == "scas" || Name == "scasb" || Name == "scasw" || 02126 Name == "scasl" || Name == "scasd" || Name == "scasq")) 02127 Operands.push_back(DefaultMemDIOperand(NameLoc)); 02128 02129 // Add default SI and DI operands to "cmps[bwlq]". 02130 if (Name.startswith("cmps") && 02131 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" || 02132 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) { 02133 if (Operands.size() == 1) { 02134 if (isParsingIntelSyntax()) { 02135 Operands.push_back(DefaultMemSIOperand(NameLoc)); 02136 Operands.push_back(DefaultMemDIOperand(NameLoc)); 02137 } else { 02138 Operands.push_back(DefaultMemDIOperand(NameLoc)); 02139 Operands.push_back(DefaultMemSIOperand(NameLoc)); 02140 } 02141 } else if (Operands.size() == 3) { 02142 X86Operand &Op = (X86Operand &)*Operands[1]; 02143 X86Operand &Op2 = (X86Operand &)*Operands[2]; 02144 if (!doSrcDstMatch(Op, Op2)) 02145 return Error(Op.getStartLoc(), 02146 "mismatching source and destination index registers"); 02147 } 02148 } 02149 02150 // Add default SI and DI operands to "movs[bwlq]". 02151 if ((Name.startswith("movs") && 02152 (Name == "movs" || Name == "movsb" || Name == "movsw" || 02153 Name == "movsl" || Name == "movsd" || Name == "movsq")) || 02154 (Name.startswith("smov") && 02155 (Name == "smov" || Name == "smovb" || Name == "smovw" || 02156 Name == "smovl" || Name == "smovd" || Name == "smovq"))) { 02157 if (Operands.size() == 1) { 02158 if (Name == "movsd") 02159 Operands.back() = X86Operand::CreateToken("movsl", NameLoc); 02160 if (isParsingIntelSyntax()) { 02161 Operands.push_back(DefaultMemDIOperand(NameLoc)); 02162 Operands.push_back(DefaultMemSIOperand(NameLoc)); 02163 } else { 02164 Operands.push_back(DefaultMemSIOperand(NameLoc)); 02165 Operands.push_back(DefaultMemDIOperand(NameLoc)); 02166 } 02167 } else if (Operands.size() == 3) { 02168 X86Operand &Op = (X86Operand &)*Operands[1]; 02169 X86Operand &Op2 = (X86Operand &)*Operands[2]; 02170 if (!doSrcDstMatch(Op, Op2)) 02171 return Error(Op.getStartLoc(), 02172 "mismatching source and destination index registers"); 02173 } 02174 } 02175 02176 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to 02177 // "shift <op>". 02178 if ((Name.startswith("shr") || Name.startswith("sar") || 02179 Name.startswith("shl") || Name.startswith("sal") || 02180 Name.startswith("rcl") || Name.startswith("rcr") || 02181 Name.startswith("rol") || Name.startswith("ror")) && 02182 Operands.size() == 3) { 02183 if (isParsingIntelSyntax()) { 02184 // Intel syntax 02185 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]); 02186 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) && 02187 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1) 02188 Operands.pop_back(); 02189 } else { 02190 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]); 02191 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) && 02192 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1) 02193 Operands.erase(Operands.begin() + 1); 02194 } 02195 } 02196 02197 // Transforms "int $3" into "int3" as a size optimization. We can't write an 02198 // instalias with an immediate operand yet. 02199 if (Name == "int" && Operands.size() == 2) { 02200 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]); 02201 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) && 02202 cast<MCConstantExpr>(Op1.getImm())->getValue() == 3) { 02203 Operands.erase(Operands.begin() + 1); 02204 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3"); 02205 } 02206 } 02207 02208 return false; 02209 } 02210 02211 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg, 02212 bool isCmp) { 02213 MCInst TmpInst; 02214 TmpInst.setOpcode(Opcode); 02215 if (!isCmp) 02216 TmpInst.addOperand(MCOperand::CreateReg(Reg)); 02217 TmpInst.addOperand(MCOperand::CreateReg(Reg)); 02218 TmpInst.addOperand(Inst.getOperand(0)); 02219 Inst = TmpInst; 02220 return true; 02221 } 02222 02223 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode, 02224 bool isCmp = false) { 02225 if (!Inst.getOperand(0).isImm() || 02226 !isImmSExti16i8Value(Inst.getOperand(0).getImm())) 02227 return false; 02228 02229 return convertToSExti8(Inst, Opcode, X86::AX, isCmp); 02230 } 02231 02232 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode, 02233 bool isCmp = false) { 02234 if (!Inst.getOperand(0).isImm() || 02235 !isImmSExti32i8Value(Inst.getOperand(0).getImm())) 02236 return false; 02237 02238 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp); 02239 } 02240 02241 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode, 02242 bool isCmp = false) { 02243 if (!Inst.getOperand(0).isImm() || 02244 !isImmSExti64i8Value(Inst.getOperand(0).getImm())) 02245 return false; 02246 02247 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp); 02248 } 02249 02250 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) { 02251 switch (Inst.getOpcode()) { 02252 default: return false; 02253 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8); 02254 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8); 02255 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8); 02256 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8); 02257 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8); 02258 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8); 02259 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8); 02260 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8); 02261 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8); 02262 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true); 02263 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true); 02264 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true); 02265 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8); 02266 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8); 02267 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8); 02268 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8); 02269 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8); 02270 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8); 02271 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8); 02272 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8); 02273 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8); 02274 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8); 02275 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8); 02276 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8); 02277 case X86::VMOVAPDrr: 02278 case X86::VMOVAPDYrr: 02279 case X86::VMOVAPSrr: 02280 case X86::VMOVAPSYrr: 02281 case X86::VMOVDQArr: 02282 case X86::VMOVDQAYrr: 02283 case X86::VMOVDQUrr: 02284 case X86::VMOVDQUYrr: 02285 case X86::VMOVUPDrr: 02286 case X86::VMOVUPDYrr: 02287 case X86::VMOVUPSrr: 02288 case X86::VMOVUPSYrr: { 02289 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) || 02290 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg())) 02291 return false; 02292 02293 unsigned NewOpc; 02294 switch (Inst.getOpcode()) { 02295 default: llvm_unreachable("Invalid opcode"); 02296 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break; 02297 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break; 02298 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break; 02299 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break; 02300 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break; 02301 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break; 02302 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break; 02303 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break; 02304 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break; 02305 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break; 02306 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break; 02307 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break; 02308 } 02309 Inst.setOpcode(NewOpc); 02310 return true; 02311 } 02312 case X86::VMOVSDrr: 02313 case X86::VMOVSSrr: { 02314 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) || 02315 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg())) 02316 return false; 02317 unsigned NewOpc; 02318 switch (Inst.getOpcode()) { 02319 default: llvm_unreachable("Invalid opcode"); 02320 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break; 02321 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break; 02322 } 02323 Inst.setOpcode(NewOpc); 02324 return true; 02325 } 02326 } 02327 } 02328 02329 static const char *getSubtargetFeatureName(uint64_t Val); 02330 02331 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands, 02332 MCStreamer &Out) { 02333 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(), 02334 MII, Out); 02335 } 02336 02337 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 02338 OperandVector &Operands, 02339 MCStreamer &Out, uint64_t &ErrorInfo, 02340 bool MatchingInlineAsm) { 02341 if (isParsingIntelSyntax()) 02342 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo, 02343 MatchingInlineAsm); 02344 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo, 02345 MatchingInlineAsm); 02346 } 02347 02348 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, 02349 OperandVector &Operands, MCStreamer &Out, 02350 bool MatchingInlineAsm) { 02351 // FIXME: This should be replaced with a real .td file alias mechanism. 02352 // Also, MatchInstructionImpl should actually *do* the EmitInstruction 02353 // call. 02354 const char *Repl = StringSwitch<const char *>(Op.getToken()) 02355 .Case("finit", "fninit") 02356 .Case("fsave", "fnsave") 02357 .Case("fstcw", "fnstcw") 02358 .Case("fstcww", "fnstcw") 02359 .Case("fstenv", "fnstenv") 02360 .Case("fstsw", "fnstsw") 02361 .Case("fstsww", "fnstsw") 02362 .Case("fclex", "fnclex") 02363 .Default(nullptr); 02364 if (Repl) { 02365 MCInst Inst; 02366 Inst.setOpcode(X86::WAIT); 02367 Inst.setLoc(IDLoc); 02368 if (!MatchingInlineAsm) 02369 EmitInstruction(Inst, Operands, Out); 02370 Operands[0] = X86Operand::CreateToken(Repl, IDLoc); 02371 } 02372 } 02373 02374 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo, 02375 bool MatchingInlineAsm) { 02376 assert(ErrorInfo && "Unknown missing feature!"); 02377 ArrayRef<SMRange> EmptyRanges = None; 02378 SmallString<126> Msg; 02379 raw_svector_ostream OS(Msg); 02380 OS << "instruction requires:"; 02381 uint64_t Mask = 1; 02382 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { 02383 if (ErrorInfo & Mask) 02384 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask); 02385 Mask <<= 1; 02386 } 02387 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm); 02388 } 02389 02390 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, 02391 OperandVector &Operands, 02392 MCStreamer &Out, 02393 uint64_t &ErrorInfo, 02394 bool MatchingInlineAsm) { 02395 assert(!Operands.empty() && "Unexpect empty operand list!"); 02396 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]); 02397 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 02398 ArrayRef<SMRange> EmptyRanges = None; 02399 02400 // First, handle aliases that expand to multiple instructions. 02401 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm); 02402 02403 bool WasOriginallyInvalidOperand = false; 02404 MCInst Inst; 02405 02406 // First, try a direct match. 02407 switch (MatchInstructionImpl(Operands, Inst, 02408 ErrorInfo, MatchingInlineAsm, 02409 isParsingIntelSyntax())) { 02410 default: break; 02411 case Match_Success: 02412 // Some instructions need post-processing to, for example, tweak which 02413 // encoding is selected. Loop on it while changes happen so the 02414 // individual transformations can chain off each other. 02415 if (!MatchingInlineAsm) 02416 while (processInstruction(Inst, Operands)) 02417 ; 02418 02419 Inst.setLoc(IDLoc); 02420 if (!MatchingInlineAsm) 02421 EmitInstruction(Inst, Operands, Out); 02422 Opcode = Inst.getOpcode(); 02423 return false; 02424 case Match_MissingFeature: 02425 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm); 02426 case Match_InvalidOperand: 02427 WasOriginallyInvalidOperand = true; 02428 break; 02429 case Match_MnemonicFail: 02430 break; 02431 } 02432 02433 // FIXME: Ideally, we would only attempt suffix matches for things which are 02434 // valid prefixes, and we could just infer the right unambiguous 02435 // type. However, that requires substantially more matcher support than the 02436 // following hack. 02437 02438 // Change the operand to point to a temporary token. 02439 StringRef Base = Op.getToken(); 02440 SmallString<16> Tmp; 02441 Tmp += Base; 02442 Tmp += ' '; 02443 Op.setTokenValue(Tmp.str()); 02444 02445 // If this instruction starts with an 'f', then it is a floating point stack 02446 // instruction. These come in up to three forms for 32-bit, 64-bit, and 02447 // 80-bit floating point, which use the suffixes s,l,t respectively. 02448 // 02449 // Otherwise, we assume that this may be an integer instruction, which comes 02450 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively. 02451 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0"; 02452 02453 // Check for the various suffix matches. 02454 uint64_t ErrorInfoIgnore; 02455 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings. 02456 unsigned Match[4]; 02457 02458 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) { 02459 Tmp.back() = Suffixes[I]; 02460 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, 02461 MatchingInlineAsm, isParsingIntelSyntax()); 02462 // If this returned as a missing feature failure, remember that. 02463 if (Match[I] == Match_MissingFeature) 02464 ErrorInfoMissingFeature = ErrorInfoIgnore; 02465 } 02466 02467 // Restore the old token. 02468 Op.setTokenValue(Base); 02469 02470 // If exactly one matched, then we treat that as a successful match (and the 02471 // instruction will already have been filled in correctly, since the failing 02472 // matches won't have modified it). 02473 unsigned NumSuccessfulMatches = 02474 std::count(std::begin(Match), std::end(Match), Match_Success); 02475 if (NumSuccessfulMatches == 1) { 02476 Inst.setLoc(IDLoc); 02477 if (!MatchingInlineAsm) 02478 EmitInstruction(Inst, Operands, Out); 02479 Opcode = Inst.getOpcode(); 02480 return false; 02481 } 02482 02483 // Otherwise, the match failed, try to produce a decent error message. 02484 02485 // If we had multiple suffix matches, then identify this as an ambiguous 02486 // match. 02487 if (NumSuccessfulMatches > 1) { 02488 char MatchChars[4]; 02489 unsigned NumMatches = 0; 02490 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) 02491 if (Match[I] == Match_Success) 02492 MatchChars[NumMatches++] = Suffixes[I]; 02493 02494 SmallString<126> Msg; 02495 raw_svector_ostream OS(Msg); 02496 OS << "ambiguous instructions require an explicit suffix (could be "; 02497 for (unsigned i = 0; i != NumMatches; ++i) { 02498 if (i != 0) 02499 OS << ", "; 02500 if (i + 1 == NumMatches) 02501 OS << "or "; 02502 OS << "'" << Base << MatchChars[i] << "'"; 02503 } 02504 OS << ")"; 02505 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm); 02506 return true; 02507 } 02508 02509 // Okay, we know that none of the variants matched successfully. 02510 02511 // If all of the instructions reported an invalid mnemonic, then the original 02512 // mnemonic was invalid. 02513 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) { 02514 if (!WasOriginallyInvalidOperand) { 02515 ArrayRef<SMRange> Ranges = 02516 MatchingInlineAsm ? EmptyRanges : Op.getLocRange(); 02517 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'", 02518 Ranges, MatchingInlineAsm); 02519 } 02520 02521 // Recover location info for the operand if we know which was the problem. 02522 if (ErrorInfo != ~0ULL) { 02523 if (ErrorInfo >= Operands.size()) 02524 return Error(IDLoc, "too few operands for instruction", 02525 EmptyRanges, MatchingInlineAsm); 02526 02527 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo]; 02528 if (Operand.getStartLoc().isValid()) { 02529 SMRange OperandRange = Operand.getLocRange(); 02530 return Error(Operand.getStartLoc(), "invalid operand for instruction", 02531 OperandRange, MatchingInlineAsm); 02532 } 02533 } 02534 02535 return Error(IDLoc, "invalid operand for instruction", EmptyRanges, 02536 MatchingInlineAsm); 02537 } 02538 02539 // If one instruction matched with a missing feature, report this as a 02540 // missing feature. 02541 if (std::count(std::begin(Match), std::end(Match), 02542 Match_MissingFeature) == 1) { 02543 ErrorInfo = ErrorInfoMissingFeature; 02544 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature, 02545 MatchingInlineAsm); 02546 } 02547 02548 // If one instruction matched with an invalid operand, report this as an 02549 // operand failure. 02550 if (std::count(std::begin(Match), std::end(Match), 02551 Match_InvalidOperand) == 1) { 02552 return Error(IDLoc, "invalid operand for instruction", EmptyRanges, 02553 MatchingInlineAsm); 02554 } 02555 02556 // If all of these were an outright failure, report it in a useless way. 02557 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix", 02558 EmptyRanges, MatchingInlineAsm); 02559 return true; 02560 } 02561 02562 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, 02563 OperandVector &Operands, 02564 MCStreamer &Out, 02565 uint64_t &ErrorInfo, 02566 bool MatchingInlineAsm) { 02567 assert(!Operands.empty() && "Unexpect empty operand list!"); 02568 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]); 02569 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 02570 StringRef Mnemonic = Op.getToken(); 02571 ArrayRef<SMRange> EmptyRanges = None; 02572 02573 // First, handle aliases that expand to multiple instructions. 02574 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm); 02575 02576 MCInst Inst; 02577 02578 // Find one unsized memory operand, if present. 02579 X86Operand *UnsizedMemOp = nullptr; 02580 for (const auto &Op : Operands) { 02581 X86Operand *X86Op = static_cast<X86Operand *>(Op.get()); 02582 if (X86Op->isMemUnsized()) 02583 UnsizedMemOp = X86Op; 02584 } 02585 02586 // Allow some instructions to have implicitly pointer-sized operands. This is 02587 // compatible with gas. 02588 if (UnsizedMemOp) { 02589 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"}; 02590 for (const char *Instr : PtrSizedInstrs) { 02591 if (Mnemonic == Instr) { 02592 UnsizedMemOp->Mem.Size = getPointerSize(); 02593 break; 02594 } 02595 } 02596 } 02597 02598 // If an unsized memory operand is present, try to match with each memory 02599 // operand size. In Intel assembly, the size is not part of the instruction 02600 // mnemonic. 02601 SmallVector<unsigned, 8> Match; 02602 uint64_t ErrorInfoMissingFeature = 0; 02603 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) { 02604 static const unsigned MopSizes[] = {8, 16, 32, 64, 80}; 02605 for (unsigned Size : MopSizes) { 02606 UnsizedMemOp->Mem.Size = Size; 02607 uint64_t ErrorInfoIgnore; 02608 unsigned LastOpcode = Inst.getOpcode(); 02609 unsigned M = 02610 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, 02611 MatchingInlineAsm, isParsingIntelSyntax()); 02612 if (Match.empty() || LastOpcode != Inst.getOpcode()) 02613 Match.push_back(M); 02614 02615 // If this returned as a missing feature failure, remember that. 02616 if (Match.back() == Match_MissingFeature) 02617 ErrorInfoMissingFeature = ErrorInfoIgnore; 02618 } 02619 02620 // Restore the size of the unsized memory operand if we modified it. 02621 if (UnsizedMemOp) 02622 UnsizedMemOp->Mem.Size = 0; 02623 } 02624 02625 // If we haven't matched anything yet, this is not a basic integer or FPU 02626 // operation. There shouldn't be any ambiguity in our mneumonic table, so try 02627 // matching with the unsized operand. 02628 if (Match.empty()) { 02629 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo, 02630 MatchingInlineAsm, 02631 isParsingIntelSyntax())); 02632 // If this returned as a missing feature failure, remember that. 02633 if (Match.back() == Match_MissingFeature) 02634 ErrorInfoMissingFeature = ErrorInfo; 02635 } 02636 02637 // Restore the size of the unsized memory operand if we modified it. 02638 if (UnsizedMemOp) 02639 UnsizedMemOp->Mem.Size = 0; 02640 02641 // If it's a bad mnemonic, all results will be the same. 02642 if (Match.back() == Match_MnemonicFail) { 02643 ArrayRef<SMRange> Ranges = 02644 MatchingInlineAsm ? EmptyRanges : Op.getLocRange(); 02645 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'", 02646 Ranges, MatchingInlineAsm); 02647 } 02648 02649 // If exactly one matched, then we treat that as a successful match (and the 02650 // instruction will already have been filled in correctly, since the failing 02651 // matches won't have modified it). 02652 unsigned NumSuccessfulMatches = 02653 std::count(std::begin(Match), std::end(Match), Match_Success); 02654 if (NumSuccessfulMatches == 1) { 02655 // Some instructions need post-processing to, for example, tweak which 02656 // encoding is selected. Loop on it while changes happen so the individual 02657 // transformations can chain off each other. 02658 if (!MatchingInlineAsm) 02659 while (processInstruction(Inst, Operands)) 02660 ; 02661 Inst.setLoc(IDLoc); 02662 if (!MatchingInlineAsm) 02663 EmitInstruction(Inst, Operands, Out); 02664 Opcode = Inst.getOpcode(); 02665 return false; 02666 } else if (NumSuccessfulMatches > 1) { 02667 assert(UnsizedMemOp && 02668 "multiple matches only possible with unsized memory operands"); 02669 ArrayRef<SMRange> Ranges = 02670 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange(); 02671 return Error(UnsizedMemOp->getStartLoc(), 02672 "ambiguous operand size for instruction '" + Mnemonic + "\'", 02673 Ranges, MatchingInlineAsm); 02674 } 02675 02676 // If one instruction matched with a missing feature, report this as a 02677 // missing feature. 02678 if (std::count(std::begin(Match), std::end(Match), 02679 Match_MissingFeature) == 1) { 02680 ErrorInfo = ErrorInfoMissingFeature; 02681 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature, 02682 MatchingInlineAsm); 02683 } 02684 02685 // If one instruction matched with an invalid operand, report this as an 02686 // operand failure. 02687 if (std::count(std::begin(Match), std::end(Match), 02688 Match_InvalidOperand) == 1) { 02689 return Error(IDLoc, "invalid operand for instruction", EmptyRanges, 02690 MatchingInlineAsm); 02691 } 02692 02693 // If all of these were an outright failure, report it in a useless way. 02694 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges, 02695 MatchingInlineAsm); 02696 } 02697 02698 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) { 02699 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo); 02700 } 02701 02702 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) { 02703 StringRef IDVal = DirectiveID.getIdentifier(); 02704 if (IDVal == ".word") 02705 return ParseDirectiveWord(2, DirectiveID.getLoc()); 02706 else if (IDVal.startswith(".code")) 02707 return ParseDirectiveCode(IDVal, DirectiveID.getLoc()); 02708 else if (IDVal.startswith(".att_syntax")) { 02709 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02710 if (Parser.getTok().getString() == "prefix") 02711 Parser.Lex(); 02712 else if (Parser.getTok().getString() == "noprefix") 02713 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not " 02714 "supported: registers must have a " 02715 "'%' prefix in .att_syntax"); 02716 } 02717 getParser().setAssemblerDialect(0); 02718 return false; 02719 } else if (IDVal.startswith(".intel_syntax")) { 02720 getParser().setAssemblerDialect(1); 02721 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02722 if (Parser.getTok().getString() == "noprefix") 02723 Parser.Lex(); 02724 else if (Parser.getTok().getString() == "prefix") 02725 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not " 02726 "supported: registers must not have " 02727 "a '%' prefix in .intel_syntax"); 02728 } 02729 return false; 02730 } 02731 return true; 02732 } 02733 02734 /// ParseDirectiveWord 02735 /// ::= .word [ expression (, expression)* ] 02736 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 02737 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02738 for (;;) { 02739 const MCExpr *Value; 02740 if (getParser().parseExpression(Value)) 02741 return false; 02742 02743 getParser().getStreamer().EmitValue(Value, Size); 02744 02745 if (getLexer().is(AsmToken::EndOfStatement)) 02746 break; 02747 02748 // FIXME: Improve diagnostic. 02749 if (getLexer().isNot(AsmToken::Comma)) { 02750 Error(L, "unexpected token in directive"); 02751 return false; 02752 } 02753 Parser.Lex(); 02754 } 02755 } 02756 02757 Parser.Lex(); 02758 return false; 02759 } 02760 02761 /// ParseDirectiveCode 02762 /// ::= .code16 | .code32 | .code64 02763 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { 02764 if (IDVal == ".code16") { 02765 Parser.Lex(); 02766 if (!is16BitMode()) { 02767 SwitchMode(X86::Mode16Bit); 02768 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 02769 } 02770 } else if (IDVal == ".code32") { 02771 Parser.Lex(); 02772 if (!is32BitMode()) { 02773 SwitchMode(X86::Mode32Bit); 02774 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 02775 } 02776 } else if (IDVal == ".code64") { 02777 Parser.Lex(); 02778 if (!is64BitMode()) { 02779 SwitchMode(X86::Mode64Bit); 02780 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64); 02781 } 02782 } else { 02783 Error(L, "unknown directive " + IDVal); 02784 return false; 02785 } 02786 02787 return false; 02788 } 02789 02790 // Force static initialization. 02791 extern "C" void LLVMInitializeX86AsmParser() { 02792 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target); 02793 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target); 02794 } 02795 02796 #define GET_REGISTER_MATCHER 02797 #define GET_MATCHER_IMPLEMENTATION 02798 #define GET_SUBTARGET_FEATURE_NAME 02799 #include "X86GenAsmMatcher.inc"