OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/v8.h" | |
6 | |
7 #include "src/arguments.h" | |
8 #include "src/base/macros.h" | |
9 #include "src/conversions.h" | |
10 #include "src/runtime/runtime-utils.h" | |
11 | |
12 // Implement Single Instruction Multiple Data (SIMD) operations as defined in | |
13 // the SIMD.js draft spec: | |
14 // http://littledan.github.io/simd.html | |
15 | |
16 #define NumberToFloat32x4Component NumberToFloat | |
17 | |
18 #define CONVERT_SIMD_LANE_ARG_CHECKED(name, index, lanes) \ | |
19 RUNTIME_ASSERT(args[index]->IsSmi()); \ | |
20 int name = args.smi_at(index); \ | |
21 RUNTIME_ASSERT(name >= 0 && name < lanes); | |
22 | |
23 #define SIMD4_CREATE_FUNCTION(type) \ | |
24 RUNTIME_FUNCTION(Runtime_Create##type) { \ | |
25 HandleScope scope(isolate); \ | |
26 DCHECK(args.length() == 4); \ | |
27 CONVERT_NUMBER_ARG_HANDLE_CHECKED(w, 0); \ | |
28 CONVERT_NUMBER_ARG_HANDLE_CHECKED(x, 1); \ | |
29 CONVERT_NUMBER_ARG_HANDLE_CHECKED(y, 2); \ | |
30 CONVERT_NUMBER_ARG_HANDLE_CHECKED(z, 3); \ | |
31 return *isolate->factory()->NewFloat32x4( \ | |
32 NumberTo##type##Component(*w), NumberTo##type##Component(*x), \ | |
33 NumberTo##type##Component(*y), NumberTo##type##Component(*z)); \ | |
34 } | |
35 | |
36 #define SIMD_CREATE_WRAPPER_FUNCTION(type) \ | |
37 RUNTIME_FUNCTION(Runtime_New##type##Wrapper) { \ | |
38 HandleScope scope(isolate); \ | |
39 DCHECK(args.length() == 1); \ | |
40 CONVERT_ARG_HANDLE_CHECKED(type, value, 0); \ | |
41 return *Object::ToObject(isolate, value).ToHandleChecked(); \ | |
42 } | |
43 | |
44 #define SIMD_CHECK_FUNCTION(type) \ | |
45 RUNTIME_FUNCTION(Runtime_##type##Check) { \ | |
46 HandleScope scope(isolate); \ | |
47 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | |
48 return *a; \ | |
49 } | |
50 | |
51 #define SIMD_EXTRACT_LANE_FUNCTION(type, lanes) \ | |
52 RUNTIME_FUNCTION(Runtime_##type##ExtractLane) { \ | |
53 HandleScope scope(isolate); \ | |
54 DCHECK(args.length() == 2); \ | |
55 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | |
56 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lanes); \ | |
57 return *isolate->factory()->NewNumber(a->get_lane(lane)); \ | |
58 } | |
59 | |
60 #define SIMD4_EQUALS_FUNCTION(type) \ | |
61 RUNTIME_FUNCTION(Runtime_##type##Equals) { \ | |
62 HandleScope scope(isolate); \ | |
63 DCHECK(args.length() == 2); \ | |
64 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | |
65 CONVERT_ARG_HANDLE_CHECKED(type, b, 1); \ | |
66 return Equals(a->get_lane(0), b->get_lane(0)) && \ | |
67 Equals(a->get_lane(1), b->get_lane(1)) && \ | |
68 Equals(a->get_lane(2), b->get_lane(2)) && \ | |
69 Equals(a->get_lane(3), b->get_lane(3)) \ | |
70 ? Smi::FromInt(EQUAL) \ | |
71 : Smi::FromInt(NOT_EQUAL); \ | |
72 } | |
73 | |
74 #define SIMD4_SAME_VALUE_FUNCTION(type) \ | |
75 RUNTIME_FUNCTION(Runtime_##type##SameValue) { \ | |
76 HandleScope scope(isolate); \ | |
77 DCHECK(args.length() == 2); \ | |
78 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | |
79 CONVERT_ARG_HANDLE_CHECKED(type, b, 1); \ | |
80 return isolate->heap()->ToBoolean( \ | |
81 SameValue(a->get_lane(0), b->get_lane(0)) && \ | |
82 SameValue(a->get_lane(1), b->get_lane(1)) && \ | |
83 SameValue(a->get_lane(2), b->get_lane(2)) && \ | |
84 SameValue(a->get_lane(3), b->get_lane(3))); \ | |
85 } | |
86 | |
87 #define SIMD4_SAME_VALUE_ZERO_FUNCTION(type) \ | |
88 RUNTIME_FUNCTION(Runtime_##type##SameValueZero) { \ | |
89 HandleScope scope(isolate); \ | |
90 DCHECK(args.length() == 2); \ | |
91 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | |
92 CONVERT_ARG_HANDLE_CHECKED(type, b, 1); \ | |
93 return isolate->heap()->ToBoolean( \ | |
94 SameValueZero(a->get_lane(0), b->get_lane(0)) && \ | |
95 SameValueZero(a->get_lane(1), b->get_lane(1)) && \ | |
96 SameValueZero(a->get_lane(2), b->get_lane(2)) && \ | |
97 SameValueZero(a->get_lane(3), b->get_lane(3))); \ | |
98 } | |
99 | |
100 #define SIMD4_EXTRACT_LANE_FUNCTION(type) SIMD_EXTRACT_LANE_FUNCTION(type, 4) | |
101 | |
102 #define SIMD4_FUNCTIONS(type) \ | |
103 SIMD4_CREATE_FUNCTION(type) \ | |
104 SIMD_CREATE_WRAPPER_FUNCTION(type) \ | |
105 SIMD_CHECK_FUNCTION(type) \ | |
106 SIMD4_EXTRACT_LANE_FUNCTION(type) \ | |
107 SIMD4_EQUALS_FUNCTION(type) \ | |
108 SIMD4_SAME_VALUE_FUNCTION(type) \ | |
109 SIMD4_SAME_VALUE_ZERO_FUNCTION(type) | |
110 | |
111 | |
112 namespace v8 { | |
113 namespace internal { | |
114 | |
115 namespace { | |
116 | |
117 // Convert from Number object to float. | |
118 inline float NumberToFloat(Object* number) { | |
119 return DoubleToFloat32(number->Number()); | |
120 } | |
121 | |
122 | |
123 inline bool Equals(float x, float y) { return x == y; } | |
124 | |
125 } // namespace | |
126 | |
127 SIMD4_FUNCTIONS(Float32x4) | |
128 } | |
129 } // namespace v8::internal | |
OLD | NEW |