1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/compiler/function-tester.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing namespace v8::internal;
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing namespace v8::internal::compiler;
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename U>
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void TypedArrayLoadHelper(const char* array_type) {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const uint32_t kValues[] = {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      0x00000000, 0x00000001, 0x00000023, 0x00000042, 0x12345678, 0x87654321,
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      0x0000003f, 0x0000007f, 0x00003fff, 0x00007fff, 0x3fffffff, 0x7fffffff,
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      0x000000ff, 0x00000080, 0x0000ffff, 0x00008000, 0xffffffff, 0x80000000};
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmbeddedVector<char, 1024> values_buffer;
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StringBuilder values_builder(values_buffer.start(), values_buffer.length());
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (size_t i = 0; i < arraysize(kValues); ++i) {
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]);
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Note that below source creates two different typed arrays with distinct
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // elements kind to get coverage for both access patterns:
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - IsFixedTypedArrayElementsKind(x)
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - IsExternalArrayElementsKind(y)
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* source =
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "(function(a) {"
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  var x = (a = new %sArray(%d)); %s;"
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);"
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  if (!%%HasFixed%sElements(x)) %%AbortJS('x');"
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  if (!%%HasExternal%sElements(y)) %%AbortJS('y');"
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  function f(a,b) {"
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    a = a | 0; b = b | 0;"
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    return x[a] + y[b];"
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  }"
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  return f;"
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "})()";
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmbeddedVector<char, 1024> source_buffer;
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SNPrintF(source_buffer, source, array_type, arraysize(kValues),
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           values_buffer.start(), array_type, arraysize(kValues),
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           values_buffer.start(), array_type, array_type);
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FunctionTester T(
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      source_buffer.start(),
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CompilationInfo::kContextSpecializing | CompilationInfo::kTypingEnabled);
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (size_t i = 0; i < arraysize(kValues); ++i) {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (size_t j = 0; j < arraysize(kValues); ++j) {
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      volatile U value_a = static_cast<U>(kValues[i]);
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      volatile U value_b = static_cast<U>(kValues[j]);
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      double expected =
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          static_cast<double>(value_a) + static_cast<double>(value_b);
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      T.CheckCall(T.Val(expected), T.Val(static_cast<double>(i)),
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  T.Val(static_cast<double>(j)));
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(TypedArrayLoad) {
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FLAG_typed_array_max_size_in_heap = 256;
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayLoadHelper<int8_t>("Int8");
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayLoadHelper<uint8_t>("Uint8");
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayLoadHelper<int16_t>("Int16");
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayLoadHelper<uint16_t>("Uint16");
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayLoadHelper<int32_t>("Int32");
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayLoadHelper<uint32_t>("Uint32");
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayLoadHelper<float>("Float32");
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayLoadHelper<double>("Float64");
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mstarzinger): Add tests for ClampedUint8.
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename U>
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void TypedArrayStoreHelper(const char* array_type) {
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const uint32_t kValues[] = {
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      0x00000000, 0x00000001, 0x00000023, 0x00000042, 0x12345678, 0x87654321,
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      0x0000003f, 0x0000007f, 0x00003fff, 0x00007fff, 0x3fffffff, 0x7fffffff,
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      0x000000ff, 0x00000080, 0x0000ffff, 0x00008000, 0xffffffff, 0x80000000};
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmbeddedVector<char, 1024> values_buffer;
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StringBuilder values_builder(values_buffer.start(), values_buffer.length());
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (size_t i = 0; i < arraysize(kValues); ++i) {
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]);
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Note that below source creates two different typed arrays with distinct
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // elements kind to get coverage for both access patterns:
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - IsFixedTypedArrayElementsKind(x)
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - IsExternalArrayElementsKind(y)
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* source =
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "(function(a) {"
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  var x = (a = new %sArray(%d)); %s;"
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);"
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  if (!%%HasFixed%sElements(x)) %%AbortJS('x');"
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  if (!%%HasExternal%sElements(y)) %%AbortJS('y');"
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  function f(a,b) {"
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    a = a | 0; b = b | 0;"
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    var t = x[a];"
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    x[a] = y[b];"
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    y[b] = t;"
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    t = y[b];"
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    y[b] = x[a];"
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    x[a] = t;"
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "    return x[a] + y[b];"
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  }"
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "  return f;"
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "})()";
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmbeddedVector<char, 2048> source_buffer;
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SNPrintF(source_buffer, source, array_type, arraysize(kValues),
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           values_buffer.start(), array_type, arraysize(kValues),
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           values_buffer.start(), array_type, array_type);
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FunctionTester T(
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      source_buffer.start(),
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CompilationInfo::kContextSpecializing | CompilationInfo::kTypingEnabled);
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (size_t i = 0; i < arraysize(kValues); ++i) {
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (size_t j = 0; j < arraysize(kValues); ++j) {
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      volatile U value_a = static_cast<U>(kValues[i]);
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      volatile U value_b = static_cast<U>(kValues[j]);
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      double expected =
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          static_cast<double>(value_a) + static_cast<double>(value_b);
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      T.CheckCall(T.Val(expected), T.Val(static_cast<double>(i)),
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  T.Val(static_cast<double>(j)));
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(TypedArrayStore) {
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FLAG_typed_array_max_size_in_heap = 256;
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayStoreHelper<int8_t>("Int8");
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayStoreHelper<uint8_t>("Uint8");
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayStoreHelper<int16_t>("Int16");
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayStoreHelper<uint16_t>("Uint16");
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayStoreHelper<int32_t>("Int32");
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayStoreHelper<uint32_t>("Uint32");
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayStoreHelper<float>("Float32");
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypedArrayStoreHelper<double>("Float64");
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mstarzinger): Add tests for ClampedUint8.
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
142