Add lock prefix support to x86. Also add the instructions necessary for the atomic ops. They are still marked pseudo, since I cannot figure out what format to use, but they are the correct opcode.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47795 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Lenharth 2008-03-01 13:37:02 +00:00
parent ec9a35a6f9
commit ea7da50e5a
5 changed files with 88 additions and 6 deletions

View File

@ -115,6 +115,7 @@ def X86InstrInfo : InstrInfo {
"hasREX_WPrefix",
"ImmTypeBits",
"FPFormBits",
"hasLockPrefix",
"Opcode"];
let TSFlagsShifts = [0,
6,
@ -123,6 +124,7 @@ def X86InstrInfo : InstrInfo {
12,
13,
16,
19,
24];
}

View File

@ -540,6 +540,9 @@ void Emitter::emitInstruction(const MachineInstr &MI,
const TargetInstrDesc *Desc) {
unsigned Opcode = Desc->Opcode;
// Emit the lock opcode prefix as needed.
if (Desc->TSFlags & X86II::LOCK) MCE.emitByte(0xF0);
// Emit the repeat opcode prefix as needed.
if ((Desc->TSFlags & X86II::Op0Mask) == X86II::REP) MCE.emitByte(0xF3);

View File

@ -62,6 +62,7 @@ def SpecialFP : FPFormat<7>;
class OpSize { bit hasOpSizePrefix = 1; }
class AdSize { bit hasAdSizePrefix = 1; }
class REX_W { bit hasREX_WPrefix = 1; }
class LOCK { bit hasLockPrefix = 1; }
class TB { bits<4> Prefix = 1; }
class REP { bits<4> Prefix = 2; }
class D8 { bits<4> Prefix = 3; }
@ -102,6 +103,7 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
bit hasREX_WPrefix = 0; // Does this inst requires the REX.W prefix?
FPFormat FPForm; // What flavor of FP instruction is this?
bits<3> FPFormBits = 0;
bit hasLockPrefix = 0; // Does this inst have a 0xF0 prefix?
}
class I<bits<8> o, Format f, dag outs, dag ins, string asm, list<dag> pattern>

View File

@ -216,7 +216,11 @@ namespace X86II {
// SpecialFP - Special instruction forms. Dispatch by opcode explicitly.
SpecialFP = 7 << FPTypeShift,
// Bits 19 -> 23 are unused
// Lock prefix
LOCKShift = 19,
LOCK = 1 << LOCKShift,
// Bits 20 -> 23 are unused
OpcodeShift = 24,
OpcodeMask = 0xFF << OpcodeShift
};

View File

