| Index: runtime/vm/intrinsifier_x64.cc
|
| ===================================================================
|
| --- runtime/vm/intrinsifier_x64.cc (revision 7950)
|
| +++ runtime/vm/intrinsifier_x64.cc (working copy)
|
| @@ -7,19 +7,35 @@
|
|
|
| #include "vm/intrinsifier.h"
|
|
|
| +#include "vm/assembler.h"
|
| +#include "vm/instructions.h"
|
| +
|
| namespace dart {
|
| +
|
| +DECLARE_FLAG(bool, enable_type_checks);
|
| +
|
| +// When entering intrinsics code:
|
| +// RBX: IC Data
|
| +// R10: Arguments descriptor
|
| +// TOS: Return address
|
| +
|
| +#define __ assembler->
|
| +
|
| bool Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
|
| return false;
|
| }
|
|
|
|
|
| bool Intrinsifier::Array_getLength(Assembler* assembler) {
|
| - return false;
|
| + __ movq(RAX, Address(RSP, + 1 * kWordSize));
|
| + __ movq(RAX, FieldAddress(RAX, Array::length_offset()));
|
| + __ ret();
|
| + return true;
|
| }
|
|
|
|
|
| bool Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
|
| - return false;
|
| + return Array_getLength(assembler);
|
| }
|
|
|
|
|
| @@ -29,7 +45,7 @@
|
|
|
|
|
| bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
|
| - return false;
|
| + return Array_getIndexed(assembler);
|
| }
|
|
|
|
|
| @@ -43,13 +59,22 @@
|
| }
|
|
|
|
|
| +// Get length of growable object array.
|
| +// On stack: growable array (+1), return-address (+0).
|
| bool Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
|
| - return false;
|
| + __ movq(RAX, Address(RSP, + 1 * kWordSize));
|
| + __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
|
| + __ ret();
|
| + return true;
|
| }
|
|
|
|
|
| bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
|
| - return false;
|
| + __ movq(RAX, Address(RSP, + 1 * kWordSize));
|
| + __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset()));
|
| + __ movq(RAX, FieldAddress(RAX, Array::length_offset()));
|
| + __ ret();
|
| + return true;
|
| }
|
|
|
|
|
| @@ -68,8 +93,17 @@
|
| }
|
|
|
|
|
| +// Set data of growable object array.
|
| +// On stack: growable array (+2), data (+1), return-address (+0).
|
| bool Intrinsifier::GrowableArray_setData(Assembler* assembler) {
|
| - return false;
|
| + if (FLAG_enable_type_checks) {
|
| + return false;
|
| + }
|
| + __ movq(RAX, Address(RSP, + 2 * kWordSize));
|
| + __ movq(RBX, Address(RSP, + 1 * kWordSize));
|
| + __ movq(FieldAddress(RAX, GrowableObjectArray::data_offset()), RBX);
|
| + __ ret();
|
| + return true;
|
| }
|
|
|
|
|
| @@ -225,7 +259,12 @@
|
|
|
|
|
| bool Intrinsifier::Double_toDouble(Assembler* assembler) {
|
| - return false;
|
| + __ movq(RAX, Address(RSP, + 1 * kWordSize));
|
| + __ ret();
|
| + // Generate enough code to satisfy patchability constraint.
|
| + intptr_t offset = __ CodeSize();
|
| + __ nop(JumpPattern::InstructionLength() - offset);
|
| + return true;
|
| }
|
|
|
| bool Intrinsifier::Double_add(Assembler* assembler) {
|
| @@ -259,7 +298,19 @@
|
|
|
|
|
| bool Intrinsifier::Double_isNaN(Assembler* assembler) {
|
| - return false;
|
| + const Bool& bool_true = Bool::ZoneHandle(Bool::True());
|
| + const Bool& bool_false = Bool::ZoneHandle(Bool::False());
|
| + Label is_true;
|
| + __ movq(RAX, Address(RSP, +1 * kWordSize));
|
| + __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
|
| + __ comisd(XMM0, XMM0);
|
| + __ j(PARITY_EVEN, &is_true, Assembler::kNearJump); // NaN -> true;
|
| + __ LoadObject(RAX, bool_false);
|
| + __ ret();
|
| + __ Bind(&is_true);
|
| + __ LoadObject(RAX, bool_true);
|
| + __ ret();
|
| + return true; // Method is complete, no slow case.
|
| }
|
|
|
|
|
| @@ -317,6 +368,8 @@
|
| return false;
|
| }
|
|
|
| +#undef __
|
| +
|
| } // namespace dart
|
|
|
| #endif // defined TARGET_ARCH_X64
|
|
|