mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-04 11:27:34 +00:00
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
This commit is contained in:
parent
056dbd0645
commit
2265ba0717
@ -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++);
|
||||
|
@ -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:
|
||||
@ -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();
|
||||
}
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user