[llvm] r315899 - This patch is a result of D37262: The issues with X86 prefixes. It closes PR7709, PR17697, PR19251, PR32809 and PR21640. There could be other bugs closed by this patch.

Andrew V. Tischenko via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 16 04:14:30 PDT 2017


Author: avt77
Date: Mon Oct 16 04:14:29 2017
New Revision: 315899

URL: http://llvm.org/viewvc/llvm-project?rev=315899&view=rev
Log:
This patch is a result of D37262: The issues with X86 prefixes. It closes  PR7709, PR17697, PR19251, PR32809 and PR21640. There could be other bugs closed by this patch.

Modified:
    llvm/trunk/include/llvm/MC/MCInst.h
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/lib/Target/X86/AsmParser/X86Operand.h
    llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp
    llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
    llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
    llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
    llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
    llvm/trunk/test/MC/Disassembler/X86/prefixes.txt
    llvm/trunk/test/MC/Disassembler/X86/x86-32.txt
    llvm/trunk/test/MC/Disassembler/X86/x86-64.txt
    llvm/trunk/test/MC/X86/intel-syntax-encoding.s
    llvm/trunk/test/MC/X86/x86-64.s

Modified: llvm/trunk/include/llvm/MC/MCInst.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCInst.h?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCInst.h (original)
+++ llvm/trunk/include/llvm/MC/MCInst.h Mon Oct 16 04:14:29 2017
@@ -160,6 +160,10 @@ class MCInst {
   unsigned Opcode = 0;
   SMLoc Loc;
   SmallVector<MCOperand, 8> Operands;
+  // These flags could be used to pass some info from one target subcomponent
+  // to another, for example, from disassembler to asm printer. The values of
+  // the flags have any sense on target level only (e.g. prefixes on x86).
+  unsigned Flags = 0;
 
 public:
   MCInst() = default;
@@ -167,6 +171,9 @@ public:
   void setOpcode(unsigned Op) { Opcode = Op; }
   unsigned getOpcode() const { return Opcode; }
 
+  void setFlags(unsigned F) { Flags = F; }
+  unsigned getFlags() const { return Flags; }
+
   void setLoc(SMLoc loc) { Loc = loc; }
   SMLoc getLoc() const { return Loc; }
 

Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Mon Oct 16 04:14:29 2017
@@ -2330,7 +2330,6 @@ bool X86AsmParser::ParseInstruction(Pars
     }
   }
 
-  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
 
   // Determine whether this is an instruction prefix.
   // FIXME:
@@ -2340,22 +2339,48 @@ bool X86AsmParser::ParseInstruction(Pars
   // lock addq %rax, %rbx ; Destination operand must be of memory type
   // xacquire <insn>      ; xacquire must be accompanied by 'lock'
   bool isPrefix = StringSwitch<bool>(Name)
-    .Cases("lock",
-           "rep",       "repe",
-           "repz",      "repne",
-           "repnz",     "rex64",
-           "data32",    "data16",   true)
-    .Cases("xacquire",  "xrelease", true)
-    .Cases("acquire",   "release",  isParsingIntelSyntax())
-    .Default(false);
+                      .Cases("rex64", "data32", "data16", true)
+                      .Cases("xacquire", "xrelease", true)
+                      .Cases("acquire", "release", isParsingIntelSyntax())
+                      .Default(false);
+
+  auto isLockRepeatPrefix = [](StringRef N) {
+    return StringSwitch<bool>(N)
+        .Cases("lock", "rep", "repe", "repz", "repne", "repnz", true)
+        .Default(false);
+  };
 
   bool CurlyAsEndOfStatement = false;
+
+  unsigned Flags = X86::IP_NO_PREFIX;
+  while (isLockRepeatPrefix(Name.lower())) {
+    unsigned Prefix =
+        StringSwitch<unsigned>(Name)
+            .Cases("lock", "lock", X86::IP_HAS_LOCK)
+            .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT)
+            .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE)
+            .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)
+    Flags |= Prefix;
+    Name = Parser.getTok().getString();
+    Parser.Lex(); // eat the prefix
+    // Hack: we could have something like
+    //    "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"
+    while (Name.startswith(";") || Name.startswith("\n") ||
+           Name.startswith("\t") or Name.startswith("/")) {
+      Name = Parser.getTok().getString();
+      Parser.Lex(); // go to next prefix or instr
+    }
+  }
+
+  if (Flags)
+    PatchedName = Name;
+  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
+
   // This does the actual operand parsing.  Don't parse any more if we have a
   // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
   // just want to parse the "lock" as the first instruction and the "incl" as
   // the next one.
   if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
-
     // Parse '*' modifier.
     if (getLexer().is(AsmToken::Star))
       Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
@@ -2593,6 +2618,8 @@ bool X86AsmParser::ParseInstruction(Pars
     }
   }
 
+  if (Flags)
+    Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));
   return false;
 }
 
@@ -2660,6 +2687,16 @@ bool X86AsmParser::ErrorMissingFeature(S
   return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
 }
 
+static unsigned getPrefixes(OperandVector &Operands) {
+  unsigned Result = 0;
+  X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());
+  if (Prefix.isPrefix()) {
+    Result = Prefix.getPrefix();
+    Operands.pop_back();
+  }
+  return Result;
+}
+
 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
                                               OperandVector &Operands,
                                               MCStreamer &Out,
@@ -2674,8 +2711,13 @@ bool X86AsmParser::MatchAndEmitATTInstru
   MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
 
   bool WasOriginallyInvalidOperand = false;
+  unsigned Prefixes = getPrefixes(Operands);
+
   MCInst Inst;
 
