[X86] Add XSAVE intrinsic family
authorAmjad Aboud <amjad.aboud@intel.com>
Mon, 12 Oct 2015 11:47:46 +0000 (11:47 +0000)
committerAmjad Aboud <amjad.aboud@intel.com>
Mon, 12 Oct 2015 11:47:46 +0000 (11:47 +0000)
Add intrinsics for the
  XSAVE instructions (XSAVE/XSAVE64/XRSTOR/XRSTOR64)
  XSAVEOPT instructions (XSAVEOPT/XSAVEOPT64)
  XSAVEC instructions (XSAVEC/XSAVEC64)
  XSAVES instructions (XSAVES/XSAVES64/XRSTORS/XRSTORS64)

Differential Revision: http://reviews.llvm.org/D13012

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250029 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
include/llvm/IR/IntrinsicsX86.td
lib/Support/Host.cpp
lib/Target/X86/X86.td
lib/Target/X86/X86InstrInfo.td
lib/Target/X86/X86InstrSystem.td
lib/Target/X86/X86Subtarget.cpp
lib/Target/X86/X86Subtarget.h
test/CodeGen/X86/system-intrinsics-64-xsave.ll [new file with mode: 0644]
test/CodeGen/X86/system-intrinsics-64-xsavec.ll [new file with mode: 0644]
test/CodeGen/X86/system-intrinsics-64-xsaveopt.ll [new file with mode: 0644]
test/CodeGen/X86/system-intrinsics-64-xsaves.ll [new file with mode: 0644]
test/CodeGen/X86/system-intrinsics-xsave.ll [new file with mode: 0644]
test/CodeGen/X86/system-intrinsics-xsavec.ll [new file with mode: 0644]
test/CodeGen/X86/system-intrinsics-xsaveopt.ll [new file with mode: 0644]
test/CodeGen/X86/system-intrinsics-xsaves.ll [new file with mode: 0644]

index ce4208f96ba0d2d58fdcc55549d62d01e799b870..4f92363c5664d6e76b94a7cdd920f3482890e5e4 100644 (file)
@@ -3800,6 +3800,35 @@ let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
               Intrinsic<[], [llvm_ptr_ty], []>;
 }
 
+//===----------------------------------------------------------------------===//
+// XSAVE
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_xsave :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xsave64 :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xrstor :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xrstor64 :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xsaveopt :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xsaveopt64 :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xrstors :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xrstors64 :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xsavec :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xsavec64 :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xsaves :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_xsaves64 :
+              Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>;
+}
+
 //===----------------------------------------------------------------------===//
 // Half float conversion
 
index cb1c82b01456baabd9182fc912be87bd52c78f64..da918898e2fd827a2cba283cd8a5cf736db52430 100644 (file)
@@ -769,6 +769,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
   Features["movbe"]  = (ECX >> 22) & 1;
   Features["popcnt"] = (ECX >> 23) & 1;
   Features["aes"]    = (ECX >> 25) & 1;
+  Features["xsave"]  = (ECX >> 26) & 1;
   Features["rdrnd"]  = (ECX >> 30) & 1;
 
   // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
@@ -819,6 +820,14 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
   Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
   Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
 
+
+  bool HasLeafD = MaxLevel >= 0xd &&
+    !GetX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
+
+  Features["xsaveopt"] = Features["xsave"] && HasLeafD && ((EAX >> 0) & 1);
+  Features["xsavec"]   = Features["xsave"] && HasLeafD && ((EAX >> 1) & 1);
+  Features["xsaves"]   = Features["xsave"] && HasLeafD && ((EAX >> 3) & 1);
+
   return true;
 }
 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
index fa0b674ff9486b3b5ac21f8c4024b0f559962a63..ec5ea57ea9cd82e783e48ccf7451c541f34ae2ce 100644 (file)
@@ -37,6 +37,18 @@ def FeatureCMOV    : SubtargetFeature<"cmov","HasCMov", "true",
 def FeaturePOPCNT   : SubtargetFeature<"popcnt", "HasPOPCNT", "true",
                                        "Support POPCNT instruction">;
 
+def FeatureXSAVE   : SubtargetFeature<"xsave", "HasXSAVE", "true",
+                                       "Support xsave instructions">;
+
+def FeatureXSAVEOPT: SubtargetFeature<"xsaveopt", "HasXSAVEOPT", "true",
+                                       "Support xsaveopt instructions">;
+
+def FeatureXSAVEC  : SubtargetFeature<"xsavec", "HasXSAVEC", "true",
+                                       "Support xsavec instructions">;
+
+def FeatureXSAVES  : SubtargetFeature<"xsaves", "HasXSAVES", "true",
+                                       "Support xsaves instructions">;
+
 // The MMX subtarget feature is separate from the rest of the SSE features
 // because it's important (for odd compatibility reasons) to be able to
 // turn it off explicitly while allowing SSE+ to be on.
