Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Unified Diff: runtime/vm/intrinsifier_ia32.cc

Issue 9320023: Intrinisifed more core library methods: isNaN, isNegative, cos, sin. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/assembler_ia32_test.cc ('k') | tests/language/language.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intrinsifier_ia32.cc
===================================================================
--- runtime/vm/intrinsifier_ia32.cc (revision 3859)
+++ runtime/vm/intrinsifier_ia32.cc (working copy)
@@ -64,6 +64,8 @@
V(Double, toDouble, Double_toDouble) \
V(Double, mulFromInteger, Double_mulFromInteger) \
V(Double, Double.fromInteger, Double_fromInteger) \
+ V(Double, isNaN, Double_isNaN) \
+ V(Double, isNegative, Double_isNegative) \
V(ObjectArray, ObjectArray., ObjectArray_Allocate) \
V(ObjectArray, get:length, Array_getLength) \
V(ObjectArray, [], Array_getIndexed) \
@@ -74,6 +76,8 @@
V(ImmutableArray, [], Array_getIndexed) \
V(ImmutableArray, get:length, Array_getLength) \
V(Math, sqrt, Math_sqrt) \
+ V(Math, sin, Math_sin) \
+ V(Math, cos, Math_cos) \
V(Object, ==, Object_equal) \
V(FixedSizeArrayIterator, next, FixedSizeArrayIterator_next) \
V(FixedSizeArrayIterator, hasNext, FixedSizeArrayIterator_hasNext) \
@@ -859,6 +863,50 @@
}
+static bool Double_isNaN(Assembler* assembler) {
+ const Bool& bool_true = Bool::ZoneHandle(Bool::True());
+ const Bool& bool_false = Bool::ZoneHandle(Bool::False());
+ Label is_true;
+ __ movl(EAX, Address(ESP, +1 * kWordSize));
+ __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
+ __ comisd(XMM0, XMM0);
+ __ j(PARITY_EVEN, &is_true, Assembler::kNearJump); // NaN -> true;
+ __ LoadObject(EAX, bool_false);
+ __ ret();
+ __ Bind(&is_true);
+ __ LoadObject(EAX, bool_true);
+ __ ret();
+ return true; // Method is complete, no slow case.
+}
+
+
+static bool Double_isNegative(Assembler* assembler) {
+ const Bool& bool_true = Bool::ZoneHandle(Bool::True());
+ const Bool& bool_false = Bool::ZoneHandle(Bool::False());
+ Label is_false, is_true, is_zero;
+ __ movl(EAX, Address(ESP, +1 * kWordSize));
+ __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
+ __ xorps(XMM1, XMM1); // 0.0 -> XMM1.
+ __ comisd(XMM0, XMM1);
+ __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false.
+ __ j(EQUAL, &is_zero, Assembler::kNearJump); // Check for negative zero.
+ __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump); // >= 0 -> false.
+ __ Bind(&is_true);
+ __ LoadObject(EAX, bool_true);
+ __ ret();
+ __ Bind(&is_false);
+ __ LoadObject(EAX, bool_false);
+ __ ret();
+ __ Bind(&is_zero);
+ // Check for negative zero (get the sign bit).
+ __ movmskpd(EAX, XMM0);
+ __ testl(EAX, Immediate(1));
+ __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
+ __ jmp(&is_false, Assembler::kNearJump);
+ return true; // Method is complete, no slow case.
+}
+
+
// Argument type is not known
static bool Math_sqrt(Assembler* assembler) {
Label fall_through, is_smi, double_op;
@@ -886,6 +934,59 @@
}
+enum TrigonometricFunctions {
+ kSine,
+ kCosine,
+};
+
+
+static bool EmitTrigonometric(Assembler* assembler,
+ TrigonometricFunctions kind) {
+ Label fall_through, is_smi, double_op;
+ TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+ // Argument is double and is in EAX.
+ __ fldl(FieldAddress(EAX, Double::value_offset()));
+ __ Bind(&double_op);
+ switch (kind) {
+ case kSine: __ fsin(); break;
+ case kCosine: __ fcos(); break;
+ default:
+ UNREACHABLE();
+ }
+ const Class& double_class = Class::ZoneHandle(
+ Isolate::Current()->object_store()->double_class());
+ __ LoadObject(EBX, double_class);
+ AssemblerMacros::TryAllocate(assembler,
+ double_class,
+ EBX, // Class register.
+ &fall_through,
+ EAX); // Result register.
+ __ fstpl(FieldAddress(EAX, Double::value_offset()));
+ __ ret();
+
+ __ Bind(&is_smi); // smi -> double.
+ __ SmiUntag(EAX);
+ __ pushl(EAX);
+ __ filds(Address(ESP, 0));
+ __ popl(EAX);
+ __ jmp(&double_op);
+
+ __ Bind(&fall_through);
+}
+
+
+static bool Math_sin(Assembler* assembler) {
+ EmitTrigonometric(assembler, kSine);
+ return false; // Compile method for slow case.
+}
+
+
+static bool Math_cos(Assembler* assembler) {
+ EmitTrigonometric(assembler, kCosine);
+ return false; // Compile method for slow case.
+}
+
+
// Identity comparison.
static bool Object_equal(Assembler* assembler) {
Label is_true;
« no previous file with comments | « runtime/vm/assembler_ia32_test.cc ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698