Intrisify IsInfinite() (float/double) function for x86_64

Time with Base version: 60.23s
Time with Intrinsic version : 29.85s

Test: ./run-test --host --64 082-inline-execute

Signed-off-by: Shalini Salomi Bodapati <shalini.salomi.bodapati@intel.com>
Change-Id: I4b5b0eb20d516cf7709e5d75886ccbc58b557a04
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index 3a71318..d5a7cb1 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -208,6 +208,67 @@
   codegen_->GetInstructionCodegen()->Bswap(invoke->GetLocations()->Out(), DataType::Type::kInt16);
 }
 
+static void GenIsInfinite(LocationSummary* locations,
+                          bool is64bit,
+                          CodeGeneratorX86_64* codegen) {
+  X86_64Assembler* assembler = codegen->GetAssembler();
+
+  XmmRegister input = locations->InAt(0).AsFpuRegister<XmmRegister>();
+  CpuRegister output = locations->Out().AsRegister<CpuRegister>();
+
+  NearLabel done1, done2;
+
+  if (is64bit) {
+    double kPositiveInfinity = std::numeric_limits<double>::infinity();
+    double kNegativeInfinity = -1 * kPositiveInfinity;
+
+     __ xorq(output, output);
+     __ comisd(input, codegen->LiteralDoubleAddress(kPositiveInfinity));
+     __ j(kNotEqual, &done1);
+     __ j(kParityEven, &done2);
+     __ movq(output, Immediate(1));
+     __ jmp(&done2);
+     __ Bind(&done1);
+     __ comisd(input, codegen->LiteralDoubleAddress(kNegativeInfinity));
+     __ j(kNotEqual, &done2);
+     __ j(kParityEven, &done2);
+     __ movq(output, Immediate(1));
+     __ Bind(&done2);
+  } else {
+    float kPositiveInfinity = std::numeric_limits<float>::infinity();
+    float kNegativeInfinity = -1 * kPositiveInfinity;
+
+     __ xorl(output, output);
+     __ comiss(input, codegen->LiteralFloatAddress(kPositiveInfinity));
+     __ j(kNotEqual, &done1);
+     __ j(kParityEven, &done2);
+     __ movl(output, Immediate(1));
+     __ jmp(&done2);
+     __ Bind(&done1);
+     __ comiss(input, codegen->LiteralFloatAddress(kNegativeInfinity));
+     __ j(kNotEqual, &done2);
+     __ j(kParityEven, &done2);
+     __ movl(output, Immediate(1));
+     __ Bind(&done2);
+  }
+}
+
+void IntrinsicLocationsBuilderX86_64::VisitFloatIsInfinite(HInvoke* invoke) {
+  CreateFPToIntLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorX86_64::VisitFloatIsInfinite(HInvoke* invoke) {
+  GenIsInfinite(invoke->GetLocations(), /* is64bit=*/  false, codegen_);
+}
+
+void IntrinsicLocationsBuilderX86_64::VisitDoubleIsInfinite(HInvoke* invoke) {
+  CreateFPToIntLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorX86_64::VisitDoubleIsInfinite(HInvoke* invoke) {
+  GenIsInfinite(invoke->GetLocations(), /* is64bit=*/  true, codegen_);
+}
+
 static void CreateFPToFPLocations(ArenaAllocator* allocator, HInvoke* invoke) {
   LocationSummary* locations =
       new (allocator) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
@@ -4851,8 +4912,6 @@
   __ jmp(GetExitLabel());
 }
 
-UNIMPLEMENTED_INTRINSIC(X86_64, FloatIsInfinite)
-UNIMPLEMENTED_INTRINSIC(X86_64, DoubleIsInfinite)
 UNIMPLEMENTED_INTRINSIC(X86_64, CRC32Update)
 UNIMPLEMENTED_INTRINSIC(X86_64, CRC32UpdateBytes)
 UNIMPLEMENTED_INTRINSIC(X86_64, CRC32UpdateByteBuffer)