Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index a8b7024b65a71e12c899c4832a18cf5573944ee0..e407025a48655d5e25f522a1781a5701a4d57949 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -894,6 +894,14 @@ void Runtime::ArrayIdToTypeAndSize( |
*array_type = kExternalFloatArray; |
*element_size = 4; |
break; |
+ case ARRAY_ID_FLOAT32x4: |
+ *array_type = kExternalFloat32x4Array; |
+ *element_size = 16; |
+ break; |
+ case ARRAY_ID_INT32x4: |
+ *array_type = kExternalInt32x4Array; |
+ *element_size = 16; |
+ break; |
case ARRAY_ID_FLOAT64: |
*array_type = kExternalDoubleArray; |
*element_size = 8; |
@@ -5218,7 +5226,10 @@ Handle<Object> Runtime::SetObjectProperty(Isolate* isolate, |
js_object->ValidateElements(); |
if (js_object->HasExternalArrayElements()) { |
- if (!value->IsNumber() && !value->IsUndefined()) { |
+ // TODO(ningxin): Throw an error if setting a Float32x4Array element |
+ // while the value is not Float32x4Object. |
+ if (!value->IsNumber() && !value->IsFloat32x4() && |
+ !value->IsInt32x4() && !value->IsUndefined()) { |
bool has_exception; |
Handle<Object> number = |
Execution::ToNumber(isolate, value, &has_exception); |
@@ -5238,7 +5249,10 @@ Handle<Object> Runtime::SetObjectProperty(Isolate* isolate, |
Handle<Name> name = Handle<Name>::cast(key); |
if (name->AsArrayIndex(&index)) { |
if (js_object->HasExternalArrayElements()) { |
- if (!value->IsNumber() && !value->IsUndefined()) { |
+ // TODO(ningxin): Throw an error if setting a Float32x4Array element |
+ // while the value is not Float32x4Object. |
+ if (!value->IsNumber() && !value->IsFloat32x4() && |
+ !value->IsInt32x4() && !value->IsUndefined()) { |
bool has_exception; |
Handle<Object> number = |
Execution::ToNumber(isolate, value, &has_exception); |
@@ -6022,6 +6036,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) { |
Object* obj = args[0]; |
if (obj->IsNumber()) return isolate->heap()->number_string(); |
+ if (obj->IsFloat32x4()) return isolate->heap()->float32x4_string(); |
+ if (obj->IsInt32x4()) return isolate->heap()->int32x4_string(); |
HeapObject* heap_obj = HeapObject::cast(obj); |
// typeof an undetectable object is 'undefined' |
@@ -6889,6 +6905,32 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateHeapNumber) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateFloat32x4) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 0); |
+ |
+ float32x4_value_t zero; |
+ zero.storage[0] = 0; |
+ zero.storage[1] = 0; |
+ zero.storage[2] = 0; |
+ zero.storage[3] = 0; |
+ return isolate->heap()->AllocateFloat32x4(zero); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInt32x4) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 0); |
+ |
+ int32x4_value_t zero; |
+ zero.storage[0] = 0; |
+ zero.storage[1] = 0; |
+ zero.storage[2] = 0; |
+ zero.storage[3] = 0; |
+ return isolate->heap()->AllocateInt32x4(zero); |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) { |
SealHandleScope shs(isolate); |
ASSERT(args.length() == 2); |
@@ -7853,6 +7895,1013 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_PopulateTrigonometricTable) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 3); |
+ CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sin_table, 0); |
+ CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, cos_table, 1); |
+ CONVERT_SMI_ARG_CHECKED(samples, 2); |
+ RUNTIME_ASSERT(sin_table->type() == kExternalDoubleArray); |
+ RUNTIME_ASSERT(cos_table->type() == kExternalDoubleArray); |
+ double* sin_buffer = reinterpret_cast<double*>( |
+ JSArrayBuffer::cast(sin_table->buffer())->backing_store()); |
+ double* cos_buffer = reinterpret_cast<double*>( |
+ JSArrayBuffer::cast(cos_table->buffer())->backing_store()); |
+ |
+ static const double pi_half = 3.1415926535897932 / 2; |
+ double interval = pi_half / samples; |
+ for (int i = 0; i < samples + 1; i++) { |
+ double sample = sin(i * interval); |
+ sin_buffer[i] = sample; |
+ cos_buffer[samples - i] = sample * interval; |
+ } |
+ |
+ // Fill this to catch out of bound accesses when calculating Math.sin(pi/2). |
+ sin_buffer[samples + 1] = sin(pi_half + interval); |
+ cos_buffer[samples + 1] = cos(pi_half + interval) * interval; |
+ |
+ return isolate->heap()->undefined_value(); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDAbs) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = fabsf(a->x()); |
+ result.storage[1] = fabsf(a->y()); |
+ result.storage[2] = fabsf(a->z()); |
+ result.storage[3] = fabsf(a->w()); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDNeg) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = -a->x(); |
+ result.storage[1] = -a->y(); |
+ result.storage[2] = -a->z(); |
+ result.storage[3] = -a->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDAdd) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = a->x() + b->x(); |
+ result.storage[1] = a->y() + b->y(); |
+ result.storage[2] = a->z() + b->z(); |
+ result.storage[3] = a->w() + b->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDSub) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = a->x() - b->x(); |
+ result.storage[1] = a->y() - b->y(); |
+ result.storage[2] = a->z() - b->z(); |
+ result.storage[3] = a->w() - b->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDMul) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = a->x() * b->x(); |
+ result.storage[1] = a->y() * b->y(); |
+ result.storage[2] = a->z() * b->z(); |
+ result.storage[3] = a->w() * b->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDDiv) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = a->x() / b->x(); |
+ result.storage[1] = a->y() / b->y(); |
+ result.storage[2] = a->z() / b->z(); |
+ result.storage[3] = a->w() / b->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDClamp) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 3); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, lo, 1); |
+ CONVERT_ARG_CHECKED(Float32x4, hi, 2); |
+ |
+ float32x4_value_t result; |
+ float _x = self->x() > lo->x() ? self->x() : lo->x(); |
+ float _y = self->y() > lo->y() ? self->y() : lo->y(); |
+ float _z = self->z() > lo->z() ? self->z() : lo->z(); |
+ float _w = self->w() > lo->w() ? self->w() : lo->w(); |
+ result.storage[0] = _x > hi->x() ? hi->x() : _x; |
+ result.storage[1] = _y > hi->y() ? hi->y() : _y; |
+ result.storage[2] = _z > hi->z() ? hi->z() : _z; |
+ result.storage[3] = _w > hi->w() ? hi->w() : _w; |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDMin) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, other, 1); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = self->x() < other->x() ? self->x() : other->x(); |
+ result.storage[1] = self->y() < other->y() ? self->y() : other->y(); |
+ result.storage[2] = self->z() < other->z() ? self->z() : other->z(); |
+ result.storage[3] = self->w() < other->w() ? self->w() : other->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDMax) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, other, 1); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = self->x() > other->x() ? self->x() : other->x(); |
+ result.storage[1] = self->y() > other->y() ? self->y() : other->y(); |
+ result.storage[2] = self->z() > other->z() ? self->z() : other->z(); |
+ result.storage[3] = self->w() > other->w() ? self->w() : other->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDReciprocal) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = 1.0f / self->x(); |
+ result.storage[1] = 1.0f / self->y(); |
+ result.storage[2] = 1.0f / self->z(); |
+ result.storage[3] = 1.0f / self->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDReciprocalSqrt) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = sqrtf(1.0f / self->x()); |
+ result.storage[1] = sqrtf(1.0f / self->y()); |
+ result.storage[2] = sqrtf(1.0f / self->z()); |
+ result.storage[3] = sqrtf(1.0f / self->w()); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDScale) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ float _s = static_cast<float>(args.number_at(1)); |
+ float32x4_value_t result; |
+ result.storage[0] = self->x() * _s; |
+ result.storage[1] = self->y() * _s; |
+ result.storage[2] = self->z() * _s; |
+ result.storage[3] = self->w() * _s; |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDSqrt) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = sqrtf(self->x()); |
+ result.storage[1] = sqrtf(self->y()); |
+ result.storage[2] = sqrtf(self->z()); |
+ result.storage[3] = sqrtf(self->w()); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDShuffle) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ uint32_t m = NumberToUint32(args[1]); |
+ float32x4_value_t result; |
+ float data[4] = { self->x(), self->y(), self->z(), self->w() }; |
+ result.storage[0] = data[m & 0x3]; |
+ result.storage[1] = data[(m >> 2) & 0x3]; |
+ result.storage[2] = data[(m >> 4) & 0x3]; |
+ result.storage[3] = data[(m >> 6) & 0x3]; |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDShuffleu32) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ uint32_t m = NumberToUint32(args[1]); |
+ int32x4_value_t result; |
+ int32_t data[4] = { self->x(), self->y(), self->z(), self->w() }; |
+ result.storage[0] = data[m & 0x3]; |
+ result.storage[1] = data[(m >> 2) & 0x3]; |
+ result.storage[2] = data[(m >> 4) & 0x3]; |
+ result.storage[3] = data[(m >> 6) & 0x3]; |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDShuffleMix) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 3); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, first, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, second, 1); |
+ RUNTIME_ASSERT(args[2]->IsNumber()); |
+ |
+ uint32_t m = NumberToUint32(args[2]); |
+ float32x4_value_t result; |
+ float data1[4] = { first->x(), first->y(), first->z(), first->w() }; |
+ float data2[4] = { second->x(), second->y(), second->z(), second->w() }; |
+ result.storage[0] = data1[m & 0x3]; |
+ result.storage[1] = data1[(m >> 2) & 0x3]; |
+ result.storage[2] = data2[(m >> 4) & 0x3]; |
+ result.storage[3] = data2[(m >> 6) & 0x3]; |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithX) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = static_cast<float>(args.number_at(1)); |
+ result.storage[1] = self->y(); |
+ result.storage[2] = self->z(); |
+ result.storage[3] = self->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithY) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = self->x(); |
+ result.storage[1] = static_cast<float>(args.number_at(1)); |
+ result.storage[2] = self->z(); |
+ result.storage[3] = self->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithZ) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = self->x(); |
+ result.storage[1] = self->y(); |
+ result.storage[2] = static_cast<float>(args.number_at(1)); |
+ result.storage[3] = self->w(); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithW) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = self->x(); |
+ result.storage[1] = self->y(); |
+ result.storage[2] = self->z(); |
+ result.storage[3] = static_cast<float>(args.number_at(1)); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDToFloat32x4) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = static_cast<float>(self->x()); |
+ result.storage[1] = static_cast<float>(self->y()); |
+ result.storage[2] = static_cast<float>(self->z()); |
+ result.storage[3] = static_cast<float>(self->w()); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDBitsToFloat32x4) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ |
+ float32x4_value_t result; |
+ int32x4_value_t source = self->value(); |
+ memcpy(&result.storage[0], &source.storage[0], kFloatSize); |
+ memcpy(&result.storage[1], &source.storage[1], kFloatSize); |
+ memcpy(&result.storage[2], &source.storage[2], kFloatSize); |
+ memcpy(&result.storage[3], &source.storage[3], kFloatSize); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDToInt32x4) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = DoubleToInt32(static_cast<double>(self->x())); |
+ result.storage[1] = DoubleToInt32(static_cast<double>(self->y())); |
+ result.storage[2] = DoubleToInt32(static_cast<double>(self->z())); |
+ result.storage[3] = DoubleToInt32(static_cast<double>(self->w())); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDBitsToInt32x4) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ |
+ int32x4_value_t result; |
+ float32x4_value_t source = self->value(); |
+ memcpy(&result.storage[0], &source.storage[0], kInt32Size); |
+ memcpy(&result.storage[1], &source.storage[1], kInt32Size); |
+ memcpy(&result.storage[2], &source.storage[2], kInt32Size); |
+ memcpy(&result.storage[3], &source.storage[3], kInt32Size); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDLessThan) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() < b->x() ? 0xFFFFFFFF : 0x0; |
+ result.storage[1] = a->y() < b->y() ? 0xFFFFFFFF : 0x0; |
+ result.storage[2] = a->z() < b->z() ? 0xFFFFFFFF : 0x0; |
+ result.storage[3] = a->w() < b->w() ? 0xFFFFFFFF : 0x0; |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDLessThanOrEqual) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() <= b->x() ? 0xFFFFFFFF : 0x0; |
+ result.storage[1] = a->y() <= b->y() ? 0xFFFFFFFF : 0x0; |
+ result.storage[2] = a->z() <= b->z() ? 0xFFFFFFFF : 0x0; |
+ result.storage[3] = a->w() <= b->w() ? 0xFFFFFFFF : 0x0; |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDEqual) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() == b->x() ? 0xFFFFFFFF : 0x0; |
+ result.storage[1] = a->y() == b->y() ? 0xFFFFFFFF : 0x0; |
+ result.storage[2] = a->z() == b->z() ? 0xFFFFFFFF : 0x0; |
+ result.storage[3] = a->w() == b->w() ? 0xFFFFFFFF : 0x0; |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDNotEqual) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() != b->x() ? 0xFFFFFFFF : 0x0; |
+ result.storage[1] = a->y() != b->y() ? 0xFFFFFFFF : 0x0; |
+ result.storage[2] = a->z() != b->z() ? 0xFFFFFFFF : 0x0; |
+ result.storage[3] = a->w() != b->w() ? 0xFFFFFFFF : 0x0; |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDGreaterThan) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() > b->x() ? 0xFFFFFFFF : 0x0; |
+ result.storage[1] = a->y() > b->y() ? 0xFFFFFFFF : 0x0; |
+ result.storage[2] = a->z() > b->z() ? 0xFFFFFFFF : 0x0; |
+ result.storage[3] = a->w() > b->w() ? 0xFFFFFFFF : 0x0; |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDGreaterThanOrEqual) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Float32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() >= b->x() ? 0xFFFFFFFF : 0x0; |
+ result.storage[1] = a->y() >= b->y() ? 0xFFFFFFFF : 0x0; |
+ result.storage[2] = a->z() >= b->z() ? 0xFFFFFFFF : 0x0; |
+ result.storage[3] = a->w() >= b->w() ? 0xFFFFFFFF : 0x0; |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDAnd) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Int32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() & b->x(); |
+ result.storage[1] = a->y() & b->y(); |
+ result.storage[2] = a->z() & b->z(); |
+ result.storage[3] = a->w() & b->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDOr) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Int32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() | b->x(); |
+ result.storage[1] = a->y() | b->y(); |
+ result.storage[2] = a->z() | b->z(); |
+ result.storage[3] = a->w() | b->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDXor) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Int32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() ^ b->x(); |
+ result.storage[1] = a->y() ^ b->y(); |
+ result.storage[2] = a->z() ^ b->z(); |
+ result.storage[3] = a->w() ^ b->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDNot) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = ~self->x(); |
+ result.storage[1] = ~self->y(); |
+ result.storage[2] = ~self->z(); |
+ result.storage[3] = ~self->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDNegu32) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 1); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = -self->x(); |
+ result.storage[1] = -self->y(); |
+ result.storage[2] = -self->z(); |
+ result.storage[3] = -self->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDAddu32) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Int32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() + b->x(); |
+ result.storage[1] = a->y() + b->y(); |
+ result.storage[2] = a->z() + b->z(); |
+ result.storage[3] = a->w() + b->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDSubu32) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Int32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() - b->x(); |
+ result.storage[1] = a->y() - b->y(); |
+ result.storage[2] = a->z() - b->z(); |
+ result.storage[3] = a->w() - b->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDMulu32) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, a, 0); |
+ CONVERT_ARG_CHECKED(Int32x4, b, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = a->x() * b->x(); |
+ result.storage[1] = a->y() * b->y(); |
+ result.storage[2] = a->z() * b->z(); |
+ result.storage[3] = a->w() * b->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+// Used to convert between uint32_t and float32 without breaking strict |
+// aliasing rules. |
+union float32_uint32 { |
+ float f; |
+ uint32_t u; |
+ float32_uint32(float v) { |
+ f = v; |
+ } |
+ float32_uint32(uint32_t v) { |
+ u = v; |
+ } |
+}; |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDSelect) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 3); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ CONVERT_ARG_CHECKED(Float32x4, tv, 1); |
+ CONVERT_ARG_CHECKED(Float32x4, fv, 2); |
+ |
+ uint32_t _maskX = self->x(); |
+ uint32_t _maskY = self->y(); |
+ uint32_t _maskZ = self->z(); |
+ uint32_t _maskW = self->w(); |
+ // Extract floats and interpret them as masks. |
+ float32_uint32 tvx(tv->x()); |
+ float32_uint32 tvy(tv->y()); |
+ float32_uint32 tvz(tv->z()); |
+ float32_uint32 tvw(tv->w()); |
+ float32_uint32 fvx(fv->x()); |
+ float32_uint32 fvy(fv->y()); |
+ float32_uint32 fvz(fv->z()); |
+ float32_uint32 fvw(fv->w()); |
+ // Perform select. |
+ float32_uint32 tempX((_maskX & tvx.u) | (~_maskX & fvx.u)); |
+ float32_uint32 tempY((_maskY & tvy.u) | (~_maskY & fvy.u)); |
+ float32_uint32 tempZ((_maskZ & tvz.u) | (~_maskZ & fvz.u)); |
+ float32_uint32 tempW((_maskW & tvw.u) | (~_maskW & fvw.u)); |
+ |
+ float32x4_value_t result; |
+ result.storage[0] = tempX.f; |
+ result.storage[1] = tempY.f; |
+ result.storage[2] = tempZ.f; |
+ result.storage[3] = tempW.f; |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(result); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithXu32) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = NumberToUint32(args[1]); |
+ result.storage[1] = self->y(); |
+ result.storage[2] = self->z(); |
+ result.storage[3] = self->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithYu32) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = self->x(); |
+ result.storage[1] = NumberToUint32(args[1]); |
+ result.storage[2] = self->z(); |
+ result.storage[3] = self->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithZu32) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = self->x(); |
+ result.storage[1] = self->y(); |
+ result.storage[2] = NumberToUint32(args[1]); |
+ result.storage[3] = self->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithWu32) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = self->x(); |
+ result.storage[1] = self->y(); |
+ result.storage[2] = self->z(); |
+ result.storage[3] = NumberToUint32(args[1]); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithFlagX) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ CONVERT_BOOLEAN_ARG_CHECKED(flagX, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = flagX ? 0xFFFFFFFF : 0x0; |
+ result.storage[1] = self->y(); |
+ result.storage[2] = self->z(); |
+ result.storage[3] = self->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithFlagY) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ CONVERT_BOOLEAN_ARG_CHECKED(flagY, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = self->x(); |
+ result.storage[1] = flagY ? 0xFFFFFFFF : 0x0; |
+ result.storage[2] = self->z(); |
+ result.storage[3] = self->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithFlagZ) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ CONVERT_BOOLEAN_ARG_CHECKED(flagZ, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = self->x(); |
+ result.storage[1] = self->y(); |
+ result.storage[2] = flagZ ? 0xFFFFFFFF : 0x0; |
+ result.storage[3] = self->w(); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SIMDWithFlagW) { |
+ SealHandleScope shs(isolate); |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ CONVERT_BOOLEAN_ARG_CHECKED(flagW, 1); |
+ |
+ int32x4_value_t result; |
+ result.storage[0] = self->x(); |
+ result.storage[1] = self->y(); |
+ result.storage[2] = self->z(); |
+ result.storage[3] = flagW ? 0xFFFFFFFF : 0x0; |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(result); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) { |
SealHandleScope shs(isolate); |
ASSERT(args.length() == 2); |
@@ -7901,6 +8950,174 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateSetValue) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateFloat32x4) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 4); |
+ RUNTIME_ASSERT(args[0]->IsNumber()); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ RUNTIME_ASSERT(args[2]->IsNumber()); |
+ RUNTIME_ASSERT(args[3]->IsNumber()); |
+ |
+ float32x4_value_t value; |
+ value.storage[0] = static_cast<float>(args.number_at(0)); |
+ value.storage[1] = static_cast<float>(args.number_at(1)); |
+ value.storage[2] = static_cast<float>(args.number_at(2)); |
+ value.storage[3] = static_cast<float>(args.number_at(3)); |
+ |
+ Float32x4* float32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateFloat32x4(value); |
+ if (!maybe->To(&float32x4)) return maybe; |
+ return float32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Float32x4GetX) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Float32x4, float32x4, 0); |
+ return isolate->heap()->AllocateHeapNumber(float32x4->x()); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Float32x4GetY) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Float32x4, float32x4, 0); |
+ return isolate->heap()->AllocateHeapNumber(float32x4->y()); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Float32x4GetZ) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Float32x4, float32x4, 0); |
+ return isolate->heap()->AllocateHeapNumber(float32x4->z()); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Float32x4GetW) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Float32x4, float32x4, 0); |
+ return isolate->heap()->AllocateHeapNumber(float32x4->w()); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Float32x4GetSignMask) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Float32x4, self, 0); |
+ float32_uint32 x(self->x()); |
+ float32_uint32 y(self->y()); |
+ float32_uint32 z(self->z()); |
+ float32_uint32 w(self->w()); |
+ uint32_t mx = (x.u & 0x80000000) >> 31; |
+ uint32_t my = (y.u & 0x80000000) >> 31; |
+ uint32_t mz = (z.u & 0x80000000) >> 31; |
+ uint32_t mw = (w.u & 0x80000000) >> 31; |
+ uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3); |
+ return isolate->heap()->NumberFromUint32(value); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateInt32x4) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 4); |
+ RUNTIME_ASSERT(args[0]->IsNumber()); |
+ RUNTIME_ASSERT(args[1]->IsNumber()); |
+ RUNTIME_ASSERT(args[2]->IsNumber()); |
+ RUNTIME_ASSERT(args[3]->IsNumber()); |
+ |
+ int32x4_value_t value; |
+ value.storage[0] = NumberToInt32(args[0]); |
+ value.storage[1] = NumberToInt32(args[1]); |
+ value.storage[2] = NumberToInt32(args[2]); |
+ value.storage[3] = NumberToInt32(args[3]); |
+ |
+ Int32x4* int32x4; |
+ MaybeObject* maybe = isolate->heap()->AllocateInt32x4(value); |
+ if (!maybe->To(&int32x4)) return maybe; |
+ return int32x4; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Int32x4GetX) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Int32x4, int32x4, 0); |
+ return isolate->heap()->NumberFromInt32(int32x4->x()); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Int32x4GetY) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Int32x4, int32x4, 0); |
+ return isolate->heap()->NumberFromInt32(int32x4->y()); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Int32x4GetZ) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Int32x4, int32x4, 0); |
+ return isolate->heap()->NumberFromInt32(int32x4->z()); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Int32x4GetW) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Int32x4, int32x4, 0); |
+ return isolate->heap()->NumberFromInt32(int32x4->w()); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Int32x4GetFlagX) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Int32x4, int32x4, 0); |
+ return isolate->heap()->ToBoolean(int32x4->x() != 0); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Int32x4GetFlagY) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Int32x4, int32x4, 0); |
+ return isolate->heap()->ToBoolean(int32x4->y() != 0); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Int32x4GetFlagZ) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Int32x4, int32x4, 0); |
+ return isolate->heap()->ToBoolean(int32x4->z() != 0); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Int32x4GetFlagW) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Int32x4, int32x4, 0); |
+ return isolate->heap()->ToBoolean(int32x4->w() != 0); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Int32x4GetSignMask) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ CONVERT_ARG_CHECKED(Int32x4, self, 0); |
+ uint32_t mx = (self->x() & 0x80000000) >> 31; |
+ uint32_t my = (self->y() & 0x80000000) >> 31; |
+ uint32_t mz = (self->z() & 0x80000000) >> 31; |
+ uint32_t mw = (self->w() & 0x80000000) >> 31; |
+ uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3); |
+ return isolate->heap()->NumberFromUint32(value); |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
@@ -10027,6 +11244,8 @@ static uint32_t EstimateElementCount(Handle<JSArray> array) { |
case EXTERNAL_INT_ELEMENTS: |
case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: |
+ case EXTERNAL_INT32x4_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: |
case EXTERNAL_PIXEL_ELEMENTS: |
// External arrays are always dense. |
@@ -10038,7 +11257,6 @@ static uint32_t EstimateElementCount(Handle<JSArray> array) { |
} |
- |
template<class ExternalArrayClass, class ElementType> |
static void IterateExternalArrayElements(Isolate* isolate, |
Handle<JSObject> receiver, |
@@ -10082,6 +11300,38 @@ static void IterateExternalArrayElements(Isolate* isolate, |
} |
+static void IterateExternalFloat32x4ArrayElements(Isolate* isolate, |
+ Handle<JSObject> receiver, |
+ ArrayConcatVisitor* visitor) { |
+ Handle<ExternalFloat32x4Array> array( |
+ ExternalFloat32x4Array::cast(receiver->elements())); |
+ uint32_t len = static_cast<uint32_t>(array->length()); |
+ |
+ ASSERT(visitor != NULL); |
+ for (uint32_t j = 0; j < len; j++) { |
+ HandleScope loop_scope(isolate); |
+ Handle<Object> e = isolate->factory()->NewFloat32x4(array->get_scalar(j)); |
+ visitor->visit(j, e); |
+ } |
+} |
+ |
+ |
+static void IterateExternalInt32x4ArrayElements(Isolate* isolate, |
+ Handle<JSObject> receiver, |
+ ArrayConcatVisitor* visitor) { |
+ Handle<ExternalInt32x4Array> array( |
+ ExternalInt32x4Array::cast(receiver->elements())); |
+ uint32_t len = static_cast<uint32_t>(array->length()); |
+ |
+ ASSERT(visitor != NULL); |
+ for (uint32_t j = 0; j < len; j++) { |
+ HandleScope loop_scope(isolate); |
+ Handle<Object> e = isolate->factory()->NewInt32x4(array->get_scalar(j)); |
+ visitor->visit(j, e); |
+ } |
+} |
+ |
+ |
// Used for sorting indices in a List<uint32_t>. |
static int compareUInt32(const uint32_t* ap, const uint32_t* bp) { |
uint32_t a = *ap; |
@@ -10176,6 +11426,16 @@ static void CollectElementIndices(Handle<JSObject> object, |
ExternalFloatArray::cast(object->elements())->length(); |
break; |
} |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: { |
+ dense_elements_length = |
+ ExternalFloat32x4Array::cast(object->elements())->length(); |
+ break; |
+ } |
+ case EXTERNAL_INT32x4_ELEMENTS: { |
+ dense_elements_length = |
+ ExternalInt32x4Array::cast(object->elements())->length(); |
+ break; |
+ } |
case EXTERNAL_DOUBLE_ELEMENTS: { |
dense_elements_length = |
ExternalDoubleArray::cast(object->elements())->length(); |
@@ -10341,6 +11601,14 @@ static bool IterateElements(Isolate* isolate, |
isolate, receiver, false, false, visitor); |
break; |
} |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: { |
+ IterateExternalFloat32x4ArrayElements(isolate, receiver, visitor); |
+ break; |
+ } |
+ case EXTERNAL_INT32x4_ELEMENTS: { |
+ IterateExternalInt32x4ArrayElements(isolate, receiver, visitor); |
+ break; |
+ } |
case EXTERNAL_DOUBLE_ELEMENTS: { |
IterateExternalArrayElements<ExternalDoubleArray, double>( |
isolate, receiver, false, false, visitor); |
@@ -14554,6 +15822,8 @@ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) |
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) |
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements) |
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements) |
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloat32x4Elements) |
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalInt32x4Elements) |
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalDoubleElements) |
// Properties test sitting with elements tests - not fooling anyone. |
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties) |