[llvm] r278782 - [X86] Add xgetbv/xsetbv intrinsics to non-windows platforms
Guy Blank via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 15 23:41:00 PDT 2016
Author: guyblank
Date: Tue Aug 16 01:41:00 2016
New Revision: 278782
URL: http://llvm.org/viewvc/llvm-project?rev=278782&view=rev
Log:
[X86] Add xgetbv/xsetbv intrinsics to non-windows platforms
Differential Revision: https://reviews.llvm.org/D21958
Added:
llvm/trunk/test/CodeGen/X86/system-intrinsics-xgetbv.ll
llvm/trunk/test/CodeGen/X86/system-intrinsics-xsetbv.ll
Modified:
llvm/trunk/include/llvm/IR/IntrinsicsX86.td
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86InstrSystem.td
llvm/trunk/lib/Target/X86/X86IntrinsicsInfo.h
Modified: llvm/trunk/include/llvm/IR/IntrinsicsX86.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicsX86.td?rev=278782&r1=278781&r2=278782&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/IntrinsicsX86.td (original)
+++ llvm/trunk/include/llvm/IR/IntrinsicsX86.td Tue Aug 16 01:41:00 2016
@@ -4130,6 +4130,10 @@ let TargetPrefix = "x86" in { // All in
Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
def int_x86_xsaves64 :
Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+ def int_x86_xgetbv :
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty], []>;
+ def int_x86_xsetbv :
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
}
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=278782&r1=278781&r2=278782&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Aug 16 01:41:00 2016
@@ -18480,6 +18480,51 @@ static SDValue getPrefetchNode(unsigned
return SDValue(Res, 0);
}
+/// Handles the lowering of builtin intrinsic that return the value
+/// of the extended control register.
+static void getExtendedControlRegister(SDNode *N, const SDLoc &DL,
+ SelectionDAG &DAG,
+ const X86Subtarget &Subtarget,
+ SmallVectorImpl<SDValue> &Results) {
+ assert(N->getNumOperands() == 3 && "Unexpected number of operands!");
+ SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
+ SDValue LO, HI;
+
+ // The ECX register is used to select the index of the XCR register to
+ // return.
+ SDValue Chain =
+ DAG.getCopyToReg(N->getOperand(0), DL, X86::ECX, N->getOperand(2));
+ SDNode *N1 = DAG.getMachineNode(X86::XGETBV, DL, Tys, Chain);
+ Chain = SDValue(N1, 0);
+
+ // Reads the content of XCR and returns it in registers EDX:EAX.
+ if (Subtarget.is64Bit()) {
+ LO = DAG.getCopyFromReg(Chain, DL, X86::RAX, MVT::i64, SDValue(N1, 1));
+ HI = DAG.getCopyFromReg(LO.getValue(1), DL, X86::RDX, MVT::i64,
+ LO.getValue(2));
+ } else {
+ LO = DAG.getCopyFromReg(Chain, DL, X86::EAX, MVT::i32, SDValue(N1, 1));
+ HI = DAG.getCopyFromReg(LO.getValue(1), DL, X86::EDX, MVT::i32,
+ LO.getValue(2));
+ }
+ Chain = HI.getValue(1);
+
+ if (Subtarget.is64Bit()) {
+ // Merge the two 32-bit values into a 64-bit one..
+ SDValue Tmp = DAG.getNode(ISD::SHL, DL, MVT::i64, HI,
+ DAG.getConstant(32, DL, MVT::i8));
+ Results.push_back(DAG.getNode(ISD::OR, DL, MVT::i64, LO, Tmp));
+ Results.push_back(Chain);
+ return;
+ }
+
+ // Use a buildpair to merge the two 32-bit values into a 64-bit one.
+ SDValue Ops[] = { LO, HI };
+ SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Ops);
+ Results.push_back(Pair);
+ Results.push_back(Chain);
+}
+
/// Handles the lowering of builtin intrinsics that read performance monitor
/// counters (x86_rdpmc).
static void getReadPerformanceCounter(SDNode *N, const SDLoc &DL,
@@ -18722,6 +18767,12 @@ static SDValue LowerINTRINSIC_W_CHAIN(SD
getReadPerformanceCounter(Op.getNode(), dl, DAG, Subtarget, Results);
return DAG.getMergeValues(Results, dl);
}
+ // Get Extended Control Register.
+ case XGETBV: {
+ SmallVector<SDValue, 2> Results;
+ getExtendedControlRegister(Op.getNode(), dl, DAG, Subtarget, Results);
+ return DAG.getMergeValues(Results, dl);
+ }
// XTEST intrinsics.
case XTEST: {
SDVTList VTs = DAG.getVTList(Op->getValueType(0), MVT::Other);
@@ -22176,6 +22227,9 @@ void X86TargetLowering::ReplaceNodeResul
Results);
case Intrinsic::x86_rdpmc:
return getReadPerformanceCounter(N, dl, DAG, Subtarget, Results);
+
+ case Intrinsic::x86_xgetbv:
+ return getExtendedControlRegister(N, dl, DAG, Subtarget, Results);
}
}
case ISD::INTRINSIC_WO_CHAIN: {
Modified: llvm/trunk/lib/Target/X86/X86InstrSystem.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSystem.td?rev=278782&r1=278781&r2=278782&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrSystem.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrSystem.td Tue Aug 16 01:41:00 2016
@@ -481,8 +481,11 @@ let Defs = [EDX, EAX], Uses = [ECX] in
def XGETBV : I<0x01, MRM_D0, (outs), (ins), "xgetbv", []>, TB;
let Uses = [EDX, EAX, ECX] in
- def XSETBV : I<0x01, MRM_D1, (outs), (ins), "xsetbv", []>, TB;
-}
+ def XSETBV : I<0x01, MRM_D1, (outs), (ins),
+ "xsetbv",
+ [(int_x86_xsetbv ECX, EDX, EAX)]>, TB;
+
+} // HasXSAVE
let Uses = [EDX, EAX] in {
let Predicates = [HasXSAVE] in {
Modified: llvm/trunk/lib/Target/X86/X86IntrinsicsInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86IntrinsicsInfo.h?rev=278782&r1=278781&r2=278782&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86IntrinsicsInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86IntrinsicsInfo.h Tue Aug 16 01:41:00 2016
@@ -21,7 +21,7 @@ namespace llvm {
enum IntrinsicType : uint16_t {
INTR_NO_TYPE,
- GATHER, SCATTER, PREFETCH, RDSEED, RDRAND, RDPMC, RDTSC, XTEST, ADX, FPCLASS, FPCLASSS,
+ GATHER, SCATTER, PREFETCH, RDSEED, RDRAND, RDPMC, RDTSC, XTEST, XGETBV, ADX, FPCLASS, FPCLASSS,
INTR_TYPE_1OP, INTR_TYPE_2OP, INTR_TYPE_2OP_IMM8, INTR_TYPE_3OP, INTR_TYPE_4OP,
CMP_MASK, CMP_MASK_CC,CMP_MASK_SCALAR_CC, VSHIFT, COMI, COMI_RM,
INTR_TYPE_1OP_MASK, INTR_TYPE_1OP_MASK_RM,
@@ -228,6 +228,7 @@ static const IntrinsicData IntrinsicsWit
X86_INTRINSIC_DATA(subborrow_u32, ADX, X86ISD::SBB, 0),
X86_INTRINSIC_DATA(subborrow_u64, ADX, X86ISD::SBB, 0),
+ X86_INTRINSIC_DATA(xgetbv, XGETBV, X86::XGETBV, 0),
X86_INTRINSIC_DATA(xtest, XTEST, X86ISD::XTEST, 0),
};
Added: llvm/trunk/test/CodeGen/X86/system-intrinsics-xgetbv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/system-intrinsics-xgetbv.ll?rev=278782&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/system-intrinsics-xgetbv.ll (added)
+++ llvm/trunk/test/CodeGen/X86/system-intrinsics-xgetbv.ll Tue Aug 16 01:41:00 2016
@@ -0,0 +1,21 @@
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+xsave | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+xsave | FileCheck %s --check-prefix=CHECK64
+
+define i64 @test_xgetbv(i32 %in) {
+; CHECK-LABEL: test_xgetbv
+; CHECK: movl 4(%esp), %ecx
+; CHECK: xgetbv
+; CHECK: ret
+
+; CHECK64-LABEL: test_xgetbv
+; CHECK64: movl %edi, %ecx
+; CHECK64: xgetbv
+; CHECK64: shlq $32, %rdx
+; CHECK64: orq %rdx, %rax
+; CHECK64: ret
+
+ %1 = call i64 @llvm.x86.xgetbv(i32 %in)
+ ret i64 %1;
+}
+
+declare i64 @llvm.x86.xgetbv(i32)
\ No newline at end of file
Added: llvm/trunk/test/CodeGen/X86/system-intrinsics-xsetbv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/system-intrinsics-xsetbv.ll?rev=278782&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/system-intrinsics-xsetbv.ll (added)
+++ llvm/trunk/test/CodeGen/X86/system-intrinsics-xsetbv.ll Tue Aug 16 01:41:00 2016
@@ -0,0 +1,23 @@
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+xsave | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+xsave | FileCheck %s --check-prefix=CHECK64
+
+define void @test_xsetbv(i32 %in, i32 %high, i32 %low) {
+; CHECK-LABEL: test_xsetbv
+; CHECK: movl 4(%esp), %ecx
+; CHECK: movl 8(%esp), %edx
+; CHECK: movl 12(%esp), %eax
+; CHECK: xsetbv
+; CHECK: ret
+
+; CHECK64-LABEL: test_xsetbv
+; CHECK64: movl %edx, %eax
+; CHECK64: movl %edi, %ecx
+; CHECK64: movl %esi, %edx
+; CHECK64: xsetbv
+; CHECK64: ret
+
+ call void @llvm.x86.xsetbv(i32 %in, i32 %high, i32 %low)
+ ret void;
+}
+declare void @llvm.x86.xsetbv(i32, i32, i32)
+
More information about the llvm-commits
mailing list