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