OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/base/macros.h" | 8 #include "src/base/macros.h" |
9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
10 #include "src/runtime/runtime-utils.h" | 10 #include "src/runtime/runtime-utils.h" |
11 | 11 |
12 // Implement Single Instruction Multiple Data (SIMD) operations as defined in | 12 // Implement Single Instruction Multiple Data (SIMD) operations as defined in |
13 // the SIMD.js draft spec: | 13 // the SIMD.js draft spec: |
14 // http://littledan.github.io/simd.html | 14 // http://littledan.github.io/simd.html |
15 | 15 |
16 #define CONVERT_SIMD_LANE_ARG_CHECKED(name, index, lanes) \ | 16 #define CONVERT_SIMD_LANE_ARG_CHECKED(name, index, lanes) \ |
17 CONVERT_INT32_ARG_CHECKED(name, index); \ | 17 CONVERT_INT32_ARG_CHECKED(name, index); \ |
18 RUNTIME_ASSERT(name >= 0 && name < lanes); | 18 RUNTIME_ASSERT(name >= 0 && name < lanes); |
19 | 19 |
20 #define SIMD_CREATE_NUMERIC_FUNCTION(type, lane_type, lane_count) \ | 20 #define SIMD_CREATE_NUMERIC_FUNCTION(type, lane_type, lane_count) \ |
21 RUNTIME_FUNCTION(Runtime_Create##type) { \ | 21 RUNTIME_FUNCTION(Runtime_Create##type) { \ |
| 22 static const int kLaneCount = lane_count; \ |
22 HandleScope scope(isolate); \ | 23 HandleScope scope(isolate); \ |
23 DCHECK(args.length() == lane_count); \ | 24 DCHECK(args.length() == kLaneCount); \ |
24 lane_type lanes[lane_count]; \ | 25 lane_type lanes[kLaneCount]; \ |
25 for (int i = 0; i < lane_count; i++) { \ | 26 for (int i = 0; i < kLaneCount; i++) { \ |
26 CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, i); \ | 27 CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, i); \ |
27 lanes[i] = ConvertNumber<lane_type>(number->Number()); \ | 28 lanes[i] = ConvertNumber<lane_type>(number->Number()); \ |
28 } \ | 29 } \ |
29 return *isolate->factory()->New##type(lanes); \ | 30 return *isolate->factory()->New##type(lanes); \ |
30 } | 31 } |
31 | 32 |
32 #define SIMD_CREATE_BOOLEAN_FUNCTION(type, lane_count) \ | 33 #define SIMD_CREATE_BOOLEAN_FUNCTION(type, lane_count) \ |
33 RUNTIME_FUNCTION(Runtime_Create##type) { \ | 34 RUNTIME_FUNCTION(Runtime_Create##type) { \ |
| 35 static const int kLaneCount = lane_count; \ |
34 HandleScope scope(isolate); \ | 36 HandleScope scope(isolate); \ |
35 DCHECK(args.length() == lane_count); \ | 37 DCHECK(args.length() == kLaneCount); \ |
36 bool lanes[lane_count]; \ | 38 bool lanes[kLaneCount]; \ |
37 for (int i = 0; i < lane_count; i++) { \ | 39 for (int i = 0; i < kLaneCount; i++) { \ |
38 lanes[i] = args[i]->BooleanValue(); \ | 40 lanes[i] = args[i]->BooleanValue(); \ |
39 } \ | 41 } \ |
40 return *isolate->factory()->New##type(lanes); \ | 42 return *isolate->factory()->New##type(lanes); \ |
41 } | 43 } |
42 | 44 |
43 #define SIMD_CHECK_FUNCTION(type) \ | 45 #define SIMD_CHECK_FUNCTION(type) \ |
44 RUNTIME_FUNCTION(Runtime_##type##Check) { \ | 46 RUNTIME_FUNCTION(Runtime_##type##Check) { \ |
45 HandleScope scope(isolate); \ | 47 HandleScope scope(isolate); \ |
46 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 48 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ |
47 return *a; \ | 49 return *a; \ |
48 } | 50 } |
49 | 51 |
50 #define SIMD_EXTRACT_LANE_FUNCTION(type, lanes, extract_fn) \ | 52 #define SIMD_EXTRACT_LANE_FUNCTION(type, lanes, extract_fn) \ |
51 RUNTIME_FUNCTION(Runtime_##type##ExtractLane) { \ | 53 RUNTIME_FUNCTION(Runtime_##type##ExtractLane) { \ |
52 HandleScope scope(isolate); \ | 54 HandleScope scope(isolate); \ |
53 DCHECK(args.length() == 2); \ | 55 DCHECK(args.length() == 2); \ |
54 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 56 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ |
55 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lanes); \ | 57 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lanes); \ |
56 return *isolate->factory()->extract_fn(a->get_lane(lane)); \ | 58 return *isolate->factory()->extract_fn(a->get_lane(lane)); \ |
57 } | 59 } |
58 | 60 |
59 #define SIMD_REPLACE_NUMERIC_LANE_FUNCTION(type, lane_type, lane_count) \ | 61 #define SIMD_REPLACE_NUMERIC_LANE_FUNCTION(type, lane_type, lane_count) \ |
60 RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ | 62 RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ |
| 63 static const int kLaneCount = lane_count; \ |
61 HandleScope scope(isolate); \ | 64 HandleScope scope(isolate); \ |
62 DCHECK(args.length() == 3); \ | 65 DCHECK(args.length() == 3); \ |
63 CONVERT_ARG_HANDLE_CHECKED(type, simd, 0); \ | 66 CONVERT_ARG_HANDLE_CHECKED(type, simd, 0); \ |
64 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lane_count); \ | 67 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, kLaneCount); \ |
65 CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 2); \ | 68 CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 2); \ |
66 lane_type lanes[lane_count]; \ | 69 lane_type lanes[kLaneCount]; \ |
67 for (int i = 0; i < lane_count; i++) { \ | 70 for (int i = 0; i < kLaneCount; i++) { \ |
68 lanes[i] = simd->get_lane(i); \ | 71 lanes[i] = simd->get_lane(i); \ |
69 } \ | 72 } \ |
70 lanes[lane] = ConvertNumber<lane_type>(number->Number()); \ | 73 lanes[lane] = ConvertNumber<lane_type>(number->Number()); \ |
71 Handle<type> result = isolate->factory()->New##type(lanes); \ | 74 Handle<type> result = isolate->factory()->New##type(lanes); \ |
72 return *result; \ | 75 return *result; \ |
73 } | 76 } |
74 | 77 |
75 #define SIMD_REPLACE_BOOLEAN_LANE_FUNCTION(type, lane_count) \ | 78 #define SIMD_REPLACE_BOOLEAN_LANE_FUNCTION(type, lane_count) \ |
76 RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ | 79 RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ |
| 80 static const int kLaneCount = lane_count; \ |
77 HandleScope scope(isolate); \ | 81 HandleScope scope(isolate); \ |
78 DCHECK(args.length() == 3); \ | 82 DCHECK(args.length() == 3); \ |
79 CONVERT_ARG_HANDLE_CHECKED(type, simd, 0); \ | 83 CONVERT_ARG_HANDLE_CHECKED(type, simd, 0); \ |
80 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lane_count); \ | 84 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, kLaneCount); \ |
81 bool lanes[lane_count]; \ | 85 bool lanes[kLaneCount]; \ |
82 for (int i = 0; i < lane_count; i++) { \ | 86 for (int i = 0; i < kLaneCount; i++) { \ |
83 lanes[i] = simd->get_lane(i); \ | 87 lanes[i] = simd->get_lane(i); \ |
84 } \ | 88 } \ |
85 lanes[lane] = args[2]->BooleanValue(); \ | 89 lanes[lane] = args[2]->BooleanValue(); \ |
86 Handle<type> result = isolate->factory()->New##type(lanes); \ | 90 Handle<type> result = isolate->factory()->New##type(lanes); \ |
87 return *result; \ | 91 return *result; \ |
88 } | 92 } |
89 | 93 |
90 | 94 |
91 namespace v8 { | 95 namespace v8 { |
92 namespace internal { | 96 namespace internal { |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 | 259 |
256 SIMD_REPLACE_NUMERIC_LANE_FUNCTION(Float32x4, float, 4) | 260 SIMD_REPLACE_NUMERIC_LANE_FUNCTION(Float32x4, float, 4) |
257 SIMD_REPLACE_NUMERIC_LANE_FUNCTION(Int32x4, int32_t, 4) | 261 SIMD_REPLACE_NUMERIC_LANE_FUNCTION(Int32x4, int32_t, 4) |
258 SIMD_REPLACE_BOOLEAN_LANE_FUNCTION(Bool32x4, 4) | 262 SIMD_REPLACE_BOOLEAN_LANE_FUNCTION(Bool32x4, 4) |
259 SIMD_REPLACE_NUMERIC_LANE_FUNCTION(Int16x8, int16_t, 8) | 263 SIMD_REPLACE_NUMERIC_LANE_FUNCTION(Int16x8, int16_t, 8) |
260 SIMD_REPLACE_BOOLEAN_LANE_FUNCTION(Bool16x8, 8) | 264 SIMD_REPLACE_BOOLEAN_LANE_FUNCTION(Bool16x8, 8) |
261 SIMD_REPLACE_NUMERIC_LANE_FUNCTION(Int8x16, int8_t, 16) | 265 SIMD_REPLACE_NUMERIC_LANE_FUNCTION(Int8x16, int8_t, 16) |
262 SIMD_REPLACE_BOOLEAN_LANE_FUNCTION(Bool8x16, 16) | 266 SIMD_REPLACE_BOOLEAN_LANE_FUNCTION(Bool8x16, 16) |
263 } // namespace internal | 267 } // namespace internal |
264 } // namespace v8 | 268 } // namespace v8 |
OLD | NEW |