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)