index 51174fc805ca74ff5699fc3c01f93b1792e4a5cd..b54e3ded8438ac5a6a945c1f1affa637ae0c3d85 100644 (file)
@@ -773,6 +773,10 @@ def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
 
 def HasPOPCNT    : Predicate<"Subtarget->hasPOPCNT()">;
 def HasAES       : Predicate<"Subtarget->hasAES()">;
+def HasXSAVE     : Predicate<"Subtarget->hasXSAVE()">;
+def HasXSAVEOPT  : Predicate<"Subtarget->hasXSAVEOPT()">;
+def HasXSAVEC    : Predicate<"Subtarget->hasXSAVEC()">;
+def HasXSAVES    : Predicate<"Subtarget->hasXSAVES()">;
 def HasPCLMUL    : Predicate<"Subtarget->hasPCLMUL()">;
 def HasFMA       : Predicate<"Subtarget->hasFMA()">;
 def UseFMAOnAVX  : Predicate<"Subtarget->hasFMA() && !Subtarget->hasAVX512()">;
@@ -2635,7 +2639,9 @@ def : MnemonicAlias<"fxrstorq",  "fxrstor64",  "att">;
 def : MnemonicAlias<"xsaveq",    "xsave64",    "att">;
 def : MnemonicAlias<"xrstorq",   "xrstor64",   "att">;
 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
-
+def : MnemonicAlias<"xrstorsq",  "xrstors64",  "att">;
+def : MnemonicAlias<"xsavecq",   "xsavec64",   "att">;
+def : MnemonicAlias<"xsavesq",   "xsaves64",   "att">;
 
 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
                     string VariantName>
