Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -1515,7 +1515,8 @@ Name == "lock" || Name == "rep" || Name == "repe" || Name == "repz" || Name == "repne" || Name == "repnz" || - Name == "rex64" || Name == "data16"; + Name == "rex64" || Name == "data16" || + Name == "xacquire" || Name == "xrelease"; // This does the actual operand parsing. Don't parse any more if we have a Index: lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp =================================================================== --- lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp +++ lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp @@ -47,6 +47,16 @@ if (TSFlags & X86II::LOCK) OS << "\tlock\n"; + if (TSFlags & X86II::XACQUIRE) { + assert(!(TSFlags & X86II::XRELEASE) && "unknown HLE prefix hints!"); + OS << "\txacquire\n"; + } + + if (TSFlags & X86II::XRELEASE) { + assert(!(TSFlags & X86II::XACQUIRE) && "unknown HLE prefix hints!"); + OS << "\txrelease\n"; + } + // Try to print any aliases first. if (!printAliasInstr(MI, OS)) printInstruction(MI, OS); Index: lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp =================================================================== --- lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp +++ lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp @@ -39,6 +39,16 @@ if (TSFlags & X86II::LOCK) OS << "\tlock\n"; + if (TSFlags & X86II::XACQUIRE) { + assert(!(TSFlags & X86II::XRELEASE) && "unknown HLE prefix hints!"); + OS << "\txacquire\n"; + } + + if (TSFlags & X86II::XRELEASE) { + assert(!(TSFlags & X86II::XACQUIRE) && "unknown HLE prefix hints!"); + OS << "\txrelease\n"; + } + printInstruction(MI, OS); // Next always print the annotation. Index: lib/Target/X86/MCTargetDesc/X86BaseInfo.h =================================================================== --- lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -415,9 +415,19 @@ LOCKShift = FPTypeShift + 3, LOCK = 1 << LOCKShift, + // TSX/HLE prefix + TSXShift = LOCKShift + 1, + TSXMask = 3 << TSXShift, + + // XACQUIRE - Specifies that this instruction has XACQUIRE HLE prefix hint + XACQUIRE = 1 << TSXShift, + + // XRELEASE - Specifies that this instruction has XRELEASE HLE prefix hint + XRELEASE = 2 << TSXShift, + // Segment override prefixes. Currently we just need ability to address // stuff in gs and fs segments. - SegOvrShift = LOCKShift + 1, + SegOvrShift = TSXShift + 2, SegOvrMask = 3 << SegOvrShift, FS = 1 << SegOvrShift, GS = 2 << SegOvrShift, Index: lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -851,6 +851,16 @@ if (TSFlags & X86II::LOCK) EmitByte(0xF0, CurByte, OS); + if (TSFlags & X86II::XACQUIRE) { + assert(!(TSFlags & X86II::XRELEASE) && "unknown HLE prefix hints!"); + EmitByte(0xF2, CurByte, OS); + } + + if (TSFlags & X86II::XRELEASE) { + assert(!(TSFlags & X86II::XACQUIRE) && "unknown HLE prefix hints!"); + EmitByte(0xF3, CurByte, OS); + } + // Emit segment override opcode prefix as needed. EmitSegmentOverridePrefix(TSFlags, CurByte, MemOperand, MI, OS); Index: lib/Target/X86/X86InstrFormats.td =================================================================== --- lib/Target/X86/X86InstrFormats.td +++ lib/Target/X86/X86InstrFormats.td @@ -99,6 +99,8 @@ class AdSize { bit hasAdSizePrefix = 1; } class REX_W { bit hasREX_WPrefix = 1; } class LOCK { bit hasLockPrefix = 1; } +class XACQ { bit hasXAcquire = 1; } +class XREL { bit hasXRelease = 1; } class SegFS { bits<2> SegOvrBits = 1; } class SegGS { bits<2> SegOvrBits = 2; } class TB { bits<5> Prefix = 1; } @@ -163,6 +165,8 @@ bit hasREX_WPrefix = 0; // Does this inst require the REX.W prefix? FPFormat FPForm = NotFP; // What flavor of FP instruction is this? bit hasLockPrefix = 0; // Does this inst have a 0xF0 prefix? + bit hasXAcquire = 0; // Does this instruction require an XACQUIRE prefix? + bit hasXRelease = 0; // Does this instruction require an XRELEASE prefix? bits<2> SegOvrBits = 0; // Segment override prefix. Domain ExeDomain = d; bit hasVEXPrefix = 0; // Does this inst require a VEX prefix? @@ -187,19 +191,21 @@ let TSFlags{16-14} = ImmT.Value; let TSFlags{19-17} = FPForm.Value; let TSFlags{20} = hasLockPrefix; - let TSFlags{22-21} = SegOvrBits; - let TSFlags{24-23} = ExeDomain.Value; - let TSFlags{32-25} = Opcode; - let TSFlags{33} = hasVEXPrefix; - let TSFlags{34} = hasVEX_WPrefix; - let TSFlags{35} = hasVEX_4VPrefix; - let TSFlags{36} = hasVEX_4VOp3Prefix; - let TSFlags{37} = hasVEX_i8ImmReg; - let TSFlags{38} = hasVEX_L; - let TSFlags{39} = ignoresVEX_L; - let TSFlags{40} = has3DNow0F0FOpcode; - let TSFlags{41} = hasMemOp4Prefix; - let TSFlags{42} = hasXOP_Prefix; + let TSFlags{21} = hasXAcquire; + let TSFlags{22} = hasXRelease; + let TSFlags{24-23} = SegOvrBits; + let TSFlags{26-25} = ExeDomain.Value; + let TSFlags{34-27} = Opcode; + let TSFlags{35} = hasVEXPrefix; + let TSFlags{36} = hasVEX_WPrefix; + let TSFlags{37} = hasVEX_4VPrefix; + let TSFlags{38} = hasVEX_4VOp3Prefix; + let TSFlags{39} = hasVEX_i8ImmReg; + let TSFlags{40} = hasVEX_L; + let TSFlags{41} = ignoresVEX_L; + let TSFlags{42} = has3DNow0F0FOpcode; + let TSFlags{43} = hasMemOp4Prefix; + let TSFlags{44} = hasXOP_Prefix; } class PseudoI pattern> Index: lib/Target/X86/X86InstrInfo.td =================================================================== --- lib/Target/X86/X86InstrInfo.td +++ lib/Target/X86/X86InstrInfo.td @@ -1460,6 +1460,10 @@ def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>; } +// HLE hint prefix +def : MnemonicAlias<"xacquire", "repne">; +def : MnemonicAlias<"xrelease", "rep">; + // String manipulation instructions def LODSB : I<0xAC, RawFrm, (outs), (ins), "lodsb", [], IIC_LODS>; Index: test/MC/X86/x86_64-hle-encoding.s =================================================================== --- /dev/null +++ test/MC/X86/x86_64-hle-encoding.s @@ -0,0 +1,25 @@ +// RUN: llvm-mc -triple x86_64-unknown-unknown --show-encoding %s | FileCheck %s + +// CHECK: lock +// CHECK: encoding: [0xf0] +// CHECK: repne +// CHECK: encoding: [0xf2] + lock xacquire xaddq %rax, sym(%rip) + +// CHECK: repne +// CHECK: encoding: [0xf2] +// CHECK: lock +// CHECK: encoding: [0xf0] + xacquire lock xaddq %rax, sym(%rip) + +// CHECK: lock +// CHECK: encoding: [0xf0] +// CHECK: rep +// CHECK: encoding: [0xf3] + lock xrelease xaddq %rax, sym(%rip) + +// CHECK: rep +// CHECK: encoding: [0xf3] +// CHECK: lock +// CHECK: encoding: [0xf0] + xrelease lock xaddq %rax, sym(%rip)