+  if (Prefixes)
+    Inst.setFlags(Prefixes);
+
   // First, try a direct match.
   switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
                            isParsingIntelSyntax())) {
@@ -2840,12 +2882,16 @@ bool X86AsmParser::MatchAndEmitIntelInst
   StringRef Mnemonic = Op.getToken();
   SMRange EmptyRange = None;
   StringRef Base = Op.getToken();
+  unsigned Prefixes = getPrefixes(Operands);
 
   // First, handle aliases that expand to multiple instructions.
   MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
 
   MCInst Inst;
 
+  if (Prefixes)
+    Inst.setFlags(Prefixes);
+
   // Find one unsized memory operand, if present.
   X86Operand *UnsizedMemOp = nullptr;
   for (const auto &Op : Operands) {

Modified: llvm/trunk/lib/Target/X86/AsmParser/X86Operand.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86Operand.h?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86Operand.h (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86Operand.h Mon Oct 16 04:14:29 2017
@@ -28,12 +28,7 @@ namespace llvm {
 /// X86Operand - Instances of this class represent a parsed X86 machine
 /// instruction.
 struct X86Operand : public MCParsedAsmOperand {
-  enum KindTy {
-    Token,
-    Register,
-    Immediate,
-    Memory
-  } Kind;
+  enum KindTy { Token, Register, Immediate, Memory, Prefix } Kind;
 
   SMLoc StartLoc, EndLoc;
   SMLoc OffsetOfLoc;
@@ -50,6 +45,10 @@ struct X86Operand : public MCParsedAsmOp
     unsigned RegNo;
   };
 
+  struct PrefOp {
+    unsigned Prefixes;
+  };
+
   struct ImmOp {
     const MCExpr *Val;
   };
@@ -73,6 +72,7 @@ struct X86Operand : public MCParsedAsmOp
     struct RegOp Reg;
     struct ImmOp Imm;
     struct MemOp Mem;
+    struct PrefOp Pref;
   };
 
   X86Operand(KindTy K, SMLoc Start, SMLoc End)
@@ -111,6 +111,11 @@ struct X86Operand : public MCParsedAsmOp
     return Reg.RegNo;
   }
 
+  unsigned getPrefix() const {
+    assert(Kind == Prefix && "Invalid access!");
+    return Pref.Prefixes;
+  }
+
   const MCExpr *getImm() const {
     assert(Kind == Immediate && "Invalid access!");
     return Imm.Val;
@@ -387,6 +392,7 @@ struct X86Operand : public MCParsedAsmOp
     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
   }
 
+  bool isPrefix() const { return Kind == Prefix; }
   bool isReg() const override { return Kind == Register; }
 
   bool isGR32orGR64() const {
@@ -509,6 +515,13 @@ struct X86Operand : public MCParsedAsmOp
     return Res;
   }
 
+  static std::unique_ptr<X86Operand>
+  CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
+    auto Res = llvm::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
+    Res->Pref.Prefixes = Prefixes;
+    return Res;
+  }
+
   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
                                                SMLoc StartLoc, SMLoc EndLoc) {
     auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);

Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp (original)
+++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp Mon Oct 16 04:14:29 2017
@@ -74,6 +74,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "MCTargetDesc/X86BaseInfo.h"
 #include "MCTargetDesc/X86MCTargetDesc.h"
 #include "X86DisassemblerDecoder.h"
 #include "llvm/MC/MCContext.h"
@@ -232,7 +233,24 @@ MCDisassembler::DecodeStatus X86GenericD
     return Fail;
   } else {
     Size = InternalInstr.length;
-    return (!translateInstruction(Instr, InternalInstr, this)) ? Success : Fail;
+    bool Ret = translateInstruction(Instr, InternalInstr, this);
+    if (!Ret) {
+      unsigned Flags = X86::IP_NO_PREFIX;
+      if (InternalInstr.hasAdSize)
+        Flags |= X86::IP_HAS_AD_SIZE;
+      if (!InternalInstr.mandatoryPrefix) {
+        if (InternalInstr.hasOpSize)
+          Flags |= X86::IP_HAS_OP_SIZE;
+        if (InternalInstr.repeatPrefix == 0xf2)
+          Flags |= X86::IP_HAS_REPEAT_NE;
+        else if (InternalInstr.repeatPrefix == 0xf3 &&
+                 // It should not be 'pause' f3 90
+                 InternalInstr.opcode != 0x90)
+          Flags |= X86::IP_HAS_REPEAT;
+      }
+      Instr.setFlags(Flags);
+    }
+    return (!Ret) ? Success : Fail;
   }
 }
 