@ -2538,11 +2538,82 @@ def EH_RETURN : I<0xC3, RawFrm, (outs), (ins GR32:$addr),
//===----------------------------------------------------------------------===//
// Atomic support
//
let Defs = [EAX] in
def LCMPXCHGL : I<0, Pseudo, (outs GR32:$dst),
(ins GR32:$ptr, GR32:$cmp, GR32:$swap),
"movl $cmp, %eax ; lock cmpxchgl $swap,($ptr) ; movl %eax, $dst",
[(set GR32:$dst, (atomic_lcs_32 GR32:$ptr, GR32:$cmp, GR32:$swap))]>;
//FIXME: Please check the format
let Defs = [EAX], Uses = [EAX] in {
def CMPXCHG32 : I<0xB1, Pseudo, (outs), (ins GR32:$ptr, GR32:$swap),
"cmpxchgl $swap,($ptr)", []>, TB;
def LCMPXCHG32 : I<0xB1, Pseudo, (outs), (ins GR32:$ptr, GR32:$swap),
"lock cmpxchgl $swap,($ptr)", []>, TB, LOCK;
}
let Defs = [AX], Uses = [AX] in {
def CMPXCHG16 : I<0xB1, Pseudo, (outs), (ins GR32:$ptr, GR16:$swap),
"cmpxchgw $swap,($ptr)", []>, TB, OpSize;
def LCMPXCHG16 : I<0xB1, Pseudo, (outs), (ins GR32:$ptr, GR16:$swap),
"cmpxchgw $swap,($ptr)", []>, TB, OpSize, LOCK;
}
let Defs = [AL], Uses = [AL] in {
def CMPXCHG8 : I<0xB0, Pseudo, (outs), (ins GR32:$ptr, GR8:$swap),
"cmpxchgb $swap,($ptr)", []>, TB;
def LCMPXCHG8 : I<0xB0, Pseudo, (outs), (ins GR32:$ptr, GR8:$swap),
"cmpxchgb $swap,($ptr)", []>, TB, LOCK;
}
let Constraints = "$val = $dst" in {
def LXADD32 : I<0xC1, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
"lock xadd $val, $ptr",
[(set GR32:$dst, (atomic_las_32 addr:$ptr, GR32:$val))]>,
TB, LOCK;
def LXADD16 : I<0xC1, Pseudo, (outs GR16:$dst), (ins i16mem:$ptr, GR16:$val),
"lock xadd $val, $ptr",
[(set GR16:$dst, (atomic_las_16 addr:$ptr, GR16:$val))]>,
TB, OpSize, LOCK;
def LXADD8 : I<0xC0, Pseudo, (outs GR8:$dst), (ins i8mem:$ptr, GR8:$val),
"lock xadd $val, $ptr",
[(set GR8:$dst, (atomic_las_8 addr:$ptr, GR8:$val))]>,
TB, LOCK;
def XADD32 : I<0xC1, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
"lock xadd $val, $ptr", []>, TB;
def XADD16 : I<0xC1, Pseudo, (outs GR16:$dst), (ins i16mem:$ptr, GR16:$val),
"lock xadd $val, $ptr", []>, TB, OpSize;
def XADD8 : I<0xC0, Pseudo, (outs GR8:$dst), (ins i8mem:$ptr, GR8:$val),
"lock xadd $val, $ptr", []>, TB;
def LXCHG32 : I<0x87, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
"lock xchg $val, $ptr",
[(set GR32:$dst, (atomic_swap_32 addr:$ptr, GR32:$val))]>, LOCK;
def LXCHG16 : I<0x87, Pseudo, (outs GR16:$dst), (ins i16mem:$ptr, GR16:$val),
"lock xchg $val, $ptr",
[(set GR16:$dst, (atomic_swap_16 addr:$ptr, GR16:$val))]>,
OpSize, LOCK;
def LXCHG8 : I<0x86, Pseudo, (outs GR8:$dst), (ins i8mem:$ptr, GR8:$val),
"lock xchg $val, $ptr",
[(set GR8:$dst, (atomic_swap_8 addr:$ptr, GR8:$val))]>, LOCK;
def XCHG32 : I<0x87, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
"lock xchg $val, $ptr", []>;
def XCHG16 : I<0x87, Pseudo, (outs GR16:$dst), (ins i16mem:$ptr, GR16:$val),
"lock xchg $val, $ptr", []>, OpSize;
def XCHG8 : I<0x86, Pseudo, (outs GR8:$dst), (ins i8mem:$ptr, GR8:$val),
"lock xchg $val, $ptr", []>;
}
//FIXME: these are a hack until the patterns using the LCMPXCHG written
let Defs = [EAX], Uses = [EAX] in
def PLCMPXCHG32 : I<0, Pseudo, (outs GR32:$dst),
(ins i32mem:$ptr, GR32:$cmp, GR32:$swap),
"movl $cmp, %eax \n lock \n cmpxchgl $swap,$ptr \n movl %eax, $dst",
[(set GR32:$dst, (atomic_lcs_32 addr:$ptr, GR32:$cmp, GR32:$swap))]>;
let Defs = [AX] in
def PLCMPXCHG16 : I<0, Pseudo, (outs GR16:$dst),
(ins i16mem:$ptr, GR16:$cmp, GR16:$swap),
"movw $cmp, %ax \n lock \n cmpxchgw $swap,$ptr \n movw %ax, $dst",
[(set GR16:$dst, (atomic_lcs_16 addr:$ptr, GR16:$cmp, GR16:$swap))]>;
let Defs = [AL] in
def PLCMPXCHG8 : I<0, Pseudo, (outs GR8:$dst),
(ins i8mem:$ptr, GR8:$cmp, GR8:$swap),
"movb $cmp, %al \n lock cmpxchgb $swap,$ptr \n movb %al, $dst",
[(set GR8:$dst, (atomic_lcs_8 addr:$ptr, GR8:$cmp, GR8:$swap))]>;
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns