diff options
Diffstat (limited to 'llvm/lib')
3 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp index ca71c4f3519..f03068e0cdc 100644 --- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -683,6 +683,15 @@ static bool translateInstruction(MCInst &mcInst,    }    mcInst.setOpcode(insn.instructionID); +  // If when reading the prefix bytes we determined the overlapping 0xf2 or 0xf3 +  // prefix bytes should be disassembled as xrelease and xacquire then set the +  // opcode to those instead of the rep and repne opcodes. +  if (insn.xAcquireRelease) { +    if(mcInst.getOpcode() == X86::REP_PREFIX) +      mcInst.setOpcode(X86::XRELEASE_PREFIX); +    else if(mcInst.getOpcode() == X86::REPNE_PREFIX) +      mcInst.setOpcode(X86::XACQUIRE_PREFIX); +  }    int index; diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index e40edba6d68..55ab8ebe7b0 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -328,6 +328,27 @@ static int readPrefixes(struct InternalInstruction* insn) {          break;        if (lookAtByte(insn, &nextByte))          return -1; +      /* +       * If the byte is 0xf2 or 0xf3, and any of the following conditions are +       * met: +       * - it is followed by a LOCK (0xf0) prefix +       * - 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))) +        insn->xAcquireRelease = TRUE; +      /* +       * 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)) +        insn->xAcquireRelease = TRUE;        if (insn->mode == MODE_64BIT && (nextByte & 0xf0) == 0x40) {          if (consumeByte(insn, &nextByte))            return -1; diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h index 407ead3cafa..04a0dc038bc 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h @@ -457,6 +457,8 @@ struct InternalInstruction {    uint64_t necessaryPrefixLocation;    /* The segment override type */    SegmentOverride segmentOverride; +  /* 1 if the prefix byte, 0xf2 or 0xf3 is xacquire or xrelease */ +  BOOL xAcquireRelease;    /* Sizes of various critical pieces of data, in bytes */    uint8_t registerSize;  | 