index 8a3c2ca7b434753ed54375fad713aaa08e330b1f..8222db5922a718a166659bda6afe8a5bfe169245 100644 (file)
@@ -478,39 +478,60 @@ def WBINVD : I<0x09, RawFrm, (outs), (ins), "wbinvd", [], IIC_INVD>, TB;
 //===----------------------------------------------------------------------===//
 // XSAVE instructions
 let SchedRW = [WriteSystem] in {
+let Predicates = [HasXSAVE] in {
 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;
+}
 
-let Uses = [RDX, RAX] in {
-  def XSAVE : I<0xAE, MRM4m, (outs opaque512mem:$dst), (ins),
-               "xsave\t$dst", []>, TB;
-  def XSAVE64 : RI<0xAE, MRM4m, (outs opaque512mem:$dst), (ins),
-                 "xsave64\t$dst", []>, TB, Requires<[In64BitMode]>;
+let Uses = [EDX, EAX] in {
+let Predicates = [HasXSAVE] in {
+  def XSAVE : I<0xAE, MRM4m, (outs), (ins opaque512mem:$dst),
+                "xsave\t$dst",
+                [(int_x86_xsave addr:$dst, EDX, EAX)]>, TB;
+  def XSAVE64 : RI<0xAE, MRM4m, (outs), (ins opaque512mem:$dst),
+                   "xsave64\t$dst",
+                   [(int_x86_xsave64 addr:$dst, EDX, EAX)]>, TB, Requires<[In64BitMode]>;
   def XRSTOR : I<0xAE, MRM5m, (outs), (ins opaque512mem:$dst),
-               "xrstor\t$dst", []>, TB;
+                 "xrstor\t$dst",
+                 [(int_x86_xrstor addr:$dst, EDX, EAX)]>, TB;
   def XRSTOR64 : RI<0xAE, MRM5m, (outs), (ins opaque512mem:$dst),
-                 "xrstor64\t$dst", []>, TB, Requires<[In64BitMode]>;
-  def XSAVEOPT : I<0xAE, MRM6m, (outs opaque512mem:$dst), (ins),
-                  "xsaveopt\t$dst", []>, PS;
-  def XSAVEOPT64 : RI<0xAE, MRM6m, (outs opaque512mem:$dst), (ins),
-                    "xsaveopt64\t$dst", []>, PS, Requires<[In64BitMode]>;
-
+                    "xrstor64\t$dst",
+                    [(int_x86_xrstor64 addr:$dst, EDX, EAX)]>, TB, Requires<[In64BitMode]>;
+}
+let Predicates = [HasXSAVEOPT] in {
+  def XSAVEOPT : I<0xAE, MRM6m, (outs), (ins opaque512mem:$dst),
+                   "xsaveopt\t$dst",
+                   [(int_x86_xsaveopt addr:$dst, EDX, EAX)]>, TB;
+  def XSAVEOPT64 : RI<0xAE, MRM6m, (outs), (ins opaque512mem:$dst),
+                      "xsaveopt64\t$dst",
+                      [(int_x86_xsaveopt64 addr:$dst, EDX, EAX)]>, TB, Requires<[In64BitMode]>;
+}
+let Predicates = [HasXSAVEC] in {
+  def XSAVEC : I<0xC7, MRM4m, (outs), (ins opaque512mem:$dst),
+                 "xsavec\t$dst",
+                 [(int_x86_xsavec addr:$dst, EDX, EAX)]>, TB;
+  def XSAVEC64 : RI<0xC7, MRM4m, (outs), (ins opaque512mem:$dst),
+                   "xsavec64\t$dst",
+                   [(int_x86_xsavec64 addr:$dst, EDX, EAX)]>, TB, Requires<[In64BitMode]>;
+}
+let Predicates = [HasXSAVES] in {
+  def XSAVES : I<0xC7, MRM5m, (outs), (ins opaque512mem:$dst),
+                 "xsaves\t$dst",
+                 [(int_x86_xsaves addr:$dst, EDX, EAX)]>, TB;
+  def XSAVES64 : RI<0xC7, MRM5m, (outs), (ins opaque512mem:$dst),
+                    "xsaves64\t$dst",
+                    [(int_x86_xsaves64 addr:$dst, EDX, EAX)]>, TB, Requires<[In64BitMode]>;
   def XRSTORS : I<0xC7, MRM3m, (outs), (ins opaque512mem:$dst),
-                "xrstors\t$dst", []>, TB;
+                  "xrstors\t$dst",
+                  [(int_x86_xrstors addr:$dst, EDX, EAX)]>, TB;
   def XRSTORS64 : RI<0xC7, MRM3m, (outs), (ins opaque512mem:$dst),
-                  "xrstors64\t$dst", []>, TB, Requires<[In64BitMode]>;
-  def XSAVEC : I<0xC7, MRM4m, (outs opaque512mem:$dst), (ins),
-                "xsavec\t$dst", []>, TB;
-  def XSAVEC64 : RI<0xC7, MRM4m, (outs opaque512mem:$dst), (ins),
-                  "xsavec64\t$dst", []>, TB, Requires<[In64BitMode]>;
-  def XSAVES : I<0xC7, MRM5m, (outs opaque512mem:$dst), (ins),
-                "xsaves\t$dst", []>, TB;
-  def XSAVES64 : RI<0xC7, MRM5m, (outs opaque512mem:$dst), (ins),
-                  "xsaves64\t$dst", []>, TB, Requires<[In64BitMode]>;
+                     "xrstors64\t$dst",
+                     [(int_x86_xrstors64 addr:$dst, EDX, EAX)]>, TB, Requires<[In64BitMode]>;
 }
+} // Uses
 } // SchedRW
 
 //===----------------------------------------------------------------------===//
index a4db4e6028006d2f53116803baffcde86484893f..428b715480b2ad4f94167ddbc15f324375e7dc58 100644 (file)
@@ -236,6 +236,10 @@ void X86Subtarget::initializeEnvironment() {
   HasPOPCNT = false;
   HasSSE4A = false;
   HasAES = false;
+  HasXSAVE = false;
+  HasXSAVEOPT = false;
+  HasXSAVEC = false;
+  HasXSAVES = false;
   HasPCLMUL = false;
   HasFMA = false;
   HasFMA4 = false;
index 382f7375f6f7685f838fe71a5dce9df9a7156543..7ba0723f03b29c1c97b8750e427b6c2070cd88c5 100644 (file)
@@ -89,6 +89,15 @@ protected:
   /// Target has AES instructions
   bool HasAES;
 
+  /// Target has XSAVE instructions
+  bool HasXSAVE;
+  /// Target has XSAVEOPT instructions
+  bool HasXSAVEOPT;
+  /// Target has XSAVEC instructions
+  bool HasXSAVEC;
+  /// Target has XSAVES instructions
+  bool HasXSAVES;
+
   /// Target has carry-less multiplication
   bool HasPCLMUL;
 
@@ -339,6 +348,10 @@ public:
   bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; }
   bool hasPOPCNT() const { return HasPOPCNT; }
   bool hasAES() const { return HasAES; }
+  bool hasXSAVE() const { return HasXSAVE; }
+  bool hasXSAVEOPT() const { return HasXSAVEOPT; }
+  bool hasXSAVEC() const { return HasXSAVEC; }
+  bool hasXSAVES() const { return HasXSAVES; }
   bool hasPCLMUL() const { return HasPCLMUL; }
   bool hasFMA() const { return HasFMA; }
   // FIXME: Favor FMA when both are enabled. Is this the right thing to do?
diff --git a/test/CodeGen/X86/system-intrinsics-64-xsave.ll b/test/CodeGen/X86/system-intrinsics-64-xsave.ll
new file mode 100644 (file)
index 0000000..feec951
--- /dev/null
@@ -0,0 +1,41 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+xsave | FileCheck %s\r
+\r
+define void @test_xsave(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsave\r
+; CHECK: movl  %edx, %eax\r
+; CHECK: movl  %esi, %edx\r
+; CHECK: xsave (%rdi)\r
+  call void @llvm.x86.xsave(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsave(i8*, i32, i32)\r
+\r
+define void @test_xsave64(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsave64\r
+; CHECK: movl    %edx, %eax\r
+; CHECK: movl    %esi, %edx\r
+; CHECK: xsave64 (%rdi)\r
+  call void @llvm.x86.xsave64(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsave64(i8*, i32, i32)\r
+\r
+define void @test_xrstor(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xrstor\r
+; CHECK: movl   %edx, %eax\r
+; CHECK: movl   %esi, %edx\r
+; CHECK: xrstor (%rdi)\r
+  call void @llvm.x86.xrstor(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xrstor(i8*, i32, i32)\r
+\r
+define void @test_xrstor64(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xrstor64\r
+; CHECK: movl     %edx, %eax\r
+; CHECK: movl     %esi, %edx\r
+; CHECK: xrstor64 (%rdi)\r
+  call void @llvm.x86.xrstor64(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xrstor64(i8*, i32, i32)\r
diff --git a/test/CodeGen/X86/system-intrinsics-64-xsavec.ll b/test/CodeGen/X86/system-intrinsics-64-xsavec.ll
new file mode 100644 (file)
index 0000000..0680348
--- /dev/null
@@ -0,0 +1,21 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+xsave,+xsavec | FileCheck %s\r
+\r
+define void @test_xsavec(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsavec\r
+; CHECK: movl   %edx, %eax\r
+; CHECK: movl   %esi, %edx\r
+; CHECK: xsavec (%rdi)\r
+  call void @llvm.x86.xsavec(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsavec(i8*, i32, i32)\r
+\r
+define void @test_xsavec64(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsavec64\r
+; CHECK: movl     %edx, %eax\r
+; CHECK: movl     %esi, %edx\r
+; CHECK: xsavec64 (%rdi)\r
+  call void @llvm.x86.xsavec64(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsavec64(i8*, i32, i32)\r
diff --git a/test/CodeGen/X86/system-intrinsics-64-xsaveopt.ll b/test/CodeGen/X86/system-intrinsics-64-xsaveopt.ll
new file mode 100644 (file)
index 0000000..ee0a536
--- /dev/null
@@ -0,0 +1,21 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+xsaveopt | FileCheck %s\r
+\r
+define void @test_xsaveopt(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsaveopt\r
+; CHECK: movl     %edx, %eax\r
+; CHECK: movl     %esi, %edx\r
+; CHECK: xsaveopt (%rdi)\r
+  call void @llvm.x86.xsaveopt(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsaveopt(i8*, i32, i32)\r
+\r
+define void @test_xsaveopt64(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsaveopt64\r
+; CHECK: movl       %edx, %eax\r
+; CHECK: movl       %esi, %edx\r
+; CHECK: xsaveopt64 (%rdi)\r
+  call void @llvm.x86.xsaveopt64(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsaveopt64(i8*, i32, i32)\r
diff --git a/test/CodeGen/X86/system-intrinsics-64-xsaves.ll b/test/CodeGen/X86/system-intrinsics-64-xsaves.ll
new file mode 100644 (file)
index 0000000..5c1c5be
--- /dev/null
@@ -0,0 +1,41 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+xsave,+xsaves | FileCheck %s\r
+\r
+define void @test_xsaves(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsaves\r
+; CHECK: movl   %edx, %eax\r
+; CHECK: movl   %esi, %edx\r
+; CHECK: xsaves (%rdi)\r
+  call void @llvm.x86.xsaves(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsaves(i8*, i32, i32)\r
+\r
+define void @test_xsaves64(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsaves64\r
+; CHECK: movl     %edx, %eax\r
+; CHECK: movl     %esi, %edx\r
+; CHECK: xsaves64 (%rdi)\r
+  call void @llvm.x86.xsaves64(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsaves64(i8*, i32, i32)\r
+\r
+define void @test_xrstors(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xrstors\r
+; CHECK: movl    %edx, %eax\r
+; CHECK: movl    %esi, %edx\r
+; CHECK: xrstors (%rdi)\r
+  call void @llvm.x86.xrstors(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xrstors(i8*, i32, i32)\r
+\r
+define void @test_xrstors64(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xrstors64\r
+; CHECK: movl      %edx, %eax\r
+; CHECK: movl      %esi, %edx\r
+; CHECK: xrstors64 (%rdi)\r
+  call void @llvm.x86.xrstors64(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xrstors64(i8*, i32, i32)\r
diff --git a/test/CodeGen/X86/system-intrinsics-xsave.ll b/test/CodeGen/X86/system-intrinsics-xsave.ll
new file mode 100644 (file)
index 0000000..ff9fb7e
--- /dev/null
@@ -0,0 +1,23 @@
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+xsave | FileCheck %s\r
+\r
+define void @test_xsave(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsave\r
+; CHECK: movl  8(%esp), %edx\r
+; CHECK: movl  12(%esp), %eax\r
+; CHECK: movl  4(%esp), %ecx\r
+; CHECK: xsave (%ecx)\r
+  call void @llvm.x86.xsave(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsave(i8*, i32, i32)\r
+\r
+define void @test_xrstor(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xrstor\r
+; CHECK: movl   8(%esp), %edx\r
+; CHECK: movl   12(%esp), %eax\r
+; CHECK: movl   4(%esp), %ecx\r
+; CHECK: xrstor (%ecx)\r
+  call void @llvm.x86.xrstor(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xrstor(i8*, i32, i32)\r
diff --git a/test/CodeGen/X86/system-intrinsics-xsavec.ll b/test/CodeGen/X86/system-intrinsics-xsavec.ll
new file mode 100644 (file)
index 0000000..4a55ea9
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+xsave,+xsavec | FileCheck %s\r
+\r
+define void @test_xsavec(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsavec\r
+; CHECK: movl   8(%esp), %edx\r
+; CHECK: movl   12(%esp), %eax\r
+; CHECK: movl   4(%esp), %ecx\r
+; CHECK: xsavec (%ecx)\r
+  call void @llvm.x86.xsavec(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsavec(i8*, i32, i32)\r
diff --git a/test/CodeGen/X86/system-intrinsics-xsaveopt.ll b/test/CodeGen/X86/system-intrinsics-xsaveopt.ll
new file mode 100644 (file)
index 0000000..f9bd7ac
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+xsave,+xsaveopt | FileCheck %s\r
+\r
+define void @test_xsaveopt(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsaveopt\r
+; CHECK: movl     8(%esp), %edx\r
+; CHECK: movl     12(%esp), %eax\r
+; CHECK: movl     4(%esp), %ecx\r
+; CHECK: xsaveopt (%ecx)\r
+  call void @llvm.x86.xsaveopt(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsaveopt(i8*, i32, i32)\r
diff --git a/test/CodeGen/X86/system-intrinsics-xsaves.ll b/test/CodeGen/X86/system-intrinsics-xsaves.ll
new file mode 100644 (file)
index 0000000..ca1c5c1
--- /dev/null
@@ -0,0 +1,23 @@
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+xsave,+xsaves | FileCheck %s\r
+\r
+define void @test_xsaves(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xsaves\r
+; CHECK: movl   8(%esp), %edx\r
+; CHECK: movl   12(%esp), %eax\r
+; CHECK: movl   4(%esp), %ecx\r
+; CHECK: xsaves (%ecx)\r
+  call void @llvm.x86.xsaves(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xsaves(i8*, i32, i32)\r
+\r
+define void @test_xrstors(i8* %ptr, i32 %hi, i32 %lo) {\r
+; CHECK-LABEL: test_xrstors\r
+; CHECK: movl    8(%esp), %edx\r
+; CHECK: movl    12(%esp), %eax\r
+; CHECK: movl    4(%esp), %ecx\r
+; CHECK: xrstors (%ecx)\r
+  call void @llvm.x86.xrstors(i8* %ptr, i32 %hi, i32 %lo)\r
+  ret void;\r
+}\r
+declare void @llvm.x86.xrstors(i8*, i32, i32)\r