Upstream version 11.39.258.0
[platform/framework/web/crosswalk.git] / src / v8 / src / runtime.cc
index 2e51433..a992704 100644 (file)
@@ -15450,6 +15450,132 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInNext) {
 }
 
 
+template<typename T, int Bytes>
+inline static bool SimdTypeLoadValue(
+    Isolate* isolate,
+    Handle<JSArrayBuffer> buffer,
+    Handle<Object> byte_offset_obj,
+    T* result) {
+  size_t byte_offset = 0;
+  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+    return false;
+  }
+
+  size_t buffer_byte_length =
+      NumberToSize(isolate, buffer->byte_length());
+  if (byte_offset + Bytes > buffer_byte_length)  {  // overflow
+    return false;
+  }
+
+  union Value {
+    T data;
+    uint8_t bytes[sizeof(T)];
+  };
+
+  Value value;
+  memset(value.bytes, 0, sizeof(T));
+  uint8_t* source =
+      static_cast<uint8_t*>(buffer->backing_store()) + byte_offset;
+  DCHECK(Bytes <= sizeof(T));
+  CopyBytes<Bytes>(value.bytes, source);
+  *result = value.data;
+  return true;
+}
+
+
+template<typename T, int Bytes>
+static bool SimdTypeStoreValue(
+    Isolate* isolate,
+    Handle<JSArrayBuffer> buffer,
+    Handle<Object> byte_offset_obj,
+    T data) {
+  size_t byte_offset = 0;
+  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+    return false;
+  }
+
+  size_t buffer_byte_length =
+      NumberToSize(isolate, buffer->byte_length());
+  if (byte_offset + Bytes > buffer_byte_length)  {  // overflow
+    return false;
+  }
+
+  union Value {
+    T data;
+    uint8_t bytes[sizeof(T)];
+  };
+
+  Value value;
+  value.data = data;
+
+  uint8_t* target =
+      static_cast<uint8_t*>(buffer->backing_store()) + byte_offset;
+  DCHECK(Bytes <= sizeof(T));
+  CopyBytes<Bytes>(target, value.bytes);
+  return true;
+}
+
+
+#define SIMD128_LOAD_RUNTIME_FUNCTION(Type, ValueType, Lanes, Bytes)   \
+RUNTIME_FUNCTION(Runtime_##Type##Load##Lanes) {                        \
+  HandleScope scope(isolate);                                          \
+  DCHECK(args.length() == 2);                                          \
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0);                \
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                        \
+  ValueType result;                                                    \
+  if (SimdTypeLoadValue<ValueType, Bytes>(                             \
+          isolate, buffer, offset, &result)) {                         \
+    return *isolate->factory()->New##Type(result);                     \
+  } else {                                                             \
+    THROW_NEW_ERROR_RETURN_FAILURE(                                    \
+        isolate, NewRangeError("invalid_offset",                       \
+        HandleVector<Object>(NULL, 0)));                               \
+  }                                                                    \
+}
+
+
+SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZW, 16)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZ, 12)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XY, 8)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, X, 4)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, XY, 16)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, X, 8)
+SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZW, 16)
+SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZ, 12)
+SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XY, 8)
+SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, X, 4)
+
+
+#define SIMD128_STORE_RUNTIME_FUNCTION(Type, ValueType, Lanes, Bytes)       \
+RUNTIME_FUNCTION(Runtime_##Type##Store##Lanes) {                            \
+  HandleScope scope(isolate);                                               \
+  DCHECK(args.length() == 3);                                               \
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0);                     \
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                             \
+  CONVERT_ARG_CHECKED(Type, value, 2);                                      \
+  ValueType v = value->get();                                               \
+  if (SimdTypeStoreValue<ValueType, Bytes>(isolate, buffer, offset, v)) {   \
+    return isolate->heap()->undefined_value();                              \
+  } else {                                                                  \
+    THROW_NEW_ERROR_RETURN_FAILURE(                                         \
+      isolate, NewRangeError("invalid_offset",                              \
+      HandleVector<Object>(NULL, 0)));                                      \
+  }                                                                         \
+}
+
+
+SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZW, 16)
+SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZ, 12)
+SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XY, 8)
+SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, X, 4)
+SIMD128_STORE_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, XY, 16)
+SIMD128_STORE_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, X, 8)
+SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZW, 16)
+SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZ, 12)
+SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XY, 8)
+SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, X, 4)
+
+
 #define RETURN_Float32x4_RESULT(value)                                         \
   return *isolate->factory()->NewFloat32x4(value);