@@ -315,12 +333,12 @@ static bool translateSrcIndex(MCInst &mc
   unsigned baseRegNo;
 
   if (insn.mode == MODE_64BIT)
-    baseRegNo = insn.prefixPresent[0x67] ? X86::ESI : X86::RSI;
+    baseRegNo = insn.hasAdSize ? X86::ESI : X86::RSI;
   else if (insn.mode == MODE_32BIT)
-    baseRegNo = insn.prefixPresent[0x67] ? X86::SI : X86::ESI;
+    baseRegNo = insn.hasAdSize ? X86::SI : X86::ESI;
   else {
     assert(insn.mode == MODE_16BIT);
-    baseRegNo = insn.prefixPresent[0x67] ? X86::ESI : X86::SI;
+    baseRegNo = insn.hasAdSize ? X86::ESI : X86::SI;
   }
   MCOperand baseReg = MCOperand::createReg(baseRegNo);
   mcInst.addOperand(baseReg);
@@ -340,12 +358,12 @@ static bool translateDstIndex(MCInst &mc
   unsigned baseRegNo;
 
   if (insn.mode == MODE_64BIT)
-    baseRegNo = insn.prefixPresent[0x67] ? X86::EDI : X86::RDI;
+    baseRegNo = insn.hasAdSize ? X86::EDI : X86::RDI;
   else if (insn.mode == MODE_32BIT)
-    baseRegNo = insn.prefixPresent[0x67] ? X86::DI : X86::EDI;
+    baseRegNo = insn.hasAdSize ? X86::DI : X86::EDI;
   else {
     assert(insn.mode == MODE_16BIT);
-    baseRegNo = insn.prefixPresent[0x67] ? X86::EDI : X86::DI;
+    baseRegNo = insn.hasAdSize ? X86::EDI : X86::DI;
   }
   MCOperand baseReg = MCOperand::createReg(baseRegNo);
   mcInst.addOperand(baseReg);

Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp (original)
+++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp Mon Oct 16 04:14:29 2017
@@ -277,38 +277,44 @@ static void dbgprintf(struct InternalIns
   insn->dlog(insn->dlogArg, buffer);
 }
 
-/*
- * setPrefixPresent - Marks that a particular prefix is present at a particular
- *   location.
- *
- * @param insn      - The instruction to be marked as having the prefix.
- * @param prefix    - The prefix that is present.
- * @param location  - The location where the prefix is located (in the address
- *                    space of the instruction's reader).
- */
-static void setPrefixPresent(struct InternalInstruction* insn,
-                                    uint8_t prefix,
-                                    uint64_t location)
-{
-  insn->prefixPresent[prefix] = 1;
-  insn->prefixLocations[prefix] = location;
+static bool isREX(struct InternalInstruction *insn, uint8_t prefix) {
+  if (insn->mode == MODE_64BIT)
+    return prefix >= 0x40 && prefix <= 0x4f;
+  return false;
 }
 
 /*
- * isPrefixAtLocation - Queries an instruction to determine whether a prefix is
- *   present at a given location.
+ * setPrefixPresent - Marks that a particular prefix is present as mandatory
  *
- * @param insn      - The instruction to be queried.
- * @param prefix    - The prefix.
- * @param location  - The location to query.
- * @return          - Whether the prefix is at that location.
+ * @param insn      - The instruction to be marked as having the prefix.
+ * @param prefix    - The prefix that is present.
  */
-static bool isPrefixAtLocation(struct InternalInstruction* insn,
-                               uint8_t prefix,
-                               uint64_t location)
-{
-  return insn->prefixPresent[prefix] == 1 &&
-     insn->prefixLocations[prefix] == location;
+static void setPrefixPresent(struct InternalInstruction *insn, uint8_t prefix) {
+  uint8_t nextByte;
+  switch (prefix) {
+  case 0xf2:
+  case 0xf3:
+    if (lookAtByte(insn, &nextByte))
+      break;
+    // TODO:
+    //  1. There could be several 0x66
+    //  2. if (nextByte == 0x66) and nextNextByte != 0x0f then
+    //      it's not mandatory prefix
+    //  3. if (nextByte >= 0x40 && nextByte <= 0x4f) it's REX and we need
+    //     0x0f exactly after it to be mandatory prefix
+    if (isREX(insn, nextByte) || nextByte == 0x0f || nextByte == 0x66)
+      // The last of 0xf2 /0xf3 is mandatory prefix
+      insn->mandatoryPrefix = prefix;
+    insn->repeatPrefix = prefix;
+    break;
+  case 0x66:
+    if (lookAtByte(insn, &nextByte))
+      break;
+    // 0x66 can't overwrite existing mandatory prefix and should be ignored
+    if (!insn->mandatoryPrefix && (nextByte == 0x0f || isREX(insn, nextByte)))
+      insn->mandatoryPrefix = prefix;
+    break;
+  }
 }
 
 /*
@@ -322,19 +328,12 @@ static bool isPrefixAtLocation(struct In
  */
 static int readPrefixes(struct InternalInstruction* insn) {
   bool isPrefix = true;
-  bool prefixGroups[4] = { false };
-  uint64_t prefixLocation;
   uint8_t byte = 0;
   uint8_t nextByte;
 
-  bool hasAdSize = false;
-  bool hasOpSize = false;
-
   dbgprintf(insn, "readPrefixes()");
 
   while (isPrefix) {
-    prefixLocation = insn->readerCursor;
-
     /* If we fail reading prefixes, just stop here and let the opcode reader deal with it */
     if (consumeByte(insn, &byte))
       break;
@@ -343,13 +342,10 @@ static int readPrefixes(struct InternalI
      * If the byte is a LOCK/REP/REPNE prefix and not a part of the opcode, then
      * break and let it be disassembled as a normal "instruction".
      */
-    if (insn->readerCursor - 1 == insn->startLocation && byte == 0xf0)
+    if (insn->readerCursor - 1 == insn->startLocation && byte == 0xf0) // LOCK
       break;
 
-    if (insn->readerCursor - 1 == insn->startLocation
-        && (byte == 0xf2 || byte == 0xf3)
-        && !lookAtByte(insn, &nextByte))
-    {
+    if ((byte == 0xf2 || byte == 0xf3) && !lookAtByte(insn, &nextByte)) {
       /*
        * If the byte is 0xf2 or 0xf3, and any of the following conditions are
        * met:
@@ -357,39 +353,41 @@ static int readPrefixes(struct InternalI
        * - it is followed by an xchg instruction
        * then it should be disassembled as a xacquire/xrelease not repne/rep.
        */
-      if ((byte == 0xf2 || byte == 0xf3) &&
-          ((nextByte == 0xf0) ||
-          ((nextByte & 0xfe) == 0x86 || (nextByte & 0xf8) == 0x90)))
+      if (((nextByte == 0xf0) ||
+           ((nextByte & 0xfe) == 0x86 || (nextByte & 0xf8) == 0x90))) {
         insn->xAcquireRelease = true;
+        if (!(byte == 0xf3 && nextByte == 0x90)) // PAUSE instruction support
+          break;
+      }
       /*
        * Also if the byte is 0xf3, and the following condition is met:
        * - it is followed by a "mov mem, reg" (opcode 0x88/0x89) or
        *                       "mov mem, imm" (opcode 0xc6/0xc7) instructions.
        * then it should be disassembled as an xrelease not rep.
        */
-      if (byte == 0xf3 &&
-          (nextByte == 0x88 || nextByte == 0x89 ||
-           nextByte == 0xc6 || nextByte == 0xc7))
+      if (byte == 0xf3 && (nextByte == 0x88 || nextByte == 0x89 ||
+                           nextByte == 0xc6 || nextByte == 0xc7)) {
         insn->xAcquireRelease = true;
-      if (insn->mode == MODE_64BIT && (nextByte & 0xf0) == 0x40) {
-        if (consumeByte(insn, &nextByte))
+        if (nextByte != 0x90) // PAUSE instruction support
+          break;
+      }
+      if (isREX(insn, nextByte)) {
+        uint8_t nnextByte;
+        // Go to REX prefix after the current one
+        if (consumeByte(insn, &nnextByte))
           return -1;
-        if (lookAtByte(insn, &nextByte))
+        // We should be able to read next byte after REX prefix
+        if (lookAtByte(insn, &nnextByte))
           return -1;
         unconsumeByte(insn);
       }
-      if (nextByte != 0x0f && nextByte != 0x90)
-        break;
     }
 
     switch (byte) {
     case 0xf0:  /* LOCK */
     case 0xf2:  /* REPNE/REPNZ */
     case 0xf3:  /* REP or REPE/REPZ */
-      if (prefixGroups[0])
-        dbgprintf(insn, "Redundant Group 1 prefix");
-      prefixGroups[0] = true;
-      setPrefixPresent(insn, byte, prefixLocation);
+      setPrefixPresent(insn, byte);
       break;
     case 0x2e:  /* CS segment override -OR- Branch not taken */
     case 0x36:  /* SS segment override -OR- Branch taken */
@@ -420,24 +418,15 @@ static int readPrefixes(struct InternalI
         debug("Unhandled override");
         return -1;
       }
-      if (prefixGroups[1])
-        dbgprintf(insn, "Redundant Group 2 prefix");
-      prefixGroups[1] = true;
-      setPrefixPresent(insn, byte, prefixLocation);
+      setPrefixPresent(insn, byte);
       break;
     case 0x66:  /* Operand-size override */
-      if (prefixGroups[2])
-        dbgprintf(insn, "Redundant Group 3 prefix");
-      prefixGroups[2] = true;
-      hasOpSize = true;
-      setPrefixPresent(insn, byte, prefixLocation);
+      insn->hasOpSize = true;
+      setPrefixPresent(insn, byte);
       break;
     case 0x67:  /* Address-size override */
-      if (prefixGroups[3])
-        dbgprintf(insn, "Redundant Group 4 prefix");
-      prefixGroups[3] = true;
-      hasAdSize = true;
-      setPrefixPresent(insn, byte, prefixLocation);
+      insn->hasAdSize = true;
+      setPrefixPresent(insn, byte);
       break;
     default:    /* Not a prefix byte */
       isPrefix = false;
@@ -469,7 +458,6 @@ static int readPrefixes(struct InternalI
     } else {
       unconsumeByte(insn); /* unconsume byte1 */
       unconsumeByte(insn); /* unconsume byte  */
-      insn->necessaryPrefixLocation = insn->readerCursor - 2;
     }
 
     if (insn->vectorExtensionType == TYPE_EVEX) {
@@ -505,13 +493,10 @@ static int readPrefixes(struct InternalI
       return -1;
     }
 
-    if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
+    if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0)
       insn->vectorExtensionType = TYPE_VEX_3B;
-      insn->necessaryPrefixLocation = insn->readerCursor - 1;
-    } else {
+    else
       unconsumeByte(insn);
-      insn->necessaryPrefixLocation = insn->readerCursor - 1;
-    }
 
     if (insn->vectorExtensionType == TYPE_VEX_3B) {
       insn->vectorExtensionPrefix[0] = byte;
@@ -520,13 +505,12 @@ static int readPrefixes(struct InternalI
 
       /* We simulate the REX prefix for simplicity's sake */
 
-      if (insn->mode == MODE_64BIT) {
+      if (insn->mode == MODE_64BIT)
         insn->rexPrefix = 0x40
                         | (wFromVEX3of3(insn->vectorExtensionPrefix[2]) << 3)
                         | (rFromVEX2of3(insn->vectorExtensionPrefix[1]) << 2)
                         | (xFromVEX2of3(insn->vectorExtensionPrefix[1]) << 1)
                         | (bFromVEX2of3(insn->vectorExtensionPrefix[1]) << 0);
-      }
 
       dbgprintf(insn, "Found VEX prefix 0x%hhx 0x%hhx 0x%hhx",
                 insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
@@ -540,26 +524,24 @@ static int readPrefixes(struct InternalI
       return -1;
     }
 
-    if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
+    if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0)
       insn->vectorExtensionType = TYPE_VEX_2B;
-    } else {
+    else
       unconsumeByte(insn);
-    }
 
     if (insn->vectorExtensionType == TYPE_VEX_2B) {
       insn->vectorExtensionPrefix[0] = byte;
       consumeByte(insn, &insn->vectorExtensionPrefix[1]);
 
-      if (insn->mode == MODE_64BIT) {
+      if (insn->mode == MODE_64BIT)
         insn->rexPrefix = 0x40
                         | (rFromVEX2of2(insn->vectorExtensionPrefix[1]) << 2);
-      }
 
       switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
       default:
         break;
       case VEX_PREFIX_66:
-        hasOpSize = true;
+        insn->hasOpSize = true;
         break;
       }
 
@@ -575,13 +557,10 @@ static int readPrefixes(struct InternalI
       return -1;
     }
 
-    if ((byte1 & 0x38) != 0x0) { /* 0 in these 3 bits is a POP instruction. */
+    if ((byte1 & 0x38) != 0x0) /* 0 in these 3 bits is a POP instruction. */
       insn->vectorExtensionType = TYPE_XOP;
-      insn->necessaryPrefixLocation = insn->readerCursor - 1;
-    } else {
+    else
       unconsumeByte(insn);
-      insn->necessaryPrefixLocation = insn->readerCursor - 1;
-    }
 
     if (insn->vectorExtensionType == TYPE_XOP) {
       insn->vectorExtensionPrefix[0] = byte;
@@ -590,19 +569,18 @@ static int readPrefixes(struct InternalI
 
       /* We simulate the REX prefix for simplicity's sake */
 
-      if (insn->mode == MODE_64BIT) {
+      if (insn->mode == MODE_64BIT)
         insn->rexPrefix = 0x40
                         | (wFromXOP3of3(insn->vectorExtensionPrefix[2]) << 3)
                         | (rFromXOP2of3(insn->vectorExtensionPrefix[1]) << 2)
                         | (xFromXOP2of3(insn->vectorExtensionPrefix[1]) << 1)
                         | (bFromXOP2of3(insn->vectorExtensionPrefix[1]) << 0);
-      }
 
       switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
       default:
         break;
       case VEX_PREFIX_66:
-        hasOpSize = true;
+        insn->hasOpSize = true;
         break;
       }
 
@@ -610,51 +588,35 @@ static int readPrefixes(struct InternalI
                 insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
                 insn->vectorExtensionPrefix[2]);
     }
-  } else {
-    if (insn->mode == MODE_64BIT) {
-      if ((byte & 0xf0) == 0x40) {
-        uint8_t opcodeByte;
-
-        if (lookAtByte(insn, &opcodeByte) || ((opcodeByte & 0xf0) == 0x40)) {
-          dbgprintf(insn, "Redundant REX prefix");
-          return -1;
-        }
-
-        insn->rexPrefix = byte;
-        insn->necessaryPrefixLocation = insn->readerCursor - 2;
-
-        dbgprintf(insn, "Found REX prefix 0x%hhx", byte);
-      } else {
-        unconsumeByte(insn);
-        insn->necessaryPrefixLocation = insn->readerCursor - 1;
-      }
-    } else {
-      unconsumeByte(insn);
-      insn->necessaryPrefixLocation = insn->readerCursor - 1;
-    }
-  }
+  } else if (isREX(insn, byte)) {
+    if (lookAtByte(insn, &nextByte))
+      return -1;
+    insn->rexPrefix = byte;
+    dbgprintf(insn, "Found REX prefix 0x%hhx", byte);
+  } else
+    unconsumeByte(insn);
 
   if (insn->mode == MODE_16BIT) {
-    insn->registerSize       = (hasOpSize ? 4 : 2);
-    insn->addressSize        = (hasAdSize ? 4 : 2);
-    insn->displacementSize   = (hasAdSize ? 4 : 2);
-    insn->immediateSize      = (hasOpSize ? 4 : 2);
+    insn->registerSize = (insn->hasOpSize ? 4 : 2);
+    insn->addressSize = (insn->hasAdSize ? 4 : 2);
+    insn->displacementSize = (insn->hasAdSize ? 4 : 2);
+    insn->immediateSize = (insn->hasOpSize ? 4 : 2);
   } else if (insn->mode == MODE_32BIT) {
-    insn->registerSize       = (hasOpSize ? 2 : 4);
-    insn->addressSize        = (hasAdSize ? 2 : 4);
-    insn->displacementSize   = (hasAdSize ? 2 : 4);
-    insn->immediateSize      = (hasOpSize ? 2 : 4);
+    insn->registerSize = (insn->hasOpSize ? 2 : 4);
+    insn->addressSize = (insn->hasAdSize ? 2 : 4);
+    insn->displacementSize = (insn->hasAdSize ? 2 : 4);
+    insn->immediateSize = (insn->hasOpSize ? 2 : 4);
   } else if (insn->mode == MODE_64BIT) {
     if (insn->rexPrefix && wFromREX(insn->rexPrefix)) {
       insn->registerSize       = 8;
-      insn->addressSize        = (hasAdSize ? 4 : 8);
+      insn->addressSize = (insn->hasAdSize ? 4 : 8);
       insn->displacementSize   = 4;
       insn->immediateSize      = 4;
     } else {
-      insn->registerSize       = (hasOpSize ? 2 : 4);
-      insn->addressSize        = (hasAdSize ? 4 : 8);
-      insn->displacementSize   = (hasOpSize ? 2 : 4);
-      insn->immediateSize      = (hasOpSize ? 2 : 4);
+      insn->registerSize = (insn->hasOpSize ? 2 : 4);
+      insn->addressSize = (insn->hasAdSize ? 4 : 8);
+      insn->displacementSize = (insn->hasOpSize ? 2 : 4);
+      insn->immediateSize = (insn->hasOpSize ? 2 : 4);
     }
   }
 
@@ -758,7 +720,10 @@ static int readOpcode(struct InternalIns
 
       insn->opcodeType = TWOBYTE;
     }
-  }
+  } else if (insn->mandatoryPrefix)
+    // The opcode with mandatory prefix must start with opcode escape.
+    // If not it's legacy repeat prefix
+    insn->mandatoryPrefix = 0;
 
   /*
    * At this point we have consumed the full opcode.
@@ -950,15 +915,38 @@ static int getID(struct InternalInstruct
     } else {
       return -1;
     }
-  } else {
-    if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation))
+  } else if (!insn->mandatoryPrefix) {
+    // If we don't have mandatory prefix we should use legacy prefixes here
+    if (insn->hasOpSize && (insn->mode != MODE_16BIT))
       attrMask |= ATTR_OPSIZE;
-    else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation))
+    if (insn->hasAdSize)
       attrMask |= ATTR_ADSIZE;
-    else if (isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation))
-      attrMask |= ATTR_XS;
-    else if (isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation))
+    if (insn->opcodeType == ONEBYTE) {
+      if (insn->repeatPrefix == 0xf3 && (insn->opcode == 0x90))
+        // Special support for PAUSE
+        attrMask |= ATTR_XS;
+    } else {
+      if (insn->repeatPrefix == 0xf2)
+        attrMask |= ATTR_XD;
+      else if (insn->repeatPrefix == 0xf3)
+        attrMask |= ATTR_XS;
+    }
+  } else {
+    switch (insn->mandatoryPrefix) {
+    case 0xf2:
       attrMask |= ATTR_XD;
+      break;
+    case 0xf3:
+      attrMask |= ATTR_XS;
+      break;
+    case 0x66:
+      if (insn->mode != MODE_16BIT)
+        attrMask |= ATTR_OPSIZE;
+      break;
+    case 0x67:
+      attrMask |= ATTR_ADSIZE;
+      break;
+    }
   }
 
   if (insn->rexPrefix & 0x08)
@@ -977,8 +965,7 @@ static int getID(struct InternalInstruct
    * CALL/JMP/JCC instructions need to ignore 0x66 and consume 4 bytes
    */
 
-  if (insn->mode == MODE_64BIT &&
-      isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) {
+  if ((insn->mode == MODE_64BIT) && insn->hasOpSize) {
     switch (insn->opcode) {
     case 0xE8:
     case 0xE9:
@@ -1058,9 +1045,9 @@ static int getID(struct InternalInstruct
    */
   if (insn->opcodeType == ONEBYTE && ((insn->opcode & 0xFC) == 0xA0)) {
     /* Make sure we observed the prefixes in any position. */
-    if (insn->prefixPresent[0x67])
+    if (insn->hasAdSize)
       attrMask |= ATTR_ADSIZE;
-    if (insn->prefixPresent[0x66])
+    if (insn->hasOpSize)
       attrMask |= ATTR_OPSIZE;
 
     /* In 16-bit, invert the attributes. */
@@ -1075,7 +1062,7 @@ static int getID(struct InternalInstruct
     return 0;
   }
 
-  if ((insn->mode == MODE_16BIT || insn->prefixPresent[0x66]) &&
+  if ((insn->mode == MODE_16BIT || insn->hasOpSize) &&
       !(attrMask & ATTR_OPSIZE)) {
     /*
      * The instruction tables make no distinction between instructions that
@@ -1108,7 +1095,7 @@ static int getID(struct InternalInstruct
     specWithOpSizeName = GetInstrName(instructionIDWithOpsize, miiArg);
 
     if (is16BitEquivalent(specName.data(), specWithOpSizeName.data()) &&
-        (insn->mode == MODE_16BIT) ^ insn->prefixPresent[0x66]) {
+        (insn->mode == MODE_16BIT) ^ insn->hasOpSize) {
       insn->instructionID = instructionIDWithOpsize;
       insn->spec = specifierForUID(instructionIDWithOpsize);
     } else {

Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h (original)
+++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h Mon Oct 16 04:14:29 2017
@@ -546,24 +546,26 @@ struct InternalInstruction {
 
   // Prefix state
 
-  // 1 if the prefix byte corresponding to the entry is present; 0 if not
-  uint8_t prefixPresent[0x100];
-  // contains the location (for use with the reader) of the prefix byte
-  uint64_t prefixLocations[0x100];
+  // The possible mandatory prefix
+  uint8_t mandatoryPrefix;
   // The value of the vector extension prefix(EVEX/VEX/XOP), if present
   uint8_t vectorExtensionPrefix[4];
   // The type of the vector extension prefix
   VectorExtensionType vectorExtensionType;
   // The value of the REX prefix, if present
   uint8_t rexPrefix;
-  // The location where a mandatory prefix would have to be (i.e., right before
-  // the opcode, or right before the REX prefix if one is present).
-  uint64_t necessaryPrefixLocation;
   // The segment override type
   SegmentOverride segmentOverride;
   // 1 if the prefix byte, 0xf2 or 0xf3 is xacquire or xrelease
   bool xAcquireRelease;
 
+  // Address-size override
+  bool hasAdSize;
+  // Operand-size override
+  bool hasOpSize;
+  // The repeat prefix if any
+  uint8_t repeatPrefix;
+
   // Sizes of various critical pieces of data, in bytes
   uint8_t registerSize;
   uint8_t addressSize;

Modified: llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp Mon Oct 16 04:14:29 2017
@@ -50,8 +50,16 @@ void X86ATTInstPrinter::printInst(const
     HasCustomInstComment =
         EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
 
+  unsigned Flags = MI->getFlags();
   if (TSFlags & X86II::LOCK)
     OS << "\tlock\t";
+  if (!(TSFlags & X86II::LOCK) && Flags & X86::IP_HAS_LOCK)
+    OS << "\tlock\n";
+
+  if (Flags & X86::IP_HAS_REPEAT_NE)
+    OS << "\trepne\n";
+  else if (Flags & X86::IP_HAS_REPEAT)
+    OS << "\trep\n";
 
   // Output CALLpcrel32 as "callq" in 64-bit mode.
   // In Intel annotation it's always emitted as "call".

Modified: llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp Mon Oct 16 04:14:29 2017
@@ -43,6 +43,12 @@ void X86IntelInstPrinter::printInst(cons
   if (TSFlags & X86II::LOCK)
     OS << "\tlock\n";
 
+  unsigned Flags = MI->getFlags();
+  if (Flags & X86::IP_HAS_REPEAT_NE)
+    OS << "\trepne\n";
+  else if (Flags & X86::IP_HAS_REPEAT)
+    OS << "\trep\n";
+
   printInstruction(MI, OS);
 
   // Next always print the annotation.

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h Mon Oct 16 04:14:29 2017
@@ -51,6 +51,16 @@ namespace X86 {
     TO_ZERO = 3,
     CUR_DIRECTION = 4
   };
+
+  /// The constants to describe instr prefixes if there are
+  enum IPREFIXES {
+    IP_NO_PREFIX = 0,
+    IP_HAS_OP_SIZE = 1,
+    IP_HAS_AD_SIZE = 2,
+    IP_HAS_REPEAT_NE = 4,
+    IP_HAS_REPEAT = 8,
+    IP_HAS_LOCK = 16
+  };
 } // end namespace X86;
 
 /// X86II - This namespace holds all of the target specific flags that

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp Mon Oct 16 04:14:29 2017
@@ -1108,7 +1108,7 @@ bool X86MCCodeEmitter::emitOpcodePrefix(
     EmitByte(0x66, CurByte, OS);
 
   // Emit the LOCK opcode prefix.
-  if (TSFlags & X86II::LOCK)
+  if (TSFlags & X86II::LOCK || MI.getFlags() & X86::IP_HAS_LOCK)
     EmitByte(0xF0, CurByte, OS);
 
   switch (TSFlags & X86II::OpPrefixMask) {
@@ -1159,6 +1159,7 @@ encodeInstruction(const MCInst &MI, raw_
   unsigned Opcode = MI.getOpcode();
   const MCInstrDesc &Desc = MCII.get(Opcode);
   uint64_t TSFlags = Desc.TSFlags;
+  unsigned Flags = MI.getFlags();
 
   // Pseudo instructions don't get encoded.
   if ((TSFlags & X86II::FormMask) == X86II::Pseudo)
@@ -1194,8 +1195,10 @@ encodeInstruction(const MCInst &MI, raw_
                               MI, OS);
 
   // Emit the repeat opcode prefix as needed.
-  if (TSFlags & X86II::REP)
+  if (TSFlags & X86II::REP || Flags & X86::IP_HAS_REPEAT)
     EmitByte(0xF3, CurByte, OS);
+  if (Flags & X86::IP_HAS_REPEAT_NE)
+    EmitByte(0xF2, CurByte, OS);
 
   // Emit the address size opcode prefix as needed.
   bool need_address_override;

Modified: llvm/trunk/test/MC/Disassembler/X86/prefixes.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/prefixes.txt?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/X86/prefixes.txt (original)
+++ llvm/trunk/test/MC/Disassembler/X86/prefixes.txt Mon Oct 16 04:14:29 2017
@@ -1,5 +1,60 @@
 # RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s
 
+# CHECK: rep
+# CHECK-NEXT: insb    %dx, %es:(%rdi)
+0xf3 0x6c #rep ins
+# CHECK: rep
+# CHECK-NEXT: insl    %dx, %es:(%rdi)
+0xf3 0x6d #rep ins
+# CHECK: rep
+# CHECK-NEXT: movsb   (%rsi), %es:(%rdi)
+0xf3 0xa4 #rep movs
+# CHECK: rep
+# CHECK-NEXT: movsl   (%rsi), %es:(%rdi)
+0xf3 0xa5 #rep movs
+# CHECK: rep
+# CHECK-NEXT: outsb   (%rsi), %dx
+0xf3 0x6e #rep outs
+# CHECK: rep
+# CHECK-NEXT: outsl   (%rsi), %dx
+0xf3 0x6f #rep outs
+# CHECK: rep
+# CHECK-NEXT: lodsb   (%rsi), %al
+0xf3 0xac #rep lods
+# CHECK: rep
+# CHECK-NEXT: lodsl   (%rsi), %eax
+0xf3 0xad #rep lods
+# CHECK: rep
+# CHECK-NEXT: stosb   %al, %es:(%rdi)
+0xf3 0xaa #rep stos
+# CHECK: rep
+# CHECK-NEXT: stosl   %eax, %es:(%rdi)
+0xf3 0xab #rep stos
+# CHECK: rep
+# CHECK-NEXT: cmpsb   %es:(%rdi), (%rsi)
+0xf3 0xa6 #rep cmps
+# CHECK: rep
+# CHECK-NEXT: cmpsl   %es:(%rdi), (%rsi)
+0xf3 0xa7 #repe cmps
+# CHECK: rep
+# CHECK-NEXT: scasb   %es:(%rdi), %al
+0xf3 0xae #repe scas
+# CHECK: rep
+# CHECK-NEXT: scasl   %es:(%rdi), %eax
+0xf3 0xaf #repe scas
+# CHECK: repne
+# CHECK-NEXT: cmpsb   %es:(%rdi), (%rsi)
+0xf2 0xa6 #repne cmps
+# CHECK: repne
+# CHECK-NEXT: cmpsl   %es:(%rdi), (%rsi)
+0xf2 0xa7 #repne cmps
+# CHECK: repne
+# CHECK-NEXT: scasb   %es:(%rdi), %al
+0xf2 0xae #repne scas
+# CHECK: repne
+# CHECK-NEXT: scasl   %es:(%rdi), %eax
+0xf2 0xaf #repne scas
+
 # CHECK: lock
 # CHECK-NEXT:	orl	$16, %fs:776
 0xf0 0x64 0x83 0x0c 0x25 0x08 0x03 0x00 0x00 0x10
@@ -50,7 +105,6 @@
 
 # Test that multiple redundant prefixes work (redundant, but valid x86).
 # CHECK: rep
-# CHECK-NEXT: rep
 # CHECK-NEXT: stosq
 0xf3 0xf3 0x48 0xab
 

Modified: llvm/trunk/test/MC/Disassembler/X86/x86-32.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/x86-32.txt?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/X86/x86-32.txt (original)
+++ llvm/trunk/test/MC/Disassembler/X86/x86-32.txt Mon Oct 16 04:14:29 2017
@@ -797,3 +797,14 @@
 
 # CHECK: nopw %ax
 0x66 0x0f 0x1f 0xc0
+
+# CHECK: movw    %bx, %cs:(%esi,%ebp)
+0x2e 0x66 0x89 0x1c 0x2e
+# CHECK: movl    %ebx, %cs:(%si)
+0x2e 0x67 0x89 0x1c
+# CHECK: movl    %ebx, %cs:(%esi,%ebp)
+0x2e 0x89 0x1c 0x2e
+# CHECK: movw    %bx, %cs:(%si)
+0x2e 0x67 0x66 0x89 0x1c
+# CHECK: movw    %bx, %cs:(%si)
+0x2e 0x66 0x67 0x89 0x1c

Modified: llvm/trunk/test/MC/Disassembler/X86/x86-64.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/x86-64.txt?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/X86/x86-64.txt (original)
+++ llvm/trunk/test/MC/Disassembler/X86/x86-64.txt Mon Oct 16 04:14:29 2017
@@ -486,3 +486,18 @@
 
 # CHECK: nopq %rax
 0x48 0x0f 0x1f 0xC0
+
+# CHECK:  xchgw   %di, %ax
+0x66 0x3e 0x97
+
+# CHECK: movw    %bx, %cs:(%rsi,%rbp)
+0x2e 0x66 0x89 0x1c 0x2e
+# CHECK: movl    %ebx, %cs:(%esi,%ebp)
+0x2e 0x67 0x89 0x1c 0x2e
+# CHECK: movl    %ebx, %cs:(%rsi,%rbp)
+0x2e 0x89 0x1c 0x2e
+# CHECK: movw    %bx, %cs:(%esi,%ebp)
+0x2e 0x67 0x66 0x89 0x1c 0x2e
+# CHECK: movw    %bx, %cs:(%esi,%ebp)
+0x2e 0x66 0x67 0x89 0x1c 0x2e
+

Modified: llvm/trunk/test/MC/X86/intel-syntax-encoding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/intel-syntax-encoding.s?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/intel-syntax-encoding.s (original)
+++ llvm/trunk/test/MC/X86/intel-syntax-encoding.s Mon Oct 16 04:14:29 2017
@@ -54,12 +54,10 @@
 
   acquire lock add [rax], rax
 // CHECK: encoding: [0xf2]
-// CHECK: encoding: [0xf0]
-// CHECK: encoding: [0x48,0x01,0x00]
+// CHECK: encoding: [0xf0,0x48,0x01,0x00]
   release lock add [rax], rax
 // CHECK: encoding: [0xf3]
-// CHECK: encoding: [0xf0]
-// CHECK: encoding: [0x48,0x01,0x00]
+// CHECK: encoding: [0xf0,0x48,0x01,0x00]
 
 // CHECK: encoding: [0x9c]
 // CHECK: encoding: [0x9d]

Modified: llvm/trunk/test/MC/X86/x86-64.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-64.s?rev=315899&r1=315898&r2=315899&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/x86-64.s (original)
+++ llvm/trunk/test/MC/X86/x86-64.s Mon Oct 16 04:14:29 2017
@@ -902,56 +902,48 @@ lock/incl 1(%rsp)
 
 lock addq %rsi, (%rdi)
 // CHECK: lock
-// CHECK: encoding: [0xf0]
 // CHECK: addq %rsi, (%rdi)
-// CHECK: encoding: [0x48,0x01,0x37]
+// CHECK: encoding: [0xf0,0x48,0x01,0x37]
 
 lock subq %rsi, (%rdi)
 // CHECK: lock
-// CHECK: encoding: [0xf0]
 // CHECK: subq %rsi, (%rdi)
-// CHECK: encoding: [0x48,0x29,0x37]
+// CHECK: encoding: [0xf0,0x48,0x29,0x37]
 
 lock andq %rsi, (%rdi)
 // CHECK: lock
-// CHECK: encoding: [0xf0]
 // CHECK: andq %rsi, (%rdi)
-// CHECK: encoding: [0x48,0x21,0x37]
+// CHECK: encoding: [0xf0,0x48,0x21,0x37]
 
 lock orq %rsi, (%rdi)
 // CHECK: lock
-// CHECK: encoding: [0xf0]
 // CHECK: orq %rsi, (%rdi)
-// CHECK: encoding: [0x48,0x09,0x37]
+// CHECK: encoding: [0xf0,0x48,0x09,0x37]
 
 lock xorq %rsi, (%rdi)
 // CHECK: lock
-// CHECK: encoding: [0xf0]
 // CHECK: xorq %rsi, (%rdi)
-// CHECK: encoding: [0x48,0x31,0x37]
+// CHECK: encoding: [0xf0,0x48,0x31,0x37]
 
 xacquire lock addq %rax, (%rax)
 // CHECK: xacquire
 // CHECK: encoding: [0xf2]
 // CHECK: lock
-// CHECK: encoding: [0xf0]
 // CHECK: addq %rax, (%rax)
-// CHECK: encoding: [0x48,0x01,0x00]
+// CHECK: encoding: [0xf0,0x48,0x01,0x00]
 
 xrelease lock addq %rax, (%rax)
 // CHECK: xrelease
 // CHECK: encoding: [0xf3]
 // CHECK: lock
-// CHECK: encoding: [0xf0]
 // CHECK: addq %rax, (%rax)
-// CHECK: encoding: [0x48,0x01,0x00]
+// CHECK: encoding: [0xf0,0x48,0x01,0x00]
 
 // rdar://8033482
 rep movsl
 // CHECK: rep
-// CHECK: encoding: [0xf3]
 // CHECK: movsl
-// CHECK: encoding: [0xa5]
+// CHECK: encoding: [0xf3,0xa5]
 
 
 // rdar://8403974




More information about the llvm-commits mailing list