mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
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:
parent
ec9a35a6f9
commit
ea7da50e5a
@ -115,6 +115,7 @@ def X86InstrInfo : InstrInfo {
|
|||||||
"hasREX_WPrefix",
|
"hasREX_WPrefix",
|
||||||
"ImmTypeBits",
|
"ImmTypeBits",
|
||||||
"FPFormBits",
|
"FPFormBits",
|
||||||
|
"hasLockPrefix",
|
||||||
"Opcode"];
|
"Opcode"];
|
||||||
let TSFlagsShifts = [0,
|
let TSFlagsShifts = [0,
|
||||||
6,
|
6,
|
||||||
@ -123,6 +124,7 @@ def X86InstrInfo : InstrInfo {
|
|||||||
12,
|
12,
|
||||||
13,
|
13,
|
||||||
16,
|
16,
|
||||||
|
19,
|
||||||
24];
|
24];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,6 +540,9 @@ void Emitter::emitInstruction(const MachineInstr &MI,
|
|||||||
const TargetInstrDesc *Desc) {
|
const TargetInstrDesc *Desc) {
|
||||||
unsigned Opcode = Desc->Opcode;
|
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.
|
// Emit the repeat opcode prefix as needed.
|
||||||
if ((Desc->TSFlags & X86II::Op0Mask) == X86II::REP) MCE.emitByte(0xF3);
|
if ((Desc->TSFlags & X86II::Op0Mask) == X86II::REP) MCE.emitByte(0xF3);
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ def SpecialFP : FPFormat<7>;
|
|||||||
class OpSize { bit hasOpSizePrefix = 1; }
|
class OpSize { bit hasOpSizePrefix = 1; }
|
||||||
class AdSize { bit hasAdSizePrefix = 1; }
|
class AdSize { bit hasAdSizePrefix = 1; }
|
||||||
class REX_W { bit hasREX_WPrefix = 1; }
|
class REX_W { bit hasREX_WPrefix = 1; }
|
||||||
|
class LOCK { bit hasLockPrefix = 1; }
|
||||||
class TB { bits<4> Prefix = 1; }
|
class TB { bits<4> Prefix = 1; }
|
||||||
class REP { bits<4> Prefix = 2; }
|
class REP { bits<4> Prefix = 2; }
|
||||||
class D8 { bits<4> Prefix = 3; }
|
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?
|
bit hasREX_WPrefix = 0; // Does this inst requires the REX.W prefix?
|
||||||
FPFormat FPForm; // What flavor of FP instruction is this?
|
FPFormat FPForm; // What flavor of FP instruction is this?
|
||||||
bits<3> FPFormBits = 0;
|
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>
|
class I<bits<8> o, Format f, dag outs, dag ins, string asm, list<dag> pattern>
|
||||||
|
@ -216,7 +216,11 @@ namespace X86II {
|
|||||||
// SpecialFP - Special instruction forms. Dispatch by opcode explicitly.
|
// SpecialFP - Special instruction forms. Dispatch by opcode explicitly.
|
||||||
SpecialFP = 7 << FPTypeShift,
|
SpecialFP = 7 << FPTypeShift,
|
||||||
|
|
||||||
// Bits 19 -> 23 are unused
|
// Lock prefix
|
||||||
|
LOCKShift = 19,
|
||||||
|
LOCK = 1 << LOCKShift,
|
||||||
|
|
||||||
|
// Bits 20 -> 23 are unused
|
||||||
OpcodeShift = 24,
|
OpcodeShift = 24,
|
||||||
OpcodeMask = 0xFF << OpcodeShift
|
OpcodeMask = 0xFF << OpcodeShift
|
||||||
};
|
};
|
||||||
|
@ -2538,11 +2538,82 @@ def EH_RETURN : I<0xC3, RawFrm, (outs), (ins GR32:$addr),
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Atomic support
|
// Atomic support
|
||||||
//
|
//
|
||||||
let Defs = [EAX] in
|
|
||||||
def LCMPXCHGL : I<0, Pseudo, (outs GR32:$dst),
|
//FIXME: Please check the format
|
||||||
(ins GR32:$ptr, GR32:$cmp, GR32:$swap),
|
|
||||||
"movl $cmp, %eax ; lock cmpxchgl $swap,($ptr) ; movl %eax, $dst",
|
let Defs = [EAX], Uses = [EAX] in {
|
||||||
[(set GR32:$dst, (atomic_lcs_32 GR32:$ptr, GR32:$cmp, GR32:$swap))]>;
|
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
|
// Non-Instruction Patterns
|
||||||
|
Loading…
Reference in New Issue
Block a user