patch is attached. - michael On Tue, 2013-02-19 at 14:12 -0800, Michael Liao wrote: > Here is the patch > 0003-Add-XACQ-XREL-prefix-and-encoding-asm-printer-suppor.patch > > Yours > - Michael > > On Tue, 2013-02-19 at 14:07 -0800, Michael Liao wrote: > > Hi All, > > > > I'd like to add HLE support in LLVM/clang consistent to GCC's style [1]. > > HLE from Intel TSX [2] is legacy compatible instruction set extension to > > specify transactional region by adding XACQUIRE and XRELEASE prefixes. > > To support that, GCC chooses the approach by extending the memory order > > flag in __atomic_* builtins with target-specific memory model in high > > bits (bit 31-16 for target-specific memory model, bit 15-0 for the > > general memory model.) To follow the similar approach, I propose to > > change LLVM/clang by adding: > > > > + a metadata 'targetflags' in LLVM atomic IR to pass this > > target-specific memory model hint > > > > + one extra target flag in AtomicSDNode & MemIntrinsicSDNode to specify > > XACQUIRE or XRELEASE hints > > This extra target flag is embedded into the SubclassData fields. The > > following is rationale how such target flags are embedded into > > SubclassData in SDNode > > > > here is the current SDNode class hierarchy of memory related nodes > > > > SDNode -> MemSDNode -> LSBaseNode -> LoadSDNode > > | + -> StoreSDNode > > + -> AtomicSDNode > > + -> MemIntrinsicSDNode > > > > here is the current SubclassData definitions: > > > > bit 0~1 : extension type used in LoadSDNode > > bit 0 : truncating store in StoreSDNode > > bit 2~4 : addressing mode in LSBaseNode > > bit 5 : volatile bit in MemSDNode > > bit 6 : non-temporal bit in MemSDNode > > bit 7 : invariant bit in MemSDNode > > bit 8~11: memory order in AtomicSDNode > > bit 12 : synch scope in AtomicSDNode > > > > Considering the class hierarchy, we could safely reused bit 0~1 as the > > target flags in AtomicSDNode/MemIntrinsicNode > > > > + X86 backend is modified to generate additional XACQUIRE/XRELEASE > > prefix based on the specified target flag > > > > > > The following are details of each patch: > > > > * 0001-Add-targetflags-in-AtomicSDNode-MemIntrinsicSDNode.patch > > > > This patch adds 'targetflags' support in AtomicSDNode and > > MemIntrinsicSDNode. It will check metadata 'targetflags' and embedded > > its value into SubclassData. Currently, only two bits are defined. > > > > * 0002-Add-HLE-target-feature.patch > > > > This patch adds HLE feature and auto-detection support > > > > * 0003-Add-XACQ-XREL-prefix-and-encoding-asm-printer-suppor.patch > > > > This patch adds XACQUIRE/XRELEASE prefix and its assembler/encoding > > support > > > > * 0004-Enable-HLE-code-generation.patch > > > > This patch enables HLE code generation by extending the current logic to > > handle 'targetflags'. > > > > * 0001-Add-target-flags-support-for-atomic-ops.patch > > > > This patch adds target flags support in __atomic_* builtins. It splits > > the whole 32-bit order word into high and low 16-bit parts. The low > > 16-bit is the original memory order and the high 16-bit will be > > re-defined as target-specific flags and passed through 'targetflags' > > metadata. > > > > * 0002-Add-mhle-option-support-and-populate-pre-defined-mac.patch > > > > It adds '-m[no]hle' option to turn on HLE feature or not. Once HLE > > feature is turned on, two more macros (__ATOMIC_HLE_ACQUIRE and > > __ATOMIC_HLE_RELEASE) are defined for developers to mark atomic > > builtins. > > > > Thanks for your time to review! > > > > Yours > > - Michael > > --- > > [1] http://gcc.gnu.org/ml/gcc-patches/2012-04/msg01073.html > > [2] http://software.intel.com/sites/default/files/319433-014.pdf > > >
>From 3fc0f1c4b089f16cc064437ba238c5e17b67ea04 Mon Sep 17 00:00:00 2001 From: Michael Liao <[email protected]> Date: Thu, 5 Jul 2012 21:32:14 -0700 Subject: [PATCH 3/4] Add XACQ/XREL prefix and encoding/asm-printer support --- lib/Target/X86/AsmParser/X86AsmParser.cpp | 3 +- lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp | 10 ++++++ lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp | 10 ++++++ lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 12 +++++++- lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 10 ++++++ lib/Target/X86/X86InstrFormats.td | 32 ++++++++++++-------- lib/Target/X86/X86InstrInfo.td | 4 +++ test/MC/X86/x86_64-hle-encoding.s | 25 +++++++++++++++ 8 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 test/MC/X86/x86_64-hle-encoding.s diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 8c4c447..b9dc8bb 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -1515,7 +1515,8 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 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 diff --git a/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp index e357710..7764961 100644 --- a/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp +++ b/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp @@ -47,6 +47,16 @@ void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 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); diff --git a/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp b/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp index 141f4a4..734dfe2 100644 --- a/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp +++ b/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp @@ -39,6 +39,16 @@ void X86IntelInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 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. diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index 9e68388..fb21398 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -415,9 +415,19 @@ namespace X86II { 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, diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 122204a..f227d7c 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -851,6 +851,16 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, 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); diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index 44e574d..d5bd098 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -99,6 +99,8 @@ class OpSize { bit hasOpSizePrefix = 1; } 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 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins, 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 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins, 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<dag oops, dag iops, list<dag> pattern> diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 46daaad..04d8f19 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1460,6 +1460,10 @@ def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>; 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>; diff --git a/test/MC/X86/x86_64-hle-encoding.s b/test/MC/X86/x86_64-hle-encoding.s new file mode 100644 index 0000000..4109fb4 --- /dev/null +++ b/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) -- 1.7.9.5
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
