diff options
author | Bill Wendling <isanbard@gmail.com> | 2009-05-28 23:40:46 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2009-05-28 23:40:46 +0000 |
commit | 6ee7655838955fd02c8232db3825a976f3d1cab1 (patch) | |
tree | 12961df453e2c0405f6fb6daf20d2216d238b3c2 /lib/Target/X86 | |
parent | f8cdaecee9dd22420273d0173b956e794dfb403b (diff) | |
download | external_llvm-6ee7655838955fd02c8232db3825a976f3d1cab1.zip external_llvm-6ee7655838955fd02c8232db3825a976f3d1cab1.tar.gz external_llvm-6ee7655838955fd02c8232db3825a976f3d1cab1.tar.bz2 |
The MONITOR and MWAIT instructions have insufficient information for
decoding. Essentially, they both map to the same column in the "opcode
extensions for one- and two-byte opcodes" table in the x86 manual. The RawFrm
complicates decoding this.
Instead, use opcode 0x01, prefix 0x01, and form MRM1r. Then have the code
emitter special case these, a la [SML]FENCE.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72556 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86')
-rw-r--r-- | lib/Target/X86/X86CodeEmitter.cpp | 19 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.cpp | 14 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrSSE.td | 4 |
3 files changed, 27 insertions, 10 deletions
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index 63bf18d..efd64e0 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -671,13 +671,26 @@ void Emitter::emitInstruction(const MachineInstr &MI, case X86II::MRM6r: case X86II::MRM7r: { MCE.emitByte(BaseOpcode); - // Special handling of lfence and mfence. + // Special handling of lfence, mfence, monitor, and mwait. if (Desc->getOpcode() == X86::LFENCE || - Desc->getOpcode() == X86::MFENCE) + Desc->getOpcode() == X86::MFENCE || + Desc->getOpcode() == X86::MONITOR || + Desc->getOpcode() == X86::MWAIT) { emitRegModRMByte((Desc->TSFlags & X86II::FormMask)-X86II::MRM0r); - else + + switch (Desc->getOpcode()) { + default: break; + case X86::MONITOR: + MCE.emitByte(0xC8); + break; + case X86::MWAIT: + MCE.emitByte(0xC9); + break; + } + } else { emitRegModRMByte(MI.getOperand(CurOp++).getReg(), (Desc->TSFlags & X86II::FormMask)-X86II::MRM0r); + } if (CurOp != NumOps) { const MachineOperand &MO1 = MI.getOperand(CurOp++); diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 5fca9c7..2cd3733 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -2885,7 +2885,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI, // Emit the lock opcode prefix as needed. if (Desc->TSFlags & X86II::LOCK) ++FinalSize; - // Emit segment overrid opcode prefix as needed. + // Emit segment override opcode prefix as needed. switch (Desc->TSFlags & X86II::SegOvrMask) { case X86II::FS: case X86II::GS: @@ -2943,7 +2943,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI, case X86II::T8: // 0F 38 ++FinalSize; break; - case X86II::TA: // 0F 3A + case X86II::TA: // 0F 3A ++FinalSize; break; } @@ -3087,11 +3087,15 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI, case X86II::MRM4r: case X86II::MRM5r: case X86II::MRM6r: case X86II::MRM7r: ++FinalSize; - // Special handling of lfence and mfence. if (Desc->getOpcode() == X86::LFENCE || - Desc->getOpcode() == X86::MFENCE) + Desc->getOpcode() == X86::MFENCE) { + // Special handling of lfence and mfence; FinalSize += sizeRegModRMByte(); - else { + } else if (Desc->getOpcode() == X86::MONITOR || + Desc->getOpcode() == X86::MWAIT) { + // Special handling of monitor and mwait. + FinalSize += sizeRegModRMByte() + 1; // +1 for the opcode. + } else { ++CurOp; FinalSize += sizeRegModRMByte(); } diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index 83eae18..1fafa46 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -2504,9 +2504,9 @@ let Constraints = "$src1 = $dst" in { } // Thread synchronization -def MONITOR : I<0xC8, RawFrm, (outs), (ins), "monitor", +def MONITOR : I<0x01, MRM1r, (outs), (ins), "monitor", [(int_x86_sse3_monitor EAX, ECX, EDX)]>,TB, Requires<[HasSSE3]>; -def MWAIT : I<0xC9, RawFrm, (outs), (ins), "mwait", +def MWAIT : I<0x01, MRM1r, (outs), (ins), "mwait", [(int_x86_sse3_mwait ECX, EAX)]>, TB, Requires<[HasSSE3]>; // vector_shuffle v1, <undef> <1, 1, 3, 3> |