1092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===// 2092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// 3092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// The LLVM Compiler Infrastructure 4092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// 5092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// This file is distributed under the University of Illinois Open Source 6092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// License. See LICENSE.TXT for details. 7092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// 8092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//===----------------------------------------------------------------------===// 9092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/X86BaseInfo.h" 114284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier#include "llvm/ADT/APFloat.h" 12f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper#include "llvm/ADT/STLExtras.h" 1333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallString.h" 1433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallVector.h" 1533d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringSwitch.h" 1633d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/Twine.h" 1730c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier#include "llvm/MC/MCContext.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCInst.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmLexer.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmParser.h" 22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCRegisterInfo.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCStreamer.h" 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSubtargetInfo.h" 26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSymbol.h" 27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCTargetAsmParser.h" 2816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h" 293e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 3009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar#include "llvm/Support/raw_ostream.h" 31ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 32092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm; 33092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 34092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace { 35c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand; 36092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 378ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosierstatic const char OpPrecedence[] = { 388ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 0, // IC_PLUS 398ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 0, // IC_MINUS 408ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 1, // IC_MULTIPLY 418ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 1, // IC_DIVIDE 428ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 2, // IC_RPAREN 438ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 3, // IC_LPAREN 448ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 0, // IC_IMM 458ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 0 // IC_REGISTER 468ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier}; 478ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 48dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelclass X86AsmParser : public MCTargetAsmParser { 49ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 5016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &Parser; 516a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier ParseInstructionInfo *InstInfo; 5216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate: 538ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier enum InfixCalculatorTok { 548ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC_PLUS = 0, 558ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC_MINUS, 568ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC_MULTIPLY, 578ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC_DIVIDE, 588ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC_RPAREN, 598ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC_LPAREN, 608ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC_IMM, 618ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC_REGISTER 628ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier }; 638ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 648ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier class InfixCalculator { 658ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier typedef std::pair< InfixCalculatorTok, int64_t > ICToken; 668ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier SmallVector<InfixCalculatorTok, 4> InfixOperatorStack; 678ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier SmallVector<ICToken, 4> PostfixStack; 688ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 698ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier public: 708ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier int64_t popOperand() { 718ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier assert (!PostfixStack.empty() && "Poped an empty stack!"); 728ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier ICToken Op = PostfixStack.pop_back_val(); 738ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier assert ((Op.first == IC_IMM || Op.first == IC_REGISTER) 748ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier && "Expected and immediate or register!"); 758ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier return Op.second; 768ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 778ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) { 788ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier assert ((Op == IC_IMM || Op == IC_REGISTER) && 798ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier "Unexpected operand!"); 808ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier PostfixStack.push_back(std::make_pair(Op, Val)); 818ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 828ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 838ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void popOperator() { InfixOperatorStack.pop_back_val(); } 848ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void pushOperator(InfixCalculatorTok Op) { 858ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // Push the new operator if the stack is empty. 868ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (InfixOperatorStack.empty()) { 878ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier InfixOperatorStack.push_back(Op); 888ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier return; 898ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 908ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 918ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // Push the new operator if it has a higher precedence than the operator 928ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // on the top of the stack or the operator on the top of the stack is a 938ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // left parentheses. 948ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier unsigned Idx = InfixOperatorStack.size() - 1; 958ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier InfixCalculatorTok StackOp = InfixOperatorStack[Idx]; 968ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) { 978ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier InfixOperatorStack.push_back(Op); 988ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier return; 998ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 1008ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 1018ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // The operator on the top of the stack has higher precedence than the 1028ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // new operator. 1038ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier unsigned ParenCount = 0; 1048ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier while (1) { 1058ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // Nothing to process. 1068ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (InfixOperatorStack.empty()) 1078ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 1088ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 1098ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier Idx = InfixOperatorStack.size() - 1; 1108ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier StackOp = InfixOperatorStack[Idx]; 1118ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount)) 1128ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 1138ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 1148ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // If we have an even parentheses count and we see a left parentheses, 1158ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // then stop processing. 1168ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (!ParenCount && StackOp == IC_LPAREN) 1178ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 1188ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 1198ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (StackOp == IC_RPAREN) { 1208ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier ++ParenCount; 1218ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier InfixOperatorStack.pop_back_val(); 1228ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } else if (StackOp == IC_LPAREN) { 1238ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier --ParenCount; 1248ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier InfixOperatorStack.pop_back_val(); 1258ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } else { 1268ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier InfixOperatorStack.pop_back_val(); 1278ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier PostfixStack.push_back(std::make_pair(StackOp, 0)); 1288ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 1298ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 1308ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // Push the new operator. 1318ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier InfixOperatorStack.push_back(Op); 1328ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 1338ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier int64_t execute() { 1348ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // Push any remaining operators onto the postfix stack. 1358ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier while (!InfixOperatorStack.empty()) { 1368ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val(); 1378ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (StackOp != IC_LPAREN && StackOp != IC_RPAREN) 1388ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier PostfixStack.push_back(std::make_pair(StackOp, 0)); 1398ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 1408ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 1418ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (PostfixStack.empty()) 1428ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier return 0; 1438ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 1448ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier SmallVector<ICToken, 16> OperandStack; 1458ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) { 1468ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier ICToken Op = PostfixStack[i]; 1478ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (Op.first == IC_IMM || Op.first == IC_REGISTER) { 1488ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier OperandStack.push_back(Op); 1498ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } else { 1508ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier assert (OperandStack.size() > 1 && "Too few operands."); 1518ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier int64_t Val; 1528ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier ICToken Op2 = OperandStack.pop_back_val(); 1538ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier ICToken Op1 = OperandStack.pop_back_val(); 1548ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (Op.first) { 1558ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 1568ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier report_fatal_error("Unexpected operator!"); 1578ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 1588ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IC_PLUS: 1598ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier Val = Op1.second + Op2.second; 1608ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier OperandStack.push_back(std::make_pair(IC_IMM, Val)); 1618ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 1628ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IC_MINUS: 1638ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier Val = Op1.second - Op2.second; 1648ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier OperandStack.push_back(std::make_pair(IC_IMM, Val)); 1658ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 1668ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IC_MULTIPLY: 1678ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 1688ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier "Multiply operation with an immediate and a register!"); 1698ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier Val = Op1.second * Op2.second; 1708ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier OperandStack.push_back(std::make_pair(IC_IMM, Val)); 1718ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 1728ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IC_DIVIDE: 1738ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 1748ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier "Divide operation with an immediate and a register!"); 1758ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier assert (Op2.second != 0 && "Division by zero!"); 1768ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier Val = Op1.second / Op2.second; 1778ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier OperandStack.push_back(std::make_pair(IC_IMM, Val)); 1788ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 1798ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 1808ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 1818ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 1828ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier assert (OperandStack.size() == 1 && "Expected a single result."); 1838ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier return OperandStack.pop_back_val().second; 1848ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 1858ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier }; 1868ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 1878ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier enum IntelExprState { 1888ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_PLUS, 1898ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_MINUS, 1908ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_MULTIPLY, 1918ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_DIVIDE, 1928ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_LBRAC, 1938ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_RBRAC, 1948ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_LPAREN, 1958ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_RPAREN, 1968ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_REGISTER, 1978ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_INTEGER, 1988ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_IDENTIFIER, 1998ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IES_ERROR 2008ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier }; 2018ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 2028ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier class IntelExprStateMachine { 203d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IntelExprState State, PrevState; 2048ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier unsigned BaseReg, IndexReg, TmpReg, Scale; 2054afa9b7ffc636104e225e815afc568af27a134daChad Rosier int64_t Imm; 2068ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier const MCExpr *Sym; 2078ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier StringRef SymName; 2084afa9b7ffc636104e225e815afc568af27a134daChad Rosier bool StopOnLBrac, AddImmPrefix; 2098ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier InfixCalculator IC; 2106804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo Info; 2118ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier public: 2124afa9b7ffc636104e225e815afc568af27a134daChad Rosier IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) : 213d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0), 214d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier Scale(1), Imm(imm), Sym(0), StopOnLBrac(stoponlbrac), 2156804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier AddImmPrefix(addimmprefix) { Info.clear(); } 2168ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 2178ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier unsigned getBaseReg() { return BaseReg; } 2188ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier unsigned getIndexReg() { return IndexReg; } 2198ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier unsigned getScale() { return Scale; } 2208ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier const MCExpr *getSym() { return Sym; } 2218ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier StringRef getSymName() { return SymName; } 2224afa9b7ffc636104e225e815afc568af27a134daChad Rosier int64_t getImm() { return Imm + IC.execute(); } 223a70d02ff2841d535875fe80bd3d3c25ba90613daChad Rosier bool isValidEndState() { 224a70d02ff2841d535875fe80bd3d3c25ba90613daChad Rosier return State == IES_RBRAC || State == IES_INTEGER; 225a70d02ff2841d535875fe80bd3d3c25ba90613daChad Rosier } 2264afa9b7ffc636104e225e815afc568af27a134daChad Rosier bool getStopOnLBrac() { return StopOnLBrac; } 2274afa9b7ffc636104e225e815afc568af27a134daChad Rosier bool getAddImmPrefix() { return AddImmPrefix; } 228d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier bool hadError() { return State == IES_ERROR; } 2294afa9b7ffc636104e225e815afc568af27a134daChad Rosier 2306804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo &getIdentifierInfo() { 2316804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier return Info; 2326804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier } 2336804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier 2348ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onPlus() { 235d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IntelExprState CurrState = State; 2368ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 2378ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 2388ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 2398ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 2408ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_INTEGER: 2418ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_RPAREN: 2428ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_REGISTER: 2438ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_PLUS; 2448ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC.pushOperator(IC_PLUS); 245d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 246d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // If we already have a BaseReg, then assume this is the IndexReg with 247d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // a scale of 1. 248d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (!BaseReg) { 249d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier BaseReg = TmpReg; 250d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } else { 251d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier assert (!IndexReg && "BaseReg/IndexReg already set!"); 252d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IndexReg = TmpReg; 253d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier Scale = 1; 254d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } 255d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } 2568ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 2578ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 258d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier PrevState = CurrState; 2598ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 2608ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onMinus() { 261d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IntelExprState CurrState = State; 2628ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 2638ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 2648ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 2658ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 2668ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_PLUS: 267d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_MULTIPLY: 268d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_DIVIDE: 2698ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_LPAREN: 2708ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_RPAREN: 271d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_LBRAC: 272d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_RBRAC: 273d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_INTEGER: 2748ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_REGISTER: 2758ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_MINUS; 276d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // Only push the minus operator if it is not a unary operator. 277d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (!(CurrState == IES_PLUS || CurrState == IES_MINUS || 278d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE || 279d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier CurrState == IES_LPAREN || CurrState == IES_LBRAC)) 280d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IC.pushOperator(IC_MINUS); 281d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 282d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // If we already have a BaseReg, then assume this is the IndexReg with 283d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // a scale of 1. 284d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (!BaseReg) { 285d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier BaseReg = TmpReg; 286d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } else { 287d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier assert (!IndexReg && "BaseReg/IndexReg already set!"); 288d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IndexReg = TmpReg; 289d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier Scale = 1; 290d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } 2918ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 2928ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 2938ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 294d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier PrevState = CurrState; 2958ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 2968ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onRegister(unsigned Reg) { 297d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IntelExprState CurrState = State; 2988ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 2998ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 3008ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 3018ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3028ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_PLUS: 3038ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_LPAREN: 3048ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_REGISTER; 3058ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier TmpReg = Reg; 3068ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC.pushOperand(IC_REGISTER); 3078ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 308d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_MULTIPLY: 309d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // Index Register - Scale * Register 310d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (PrevState == IES_INTEGER) { 311d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier assert (!IndexReg && "IndexReg already set!"); 312d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier State = IES_REGISTER; 313d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IndexReg = Reg; 314d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // Get the scale and replace the 'Scale * Register' with '0'. 315d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier Scale = IC.popOperand(); 316d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IC.pushOperand(IC_IMM); 317d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IC.popOperator(); 318d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } else { 319d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier State = IES_ERROR; 320d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } 3218ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3228ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 323d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier PrevState = CurrState; 3248ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 325e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) { 326c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier PrevState = State; 3278ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 3288ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 3298ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 3308ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3318ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_PLUS: 3328ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_MINUS: 3338ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_INTEGER; 3348ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier Sym = SymRef; 3358ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier SymName = SymRefName; 3368ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC.pushOperand(IC_IMM); 3378ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3388ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 3398ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 3408ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onInteger(int64_t TmpInt) { 341d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IntelExprState CurrState = State; 3428ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 3438ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 3448ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 3458ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3468ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_PLUS: 3478ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_MINUS: 3488ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_DIVIDE: 349d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_MULTIPLY: 3508ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_LPAREN: 3518ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_INTEGER; 352d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) { 353d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // Index Register - Register * Scale 354d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier assert (!IndexReg && "IndexReg already set!"); 355d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IndexReg = TmpReg; 356d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier Scale = TmpInt; 357d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // Get the scale and replace the 'Register * Scale' with '0'. 358d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IC.popOperator(); 359d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS || 360d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || 361d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier PrevState == IES_LPAREN || PrevState == IES_LBRAC) && 362d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier CurrState == IES_MINUS) { 363d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // Unary minus. No need to pop the minus operand because it was never 364d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // pushed. 365d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm. 366d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } else { 367d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IC.pushOperand(IC_IMM, TmpInt); 368d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } 3698ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3708ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 371d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier PrevState = CurrState; 3728ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 3738ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onStar() { 374c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier PrevState = State; 3758ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 3768ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 3778ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 3788ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3798ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_INTEGER: 3808ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_REGISTER: 3818ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_RPAREN: 3828ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_MULTIPLY; 3838ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC.pushOperator(IC_MULTIPLY); 3848ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3858ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 3868ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 3878ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onDivide() { 388c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier PrevState = State; 3898ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 3908ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 3918ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 3928ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3938ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_INTEGER: 394d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_RPAREN: 3958ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_DIVIDE; 3968ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC.pushOperator(IC_DIVIDE); 3978ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 3988ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 3998ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 4008ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onLBrac() { 401c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier PrevState = State; 4028ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 4038ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 4048ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 4058ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 4068ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_RBRAC: 4078ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_PLUS; 4088ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC.pushOperator(IC_PLUS); 4098ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 4108ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 4118ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 4128ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onRBrac() { 413d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IntelExprState CurrState = State; 4148ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 4158ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 4168ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 4178ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 4188ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_INTEGER: 4198ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_REGISTER: 420d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_RPAREN: 4218ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_RBRAC; 422d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 423d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // If we already have a BaseReg, then assume this is the IndexReg with 424d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // a scale of 1. 425d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (!BaseReg) { 426d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier BaseReg = TmpReg; 427d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } else { 428d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier assert (!IndexReg && "BaseReg/IndexReg already set!"); 429d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IndexReg = TmpReg; 430d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier Scale = 1; 431d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier } 4328ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 4338ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 4348ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 435d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier PrevState = CurrState; 4368ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 4378ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onLParen() { 438d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier IntelExprState CurrState = State; 4398ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 4408ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 4418ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 4428ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 4438ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_PLUS: 4448ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_MINUS: 4458ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_MULTIPLY: 4468ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_DIVIDE: 4478ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_LPAREN: 448c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier // FIXME: We don't handle this type of unary minus, yet. 449c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier if ((PrevState == IES_PLUS || PrevState == IES_MINUS || 450c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || 451c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier PrevState == IES_LPAREN || PrevState == IES_LBRAC) && 452c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier CurrState == IES_MINUS) { 453c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier State = IES_ERROR; 454c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier break; 455c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier } 4568ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_LPAREN; 4578ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC.pushOperator(IC_LPAREN); 4588ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 4598ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 460d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier PrevState = CurrState; 4618ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 4628ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier void onRParen() { 463c3a9574eed4420985533b7223fda094d3c191f68Chad Rosier PrevState = State; 4648ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier switch (State) { 4658ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier default: 4668ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_ERROR; 4678ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 4688ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_INTEGER: 469d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier case IES_REGISTER: 4708ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier case IES_RPAREN: 4718ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier State = IES_RPAREN; 4728ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier IC.pushOperator(IC_RPAREN); 4738ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier break; 4748ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 4758ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier } 4768ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier }; 4778ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 47816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &getParser() const { return Parser; } 479a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar 48016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmLexer &getLexer() const { return Parser.getLexer(); } 48116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 482d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner bool Error(SMLoc L, const Twine &Msg, 4835c332dbd30d9398ed25b30c3080506f7b8e92290Dmitri Gribenko ArrayRef<SMRange> Ranges = None, 4847a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier bool MatchingInlineAsm = false) { 4857a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier if (MatchingInlineAsm) return true; 486d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner return Parser.Error(L, Msg, Ranges); 487d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner } 48816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 489d37ad247cc04c2a436e537767ac1aec709901594Devang Patel X86Operand *ErrorOperand(SMLoc Loc, StringRef Msg) { 490d37ad247cc04c2a436e537767ac1aec709901594Devang Patel Error(Loc, Msg); 491d37ad247cc04c2a436e537767ac1aec709901594Devang Patel return 0; 492d37ad247cc04c2a436e537767ac1aec709901594Devang Patel } 493d37ad247cc04c2a436e537767ac1aec709901594Devang Patel 494309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner X86Operand *ParseOperand(); 4950a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel X86Operand *ParseATTOperand(); 4960a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel X86Operand *ParseIntelOperand(); 497bad493e9126fd601c01d4eb5bd9c30f517382e69Chad Rosier X86Operand *ParseIntelOffsetOfOperator(); 49889ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier X86Operand *ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp); 499bad493e9126fd601c01d4eb5bd9c30f517382e69Chad Rosier X86Operand *ParseIntelOperator(unsigned OpKind); 50053c9def43359f9b908565b28340e461ce5463009Chad Rosier X86Operand *ParseIntelMemOperand(unsigned SegReg, int64_t ImmDisp, 501dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier SMLoc StartLoc); 5028ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier X86Operand *ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End); 503d0dd5e413a53e4f743dece52b3e912749e2880aeChad Rosier X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc Start, 50453c9def43359f9b908565b28340e461ce5463009Chad Rosier int64_t ImmDisp, unsigned Size); 505e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier X86Operand *ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier, 50626f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall InlineAsmIdentifierInfo &Info, 50726f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall bool IsUnevaluatedOperand, SMLoc &End); 5086804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier 509eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc); 5109c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 5119458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier X86Operand *CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, 5129458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier unsigned BaseReg, unsigned IndexReg, 5139458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier unsigned Scale, SMLoc Start, SMLoc End, 5146804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier unsigned Size, StringRef Identifier, 5156804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo &Info); 516d3e7416de7f4aae708a5cc57a9fcc75ad43e1e96Chad Rosier 5179c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 518bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng bool ParseDirectiveCode(StringRef IDVal, SMLoc L); 5199c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 520b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel bool processInstruction(MCInst &Inst, 521b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 522b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel 52384125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 5247c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 52584125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MCStreamer &Out, unsigned &ErrorInfo, 52684125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchingInlineAsm); 5273246176838a47fa088b98772d4899063a9b7f731Chad Rosier 52896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi) 5290f5ab7c5f392d8207a4b0c5bf1f8b274a9f410dfKevin Enderby /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode. 53096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger bool isSrcOp(X86Operand &Op); 53196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 5320f5ab7c5f392d8207a4b0c5bf1f8b274a9f410dfKevin Enderby /// isDstOp - Returns true if operand is either (%rdi) or %es:(%rdi) 5330f5ab7c5f392d8207a4b0c5bf1f8b274a9f410dfKevin Enderby /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode. 53496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger bool isDstOp(X86Operand &Op); 53596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 53659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool is64BitMode() const { 537ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 538ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & X86::Mode64Bit) != 0; 539ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 540bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng void SwitchMode() { 541bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit)); 542bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng setAvailableFeatures(FB); 543bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 544ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 5456c8afad198688649ba7fc024bd5521d6b77a7ad5Chad Rosier bool isParsingIntelSyntax() { 5466c8afad198688649ba7fc024bd5521d6b77a7ad5Chad Rosier return getParser().getAssemblerDialect(); 5476c8afad198688649ba7fc024bd5521d6b77a7ad5Chad Rosier } 5486c8afad198688649ba7fc024bd5521d6b77a7ad5Chad Rosier 54954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// @name Auto-generated Matcher Functions 55054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// { 551c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 5520692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 5530692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc" 554c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 5550e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// } 55616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 55716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic: 558dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 5596a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier : MCTargetAsmParser(), STI(sti), Parser(parser), InstInfo(0) { 560c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 56154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Initialize the set of available features. 562ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 56354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 564bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 56516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 5666a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 5676a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier SMLoc NameLoc, 5689898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 5699c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 5709c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 57116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 57237dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace 57337dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 574e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions 575f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes/// { 576e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan 577b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name); 578e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan 579e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// } 58037dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 58176bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topperstatic bool isImmSExti16i8Value(uint64_t Value) { 582b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return (( Value <= 0x000000000000007FULL)|| 583b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)|| 584b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 585b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel} 586b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel 587b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmSExti32i8Value(uint64_t Value) { 588b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return (( Value <= 0x000000000000007FULL)|| 589b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)|| 590b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 591b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel} 592b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel 593b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmZExtu32u8Value(uint64_t Value) { 594b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return (Value <= 0x00000000000000FFULL); 595b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel} 596b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel 597b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmSExti64i8Value(uint64_t Value) { 598b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return (( Value <= 0x000000000000007FULL)|| 59976bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 600b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel} 601b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel 602b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmSExti64i32Value(uint64_t Value) { 603b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return (( Value <= 0x000000007FFFFFFFULL)|| 60476bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 605b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel} 60637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace { 60716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 60816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine 60916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction. 61045220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand { 6111f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner enum KindTy { 61220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Token, 61316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Register, 61416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Immediate, 615f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier Memory 61616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Kind; 61716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 61829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc StartLoc, EndLoc; 6195a719fcb5ea91ec4e7af6fc2e48ec31774a859ddChad Rosier SMLoc OffsetOfLoc; 620b976e407dcd7794eb9e151b81cdc8fbbe05e6bd8Chad Rosier StringRef SymName; 621248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier void *OpDecl; 622c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier bool AddressOf; 623f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 624a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct TokOp { 625a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const char *Data; 626a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Length; 627a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 628a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 629a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct RegOp { 630a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned RegNo; 631a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 632a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 633a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp { 634a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Val; 635a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 636a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 637a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp { 638a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned SegReg; 639a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Disp; 640a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned BaseReg; 641a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned IndexReg; 642a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Scale; 643a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Size; 644a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 645a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 64616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar union { 647a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct TokOp Tok; 648a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct RegOp Reg; 649a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp Imm; 650a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp Mem; 651dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar }; 65216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 6530a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner X86Operand(KindTy K, SMLoc Start, SMLoc End) 6541f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner : Kind(K), StartLoc(Start), EndLoc(End) {} 655c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 656b976e407dcd7794eb9e151b81cdc8fbbe05e6bd8Chad Rosier StringRef getSymName() { return SymName; } 657248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier void *getOpDecl() { return OpDecl; } 658b976e407dcd7794eb9e151b81cdc8fbbe05e6bd8Chad Rosier 6591f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner /// getStartLoc - Get the location of the first token of this operand. 6601f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner SMLoc getStartLoc() const { return StartLoc; } 6611f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner /// getEndLoc - Get the location of the last token of this operand. 6621f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner SMLoc getEndLoc() const { return EndLoc; } 6637d4e989da972c2e9c89dad2d4e8f6ff9e1c73394Chad Rosier /// getLocRange - Get the range between the first and last token of this 6647d4e989da972c2e9c89dad2d4e8f6ff9e1c73394Chad Rosier /// operand. 665d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 6665a719fcb5ea91ec4e7af6fc2e48ec31774a859ddChad Rosier /// getOffsetOfLoc - Get the location of the offset operator. 6675a719fcb5ea91ec4e7af6fc2e48ec31774a859ddChad Rosier SMLoc getOffsetOfLoc() const { return OffsetOfLoc; } 6681f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner 669b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const {} 670b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 67120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef getToken() const { 67220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(Kind == Token && "Invalid access!"); 67320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return StringRef(Tok.Data, Tok.Length); 67420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 675c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar void setTokenValue(StringRef Value) { 676c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar assert(Kind == Token && "Invalid access!"); 677c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Tok.Data = Value.data(); 678c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Tok.Length = Value.size(); 679c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar } 68020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 68116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned getReg() const { 68216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar assert(Kind == Register && "Invalid access!"); 68316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Reg.RegNo; 68416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 68516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 6868c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *getImm() const { 687022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Immediate && "Invalid access!"); 688022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Imm.Val; 689022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 690022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 6918c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *getMemDisp() const { 692022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 693022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Disp; 694022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 695022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemSegReg() const { 696022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 697022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.SegReg; 698022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 699022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemBaseReg() const { 700022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 701022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.BaseReg; 702022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 703022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemIndexReg() const { 704022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 705022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.IndexReg; 706022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 707022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemScale() const { 708022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 709022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Scale; 710022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 711022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 712a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar bool isToken() const {return Kind == Token; } 71320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 71420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isImm() const { return Kind == Immediate; } 715f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 71662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti16i8() const { 7175fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar if (!isImm()) 7185fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return false; 7195fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 72062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 72162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 72262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 72362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 72462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 72562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 72662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 72762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 728b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return isImmSExti16i8Value(CE->getValue()); 72962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar } 73062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti32i8() const { 73162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!isImm()) 73262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return false; 7335fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 73462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 73562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 73662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 73762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 73862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 73962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 74062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 74162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 742b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return isImmSExti32i8Value(CE->getValue()); 7435fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 744c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby bool isImmZExtu32u8() const { 745c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby if (!isImm()) 746c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby return false; 747c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby 748c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby // If this isn't a constant expr, just assume it fits and let relaxation 749c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby // handle it. 750c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 751c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby if (!CE) 752c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby return true; 753c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby 754c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby // Otherwise, check the value is in a range that makes sense for this 755c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby // extension. 756b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return isImmZExtu32u8Value(CE->getValue()); 757c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby } 75862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti64i8() const { 7591fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar if (!isImm()) 7601fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar return false; 7611fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar 76262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 76362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 76462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 76562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 76662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 76762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 76862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 76962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 770b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return isImmSExti64i8Value(CE->getValue()); 77162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar } 77262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti64i32() const { 77362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!isImm()) 77462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return false; 7751fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar 77662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 77762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 77862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 77962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 78062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 78162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 78262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 78362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 784b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel return isImmSExti64i32Value(CE->getValue()); 7851fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar } 7861fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar 787a703fb9e5e86ed29f7334736f7c085ec81a2006fChad Rosier bool isOffsetOf() const { 788c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier return OffsetOfLoc.getPointer(); 789a703fb9e5e86ed29f7334736f7c085ec81a2006fChad Rosier } 790a703fb9e5e86ed29f7334736f7c085ec81a2006fChad Rosier 791c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier bool needAddressOf() const { 792c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier return AddressOf; 793c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier } 794c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier 79520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isMem() const { return Kind == Memory; } 79636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier bool isMem8() const { 797f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier return Kind == Memory && (!Mem.Size || Mem.Size == 8); 798c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 79936b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier bool isMem16() const { 800f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier return Kind == Memory && (!Mem.Size || Mem.Size == 16); 801c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 80236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier bool isMem32() const { 803f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier return Kind == Memory && (!Mem.Size || Mem.Size == 32); 804c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 80536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier bool isMem64() const { 806f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier return Kind == Memory && (!Mem.Size || Mem.Size == 64); 807c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 80836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier bool isMem80() const { 809f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier return Kind == Memory && (!Mem.Size || Mem.Size == 80); 810c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 81136b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier bool isMem128() const { 812f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier return Kind == Memory && (!Mem.Size || Mem.Size == 128); 813c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 81436b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier bool isMem256() const { 815f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier return Kind == Memory && (!Mem.Size || Mem.Size == 256); 816c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 81720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 81875dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper bool isMemVX32() const { 81975dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 82075dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15; 82175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper } 82275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper bool isMemVY32() const { 82375dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 82475dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15; 82575dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper } 82675dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper bool isMemVX64() const { 82775dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 82875dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15; 82975dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper } 83075dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper bool isMemVY64() const { 83175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 83275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15; 83375dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper } 834c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky bool isMemVZ32() const { 835c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 836c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31; 837c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky } 838c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky bool isMemVZ64() const { 839c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 840c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31; 841c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky } 842c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky 843c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky bool isMem512() const { 844c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky return Kind == Memory && (!Mem.Size || Mem.Size == 512); 845c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky } 84675dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper 847b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar bool isAbsMem() const { 848b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 8497b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar !getMemIndexReg() && getMemScale() == 1; 850b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar } 851b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar 85220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isReg() const { return Kind == Register; } 85320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 8549c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 8559c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar // Add as immediates when possible. 8569c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 8579c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 8589c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar else 8599c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 8609c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar } 8619c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar 8625c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addRegOperands(MCInst &Inst, unsigned N) const { 86320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 86420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getReg())); 86520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 86620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 8675c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 86820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 8699c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar addExpr(Inst, getImm()); 87020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 87120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 87236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier void addMem8Operands(MCInst &Inst, unsigned N) const { 87336b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier addMemOperands(Inst, N); 874c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 87536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier void addMem16Operands(MCInst &Inst, unsigned N) const { 87636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier addMemOperands(Inst, N); 877c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 87836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier void addMem32Operands(MCInst &Inst, unsigned N) const { 87936b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier addMemOperands(Inst, N); 880c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 88136b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier void addMem64Operands(MCInst &Inst, unsigned N) const { 88236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier addMemOperands(Inst, N); 883c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 88436b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier void addMem80Operands(MCInst &Inst, unsigned N) const { 88536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier addMemOperands(Inst, N); 886c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 88736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier void addMem128Operands(MCInst &Inst, unsigned N) const { 88836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier addMemOperands(Inst, N); 889c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 89036b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier void addMem256Operands(MCInst &Inst, unsigned N) const { 89175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper addMemOperands(Inst, N); 89275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper } 89375dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper void addMemVX32Operands(MCInst &Inst, unsigned N) const { 89475dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper addMemOperands(Inst, N); 89575dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper } 89675dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper void addMemVY32Operands(MCInst &Inst, unsigned N) const { 89775dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper addMemOperands(Inst, N); 89875dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper } 89975dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper void addMemVX64Operands(MCInst &Inst, unsigned N) const { 90075dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper addMemOperands(Inst, N); 90175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper } 90275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper void addMemVY64Operands(MCInst &Inst, unsigned N) const { 90336b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier addMemOperands(Inst, N); 904c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel } 905c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel 906c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky void addMemVZ32Operands(MCInst &Inst, unsigned N) const { 907c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky addMemOperands(Inst, N); 908c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky } 909c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky void addMemVZ64Operands(MCInst &Inst, unsigned N) const { 910c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky addMemOperands(Inst, N); 911c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky } 912c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky void addMem512Operands(MCInst &Inst, unsigned N) const { 913c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky addMemOperands(Inst, N); 914c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky } 915c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky 9165c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addMemOperands(MCInst &Inst, unsigned N) const { 917ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar assert((N == 5) && "Invalid number of operands!"); 91820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 91920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(getMemScale())); 92020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); 9219c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar addExpr(Inst, getMemDisp()); 922ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 923ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar } 924ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar 925b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar void addAbsMemOperands(MCInst &Inst, unsigned N) const { 926b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar assert((N == 1) && "Invalid number of operands!"); 927b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby // Add as immediates when possible. 928b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 929b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 930b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby else 931b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); 932b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar } 933b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar 934b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner static X86Operand *CreateToken(StringRef Str, SMLoc Loc) { 9353ebe59c892051375623fea55e977ff559fdb3323Jordan Rose SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size()); 936f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer X86Operand *Res = new X86Operand(Token, Loc, EndLoc); 93729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Tok.Data = Str.data(); 93829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Tok.Length = Str.size(); 93920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return Res; 94020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 94120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 942c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, 943c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier bool AddressOf = false, 944b976e407dcd7794eb9e151b81cdc8fbbe05e6bd8Chad Rosier SMLoc OffsetOfLoc = SMLoc(), 945248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier StringRef SymName = StringRef(), 946248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier void *OpDecl = 0) { 9471f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc); 94829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Reg.RegNo = RegNo; 949c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier Res->AddressOf = AddressOf; 950c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier Res->OffsetOfLoc = OffsetOfLoc; 951b976e407dcd7794eb9e151b81cdc8fbbe05e6bd8Chad Rosier Res->SymName = SymName; 952248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier Res->OpDecl = OpDecl; 95329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner return Res; 95416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 95520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 956811ddf64afb03fb2262209034900f03fa797879cChad Rosier static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){ 957b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc); 95829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Imm.Val = Val; 95929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner return Res; 96016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 96120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 962b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar /// Create an absolute memory operand. 9634284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, 964248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier unsigned Size = 0, StringRef SymName = StringRef(), 965248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier void *OpDecl = 0) { 966b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 967b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.SegReg = 0; 968b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.Disp = Disp; 969b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.BaseReg = 0; 970b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.IndexReg = 0; 9717b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar Res->Mem.Scale = 1; 972c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel Res->Mem.Size = Size; 973248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier Res->SymName = SymName; 974248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier Res->OpDecl = OpDecl; 975248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier Res->AddressOf = false; 976b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return Res; 977b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar } 978b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar 979b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar /// Create a generalized memory operand. 980309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp, 981309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner unsigned BaseReg, unsigned IndexReg, 982c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel unsigned Scale, SMLoc StartLoc, SMLoc EndLoc, 983b976e407dcd7794eb9e151b81cdc8fbbe05e6bd8Chad Rosier unsigned Size = 0, 984248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier StringRef SymName = StringRef(), 985248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier void *OpDecl = 0) { 986b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar // We should never just have a displacement, that should be parsed as an 987b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar // absolute memory operand. 988c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 989c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar 990022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar // The scale should always be one of {1,2,4,8}. 991022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 99216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar "Invalid scale!"); 9930a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 99429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.SegReg = SegReg; 99529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.Disp = Disp; 99629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.BaseReg = BaseReg; 99729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.IndexReg = IndexReg; 99829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.Scale = Scale; 999c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel Res->Mem.Size = Size; 1000248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier Res->SymName = SymName; 1001248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier Res->OpDecl = OpDecl; 1002248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier Res->AddressOf = false; 100329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner return Res; 100416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 100516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 100616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 100737dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace. 100816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1009dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isSrcOp(X86Operand &Op) { 101059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI; 101196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 101296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger return (Op.isMem() && 101396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) && 101496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger isa<MCConstantExpr>(Op.Mem.Disp) && 101596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 101696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0); 101796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger} 101896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 1019dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isDstOp(X86Operand &Op) { 102059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI; 102196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 102236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier return Op.isMem() && 10230f5ab7c5f392d8207a4b0c5bf1f8b274a9f410dfKevin Enderby (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) && 102496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger isa<MCConstantExpr>(Op.Mem.Disp) && 102596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 102696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0; 102796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger} 102816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1029dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseRegister(unsigned &RegNo, 1030dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel SMLoc &StartLoc, SMLoc &EndLoc) { 103123075746a1418f281bc2a088ea85560bfd833599Chris Lattner RegNo = 0; 10328e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer const AsmToken &PercentTok = Parser.getTok(); 10338e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer StartLoc = PercentTok.getLoc(); 10348e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer 10358e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer // If we encounter a %, ignore it. This code handles registers with and 10368e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer // without the prefix, unprefixed registers can occur in cfi directives. 10378e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent)) 1038d37ad247cc04c2a436e537767ac1aec709901594Devang Patel Parser.Lex(); // Eat percent token. 10397b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby 104018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 10413ebe59c892051375623fea55e977ff559fdb3323Jordan Rose EndLoc = Tok.getEndLoc(); 10423ebe59c892051375623fea55e977ff559fdb3323Jordan Rose 10431aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel if (Tok.isNot(AsmToken::Identifier)) { 1044be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel if (isParsingIntelSyntax()) return true; 10455efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer return Error(StartLoc, "invalid register name", 10463ebe59c892051375623fea55e977ff559fdb3323Jordan Rose SMRange(StartLoc, EndLoc)); 10471aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel } 104816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 10497b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby RegNo = MatchRegisterName(Tok.getString()); 1050f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 105133d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner // If the match failed, try the register name as lowercase. 105233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner if (RegNo == 0) 1053590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer RegNo = MatchRegisterName(Tok.getString().lower()); 1054c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 10555de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng if (!is64BitMode()) { 10565de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng // FIXME: This should be done using Requires<In32BitMode> and 10575de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also 10585de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng // checked. 10595de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a 10605de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng // REX prefix. 10615de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng if (RegNo == X86::RIZ || 10625de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) || 10635de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng X86II::isX86_64NonExtLowByteReg(RegNo) || 10645de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng X86II::isX86_64ExtendedReg(RegNo)) 10655efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer return Error(StartLoc, "register %" 10665efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer + Tok.getString() + " is only available in 64-bit mode", 10673ebe59c892051375623fea55e977ff559fdb3323Jordan Rose SMRange(StartLoc, EndLoc)); 10685de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng } 10693c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes 107033d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. 107133d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) { 1072e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner RegNo = X86::ST0; 1073e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner Parser.Lex(); // Eat 'st' 1074f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 1075e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner // Check to see if we have '(4)' after %st. 1076e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner if (getLexer().isNot(AsmToken::LParen)) 1077e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return false; 1078e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner // Lex the paren. 1079e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner getParser().Lex(); 1080e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner 1081e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner const AsmToken &IntTok = Parser.getTok(); 1082e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner if (IntTok.isNot(AsmToken::Integer)) 1083e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return Error(IntTok.getLoc(), "expected stack index"); 1084e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner switch (IntTok.getIntVal()) { 1085e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 0: RegNo = X86::ST0; break; 1086e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 1: RegNo = X86::ST1; break; 1087e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 2: RegNo = X86::ST2; break; 1088e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 3: RegNo = X86::ST3; break; 1089e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 4: RegNo = X86::ST4; break; 1090e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 5: RegNo = X86::ST5; break; 1091e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 6: RegNo = X86::ST6; break; 1092e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 7: RegNo = X86::ST7; break; 1093e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner default: return Error(IntTok.getLoc(), "invalid stack index"); 1094e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner } 1095f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 1096e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner if (getParser().Lex().isNot(AsmToken::RParen)) 1097e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return Error(Parser.getTok().getLoc(), "expected ')'"); 1098f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 10993ebe59c892051375623fea55e977ff559fdb3323Jordan Rose EndLoc = Parser.getTok().getEndLoc(); 1100e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner Parser.Lex(); // Eat ')' 1101e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return false; 1102e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner } 1103f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 11043ebe59c892051375623fea55e977ff559fdb3323Jordan Rose EndLoc = Parser.getTok().getEndLoc(); 11053ebe59c892051375623fea55e977ff559fdb3323Jordan Rose 1106645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // If this is "db[0-7]", match it as an alias 1107645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // for dr[0-7]. 1108645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (RegNo == 0 && Tok.getString().size() == 3 && 1109645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner Tok.getString().startswith("db")) { 1110645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner switch (Tok.getString()[2]) { 1111645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '0': RegNo = X86::DR0; break; 1112645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '1': RegNo = X86::DR1; break; 1113645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '2': RegNo = X86::DR2; break; 1114645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '3': RegNo = X86::DR3; break; 1115645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '4': RegNo = X86::DR4; break; 1116645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '5': RegNo = X86::DR5; break; 1117645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '6': RegNo = X86::DR6; break; 1118645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '7': RegNo = X86::DR7; break; 1119645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 1120f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 1121645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (RegNo != 0) { 11223ebe59c892051375623fea55e977ff559fdb3323Jordan Rose EndLoc = Parser.getTok().getEndLoc(); 1123645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner Parser.Lex(); // Eat it. 1124645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner return false; 1125645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 1126645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 1127f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 11281aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel if (RegNo == 0) { 1129be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel if (isParsingIntelSyntax()) return true; 11305efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer return Error(StartLoc, "invalid register name", 11313ebe59c892051375623fea55e977ff559fdb3323Jordan Rose SMRange(StartLoc, EndLoc)); 11321aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel } 11330e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 1134b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 113516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 1136092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 1137092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 1138dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseOperand() { 1139be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel if (isParsingIntelSyntax()) 11400a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel return ParseIntelOperand(); 11410a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel return ParseATTOperand(); 11420a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel} 11430a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel 1144d37ad247cc04c2a436e537767ac1aec709901594Devang Patel/// getIntelMemOperandSize - Return intel memory operand size. 1145d37ad247cc04c2a436e537767ac1aec709901594Devang Patelstatic unsigned getIntelMemOperandSize(StringRef OpStr) { 114666b64bec6021e3f38af090429c7e41d1180df5a9Chad Rosier unsigned Size = StringSwitch<unsigned>(OpStr) 1147f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier .Cases("BYTE", "byte", 8) 1148f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier .Cases("WORD", "word", 16) 1149f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier .Cases("DWORD", "dword", 32) 1150f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier .Cases("QWORD", "qword", 64) 1151f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier .Cases("XWORD", "xword", 80) 1152f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier .Cases("XMMWORD", "xmmword", 128) 1153f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier .Cases("YMMWORD", "ymmword", 256) 115466b64bec6021e3f38af090429c7e41d1180df5a9Chad Rosier .Default(0); 115566b64bec6021e3f38af090429c7e41d1180df5a9Chad Rosier return Size; 11560a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel} 11570a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel 11589458f3ecee4d17ec9759a0351d2f339315cdebb1Chad RosierX86Operand * 11599458f3ecee4d17ec9759a0351d2f339315cdebb1Chad RosierX86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, 11609458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier unsigned BaseReg, unsigned IndexReg, 11619458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier unsigned Scale, SMLoc Start, SMLoc End, 11626804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier unsigned Size, StringRef Identifier, 11636804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo &Info){ 1164d50dc20f06d9cf95562899020f773cd9f8309786Chad Rosier if (isa<MCSymbolRefExpr>(Disp)) { 11659458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier // If this is not a VarDecl then assume it is a FuncDecl or some other label 11669458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier // reference. We need an 'r' constraint here, so we need to create register 11679458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier // operand to ensure proper matching. Just pick a GPR based on the size of 11689458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier // a pointer. 116944021515d76ec9b529f2adbc252552869b1357d5Chad Rosier if (!Info.IsVarDecl) { 11709458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX; 11719458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true, 1172248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier SMLoc(), Identifier, Info.OpDecl); 11739458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier } 11746804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier if (!Size) { 11756804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier Size = Info.Type * 8; // Size is in terms of bits in this context. 11766804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier if (Size) 11776804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start, 11786804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier /*Len=*/0, Size)); 11796804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier } 1180d3e7416de7f4aae708a5cc57a9fcc75ad43e1e96Chad Rosier } 1181d3e7416de7f4aae708a5cc57a9fcc75ad43e1e96Chad Rosier 1182d3e7416de7f4aae708a5cc57a9fcc75ad43e1e96Chad Rosier // When parsing inline assembly we set the base register to a non-zero value 11839458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier // if we don't know the actual value at this time. This is necessary to 1184d3e7416de7f4aae708a5cc57a9fcc75ad43e1e96Chad Rosier // get the matching correct in some cases. 11859458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier BaseReg = BaseReg ? BaseReg : 1; 11869458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start, 1187248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier End, Size, Identifier, Info.OpDecl); 1188d3e7416de7f4aae708a5cc57a9fcc75ad43e1e96Chad Rosier} 1189d3e7416de7f4aae708a5cc57a9fcc75ad43e1e96Chad Rosier 11903f42936af8be447c339a7c41bcd2b1468e39135bChad Rosierstatic void 11913f42936af8be447c339a7c41bcd2b1468e39135bChad RosierRewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites, 11923f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier StringRef SymName, int64_t ImmDisp, 11933f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier int64_t FinalImmDisp, SMLoc &BracLoc, 11943f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier SMLoc &StartInBrac, SMLoc &End) { 11953f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // Remove the '[' and ']' from the IR string. 11963f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier AsmRewrites->push_back(AsmRewrite(AOK_Skip, BracLoc, 1)); 11973f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1)); 11983f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier 11993f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // If ImmDisp is non-zero, then we parsed a displacement before the 12003f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp]) 12013f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // If ImmDisp doesn't match the displacement computed by the state machine 12023f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // then we have an additional displacement in the bracketed expression. 12033f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier if (ImmDisp != FinalImmDisp) { 12043f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier if (ImmDisp) { 12053f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // We have an immediate displacement before the bracketed expression. 12063f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // Adjust this to match the final immediate displacement. 12073f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier bool Found = false; 12083f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(), 12093f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier E = AsmRewrites->end(); I != E; ++I) { 12103f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier if ((*I).Loc.getPointer() > BracLoc.getPointer()) 12113f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier continue; 12124afa9b7ffc636104e225e815afc568af27a134daChad Rosier if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) { 12134afa9b7ffc636104e225e815afc568af27a134daChad Rosier assert (!Found && "ImmDisp already rewritten."); 12143f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier (*I).Kind = AOK_Imm; 12153f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer(); 12163f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier (*I).Val = FinalImmDisp; 12173f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier Found = true; 12183f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier break; 12193f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier } 12203f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier } 12213f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier assert (Found && "Unable to rewrite ImmDisp."); 1222b99052ce4a75a3eac638afcd5171903514aa28e9Duncan Sands (void)Found; 12233f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier } else { 12243f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // We have a symbolic and an immediate displacement, but no displacement 12254afa9b7ffc636104e225e815afc568af27a134daChad Rosier // before the bracketed expression. Put the immediate displacement 12263f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // before the bracketed expression. 12274afa9b7ffc636104e225e815afc568af27a134daChad Rosier AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp)); 12283f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier } 12293f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier } 12303f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // Remove all the ImmPrefix rewrites within the brackets. 12313f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(), 12323f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier E = AsmRewrites->end(); I != E; ++I) { 12333f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier if ((*I).Loc.getPointer() < StartInBrac.getPointer()) 12343f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier continue; 12353f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier if ((*I).Kind == AOK_ImmPrefix) 12363f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier (*I).Kind = AOK_Delete; 12373f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier } 12383f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier const char *SymLocPtr = SymName.data(); 12393f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // Skip everything before the symbol. 12403f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) { 12413f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier assert(Len > 0 && "Expected a non-negative length."); 12423f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len)); 12433f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier } 12443f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // Skip everything after the symbol. 12453f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) { 12463f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size()); 12473f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier assert(Len > 0 && "Expected a non-negative length."); 12483f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len)); 12493f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier } 12503f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier} 12513f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier 12528ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad RosierX86Operand * 12538ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad RosierX86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) { 12544284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier const AsmToken &Tok = Parser.getTok(); 125536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier 1256dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier bool Done = false; 1257dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier while (!Done) { 1258dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier bool UpdateLocLex = true; 1259dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier 1260dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an 1261dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier // identifier. Don't try an parse it as a register. 1262dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier if (Tok.getString().startswith(".")) 1263dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier break; 12644afa9b7ffc636104e225e815afc568af27a134daChad Rosier 12654afa9b7ffc636104e225e815afc568af27a134daChad Rosier // If we're parsing an immediate expression, we don't expect a '['. 12664afa9b7ffc636104e225e815afc568af27a134daChad Rosier if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac) 12674afa9b7ffc636104e225e815afc568af27a134daChad Rosier break; 1268dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier 1269dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier switch (getLexer().getKind()) { 1270dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier default: { 1271dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier if (SM.isValidEndState()) { 1272dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier Done = true; 1273dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier break; 1274dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier } 1275dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier return ErrorOperand(Tok.getLoc(), "Unexpected token!"); 1276dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier } 12774afa9b7ffc636104e225e815afc568af27a134daChad Rosier case AsmToken::EndOfStatement: { 12784afa9b7ffc636104e225e815afc568af27a134daChad Rosier Done = true; 12794afa9b7ffc636104e225e815afc568af27a134daChad Rosier break; 12804afa9b7ffc636104e225e815afc568af27a134daChad Rosier } 1281dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier case AsmToken::Identifier: { 12829458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier // This could be a register or a symbolic displacement. 12839458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier unsigned TmpReg; 1284e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier const MCExpr *Val; 1285b71ce6a4234f78aef982c3580eb19a90c40302c5Chad Rosier SMLoc IdentLoc = Tok.getLoc(); 1286b71ce6a4234f78aef982c3580eb19a90c40302c5Chad Rosier StringRef Identifier = Tok.getString(); 12879458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier if(!ParseRegister(TmpReg, IdentLoc, End)) { 1288dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier SM.onRegister(TmpReg); 1289dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier UpdateLocLex = false; 1290dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier break; 1291e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier } else { 1292e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier if (!isParsingInlineAsm()) { 1293e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier if (getParser().parsePrimaryExpr(Val, End)) 1294e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier return ErrorOperand(Tok.getLoc(), "Unexpected identifier!"); 1295e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier } else { 12966804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo(); 129726f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info, 129826f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall /*Unevaluated*/ false, End)) 1299e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier return Err; 1300e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier } 1301e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier SM.onIdentifierExpr(Val, Identifier); 1302dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier UpdateLocLex = false; 1303dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier break; 1304dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier } 1305dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier return ErrorOperand(Tok.getLoc(), "Unexpected identifier!"); 1306dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier } 1307e112453fc39b97147ea3f23bf0b1973cd9f739b1Chad Rosier case AsmToken::Integer: 13084afa9b7ffc636104e225e815afc568af27a134daChad Rosier if (isParsingInlineAsm() && SM.getAddImmPrefix()) 1309e112453fc39b97147ea3f23bf0b1973cd9f739b1Chad Rosier InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, 1310e112453fc39b97147ea3f23bf0b1973cd9f739b1Chad Rosier Tok.getLoc())); 1311e112453fc39b97147ea3f23bf0b1973cd9f739b1Chad Rosier SM.onInteger(Tok.getIntVal()); 1312dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier break; 1313dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier case AsmToken::Plus: SM.onPlus(); break; 1314dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier case AsmToken::Minus: SM.onMinus(); break; 1315dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier case AsmToken::Star: SM.onStar(); break; 1316e112453fc39b97147ea3f23bf0b1973cd9f739b1Chad Rosier case AsmToken::Slash: SM.onDivide(); break; 1317dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier case AsmToken::LBrac: SM.onLBrac(); break; 1318dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier case AsmToken::RBrac: SM.onRBrac(); break; 1319e112453fc39b97147ea3f23bf0b1973cd9f739b1Chad Rosier case AsmToken::LParen: SM.onLParen(); break; 1320e112453fc39b97147ea3f23bf0b1973cd9f739b1Chad Rosier case AsmToken::RParen: SM.onRParen(); break; 1321dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier } 1322d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier if (SM.hadError()) 1323d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier return ErrorOperand(Tok.getLoc(), "Unexpected token!"); 1324d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier 1325dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier if (!Done && UpdateLocLex) { 1326dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier End = Tok.getLoc(); 1327dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier Parser.Lex(); // Consume the token. 13282fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier } 13292fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier } 13308ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier return 0; 13318ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier} 13328ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 13338ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad RosierX86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start, 133453c9def43359f9b908565b28340e461ce5463009Chad Rosier int64_t ImmDisp, 13358ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier unsigned Size) { 13368ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier const AsmToken &Tok = Parser.getTok(); 13378ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc(); 13388ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (getLexer().isNot(AsmToken::LBrac)) 13398ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier return ErrorOperand(BracLoc, "Expected '[' token!"); 13408ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier Parser.Lex(); // Eat '[' 13418ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier 13428ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier SMLoc StartInBrac = Tok.getLoc(); 13438ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We 13448ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // may have already parsed an immediate displacement before the bracketed 13458ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier // expression. 13464afa9b7ffc636104e225e815afc568af27a134daChad Rosier IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true); 13478ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier if (X86Operand *Err = ParseIntelExpression(SM, End)) 13488ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier return Err; 1349c798cc42831150f678b080c0994c1cc024bae653Devang Patel 13509458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier const MCExpr *Disp; 13519458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier if (const MCExpr *Sym = SM.getSym()) { 13523f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier // A symbolic displacement. 13539458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier Disp = Sym; 13543f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier if (isParsingInlineAsm()) 13553f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(), 13568ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier ImmDisp, SM.getImm(), BracLoc, StartInBrac, 13573f42936af8be447c339a7c41bcd2b1468e39135bChad Rosier End); 13589458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier } else { 1359d58f773b96fdb5539d9da2192b8cf2ff6112239fChad Rosier // An immediate displacement only. 13608ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier Disp = MCConstantExpr::Create(SM.getImm(), getContext()); 13619458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier } 1362fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel 1363ddb53ef4a8aa526c293ff316c2134bf1629e6812Chad Rosier // Parse the dot operator (e.g., [ebx].foo.bar). 13645e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier if (Tok.getString().startswith(".")) { 13655e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier const MCExpr *NewDisp; 136689ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier if (X86Operand *Err = ParseIntelDotOperator(Disp, NewDisp)) 136789ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier return Err; 13685e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier 136937c04bcff28ae24aa84c44d73b1079bdab09c8c5Chad Rosier End = Tok.getEndLoc(); 13705e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier Parser.Lex(); // Eat the field. 13715e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier Disp = NewDisp; 13725e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier } 137322f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier 1374dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier int BaseReg = SM.getBaseReg(); 1375dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier int IndexReg = SM.getIndexReg(); 13769458f3ecee4d17ec9759a0351d2f339315cdebb1Chad Rosier int Scale = SM.getScale(); 13774acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier if (!isParsingInlineAsm()) { 13784acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier // handle [-42] 13794acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier if (!BaseReg && !IndexReg) { 13804acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier if (!SegReg) 13814acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier return X86Operand::CreateMem(Disp, Start, End, Size); 13824acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier else 13834acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size); 13844acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier } 13854acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start, 13864acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier End, Size); 1387dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier } 13884acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier 13896804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo(); 13904acef770cfb9622a5baf3e1c72e99c4fc84e48eaChad Rosier return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start, 13916804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier End, Size, SM.getSymName(), Info); 1392d37ad247cc04c2a436e537767ac1aec709901594Devang Patel} 1393d37ad247cc04c2a436e537767ac1aec709901594Devang Patel 139430c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier// Inline assembly may use variable names with namespace alias qualifiers. 1395e43624e345bcef09d4d57dca2c27d33cb6a34eddChad RosierX86Operand *X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val, 1396e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier StringRef &Identifier, 13976804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo &Info, 139826f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall bool IsUnevaluatedOperand, 1399e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier SMLoc &End) { 1400e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier assert (isParsingInlineAsm() && "Expected to be parsing inline assembly."); 1401e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier Val = 0; 140230c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier 14036804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier StringRef LineBuf(Identifier.data()); 140426f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand); 14056804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier 140630c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier const AsmToken &Tok = Parser.getTok(); 140726f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall 140826f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall // Advance the token stream until the end of the current token is 140926f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall // after the end of what the frontend claimed. 141026f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size(); 141126f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall while (true) { 141226f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall End = Tok.getEndLoc(); 141326f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall getLexer().Lex(); 141426f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall 141526f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?"); 141626f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall if (End.getPointer() == EndPtr) break; 14176804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier } 14186804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier 14196804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier // Create the symbol reference. 14206804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier Identifier = LineBuf; 142130c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier); 142230c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 1423e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier Val = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext()); 142430c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier return 0; 142530c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier} 142630c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier 1427d37ad247cc04c2a436e537767ac1aec709901594Devang Patel/// ParseIntelMemOperand - Parse intel style memory operand. 1428dd40e8cd54805aa81c8548ac8c87755c562c1723Chad RosierX86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg, 142953c9def43359f9b908565b28340e461ce5463009Chad Rosier int64_t ImmDisp, 1430dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier SMLoc Start) { 1431d37ad247cc04c2a436e537767ac1aec709901594Devang Patel const AsmToken &Tok = Parser.getTok(); 1432c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier SMLoc End; 1433d37ad247cc04c2a436e537767ac1aec709901594Devang Patel 1434d37ad247cc04c2a436e537767ac1aec709901594Devang Patel unsigned Size = getIntelMemOperandSize(Tok.getString()); 1435d37ad247cc04c2a436e537767ac1aec709901594Devang Patel if (Size) { 1436fea1f8ee7a707c1a37a69f92459046ede590d834Chad Rosier Parser.Lex(); // Eat operand size (e.g., byte, word). 1437fea1f8ee7a707c1a37a69f92459046ede590d834Chad Rosier if (Tok.getString() != "PTR" && Tok.getString() != "ptr") 1438fea1f8ee7a707c1a37a69f92459046ede590d834Chad Rosier return ErrorOperand(Start, "Expected 'PTR' or 'ptr' token!"); 1439fea1f8ee7a707c1a37a69f92459046ede590d834Chad Rosier Parser.Lex(); // Eat ptr. 1440d37ad247cc04c2a436e537767ac1aec709901594Devang Patel } 1441d37ad247cc04c2a436e537767ac1aec709901594Devang Patel 1442dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ]. 1443dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier if (getLexer().is(AsmToken::Integer)) { 1444dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier if (isParsingInlineAsm()) 1445dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, 144637c04bcff28ae24aa84c44d73b1079bdab09c8c5Chad Rosier Tok.getLoc())); 144753c9def43359f9b908565b28340e461ce5463009Chad Rosier int64_t ImmDisp = Tok.getIntVal(); 1448dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier Parser.Lex(); // Eat the integer. 1449dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier if (getLexer().isNot(AsmToken::LBrac)) 1450dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier return ErrorOperand(Start, "Expected '[' token!"); 14516b369ceb582f2deba9c252af301667975456ff86Chad Rosier return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size); 1452dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier } 1453dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier 1454c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier if (getLexer().is(AsmToken::LBrac)) 14556b369ceb582f2deba9c252af301667975456ff86Chad Rosier return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size); 14567c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel 14577c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel if (!ParseRegister(SegReg, Start, End)) { 14587c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel // Handel SegReg : [ ... ] 14597c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel if (getLexer().isNot(AsmToken::Colon)) 14607c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel return ErrorOperand(Start, "Expected ':' token!"); 14617c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel Parser.Lex(); // Eat : 14627c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel if (getLexer().isNot(AsmToken::LBrac)) 14637c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel return ErrorOperand(Start, "Expected '[' token!"); 14646b369ceb582f2deba9c252af301667975456ff86Chad Rosier return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size); 14657c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel } 1466d37ad247cc04c2a436e537767ac1aec709901594Devang Patel 1467e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier const MCExpr *Val; 1468e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier if (!isParsingInlineAsm()) { 1469e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier if (getParser().parsePrimaryExpr(Val, End)) 1470e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier return ErrorOperand(Tok.getLoc(), "Unexpected token!"); 147196d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier 1472e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier return X86Operand::CreateMem(Val, Start, End, Size); 1473e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier } 147430c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier 14756804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo Info; 1476e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier StringRef Identifier = Tok.getString(); 147726f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info, 147826f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall /*Unevaluated*/ false, End)) 147930c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosier return Err; 1480e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0, 14816804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier /*Scale=*/1, Start, End, Size, Identifier, Info); 1482c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier} 1483c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier 148422f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier/// Parse the '.' operator. 148589ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad RosierX86Operand *X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp, 148689ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier const MCExpr *&NewDisp) { 148737c04bcff28ae24aa84c44d73b1079bdab09c8c5Chad Rosier const AsmToken &Tok = Parser.getTok(); 148853c9def43359f9b908565b28340e461ce5463009Chad Rosier int64_t OrigDispVal, DotDispVal; 14895e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier 14905e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier // FIXME: Handle non-constant expressions. 149189ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp)) 14925e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier OrigDispVal = OrigDisp->getValue(); 149389ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier else 149489ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier return ErrorOperand(Tok.getLoc(), "Non-constant offsets are not supported!"); 149522f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier 149622f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier // Drop the '.'. 149722f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier StringRef DotDispStr = Tok.getString().drop_front(1); 149822f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier 149922f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier // .Imm gets lexed as a real. 150022f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier if (Tok.is(AsmToken::Real)) { 150122f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier APInt DotDisp; 150222f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier DotDispStr.getAsInteger(10, DotDisp); 15035e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier DotDispVal = DotDisp.getZExtValue(); 150489ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) { 1505ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier unsigned DotDisp; 1506ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.'); 1507ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second, 150889ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier DotDisp)) 150989ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier return ErrorOperand(Tok.getLoc(), "Unable to lookup field reference!"); 1510ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier DotDispVal = DotDisp; 151189ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier } else 151289ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier return ErrorOperand(Tok.getLoc(), "Unexpected token type!"); 151322f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier 1514ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) { 1515ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data()); 1516ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier unsigned Len = DotDispStr.size(); 1517ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier unsigned Val = OrigDispVal + DotDispVal; 1518ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len, 1519ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier Val)); 152022f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier } 15215e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier 152289ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext()); 152389ab4e4cd0627be8b779c6a1e7023e9ea58c4b09Chad Rosier return 0; 152422f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier} 152522f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier 1526c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier/// Parse the 'offset' operator. This operator is used to specify the 1527c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier/// location rather then the content of a variable. 1528bad493e9126fd601c01d4eb5bd9c30f517382e69Chad RosierX86Operand *X86AsmParser::ParseIntelOffsetOfOperator() { 1529df1087061c58c1734efd363715f221ac7d426cbbChad Rosier const AsmToken &Tok = Parser.getTok(); 1530bad493e9126fd601c01d4eb5bd9c30f517382e69Chad Rosier SMLoc OffsetOfLoc = Tok.getLoc(); 1531c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier Parser.Lex(); // Eat offset. 1532c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier 1533c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier const MCExpr *Val; 15346804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo Info; 1535df1087061c58c1734efd363715f221ac7d426cbbChad Rosier SMLoc Start = Tok.getLoc(), End; 15365ea1ea8db810aaf51f68e32119006629a2f06f30Chad Rosier StringRef Identifier = Tok.getString(); 153726f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info, 153826f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall /*Unevaluated*/ false, End)) 15395ea1ea8db810aaf51f68e32119006629a2f06f30Chad Rosier return Err; 15405ea1ea8db810aaf51f68e32119006629a2f06f30Chad Rosier 15416e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier // Don't emit the offset operator. 15426e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7)); 15436e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier 1544c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier // The offset operator will have an 'r' constraint, thus we need to create 1545c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier // register operand to ensure proper matching. Just pick a GPR based on 1546c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier // the size of a pointer. 1547c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX; 1548c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true, 1549248f4965d29362db182d642cdf5fcbeba5c997a4Chad Rosier OffsetOfLoc, Identifier, Info.OpDecl); 1550d37ad247cc04c2a436e537767ac1aec709901594Devang Patel} 1551d37ad247cc04c2a436e537767ac1aec709901594Devang Patel 1552505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosierenum IntelOperatorKind { 1553505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier IOK_LENGTH, 1554505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier IOK_SIZE, 1555505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier IOK_TYPE 1556505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier}; 1557505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier 1558505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator 1559505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// returns the number of elements in an array. It returns the value 1 for 1560505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// non-array variables. The SIZE operator returns the size of a C or C++ 1561505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// variable. A variable's size is the product of its LENGTH and TYPE. The 1562505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// TYPE operator returns the size of a C or C++ type or variable. If the 1563505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// variable is an array, TYPE returns the size of a single element. 1564bad493e9126fd601c01d4eb5bd9c30f517382e69Chad RosierX86Operand *X86AsmParser::ParseIntelOperator(unsigned OpKind) { 1565df1087061c58c1734efd363715f221ac7d426cbbChad Rosier const AsmToken &Tok = Parser.getTok(); 1566bad493e9126fd601c01d4eb5bd9c30f517382e69Chad Rosier SMLoc TypeLoc = Tok.getLoc(); 1567bad493e9126fd601c01d4eb5bd9c30f517382e69Chad Rosier Parser.Lex(); // Eat operator. 1568efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier 1569e43624e345bcef09d4d57dca2c27d33cb6a34eddChad Rosier const MCExpr *Val = 0; 15706804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier InlineAsmIdentifierInfo Info; 1571df1087061c58c1734efd363715f221ac7d426cbbChad Rosier SMLoc Start = Tok.getLoc(), End; 157233c55bdfed027313b05217d7049aa0e810da5caaChad Rosier StringRef Identifier = Tok.getString(); 157326f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info, 157426f3bb997f0c5d7951d61d28a26ca6ac1481090cJohn McCall /*Unevaluated*/ true, End)) 157533c55bdfed027313b05217d7049aa0e810da5caaChad Rosier return Err; 1576efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier 157744021515d76ec9b529f2adbc252552869b1357d5Chad Rosier unsigned CVal = 0; 15786804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier switch(OpKind) { 15796804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier default: llvm_unreachable("Unexpected operand kind!"); 15806804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier case IOK_LENGTH: CVal = Info.Length; break; 15816804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier case IOK_SIZE: CVal = Info.Size; break; 15826804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier case IOK_TYPE: CVal = Info.Type; break; 15836804971dcfbba1dcf7b0f8335588ba2ab6b0f073Chad Rosier } 1584efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier 1585efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier // Rewrite the type operator and the C or C++ type or variable in terms of an 1586efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier // immediate. E.g. TYPE foo -> $$4 1587efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier unsigned Len = End.getPointer() - TypeLoc.getPointer(); 1588505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal)); 1589efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier 1590505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext()); 1591811ddf64afb03fb2262209034900f03fa797879cChad Rosier return X86Operand::CreateImm(Imm, Start, End); 1592efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier} 1593efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier 1594d37ad247cc04c2a436e537767ac1aec709901594Devang PatelX86Operand *X86AsmParser::ParseIntelOperand() { 159537c04bcff28ae24aa84c44d73b1079bdab09c8c5Chad Rosier const AsmToken &Tok = Parser.getTok(); 159637c04bcff28ae24aa84c44d73b1079bdab09c8c5Chad Rosier SMLoc Start = Tok.getLoc(), End; 1597505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier 1598505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier // Offset, length, type and size operators. 1599505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier if (isParsingInlineAsm()) { 16003031ac01311e474cb0c25fe3f6d2e86cac220485Chad Rosier StringRef AsmTokStr = Tok.getString(); 1601505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier if (AsmTokStr == "offset" || AsmTokStr == "OFFSET") 1602bad493e9126fd601c01d4eb5bd9c30f517382e69Chad Rosier return ParseIntelOffsetOfOperator(); 1603505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier if (AsmTokStr == "length" || AsmTokStr == "LENGTH") 1604bad493e9126fd601c01d4eb5bd9c30f517382e69Chad Rosier return ParseIntelOperator(IOK_LENGTH); 1605505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier if (AsmTokStr == "size" || AsmTokStr == "SIZE") 1606bad493e9126fd601c01d4eb5bd9c30f517382e69Chad Rosier return ParseIntelOperator(IOK_SIZE); 1607505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier if (AsmTokStr == "type" || AsmTokStr == "TYPE") 1608bad493e9126fd601c01d4eb5bd9c30f517382e69Chad Rosier return ParseIntelOperator(IOK_TYPE); 1609505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier } 1610505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier 1611505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier // Immediate. 16124afa9b7ffc636104e225e815afc568af27a134daChad Rosier if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) || 16134afa9b7ffc636104e225e815afc568af27a134daChad Rosier getLexer().is(AsmToken::LParen)) { 16144afa9b7ffc636104e225e815afc568af27a134daChad Rosier AsmToken StartTok = Tok; 16154afa9b7ffc636104e225e815afc568af27a134daChad Rosier IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true, 16164afa9b7ffc636104e225e815afc568af27a134daChad Rosier /*AddImmPrefix=*/false); 16174afa9b7ffc636104e225e815afc568af27a134daChad Rosier if (X86Operand *Err = ParseIntelExpression(SM, End)) 16184afa9b7ffc636104e225e815afc568af27a134daChad Rosier return Err; 16194afa9b7ffc636104e225e815afc568af27a134daChad Rosier 16204afa9b7ffc636104e225e815afc568af27a134daChad Rosier int64_t Imm = SM.getImm(); 16214afa9b7ffc636104e225e815afc568af27a134daChad Rosier if (isParsingInlineAsm()) { 16224afa9b7ffc636104e225e815afc568af27a134daChad Rosier unsigned Len = Tok.getLoc().getPointer() - Start.getPointer(); 16234afa9b7ffc636104e225e815afc568af27a134daChad Rosier if (StartTok.getString().size() == Len) 16244afa9b7ffc636104e225e815afc568af27a134daChad Rosier // Just add a prefix if this wasn't a complex immediate expression. 1625811ddf64afb03fb2262209034900f03fa797879cChad Rosier InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start)); 16264afa9b7ffc636104e225e815afc568af27a134daChad Rosier else 16274afa9b7ffc636104e225e815afc568af27a134daChad Rosier // Otherwise, rewrite the complex expression as a single immediate. 16284afa9b7ffc636104e225e815afc568af27a134daChad Rosier InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm)); 16294afa9b7ffc636104e225e815afc568af27a134daChad Rosier } 1630dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier 16314afa9b7ffc636104e225e815afc568af27a134daChad Rosier if (getLexer().isNot(AsmToken::LBrac)) { 16324afa9b7ffc636104e225e815afc568af27a134daChad Rosier const MCExpr *ImmExpr = MCConstantExpr::Create(Imm, getContext()); 16334afa9b7ffc636104e225e815afc568af27a134daChad Rosier return X86Operand::CreateImm(ImmExpr, Start, End); 1634d37ad247cc04c2a436e537767ac1aec709901594Devang Patel } 16354afa9b7ffc636104e225e815afc568af27a134daChad Rosier 16364afa9b7ffc636104e225e815afc568af27a134daChad Rosier // Only positive immediates are valid. 16374afa9b7ffc636104e225e815afc568af27a134daChad Rosier if (Imm < 0) 16384afa9b7ffc636104e225e815afc568af27a134daChad Rosier return ErrorOperand(Start, "expected a positive immediate displacement " 16394afa9b7ffc636104e225e815afc568af27a134daChad Rosier "before bracketed expr."); 16404afa9b7ffc636104e225e815afc568af27a134daChad Rosier 16414afa9b7ffc636104e225e815afc568af27a134daChad Rosier // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ]. 16424afa9b7ffc636104e225e815afc568af27a134daChad Rosier return ParseIntelMemOperand(/*SegReg=*/0, Imm, Start); 1643d37ad247cc04c2a436e537767ac1aec709901594Devang Patel } 1644d37ad247cc04c2a436e537767ac1aec709901594Devang Patel 1645505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier // Register. 16461aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel unsigned RegNo = 0; 16471aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel if (!ParseRegister(RegNo, Start, End)) { 16485b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier // If this is a segment register followed by a ':', then this is the start 16495b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier // of a memory reference, otherwise this is a normal register reference. 16505b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier if (getLexer().isNot(AsmToken::Colon)) 16513ebe59c892051375623fea55e977ff559fdb3323Jordan Rose return X86Operand::CreateReg(RegNo, Start, End); 16525b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier 16535b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier getParser().Lex(); // Eat the colon. 1654dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier return ParseIntelMemOperand(/*SegReg=*/RegNo, /*Disp=*/0, Start); 16550a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel } 16560a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel 1657505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier // Memory operand. 1658dd40e8cd54805aa81c8548ac8c87755c562c1723Chad Rosier return ParseIntelMemOperand(/*SegReg=*/0, /*Disp=*/0, Start); 16590a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel} 16600a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel 1661dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseATTOperand() { 166216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar switch (getLexer().getKind()) { 166316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar default: 1664eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // Parse a memory operand with no segment register. 1665eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner return ParseMemOperand(0, Parser.getTok().getLoc()); 166623075746a1418f281bc2a088ea85560bfd833599Chris Lattner case AsmToken::Percent: { 1667eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // Read the register. 166823075746a1418f281bc2a088ea85560bfd833599Chris Lattner unsigned RegNo; 166929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc Start, End; 167029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (ParseRegister(RegNo, Start, End)) return 0; 16713c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes if (RegNo == X86::EIZ || RegNo == X86::RIZ) { 16725efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer Error(Start, "%eiz and %riz can only be used as index registers", 16735efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer SMRange(Start, End)); 16743c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes return 0; 16753c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes } 1676f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 1677eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // If this is a segment register followed by a ':', then this is the start 1678eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // of a memory reference, otherwise this is a normal register reference. 1679eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner if (getLexer().isNot(AsmToken::Colon)) 1680eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner return X86Operand::CreateReg(RegNo, Start, End); 1681f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 1682eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner getParser().Lex(); // Eat the colon. 1683eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner return ParseMemOperand(RegNo, Start); 168423075746a1418f281bc2a088ea85560bfd833599Chris Lattner } 168516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar case AsmToken::Dollar: { 168616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // $42 -> immediate. 168718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Start = Parser.getTok().getLoc(), End; 1688b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 16898c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Val; 1690cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(Val, End)) 1691309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 1692b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner return X86Operand::CreateImm(Val, Start, End); 169316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 169416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 169516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar} 169616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1697eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix 1698eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present. 1699dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) { 1700f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 170116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // We have to disambiguate a parenthesized expression "(4+5)" from the start 170216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 170375f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner // only way to do this without lookahead is to eat the '(' and see what is 170475f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner // after it. 17058c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); 170616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 170754482b472a888c9efe003ad694ecf47b21878f0eChris Lattner SMLoc ExprEnd; 1708cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(Disp, ExprEnd)) return 0; 1709f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 171016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 171116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 171216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 1713c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 1714309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (SegReg == 0) 1715b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return X86Operand::CreateMem(Disp, MemStart, ExprEnd); 17160a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 171716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 1718f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 171916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 1720b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 172116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 172216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Okay, we have a '('. We don't know if this is an expression or not, but 172316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // so we have to eat the ( to see beyond it. 172418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc LParenLoc = Parser.getTok().getLoc(); 1725b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the '('. 1726f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 17277b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { 172816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Nothing to do here, fall into the code below with the '(' part of the 172916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory operand consumed. 173016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 1731b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner SMLoc ExprEnd; 1732f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 173316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // It must be an parenthesized expression, parse it now. 1734cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseParenExpression(Disp, ExprEnd)) 1735309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 1736f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 173716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 173816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 173916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 1740c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 1741309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (SegReg == 0) 1742b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd); 17430a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 174416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 1745f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 174616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 1747b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 174816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 174916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 1750f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 175116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // If we reached here, then we just ate the ( of the memory operand. Process 175216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // the rest of the memory operand. 1753022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 175484faf659125cb354794e457fa5a8a8daad84760dKevin Enderby SMLoc IndexLoc; 1755f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 175629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (getLexer().is(AsmToken::Percent)) { 17575efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer SMLoc StartLoc, EndLoc; 17585efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer if (ParseRegister(BaseReg, StartLoc, EndLoc)) return 0; 17593c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) { 17605efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer Error(StartLoc, "eiz and riz can only be used as index registers", 17615efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer SMRange(StartLoc, EndLoc)); 17623c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes return 0; 17633c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes } 176429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner } 1765f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 176616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Comma)) { 1767b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 176884faf659125cb354794e457fa5a8a8daad84760dKevin Enderby IndexLoc = Parser.getTok().getLoc(); 176916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 177016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Following the comma we should have either an index register, or a scale 177116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // value. We don't support the later form, but we want to parse it 177216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // correctly. 177316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // 177416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Not that even though it would be completely consistent to support syntax 17753c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. 17767b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby if (getLexer().is(AsmToken::Percent)) { 177729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc L; 177829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (ParseRegister(IndexReg, L, L)) return 0; 1779f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 178016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 178116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse the scale amount: 178216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // ::= ',' [scale-expression] 1783309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (getLexer().isNot(AsmToken::Comma)) { 178418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan Error(Parser.getTok().getLoc(), 1785309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner "expected comma in scale expression"); 1786309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 1787309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner } 1788b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 178916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 179016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 179118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 179216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 179316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t ScaleVal; 1794cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(ScaleVal)){ 179558dfaa14651f36fc9fce2031eb011e65ae267b9fKevin Enderby Error(Loc, "expected scale expression"); 1796309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 179776bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper } 1798f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 179916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Validate the scale amount. 1800309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){ 1801309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 1802309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 1803309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner } 180416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Scale = (unsigned)ScaleVal; 180516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 180616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 180716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else if (getLexer().isNot(AsmToken::RParen)) { 1808ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar // A scale amount without an index is ignored. 180916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // index. 181018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 181116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 181216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t Value; 1813cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(Value)) 1814309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 1815f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 1816ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar if (Value != 1) 1817ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar Warning(Loc, "scale factor without index register is ignored"); 1818ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar Scale = 1; 181916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 182016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 1821f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 182216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 1823309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (getLexer().isNot(AsmToken::RParen)) { 182418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan Error(Parser.getTok().getLoc(), "unexpected token in memory operand"); 1825309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 1826309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner } 18273ebe59c892051375623fea55e977ff559fdb3323Jordan Rose SMLoc MemEnd = Parser.getTok().getEndLoc(); 1828b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the ')'. 1829f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 183084faf659125cb354794e457fa5a8a8daad84760dKevin Enderby // If we have both a base register and an index register make sure they are 183184faf659125cb354794e457fa5a8a8daad84760dKevin Enderby // both 64-bit or 32-bit registers. 18321f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren // To support VSIB, IndexReg can be 128-bit or 256-bit registers. 183384faf659125cb354794e457fa5a8a8daad84760dKevin Enderby if (BaseReg != 0 && IndexReg != 0) { 183484faf659125cb354794e457fa5a8a8daad84760dKevin Enderby if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) && 18351f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 18361f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) && 183784faf659125cb354794e457fa5a8a8daad84760dKevin Enderby IndexReg != X86::RIZ) { 183884faf659125cb354794e457fa5a8a8daad84760dKevin Enderby Error(IndexLoc, "index register is 32-bit, but base register is 64-bit"); 183984faf659125cb354794e457fa5a8a8daad84760dKevin Enderby return 0; 184084faf659125cb354794e457fa5a8a8daad84760dKevin Enderby } 184184faf659125cb354794e457fa5a8a8daad84760dKevin Enderby if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) && 18421f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 18431f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) && 184484faf659125cb354794e457fa5a8a8daad84760dKevin Enderby IndexReg != X86::EIZ){ 184584faf659125cb354794e457fa5a8a8daad84760dKevin Enderby Error(IndexLoc, "index register is 64-bit, but base register is 32-bit"); 184684faf659125cb354794e457fa5a8a8daad84760dKevin Enderby return 0; 184784faf659125cb354794e457fa5a8a8daad84760dKevin Enderby } 184884faf659125cb354794e457fa5a8a8daad84760dKevin Enderby } 184984faf659125cb354794e457fa5a8a8daad84760dKevin Enderby 18500a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, 18510a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner MemStart, MemEnd); 1852dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar} 1853dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar 1854dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser:: 18556a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 18569898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 18576a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier InstInfo = &Info; 1858693173feefaa326fad0e386470846fb3199ba381Chris Lattner StringRef PatchedName = Name; 185939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar 1860d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner // FIXME: Hack to recognize setneb as setne. 1861d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner if (PatchedName.startswith("set") && PatchedName.endswith("b") && 1862d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner PatchedName != "setb" && PatchedName != "setnb") 1863d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner PatchedName = PatchedName.substr(0, Name.size()-1); 186436b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier 186539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}. 186639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar const MCExpr *ExtraImmOp = 0; 1867428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) && 186839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar (PatchedName.endswith("ss") || PatchedName.endswith("sd") || 186939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { 18709e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper bool IsVCMP = PatchedName[0] == 'v'; 1871428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes unsigned SSECCIdx = IsVCMP ? 4 : 3; 187239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar unsigned SSEComparisonCode = StringSwitch<unsigned>( 1873428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName.slice(SSECCIdx, PatchedName.size() - 2)) 18749e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("eq", 0x00) 18759e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("lt", 0x01) 18769e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("le", 0x02) 18779e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("unord", 0x03) 18789e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("neq", 0x04) 18799e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("nlt", 0x05) 18809e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("nle", 0x06) 18819e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("ord", 0x07) 18829e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper /* AVX only from here */ 18839e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("eq_uq", 0x08) 18849e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper .Case("nge", 0x09) 1885cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ngt", 0x0A) 1886cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("false", 0x0B) 1887cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq_oq", 0x0C) 1888cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ge", 0x0D) 1889cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("gt", 0x0E) 1890cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("true", 0x0F) 1891cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq_os", 0x10) 1892cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("lt_oq", 0x11) 1893cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("le_oq", 0x12) 1894cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("unord_s", 0x13) 1895cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq_us", 0x14) 1896cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nlt_uq", 0x15) 1897cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nle_uq", 0x16) 1898cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ord_s", 0x17) 1899cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq_us", 0x18) 1900cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nge_uq", 0x19) 1901cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ngt_uq", 0x1A) 1902cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("false_os", 0x1B) 1903cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq_os", 0x1C) 1904cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ge_oq", 0x1D) 1905cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("gt_oq", 0x1E) 1906cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("true_us", 0x1F) 190739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar .Default(~0U); 19089e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper if (SSEComparisonCode != ~0U && (IsVCMP || SSEComparisonCode < 8)) { 190939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode, 191039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar getParser().getContext()); 191139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar if (PatchedName.endswith("ss")) { 1912428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmpss" : "cmpss"; 191339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } else if (PatchedName.endswith("sd")) { 1914428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmpsd" : "cmpsd"; 191539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } else if (PatchedName.endswith("ps")) { 1916428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmpps" : "cmpps"; 191739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } else { 191839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar assert(PatchedName.endswith("pd") && "Unexpected mnemonic!"); 1919428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmppd" : "cmppd"; 192039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } 192139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } 192239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } 1923f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes 19241b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); 192516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1926885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel if (ExtraImmOp && !isParsingIntelSyntax()) 192739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); 1928c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 19292544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // Determine whether this is an instruction prefix. 19302544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner bool isPrefix = 1931693173feefaa326fad0e386470846fb3199ba381Chris Lattner Name == "lock" || Name == "rep" || 1932693173feefaa326fad0e386470846fb3199ba381Chris Lattner Name == "repe" || Name == "repz" || 1933beb6898df8f96ccea4ae147587479b507bb3e491Rafael Espindola Name == "repne" || Name == "repnz" || 1934bfd2d26159c87262fcf462ea442f99478a2093c9Rafael Espindola Name == "rex64" || Name == "data16"; 1935c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 1936c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 19372544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // This does the actual operand parsing. Don't parse any more if we have a 19382544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we 19392544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // just want to parse the "lock" as the first instruction and the "incl" as 19402544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // the next one. 19412544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) { 19420db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar 19430db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar // Parse '*' modifier. 19440db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar if (getLexer().is(AsmToken::Star)) { 194518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 1946b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner Operands.push_back(X86Operand::CreateToken("*", Loc)); 1947b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the star. 19480db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar } 19490db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar 195016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Read the first operand. 1951309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (X86Operand *Op = ParseOperand()) 1952309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner Operands.push_back(Op); 1953cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner else { 1954cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 195516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 1956cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 195739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar 195816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar while (getLexer().is(AsmToken::Comma)) { 1959b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 196016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 196116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse and remember the operand. 1962309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (X86Operand *Op = ParseOperand()) 1963309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner Operands.push_back(Op); 1964cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner else { 1965cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 196616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 1967cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 196816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 1969c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 1970cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 1971c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner SMLoc Loc = getLexer().getLoc(); 1972cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1973c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner return Error(Loc, "unexpected token in argument list"); 1974cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 197516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 1976c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 19772544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner if (getLexer().is(AsmToken::EndOfStatement)) 19782544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner Parser.Lex(); // Consume the EndOfStatement 197976331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby else if (isPrefix && getLexer().is(AsmToken::Slash)) 198076331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby Parser.Lex(); // Consume the prefix separator Slash 198116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1982885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel if (ExtraImmOp && isParsingIntelSyntax()) 1983885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); 1984885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel 198598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner // This is a terrible hack to handle "out[bwl]? %al, (%dx)" -> 198698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner // "outb %al, %dx". Out doesn't take a memory form, but this is a widely 198798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner // documented form in various unofficial manuals, so a lot of code uses it. 198898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") && 198998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner Operands.size() == 3) { 199098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner X86Operand &Op = *(X86Operand*)Operands.back(); 199198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner if (Op.isMem() && Op.Mem.SegReg == 0 && 199298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner isa<MCConstantExpr>(Op.Mem.Disp) && 199398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 199498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 199598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner SMLoc Loc = Op.getEndLoc(); 199698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 199798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner delete &Op; 199898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 199998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 200000743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al". 200100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") && 200200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger Operands.size() == 3) { 200300743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 200400743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger if (Op.isMem() && Op.Mem.SegReg == 0 && 200500743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger isa<MCConstantExpr>(Op.Mem.Disp) && 200600743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 200700743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 200800743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger SMLoc Loc = Op.getEndLoc(); 200900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 201000743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger delete &Op; 201100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger } 201200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger } 201396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]" 201496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("ins") && Operands.size() == 3 && 201596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "insb" || Name == "insw" || Name == "insl")) { 201696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 201796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 201896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) { 201996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 202096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 202196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op; 202296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op2; 202396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 202496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 202596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 202696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]" 202796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("outs") && Operands.size() == 3 && 202896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "outsb" || Name == "outsw" || Name == "outsl")) { 202996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 203096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 203196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) { 203296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 203396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 203496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op; 203596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op2; 203696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 203796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 203896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 203996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]" 204096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("movs") && Operands.size() == 3 && 204196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "movsb" || Name == "movsw" || Name == "movsl" || 204259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng (is64BitMode() && Name == "movsq"))) { 204396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 204496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 204596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (isSrcOp(Op) && isDstOp(Op2)) { 204696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 204796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 204896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op; 204996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op2; 205096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 205196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 205296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]" 205396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("lods") && Operands.size() == 3 && 205496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "lods" || Name == "lodsb" || Name == "lodsw" || 205559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) { 205696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 205796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]); 205896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (isSrcOp(*Op1) && Op2->isReg()) { 205996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger const char *ins; 206096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger unsigned reg = Op2->getReg(); 206196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger bool isLods = Name == "lods"; 206296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (reg == X86::AL && (isLods || Name == "lodsb")) 206396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "lodsb"; 206496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::AX && (isLods || Name == "lodsw")) 206596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "lodsw"; 206696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::EAX && (isLods || Name == "lodsl")) 206796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "lodsl"; 206896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::RAX && (isLods || Name == "lodsq")) 206996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "lodsq"; 207096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else 207196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = NULL; 207296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (ins != NULL) { 207396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 207496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 207596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete Op1; 207696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete Op2; 207796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name != ins) 207896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger static_cast<X86Operand*>(Operands[0])->setTokenValue(ins); 207996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 208096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 208196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 208296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]" 208396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("stos") && Operands.size() == 3 && 208496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "stos" || Name == "stosb" || Name == "stosw" || 208559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Name == "stosl" || (is64BitMode() && Name == "stosq"))) { 208696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 208796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]); 208896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (isDstOp(*Op2) && Op1->isReg()) { 208996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger const char *ins; 209096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger unsigned reg = Op1->getReg(); 209196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger bool isStos = Name == "stos"; 209296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (reg == X86::AL && (isStos || Name == "stosb")) 209396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "stosb"; 209496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::AX && (isStos || Name == "stosw")) 209596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "stosw"; 209696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::EAX && (isStos || Name == "stosl")) 209796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "stosl"; 209896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::RAX && (isStos || Name == "stosq")) 209996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "stosq"; 210096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else 210196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = NULL; 210296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (ins != NULL) { 210396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 210496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 210596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete Op1; 210696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete Op2; 210796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name != ins) 210896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger static_cast<X86Operand*>(Operands[0])->setTokenValue(ins); 210996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 211096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 211196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 211296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 2113e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to 2114ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner // "shift <op>". 2115d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar if ((Name.startswith("shr") || Name.startswith("sar") || 21168c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner Name.startswith("shl") || Name.startswith("sal") || 21178c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner Name.startswith("rcl") || Name.startswith("rcr") || 21188c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner Name.startswith("rol") || Name.startswith("ror")) && 211947ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner Operands.size() == 3) { 2120be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel if (isParsingIntelSyntax()) { 21213b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel // Intel syntax 21223b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel X86Operand *Op1 = static_cast<X86Operand*>(Operands[2]); 21233b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 212476bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) { 212576bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper delete Operands[2]; 212676bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper Operands.pop_back(); 21273b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel } 21283b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel } else { 21293b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 21303b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 213176bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) { 213276bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper delete Operands[1]; 213376bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper Operands.erase(Operands.begin() + 1); 21343b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel } 213547ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner } 2136f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar } 213736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier 213815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner // Transforms "int $3" into "int3" as a size optimization. We can't write an 213915f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner // instalias with an immediate operand yet. 214015f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner if (Name == "int" && Operands.size() == 2) { 214115f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 214215f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 214315f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) { 214415f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner delete Operands[1]; 214515f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner Operands.erase(Operands.begin() + 1); 214615f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner static_cast<X86Operand*>(Operands[0])->setTokenValue("int3"); 214715f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner } 214815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner } 2149c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 21509898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 2151a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar} 2152a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar 21534bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperstatic bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg, 21544bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper bool isCmp) { 21554bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper MCInst TmpInst; 21564bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper TmpInst.setOpcode(Opcode); 21574bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper if (!isCmp) 21584bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper TmpInst.addOperand(MCOperand::CreateReg(Reg)); 21594bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper TmpInst.addOperand(MCOperand::CreateReg(Reg)); 21604bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper TmpInst.addOperand(Inst.getOperand(0)); 21614bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper Inst = TmpInst; 21624bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper return true; 21634bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper} 2164ac0f0486022fb1798579c9a550154e839770efa9Devang Patel 21654bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperstatic bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode, 21664bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper bool isCmp = false) { 21674bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper if (!Inst.getOperand(0).isImm() || 21684bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper !isImmSExti16i8Value(Inst.getOperand(0).getImm())) 21694bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper return false; 2170a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel 21714bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper return convertToSExti8(Inst, Opcode, X86::AX, isCmp); 21724bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper} 2173a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel 21744bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperstatic bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode, 21754bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper bool isCmp = false) { 21764bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper if (!Inst.getOperand(0).isImm() || 21774bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper !isImmSExti32i8Value(Inst.getOperand(0).getImm())) 21784bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper return false; 2179a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel 21804bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper return convertToSExti8(Inst, Opcode, X86::EAX, isCmp); 21814bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper} 2182a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel 21834bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperstatic bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode, 21844bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper bool isCmp = false) { 21854bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper if (!Inst.getOperand(0).isImm() || 21864bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper !isImmSExti64i8Value(Inst.getOperand(0).getImm())) 21874bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper return false; 2188a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel 21894bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper return convertToSExti8(Inst, Opcode, X86::RAX, isCmp); 21904bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper} 2191a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel 21924bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperbool X86AsmParser:: 21934bef961baf9660f1ac5a5b80378631cd942636b2Craig TopperprocessInstruction(MCInst &Inst, 21944bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper const SmallVectorImpl<MCParsedAsmOperand*> &Ops) { 21954bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper switch (Inst.getOpcode()) { 21964bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper default: return false; 21974bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8); 21984bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8); 21994bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8); 22004bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8); 22014bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8); 22024bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8); 22034bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8); 22044bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8); 22054bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8); 22064bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true); 22074bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true); 22084bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true); 22094bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8); 22104bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8); 22114bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8); 22124bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8); 22134bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8); 22144bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8); 22158ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8); 22168ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8); 22178ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8); 22188ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8); 22198ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8); 22208ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8); 2221b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel } 2222b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel} 2223b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel 22243ca6382120c16e30151e19175d40480ee72de641Jim Grosbachstatic const char *getSubtargetFeatureName(unsigned Val); 2225b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelbool X86AsmParser:: 222684125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 22277c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 222884125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MCStreamer &Out, unsigned &ErrorInfo, 222984125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchingInlineAsm) { 2230f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar assert(!Operands.empty() && "Unexpect empty operand list!"); 22317c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner X86Operand *Op = static_cast<X86Operand*>(Operands[0]); 22327c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner assert(Op->isToken() && "Leading operand should always be a mnemonic!"); 22335c332dbd30d9398ed25b30c3080506f7b8e92290Dmitri Gribenko ArrayRef<SMRange> EmptyRanges = None; 22347c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner 22357c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner // First, handle aliases that expand to multiple instructions. 22367c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner // FIXME: This should be replaced with a real .td file alias mechanism. 22374ee0808d9f1c7d64b0b304e610ce0fb496dd3279Chad Rosier // Also, MatchInstructionImpl should actually *do* the EmitInstruction 223890fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner // call. 22390966ec08610c02c8556105f2fff88a7e7247a549Andrew Trick if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" || 22408b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner Op->getToken() == "fstsww" || Op->getToken() == "fstcww" || 2241905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner Op->getToken() == "finit" || Op->getToken() == "fsave" || 22425a378076a44ef3f507b91aa8e7715fabaec42074Kevin Enderby Op->getToken() == "fstenv" || Op->getToken() == "fclex") { 22437c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner MCInst Inst; 22447c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner Inst.setOpcode(X86::WAIT); 2245cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach Inst.setLoc(IDLoc); 22467a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier if (!MatchingInlineAsm) 224722685876ed7231f32f7d1698c00acab22825b74cChad Rosier Out.EmitInstruction(Inst); 2248f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar 22490bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner const char *Repl = 22500bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner StringSwitch<const char*>(Op->getToken()) 22518b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("finit", "fninit") 22528b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fsave", "fnsave") 22538b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fstcw", "fnstcw") 22548b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fstcww", "fnstcw") 2255905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner .Case("fstenv", "fnstenv") 22568b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fstsw", "fnstsw") 22578b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fstsww", "fnstsw") 22588b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fclex", "fnclex") 22590bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner .Default(0); 22600bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner assert(Repl && "Unknown wait-prefixed instruction"); 2261b0f96facd6e6637cb71bbeaf2f4e006f0b6348e3Benjamin Kramer delete Operands[0]; 22620bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner Operands[0] = X86Operand::CreateToken(Repl, IDLoc); 22637c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner } 2264c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 2265a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner bool WasOriginallyInvalidOperand = false; 22667036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner MCInst Inst; 2267c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 2268c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // First, try a direct match. 22696e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier switch (MatchInstructionImpl(Operands, Inst, 227084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier ErrorInfo, MatchingInlineAsm, 2271be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel isParsingIntelSyntax())) { 227219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 2273ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner case Match_Success: 2274b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel // Some instructions need post-processing to, for example, tweak which 2275b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel // encoding is selected. Loop on it while changes happen so the 227636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier // individual transformations can chain off each other. 22777a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier if (!MatchingInlineAsm) 227822685876ed7231f32f7d1698c00acab22825b74cChad Rosier while (processInstruction(Inst, Operands)) 227922685876ed7231f32f7d1698c00acab22825b74cChad Rosier ; 2280b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel 2281cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach Inst.setLoc(IDLoc); 22827a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier if (!MatchingInlineAsm) 228322685876ed7231f32f7d1698c00acab22825b74cChad Rosier Out.EmitInstruction(Inst); 228422685876ed7231f32f7d1698c00acab22825b74cChad Rosier Opcode = Inst.getOpcode(); 2285c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar return false; 22863ca6382120c16e30151e19175d40480ee72de641Jim Grosbach case Match_MissingFeature: { 22873ca6382120c16e30151e19175d40480ee72de641Jim Grosbach assert(ErrorInfo && "Unknown missing feature!"); 22883ca6382120c16e30151e19175d40480ee72de641Jim Grosbach // Special case the error message for the very common case where only 22893ca6382120c16e30151e19175d40480ee72de641Jim Grosbach // a single subtarget feature is missing. 22903ca6382120c16e30151e19175d40480ee72de641Jim Grosbach std::string Msg = "instruction requires:"; 22913ca6382120c16e30151e19175d40480ee72de641Jim Grosbach unsigned Mask = 1; 22923ca6382120c16e30151e19175d40480ee72de641Jim Grosbach for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { 22933ca6382120c16e30151e19175d40480ee72de641Jim Grosbach if (ErrorInfo & Mask) { 22943ca6382120c16e30151e19175d40480ee72de641Jim Grosbach Msg += " "; 22953ca6382120c16e30151e19175d40480ee72de641Jim Grosbach Msg += getSubtargetFeatureName(ErrorInfo & Mask); 22963ca6382120c16e30151e19175d40480ee72de641Jim Grosbach } 22973ca6382120c16e30151e19175d40480ee72de641Jim Grosbach Mask <<= 1; 22983ca6382120c16e30151e19175d40480ee72de641Jim Grosbach } 22993ca6382120c16e30151e19175d40480ee72de641Jim Grosbach return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm); 23003ca6382120c16e30151e19175d40480ee72de641Jim Grosbach } 2301a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner case Match_InvalidOperand: 2302a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner WasOriginallyInvalidOperand = true; 2303a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner break; 2304a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner case Match_MnemonicFail: 2305ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner break; 2306ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner } 2307c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 2308c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // FIXME: Ideally, we would only attempt suffix matches for things which are 2309c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // valid prefixes, and we could just infer the right unambiguous 2310c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // type. However, that requires substantially more matcher support than the 2311c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // following hack. 2312c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 2313c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // Change the operand to point to a temporary token. 2314c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar StringRef Base = Op->getToken(); 2315f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar SmallString<16> Tmp; 2316f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar Tmp += Base; 2317f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar Tmp += ' '; 2318f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar Op->setTokenValue(Tmp.str()); 2319c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 2320fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // If this instruction starts with an 'f', then it is a floating point stack 2321fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // instruction. These come in up to three forms for 32-bit, 64-bit, and 2322fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // 80-bit floating point, which use the suffixes s,l,t respectively. 2323fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // 2324fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // Otherwise, we assume that this may be an integer instruction, which comes 2325fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively. 2326fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0"; 232736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier 2328c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // Check for the various suffix matches. 2329fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Tmp[Base.size()] = Suffixes[0]; 2330fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner unsigned ErrorInfoIgnore; 23314d9b7c234fd2510c27e6d74a3f0653efc0141580Duncan Sands unsigned ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings. 233219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned Match1, Match2, Match3, Match4; 233336b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier 23346e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, 2335ffc49cbea41c08132587a3e622bb65191fa576a2Chad Rosier MatchingInlineAsm, isParsingIntelSyntax()); 23363ca6382120c16e30151e19175d40480ee72de641Jim Grosbach // If this returned as a missing feature failure, remember that. 23373ca6382120c16e30151e19175d40480ee72de641Jim Grosbach if (Match1 == Match_MissingFeature) 23383ca6382120c16e30151e19175d40480ee72de641Jim Grosbach ErrorInfoMissingFeature = ErrorInfoIgnore; 2339fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Tmp[Base.size()] = Suffixes[1]; 23406e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, 2341ffc49cbea41c08132587a3e622bb65191fa576a2Chad Rosier MatchingInlineAsm, isParsingIntelSyntax()); 23423ca6382120c16e30151e19175d40480ee72de641Jim Grosbach // If this returned as a missing feature failure, remember that. 23433ca6382120c16e30151e19175d40480ee72de641Jim Grosbach if (Match2 == Match_MissingFeature) 23443ca6382120c16e30151e19175d40480ee72de641Jim Grosbach ErrorInfoMissingFeature = ErrorInfoIgnore; 2345fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Tmp[Base.size()] = Suffixes[2]; 23466e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, 2347ffc49cbea41c08132587a3e622bb65191fa576a2Chad Rosier MatchingInlineAsm, isParsingIntelSyntax()); 23483ca6382120c16e30151e19175d40480ee72de641Jim Grosbach // If this returned as a missing feature failure, remember that. 23493ca6382120c16e30151e19175d40480ee72de641Jim Grosbach if (Match3 == Match_MissingFeature) 23503ca6382120c16e30151e19175d40480ee72de641Jim Grosbach ErrorInfoMissingFeature = ErrorInfoIgnore; 2351fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Tmp[Base.size()] = Suffixes[3]; 23526e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, 2353ffc49cbea41c08132587a3e622bb65191fa576a2Chad Rosier MatchingInlineAsm, isParsingIntelSyntax()); 23543ca6382120c16e30151e19175d40480ee72de641Jim Grosbach // If this returned as a missing feature failure, remember that. 23553ca6382120c16e30151e19175d40480ee72de641Jim Grosbach if (Match4 == Match_MissingFeature) 23563ca6382120c16e30151e19175d40480ee72de641Jim Grosbach ErrorInfoMissingFeature = ErrorInfoIgnore; 2357c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 2358c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // Restore the old token. 2359c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Op->setTokenValue(Base); 2360c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 2361c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // If exactly one matched, then we treat that as a successful match (and the 2362c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // instruction will already have been filled in correctly, since the failing 2363c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // matches won't have modified it). 2364ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner unsigned NumSuccessfulMatches = 2365fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match1 == Match_Success) + (Match2 == Match_Success) + 2366fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match3 == Match_Success) + (Match4 == Match_Success); 23677036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner if (NumSuccessfulMatches == 1) { 2368cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach Inst.setLoc(IDLoc); 23697a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier if (!MatchingInlineAsm) 237022685876ed7231f32f7d1698c00acab22825b74cChad Rosier Out.EmitInstruction(Inst); 237122685876ed7231f32f7d1698c00acab22825b74cChad Rosier Opcode = Inst.getOpcode(); 2372c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar return false; 23737036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner } 2374c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 2375ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // Otherwise, the match failed, try to produce a decent error message. 2376f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar 237709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar // If we had multiple suffix matches, then identify this as an ambiguous 237809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar // match. 2379ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner if (NumSuccessfulMatches > 1) { 238009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar char MatchChars[4]; 238109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar unsigned NumMatches = 0; 2382fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0]; 2383fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1]; 2384fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2]; 2385fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3]; 238609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar 238709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar SmallString<126> Msg; 238809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar raw_svector_ostream OS(Msg); 238909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << "ambiguous instructions require an explicit suffix (could be "; 239009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar for (unsigned i = 0; i != NumMatches; ++i) { 239109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar if (i != 0) 239209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << ", "; 239309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar if (i + 1 == NumMatches) 239409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << "or "; 239509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << "'" << Base << MatchChars[i] << "'"; 239609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar } 239709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << ")"; 23987a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm); 2399ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner return true; 240009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar } 2401c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 2402a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // Okay, we know that none of the variants matched successfully. 2403c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 2404a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // If all of the instructions reported an invalid mnemonic, then the original 2405a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // mnemonic was invalid. 2406fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) && 2407fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) { 2408ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner if (!WasOriginallyInvalidOperand) { 24097a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier ArrayRef<SMRange> Ranges = MatchingInlineAsm ? EmptyRanges : 2410674101e6bb3742ae743e21e9b9ebec5946b1d273Chad Rosier Op->getLocRange(); 2411f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'", 24127a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier Ranges, MatchingInlineAsm); 2413ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner } 2414ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner 2415ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner // Recover location info for the operand if we know which was the problem. 241684125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier if (ErrorInfo != ~0U) { 241784125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier if (ErrorInfo >= Operands.size()) 2418b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier return Error(IDLoc, "too few operands for instruction", 24197a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier EmptyRanges, MatchingInlineAsm); 2420c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 242184125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier X86Operand *Operand = (X86Operand*)Operands[ErrorInfo]; 2422d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner if (Operand->getStartLoc().isValid()) { 2423d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner SMRange OperandRange = Operand->getLocRange(); 2424d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner return Error(Operand->getStartLoc(), "invalid operand for instruction", 24257a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier OperandRange, MatchingInlineAsm); 2426d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner } 2427ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner } 2428ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner 2429b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier return Error(IDLoc, "invalid operand for instruction", EmptyRanges, 24307a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier MatchingInlineAsm); 2431a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner } 2432c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 2433ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // If one instruction matched with a missing feature, report this as a 2434ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // missing feature. 2435fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) + 2436fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){ 24373ca6382120c16e30151e19175d40480ee72de641Jim Grosbach std::string Msg = "instruction requires:"; 24383ca6382120c16e30151e19175d40480ee72de641Jim Grosbach unsigned Mask = 1; 24393ca6382120c16e30151e19175d40480ee72de641Jim Grosbach for (unsigned i = 0; i < (sizeof(ErrorInfoMissingFeature)*8-1); ++i) { 24403ca6382120c16e30151e19175d40480ee72de641Jim Grosbach if (ErrorInfoMissingFeature & Mask) { 24413ca6382120c16e30151e19175d40480ee72de641Jim Grosbach Msg += " "; 24423ca6382120c16e30151e19175d40480ee72de641Jim Grosbach Msg += getSubtargetFeatureName(ErrorInfoMissingFeature & Mask); 24433ca6382120c16e30151e19175d40480ee72de641Jim Grosbach } 24443ca6382120c16e30151e19175d40480ee72de641Jim Grosbach Mask <<= 1; 24453ca6382120c16e30151e19175d40480ee72de641Jim Grosbach } 24463ca6382120c16e30151e19175d40480ee72de641Jim Grosbach return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm); 2447ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner } 2448c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 2449a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // If one instruction matched with an invalid operand, report this as an 2450a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // operand failure. 2451fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) + 2452fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){ 2453b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier Error(IDLoc, "invalid operand for instruction", EmptyRanges, 24547a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier MatchingInlineAsm); 2455a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner return true; 2456a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner } 2457c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 2458ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // If all of these were an outright failure, report it in a useless way. 2459b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier Error(IDLoc, "unknown use of instruction mnemonic without a size suffix", 24607a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier EmptyRanges, MatchingInlineAsm); 2461c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar return true; 2462c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar} 2463c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 2464c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 2465dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirective(AsmToken DirectiveID) { 2466537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner StringRef IDVal = DirectiveID.getIdentifier(); 2467537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner if (IDVal == ".word") 2468537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return ParseDirectiveWord(2, DirectiveID.getLoc()); 2469bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng else if (IDVal.startswith(".code")) 2470bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng return ParseDirectiveCode(IDVal, DirectiveID.getLoc()); 24713c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier else if (IDVal.startswith(".att_syntax")) { 24723c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier getParser().setAssemblerDialect(0); 24733c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier return false; 24743c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier } else if (IDVal.startswith(".intel_syntax")) { 24750db58bfecea020ffcdfa1fc6458995371e1c3c50Devang Patel getParser().setAssemblerDialect(1); 2476be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel if (getLexer().isNot(AsmToken::EndOfStatement)) { 2477be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel if(Parser.getTok().getString() == "noprefix") { 247876bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper // FIXME : Handle noprefix 247976bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper Parser.Lex(); 2480be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel } else 248176bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper return true; 2482be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel } 2483be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel return false; 2484be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel } 2485537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return true; 2486537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner} 2487537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 2488537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner/// ParseDirectiveWord 2489537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner/// ::= .word [ expression (, expression)* ] 2490dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 2491537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 2492537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner for (;;) { 2493537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner const MCExpr *Value; 2494cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(Value)) 2495537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return true; 249636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier 24971ced208be9cab0f994c5df9000da36bc313b2507Eric Christopher getParser().getStreamer().EmitValue(Value, Size); 249836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier 2499537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner if (getLexer().is(AsmToken::EndOfStatement)) 2500537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner break; 250136b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier 2502537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner // FIXME: Improve diagnostic. 2503537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner if (getLexer().isNot(AsmToken::Comma)) 2504537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return Error(L, "unexpected token in directive"); 2505537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner Parser.Lex(); 2506537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner } 2507537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner } 250836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier 2509537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner Parser.Lex(); 2510537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return false; 2511537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner} 2512537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 2513bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng/// ParseDirectiveCode 2514bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng/// ::= .code32 | .code64 2515dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { 2516bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (IDVal == ".code32") { 2517bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng Parser.Lex(); 2518bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (is64BitMode()) { 2519bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng SwitchMode(); 2520bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 2521bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 2522bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } else if (IDVal == ".code64") { 2523bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng Parser.Lex(); 2524bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (!is64BitMode()) { 2525bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng SwitchMode(); 2526bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64); 2527bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 2528bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } else { 2529bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng return Error(L, "unexpected directive " + IDVal); 2530bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 2531537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 2532bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng return false; 2533bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng} 2534537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 2535092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization. 2536092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() { 2537dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target); 2538dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target); 2539092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 25400e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 25410692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 25420692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 25433ca6382120c16e30151e19175d40480ee72de641Jim Grosbach#define GET_SUBTARGET_FEATURE_NAME 25440e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc" 2545