Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/builtins/builtins-math.cc

Issue 2614773004: [cleanup] Refactor builtins-math.cc to use TF_BUILTIN macro (Closed)
Patch Set: formatted Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 // ----------------------------------------------------------------------------- 13 // -----------------------------------------------------------------------------
14 // ES6 section 20.2.2 Function Properties of the Math Object 14 // ES6 section 20.2.2 Function Properties of the Math Object
15 15
16 class MathBuiltinsAssembler : public CodeStubAssembler {
17 public:
18 explicit MathBuiltinsAssembler(compiler::CodeAssemblerState* state)
19 : CodeStubAssembler(state) {}
20
21 protected:
22 void MathRoundingOperation(Node* (CodeStubAssembler::*float64op)(Node*));
23 void MathUnaryOperation(Node* (CodeStubAssembler::*float64op)(Node*));
24 };
25
16 // ES6 section - 20.2.2.1 Math.abs ( x ) 26 // ES6 section - 20.2.2.1 Math.abs ( x )
17 void Builtins::Generate_MathAbs(compiler::CodeAssemblerState* state) { 27 TF_BUILTIN(MathAbs, CodeStubAssembler) {
18 typedef CodeStubAssembler::Label Label; 28 Node* context = Parameter(4);
19 typedef compiler::Node Node;
20 typedef CodeStubAssembler::Variable Variable;
21 CodeStubAssembler assembler(state);
22
23 Node* context = assembler.Parameter(4);
24 29
25 // We might need to loop once for ToNumber conversion. 30 // We might need to loop once for ToNumber conversion.
26 Variable var_x(&assembler, MachineRepresentation::kTagged); 31 Variable var_x(this, MachineRepresentation::kTagged);
27 Label loop(&assembler, &var_x); 32 Label loop(this, &var_x);
28 var_x.Bind(assembler.Parameter(1)); 33 var_x.Bind(Parameter(1));
29 assembler.Goto(&loop); 34 Goto(&loop);
30 assembler.Bind(&loop); 35 Bind(&loop);
31 { 36 {
32 // Load the current {x} value. 37 // Load the current {x} value.
33 Node* x = var_x.value(); 38 Node* x = var_x.value();
34 39
35 // Check if {x} is a Smi or a HeapObject. 40 // Check if {x} is a Smi or a HeapObject.
36 Label if_xissmi(&assembler), if_xisnotsmi(&assembler); 41 Label if_xissmi(this), if_xisnotsmi(this);
37 assembler.Branch(assembler.TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi); 42 Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
38 43
39 assembler.Bind(&if_xissmi); 44 Bind(&if_xissmi);
40 { 45 {
41 // Check if {x} is already positive. 46 // Check if {x} is already positive.
42 Label if_xispositive(&assembler), if_xisnotpositive(&assembler); 47 Label if_xispositive(this), if_xisnotpositive(this);
43 assembler.BranchIfSmiLessThanOrEqual( 48 BranchIfSmiLessThanOrEqual(SmiConstant(Smi::FromInt(0)), x,
44 assembler.SmiConstant(Smi::FromInt(0)), x, &if_xispositive, 49 &if_xispositive, &if_xisnotpositive);
45 &if_xisnotpositive); 50
46 51 Bind(&if_xispositive);
47 assembler.Bind(&if_xispositive);
48 { 52 {
49 // Just return the input {x}. 53 // Just return the input {x}.
50 assembler.Return(x); 54 Return(x);
51 } 55 }
52 56
53 assembler.Bind(&if_xisnotpositive); 57 Bind(&if_xisnotpositive);
54 { 58 {
55 // Try to negate the {x} value. 59 // Try to negate the {x} value.
56 Node* pair = assembler.IntPtrSubWithOverflow( 60 Node* pair =
57 assembler.IntPtrConstant(0), assembler.BitcastTaggedToWord(x)); 61 IntPtrSubWithOverflow(IntPtrConstant(0), BitcastTaggedToWord(x));
58 Node* overflow = assembler.Projection(1, pair); 62 Node* overflow = Projection(1, pair);
59 Label if_overflow(&assembler, Label::kDeferred), 63 Label if_overflow(this, Label::kDeferred), if_notoverflow(this);
60 if_notoverflow(&assembler); 64 Branch(overflow, &if_overflow, &if_notoverflow);
61 assembler.Branch(overflow, &if_overflow, &if_notoverflow); 65
62 66 Bind(&if_notoverflow);
63 assembler.Bind(&if_notoverflow);
64 { 67 {
65 // There is a Smi representation for negated {x}. 68 // There is a Smi representation for negated {x}.
66 Node* result = assembler.Projection(0, pair); 69 Node* result = Projection(0, pair);
67 result = assembler.BitcastWordToTagged(result); 70 Return(BitcastWordToTagged(result));
68 assembler.Return(result);
69 } 71 }
70 72
71 assembler.Bind(&if_overflow); 73 Bind(&if_overflow);
72 { 74 { Return(NumberConstant(0.0 - Smi::kMinValue)); }
73 Node* result = assembler.NumberConstant(0.0 - Smi::kMinValue); 75 }
74 assembler.Return(result); 76 }
75 } 77
76 } 78 Bind(&if_xisnotsmi);
77 }
78
79 assembler.Bind(&if_xisnotsmi);
80 { 79 {
81 // Check if {x} is a HeapNumber. 80 // Check if {x} is a HeapNumber.
82 Label if_xisheapnumber(&assembler), 81 Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred);
83 if_xisnotheapnumber(&assembler, Label::kDeferred); 82 Branch(IsHeapNumberMap(LoadMap(x)), &if_xisheapnumber,
84 assembler.Branch(assembler.IsHeapNumberMap(assembler.LoadMap(x)), 83 &if_xisnotheapnumber);
85 &if_xisheapnumber, &if_xisnotheapnumber); 84
86 85 Bind(&if_xisheapnumber);
87 assembler.Bind(&if_xisheapnumber); 86 {
88 { 87 Node* x_value = LoadHeapNumberValue(x);
89 Node* x_value = assembler.LoadHeapNumberValue(x); 88 Node* value = Float64Abs(x_value);
90 Node* value = assembler.Float64Abs(x_value); 89 Node* result = AllocateHeapNumberWithValue(value);
91 Node* result = assembler.AllocateHeapNumberWithValue(value); 90 Return(result);
92 assembler.Return(result); 91 }
93 } 92
94 93 Bind(&if_xisnotheapnumber);
95 assembler.Bind(&if_xisnotheapnumber);
96 { 94 {
97 // Need to convert {x} to a Number first. 95 // Need to convert {x} to a Number first.
98 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate()); 96 Callable callable = CodeFactory::NonNumberToNumber(isolate());
99 var_x.Bind(assembler.CallStub(callable, context, x)); 97 var_x.Bind(CallStub(callable, context, x));
100 assembler.Goto(&loop); 98 Goto(&loop);
101 } 99 }
102 } 100 }
103 } 101 }
104 } 102 }
105 103
106 namespace { 104 void MathBuiltinsAssembler::MathRoundingOperation(
107 105 Node* (CodeStubAssembler::*float64op)(Node*)) {
108 void Generate_MathRoundingOperation( 106 Node* context = Parameter(4);
109 CodeStubAssembler* assembler,
110 compiler::Node* (CodeStubAssembler::*float64op)(compiler::Node*)) {
111 typedef CodeStubAssembler::Label Label;
112 typedef compiler::Node Node;
113 typedef CodeStubAssembler::Variable Variable;
114
115 Node* context = assembler->Parameter(4);
116 107
117 // We might need to loop once for ToNumber conversion. 108 // We might need to loop once for ToNumber conversion.
118 Variable var_x(assembler, MachineRepresentation::kTagged); 109 Variable var_x(this, MachineRepresentation::kTagged);
119 Label loop(assembler, &var_x); 110 Label loop(this, &var_x);
120 var_x.Bind(assembler->Parameter(1)); 111 var_x.Bind(Parameter(1));
121 assembler->Goto(&loop); 112 Goto(&loop);
122 assembler->Bind(&loop); 113 Bind(&loop);
123 { 114 {
124 // Load the current {x} value. 115 // Load the current {x} value.
125 Node* x = var_x.value(); 116 Node* x = var_x.value();
126 117
127 // Check if {x} is a Smi or a HeapObject. 118 // Check if {x} is a Smi or a HeapObject.
128 Label if_xissmi(assembler), if_xisnotsmi(assembler); 119 Label if_xissmi(this), if_xisnotsmi(this);
129 assembler->Branch(assembler->TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi); 120 Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
130 121
131 assembler->Bind(&if_xissmi); 122 Bind(&if_xissmi);
132 { 123 {
133 // Nothing to do when {x} is a Smi. 124 // Nothing to do when {x} is a Smi.
134 assembler->Return(x); 125 Return(x);
135 } 126 }
136 127
137 assembler->Bind(&if_xisnotsmi); 128 Bind(&if_xisnotsmi);
138 { 129 {
139 // Check if {x} is a HeapNumber. 130 // Check if {x} is a HeapNumber.
140 Label if_xisheapnumber(assembler), 131 Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred);
141 if_xisnotheapnumber(assembler, Label::kDeferred); 132 Branch(IsHeapNumberMap(LoadMap(x)), &if_xisheapnumber,
142 assembler->Branch(assembler->IsHeapNumberMap(assembler->LoadMap(x)), 133 &if_xisnotheapnumber);
143 &if_xisheapnumber, &if_xisnotheapnumber); 134
144 135 Bind(&if_xisheapnumber);
145 assembler->Bind(&if_xisheapnumber); 136 {
146 { 137 Node* x_value = LoadHeapNumberValue(x);
147 Node* x_value = assembler->LoadHeapNumberValue(x); 138 Node* value = (this->*float64op)(x_value);
148 Node* value = (assembler->*float64op)(x_value); 139 Node* result = ChangeFloat64ToTagged(value);
149 Node* result = assembler->ChangeFloat64ToTagged(value); 140 Return(result);
150 assembler->Return(result); 141 }
151 } 142
152 143 Bind(&if_xisnotheapnumber);
153 assembler->Bind(&if_xisnotheapnumber);
154 { 144 {
155 // Need to convert {x} to a Number first. 145 // Need to convert {x} to a Number first.
156 Callable callable = 146 Callable callable = CodeFactory::NonNumberToNumber(isolate());
157 CodeFactory::NonNumberToNumber(assembler->isolate()); 147 var_x.Bind(CallStub(callable, context, x));
158 var_x.Bind(assembler->CallStub(callable, context, x)); 148 Goto(&loop);
159 assembler->Goto(&loop);
160 } 149 }
161 } 150 }
162 } 151 }
163 } 152 }
164 153
165 void Generate_MathUnaryOperation( 154 void MathBuiltinsAssembler::MathUnaryOperation(
166 CodeStubAssembler* assembler, 155 Node* (CodeStubAssembler::*float64op)(Node*)) {
167 compiler::Node* (CodeStubAssembler::*float64op)(compiler::Node*)) { 156 Node* x = Parameter(1);
168 typedef compiler::Node Node; 157 Node* context = Parameter(4);
169 158 Node* x_value = TruncateTaggedToFloat64(context, x);
170 Node* x = assembler->Parameter(1); 159 Node* value = (this->*float64op)(x_value);
171 Node* context = assembler->Parameter(4); 160 Node* result = AllocateHeapNumberWithValue(value);
172 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); 161 Return(result);
173 Node* value = (assembler->*float64op)(x_value); 162 }
174 Node* result = assembler->AllocateHeapNumberWithValue(value);
175 assembler->Return(result);
176 }
177
178 } // namespace
179 163
180 // ES6 section 20.2.2.2 Math.acos ( x ) 164 // ES6 section 20.2.2.2 Math.acos ( x )
181 void Builtins::Generate_MathAcos(compiler::CodeAssemblerState* state) { 165 TF_BUILTIN(MathAcos, MathBuiltinsAssembler) {
182 CodeStubAssembler assembler(state); 166 MathUnaryOperation(&CodeStubAssembler::Float64Acos);
183 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Acos);
184 } 167 }
185 168
186 // ES6 section 20.2.2.3 Math.acosh ( x ) 169 // ES6 section 20.2.2.3 Math.acosh ( x )
187 void Builtins::Generate_MathAcosh(compiler::CodeAssemblerState* state) { 170 TF_BUILTIN(MathAcosh, MathBuiltinsAssembler) {
188 CodeStubAssembler assembler(state); 171 MathUnaryOperation(&CodeStubAssembler::Float64Acosh);
189 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Acosh);
190 } 172 }
191 173
192 // ES6 section 20.2.2.4 Math.asin ( x ) 174 // ES6 section 20.2.2.4 Math.asin ( x )
193 void Builtins::Generate_MathAsin(compiler::CodeAssemblerState* state) { 175 TF_BUILTIN(MathAsin, MathBuiltinsAssembler) {
194 CodeStubAssembler assembler(state); 176 MathUnaryOperation(&CodeStubAssembler::Float64Asin);
195 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Asin);
196 } 177 }
197 178
198 // ES6 section 20.2.2.5 Math.asinh ( x ) 179 // ES6 section 20.2.2.5 Math.asinh ( x )
199 void Builtins::Generate_MathAsinh(compiler::CodeAssemblerState* state) { 180 TF_BUILTIN(MathAsinh, MathBuiltinsAssembler) {
200 CodeStubAssembler assembler(state); 181 MathUnaryOperation(&CodeStubAssembler::Float64Asinh);
201 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Asinh); 182 }
202 }
203
204 // ES6 section 20.2.2.6 Math.atan ( x ) 183 // ES6 section 20.2.2.6 Math.atan ( x )
205 void Builtins::Generate_MathAtan(compiler::CodeAssemblerState* state) { 184 TF_BUILTIN(MathAtan, MathBuiltinsAssembler) {
206 CodeStubAssembler assembler(state); 185 MathUnaryOperation(&CodeStubAssembler::Float64Atan);
207 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Atan);
208 } 186 }
209 187
210 // ES6 section 20.2.2.7 Math.atanh ( x ) 188 // ES6 section 20.2.2.7 Math.atanh ( x )
211 void Builtins::Generate_MathAtanh(compiler::CodeAssemblerState* state) { 189 TF_BUILTIN(MathAtanh, MathBuiltinsAssembler) {
212 CodeStubAssembler assembler(state); 190 MathUnaryOperation(&CodeStubAssembler::Float64Atanh);
213 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Atanh);
214 } 191 }
215 192
216 // ES6 section 20.2.2.8 Math.atan2 ( y, x ) 193 // ES6 section 20.2.2.8 Math.atan2 ( y, x )
217 void Builtins::Generate_MathAtan2(compiler::CodeAssemblerState* state) { 194 TF_BUILTIN(MathAtan2, CodeStubAssembler) {
218 using compiler::Node; 195 Node* y = Parameter(1);
219 CodeStubAssembler assembler(state); 196 Node* x = Parameter(2);
220 197 Node* context = Parameter(5);
221 Node* y = assembler.Parameter(1); 198
222 Node* x = assembler.Parameter(2); 199 Node* y_value = TruncateTaggedToFloat64(context, y);
223 Node* context = assembler.Parameter(5); 200 Node* x_value = TruncateTaggedToFloat64(context, x);
224 Node* y_value = assembler.TruncateTaggedToFloat64(context, y); 201 Node* value = Float64Atan2(y_value, x_value);
225 Node* x_value = assembler.TruncateTaggedToFloat64(context, x); 202 Node* result = AllocateHeapNumberWithValue(value);
226 Node* value = assembler.Float64Atan2(y_value, x_value); 203 Return(result);
227 Node* result = assembler.AllocateHeapNumberWithValue(value);
228 assembler.Return(result);
229 } 204 }
230 205
231 // ES6 section 20.2.2.10 Math.ceil ( x ) 206 // ES6 section 20.2.2.10 Math.ceil ( x )
232 void Builtins::Generate_MathCeil(compiler::CodeAssemblerState* state) { 207 TF_BUILTIN(MathCeil, MathBuiltinsAssembler) {
233 CodeStubAssembler assembler(state); 208 MathRoundingOperation(&CodeStubAssembler::Float64Ceil);
234 Generate_MathRoundingOperation(&assembler, &CodeStubAssembler::Float64Ceil);
235 } 209 }
236 210
237 // ES6 section 20.2.2.9 Math.cbrt ( x ) 211 // ES6 section 20.2.2.9 Math.cbrt ( x )
238 void Builtins::Generate_MathCbrt(compiler::CodeAssemblerState* state) { 212 TF_BUILTIN(MathCbrt, MathBuiltinsAssembler) {
239 CodeStubAssembler assembler(state); 213 MathUnaryOperation(&CodeStubAssembler::Float64Cbrt);
240 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Cbrt);
241 } 214 }
242 215
243 // ES6 section 20.2.2.11 Math.clz32 ( x ) 216 // ES6 section 20.2.2.11 Math.clz32 ( x )
244 void Builtins::Generate_MathClz32(compiler::CodeAssemblerState* state) { 217 TF_BUILTIN(MathClz32, CodeStubAssembler) {
245 typedef CodeStubAssembler::Label Label; 218 Node* context = Parameter(4);
246 typedef compiler::Node Node;
247 typedef CodeStubAssembler::Variable Variable;
248 CodeStubAssembler assembler(state);
249
250 Node* context = assembler.Parameter(4);
251 219
252 // Shared entry point for the clz32 operation. 220 // Shared entry point for the clz32 operation.
253 Variable var_clz32_x(&assembler, MachineRepresentation::kWord32); 221 Variable var_clz32_x(this, MachineRepresentation::kWord32);
254 Label do_clz32(&assembler); 222 Label do_clz32(this);
255 223
256 // We might need to loop once for ToNumber conversion. 224 // We might need to loop once for ToNumber conversion.
257 Variable var_x(&assembler, MachineRepresentation::kTagged); 225 Variable var_x(this, MachineRepresentation::kTagged);
258 Label loop(&assembler, &var_x); 226 Label loop(this, &var_x);
259 var_x.Bind(assembler.Parameter(1)); 227 var_x.Bind(Parameter(1));
260 assembler.Goto(&loop); 228 Goto(&loop);
261 assembler.Bind(&loop); 229 Bind(&loop);
262 { 230 {
263 // Load the current {x} value. 231 // Load the current {x} value.
264 Node* x = var_x.value(); 232 Node* x = var_x.value();
265 233
266 // Check if {x} is a Smi or a HeapObject. 234 // Check if {x} is a Smi or a HeapObject.
267 Label if_xissmi(&assembler), if_xisnotsmi(&assembler); 235 Label if_xissmi(this), if_xisnotsmi(this);
268 assembler.Branch(assembler.TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi); 236 Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
269 237
270 assembler.Bind(&if_xissmi); 238 Bind(&if_xissmi);
271 { 239 {
272 var_clz32_x.Bind(assembler.SmiToWord32(x)); 240 var_clz32_x.Bind(SmiToWord32(x));
273 assembler.Goto(&do_clz32); 241 Goto(&do_clz32);
274 } 242 }
275 243
276 assembler.Bind(&if_xisnotsmi); 244 Bind(&if_xisnotsmi);
277 { 245 {
278 // Check if {x} is a HeapNumber. 246 // Check if {x} is a HeapNumber.
279 Label if_xisheapnumber(&assembler), 247 Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred);
280 if_xisnotheapnumber(&assembler, Label::kDeferred); 248 Branch(IsHeapNumberMap(LoadMap(x)), &if_xisheapnumber,
281 assembler.Branch(assembler.IsHeapNumberMap(assembler.LoadMap(x)), 249 &if_xisnotheapnumber);
282 &if_xisheapnumber, &if_xisnotheapnumber); 250
283 251 Bind(&if_xisheapnumber);
284 assembler.Bind(&if_xisheapnumber); 252 {
285 { 253 var_clz32_x.Bind(TruncateHeapNumberValueToWord32(x));
286 var_clz32_x.Bind(assembler.TruncateHeapNumberValueToWord32(x)); 254 Goto(&do_clz32);
287 assembler.Goto(&do_clz32); 255 }
288 } 256
289 257 Bind(&if_xisnotheapnumber);
290 assembler.Bind(&if_xisnotheapnumber);
291 { 258 {
292 // Need to convert {x} to a Number first. 259 // Need to convert {x} to a Number first.
293 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate()); 260 Callable callable = CodeFactory::NonNumberToNumber(isolate());
294 var_x.Bind(assembler.CallStub(callable, context, x)); 261 var_x.Bind(CallStub(callable, context, x));
295 assembler.Goto(&loop); 262 Goto(&loop);
296 } 263 }
297 } 264 }
298 } 265 }
299 266
300 assembler.Bind(&do_clz32); 267 Bind(&do_clz32);
301 { 268 {
302 Node* x_value = var_clz32_x.value(); 269 Node* x_value = var_clz32_x.value();
303 Node* value = assembler.Word32Clz(x_value); 270 Node* value = Word32Clz(x_value);
304 Node* result = assembler.ChangeInt32ToTagged(value); 271 Node* result = ChangeInt32ToTagged(value);
305 assembler.Return(result); 272 Return(result);
306 } 273 }
307 } 274 }
308 275
309 // ES6 section 20.2.2.12 Math.cos ( x ) 276 // ES6 section 20.2.2.12 Math.cos ( x )
310 void Builtins::Generate_MathCos(compiler::CodeAssemblerState* state) { 277 TF_BUILTIN(MathCos, MathBuiltinsAssembler) {
311 CodeStubAssembler assembler(state); 278 MathUnaryOperation(&CodeStubAssembler::Float64Cos);
312 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Cos);
313 } 279 }
314 280
315 // ES6 section 20.2.2.13 Math.cosh ( x ) 281 // ES6 section 20.2.2.13 Math.cosh ( x )
316 void Builtins::Generate_MathCosh(compiler::CodeAssemblerState* state) { 282 TF_BUILTIN(MathCosh, MathBuiltinsAssembler) {
317 CodeStubAssembler assembler(state); 283 MathUnaryOperation(&CodeStubAssembler::Float64Cosh);
318 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Cosh);
319 } 284 }
320 285
321 // ES6 section 20.2.2.14 Math.exp ( x ) 286 // ES6 section 20.2.2.14 Math.exp ( x )
322 void Builtins::Generate_MathExp(compiler::CodeAssemblerState* state) { 287 TF_BUILTIN(MathExp, MathBuiltinsAssembler) {
323 CodeStubAssembler assembler(state); 288 MathUnaryOperation(&CodeStubAssembler::Float64Exp);
324 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Exp);
325 } 289 }
326 290
327 // ES6 section 20.2.2.15 Math.expm1 ( x ) 291 // ES6 section 20.2.2.15 Math.expm1 ( x )
328 void Builtins::Generate_MathExpm1(compiler::CodeAssemblerState* state) { 292 TF_BUILTIN(MathExpm1, MathBuiltinsAssembler) {
329 CodeStubAssembler assembler(state); 293 MathUnaryOperation(&CodeStubAssembler::Float64Expm1);
330 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Expm1);
331 } 294 }
332 295
333 // ES6 section 20.2.2.16 Math.floor ( x ) 296 // ES6 section 20.2.2.16 Math.floor ( x )
334 void Builtins::Generate_MathFloor(compiler::CodeAssemblerState* state) { 297 TF_BUILTIN(MathFloor, MathBuiltinsAssembler) {
335 CodeStubAssembler assembler(state); 298 MathRoundingOperation(&CodeStubAssembler::Float64Floor);
336 Generate_MathRoundingOperation(&assembler, &CodeStubAssembler::Float64Floor);
337 } 299 }
338 300
339 // ES6 section 20.2.2.17 Math.fround ( x ) 301 // ES6 section 20.2.2.17 Math.fround ( x )
340 void Builtins::Generate_MathFround(compiler::CodeAssemblerState* state) { 302 TF_BUILTIN(MathFround, CodeStubAssembler) {
341 using compiler::Node; 303 Node* x = Parameter(1);
342 CodeStubAssembler assembler(state); 304 Node* context = Parameter(4);
343 305 Node* x_value = TruncateTaggedToFloat64(context, x);
344 Node* x = assembler.Parameter(1); 306 Node* value32 = TruncateFloat64ToFloat32(x_value);
345 Node* context = assembler.Parameter(4); 307 Node* value = ChangeFloat32ToFloat64(value32);
346 Node* x_value = assembler.TruncateTaggedToFloat64(context, x); 308 Node* result = AllocateHeapNumberWithValue(value);
347 Node* value32 = assembler.TruncateFloat64ToFloat32(x_value); 309 Return(result);
348 Node* value = assembler.ChangeFloat32ToFloat64(value32);
349 Node* result = assembler.AllocateHeapNumberWithValue(value);
350 assembler.Return(result);
351 } 310 }
352 311
353 // ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values ) 312 // ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values )
354 BUILTIN(MathHypot) { 313 BUILTIN(MathHypot) {
355 HandleScope scope(isolate); 314 HandleScope scope(isolate);
356 int const length = args.length() - 1; 315 int const length = args.length() - 1;
357 if (length == 0) return Smi::kZero; 316 if (length == 0) return Smi::kZero;
358 DCHECK_LT(0, length); 317 DCHECK_LT(0, length);
359 double max = 0; 318 double max = 0;
360 bool one_arg_is_nan = false; 319 bool one_arg_is_nan = false;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 double summand = n * n - compensation; 355 double summand = n * n - compensation;
397 double preliminary = sum + summand; 356 double preliminary = sum + summand;
398 compensation = (preliminary - sum) - summand; 357 compensation = (preliminary - sum) - summand;
399 sum = preliminary; 358 sum = preliminary;
400 } 359 }
401 360
402 return *isolate->factory()->NewNumber(std::sqrt(sum) * max); 361 return *isolate->factory()->NewNumber(std::sqrt(sum) * max);
403 } 362 }
404 363
405 // ES6 section 20.2.2.19 Math.imul ( x, y ) 364 // ES6 section 20.2.2.19 Math.imul ( x, y )
406 void Builtins::Generate_MathImul(compiler::CodeAssemblerState* state) { 365 TF_BUILTIN(MathImul, CodeStubAssembler) {
407 using compiler::Node; 366 Node* x = Parameter(1);
408 CodeStubAssembler assembler(state); 367 Node* y = Parameter(2);
409 368 Node* context = Parameter(5);
410 Node* x = assembler.Parameter(1); 369 Node* x_value = TruncateTaggedToWord32(context, x);
411 Node* y = assembler.Parameter(2); 370 Node* y_value = TruncateTaggedToWord32(context, y);
412 Node* context = assembler.Parameter(5); 371 Node* value = Int32Mul(x_value, y_value);
413 Node* x_value = assembler.TruncateTaggedToWord32(context, x); 372 Node* result = ChangeInt32ToTagged(value);
414 Node* y_value = assembler.TruncateTaggedToWord32(context, y); 373 Return(result);
415 Node* value = assembler.Int32Mul(x_value, y_value);
416 Node* result = assembler.ChangeInt32ToTagged(value);
417 assembler.Return(result);
418 } 374 }
419 375
420 // ES6 section 20.2.2.20 Math.log ( x ) 376 // ES6 section 20.2.2.20 Math.log ( x )
421 void Builtins::Generate_MathLog(compiler::CodeAssemblerState* state) { 377 TF_BUILTIN(MathLog, MathBuiltinsAssembler) {
422 CodeStubAssembler assembler(state); 378 MathUnaryOperation(&CodeStubAssembler::Float64Log);
423 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Log);
424 } 379 }
425 380
426 // ES6 section 20.2.2.21 Math.log1p ( x ) 381 // ES6 section 20.2.2.21 Math.log1p ( x )
427 void Builtins::Generate_MathLog1p(compiler::CodeAssemblerState* state) { 382 TF_BUILTIN(MathLog1p, MathBuiltinsAssembler) {
428 CodeStubAssembler assembler(state); 383 MathUnaryOperation(&CodeStubAssembler::Float64Log1p);
429 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Log1p);
430 } 384 }
431 385
432 // ES6 section 20.2.2.22 Math.log10 ( x ) 386 // ES6 section 20.2.2.22 Math.log10 ( x )
433 void Builtins::Generate_MathLog10(compiler::CodeAssemblerState* state) { 387 TF_BUILTIN(MathLog10, MathBuiltinsAssembler) {
434 CodeStubAssembler assembler(state); 388 MathUnaryOperation(&CodeStubAssembler::Float64Log10);
435 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Log10);
436 } 389 }
437 390
438 // ES6 section 20.2.2.23 Math.log2 ( x ) 391 // ES6 section 20.2.2.23 Math.log2 ( x )
439 void Builtins::Generate_MathLog2(compiler::CodeAssemblerState* state) { 392 TF_BUILTIN(MathLog2, MathBuiltinsAssembler) {
440 CodeStubAssembler assembler(state); 393 MathUnaryOperation(&CodeStubAssembler::Float64Log2);
441 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Log2);
442 } 394 }
443 395
444 // ES6 section 20.2.2.26 Math.pow ( x, y ) 396 // ES6 section 20.2.2.26 Math.pow ( x, y )
445 void Builtins::Generate_MathPow(compiler::CodeAssemblerState* state) { 397 TF_BUILTIN(MathPow, CodeStubAssembler) {
446 using compiler::Node; 398 Node* x = Parameter(1);
447 CodeStubAssembler assembler(state); 399 Node* y = Parameter(2);
448 400 Node* context = Parameter(5);
449 Node* x = assembler.Parameter(1); 401 Node* x_value = TruncateTaggedToFloat64(context, x);
450 Node* y = assembler.Parameter(2); 402 Node* y_value = TruncateTaggedToFloat64(context, y);
451 Node* context = assembler.Parameter(5); 403 Node* value = Float64Pow(x_value, y_value);
452 Node* x_value = assembler.TruncateTaggedToFloat64(context, x); 404 Node* result = ChangeFloat64ToTagged(value);
453 Node* y_value = assembler.TruncateTaggedToFloat64(context, y); 405 Return(result);
454 Node* value = assembler.Float64Pow(x_value, y_value);
455 Node* result = assembler.ChangeFloat64ToTagged(value);
456 assembler.Return(result);
457 } 406 }
458 407
459 // ES6 section 20.2.2.27 Math.random ( ) 408 // ES6 section 20.2.2.27 Math.random ( )
460 void Builtins::Generate_MathRandom(compiler::CodeAssemblerState* state) { 409 TF_BUILTIN(MathRandom, CodeStubAssembler) {
461 using compiler::Node; 410 Node* context = Parameter(3);
462 CodeStubAssembler assembler(state); 411 Node* native_context = LoadNativeContext(context);
463
464 Node* context = assembler.Parameter(3);
465 Node* native_context = assembler.LoadNativeContext(context);
466 412
467 // Load cache index. 413 // Load cache index.
468 CodeStubAssembler::Variable smi_index(&assembler, 414 Variable smi_index(this, MachineRepresentation::kTagged);
469 MachineRepresentation::kTagged); 415 smi_index.Bind(
470 smi_index.Bind(assembler.LoadContextElement( 416 LoadContextElement(native_context, Context::MATH_RANDOM_INDEX_INDEX));
471 native_context, Context::MATH_RANDOM_INDEX_INDEX));
472 417
473 // Cached random numbers are exhausted if index is 0. Go to slow path. 418 // Cached random numbers are exhausted if index is 0. Go to slow path.
474 CodeStubAssembler::Label if_cached(&assembler); 419 Label if_cached(this);
475 assembler.GotoIf( 420 GotoIf(SmiAbove(smi_index.value(), SmiConstant(Smi::kZero)), &if_cached);
476 assembler.SmiAbove(smi_index.value(), assembler.SmiConstant(Smi::kZero)),
477 &if_cached);
478 421
479 // Cache exhausted, populate the cache. Return value is the new index. 422 // Cache exhausted, populate the cache. Return value is the new index.
480 smi_index.Bind( 423 smi_index.Bind(CallRuntime(Runtime::kGenerateRandomNumbers, context));
481 assembler.CallRuntime(Runtime::kGenerateRandomNumbers, context)); 424 Goto(&if_cached);
482 assembler.Goto(&if_cached);
483 425
484 // Compute next index by decrement. 426 // Compute next index by decrement.
485 assembler.Bind(&if_cached); 427 Bind(&if_cached);
486 Node* new_smi_index = assembler.SmiSub( 428 Node* new_smi_index = SmiSub(smi_index.value(), SmiConstant(Smi::FromInt(1)));
487 smi_index.value(), assembler.SmiConstant(Smi::FromInt(1))); 429 StoreContextElement(native_context, Context::MATH_RANDOM_INDEX_INDEX,
488 assembler.StoreContextElement( 430 new_smi_index);
489 native_context, Context::MATH_RANDOM_INDEX_INDEX, new_smi_index);
490 431
491 // Load and return next cached random number. 432 // Load and return next cached random number.
492 Node* array = assembler.LoadContextElement(native_context, 433 Node* array =
493 Context::MATH_RANDOM_CACHE_INDEX); 434 LoadContextElement(native_context, Context::MATH_RANDOM_CACHE_INDEX);
494 Node* random = assembler.LoadFixedDoubleArrayElement( 435 Node* random = LoadFixedDoubleArrayElement(
495 array, new_smi_index, MachineType::Float64(), 0, 436 array, new_smi_index, MachineType::Float64(), 0, SMI_PARAMETERS);
496 CodeStubAssembler::SMI_PARAMETERS); 437 Return(AllocateHeapNumberWithValue(random));
497 assembler.Return(assembler.AllocateHeapNumberWithValue(random));
498 } 438 }
499 439
500 // ES6 section 20.2.2.28 Math.round ( x ) 440 // ES6 section 20.2.2.28 Math.round ( x )
501 void Builtins::Generate_MathRound(compiler::CodeAssemblerState* state) { 441 TF_BUILTIN(MathRound, MathBuiltinsAssembler) {
502 CodeStubAssembler assembler(state); 442 MathRoundingOperation(&CodeStubAssembler::Float64Round);
503 Generate_MathRoundingOperation(&assembler, &CodeStubAssembler::Float64Round);
504 } 443 }
505 444
506 // ES6 section 20.2.2.29 Math.sign ( x ) 445 // ES6 section 20.2.2.29 Math.sign ( x )
507 void Builtins::Generate_MathSign(compiler::CodeAssemblerState* state) { 446 TF_BUILTIN(MathSign, CodeStubAssembler) {
508 typedef CodeStubAssembler::Label Label;
509 using compiler::Node;
510 CodeStubAssembler assembler(state);
511
512 // Convert the {x} value to a Number. 447 // Convert the {x} value to a Number.
513 Node* x = assembler.Parameter(1); 448 Node* x = Parameter(1);
514 Node* context = assembler.Parameter(4); 449 Node* context = Parameter(4);
515 Node* x_value = assembler.TruncateTaggedToFloat64(context, x); 450 Node* x_value = TruncateTaggedToFloat64(context, x);
516 451
517 // Return -1 if {x} is negative, 1 if {x} is positive, or {x} itself. 452 // Return -1 if {x} is negative, 1 if {x} is positive, or {x} itself.
518 Label if_xisnegative(&assembler), if_xispositive(&assembler); 453 Label if_xisnegative(this), if_xispositive(this);
519 assembler.GotoIf( 454 GotoIf(Float64LessThan(x_value, Float64Constant(0.0)), &if_xisnegative);
520 assembler.Float64LessThan(x_value, assembler.Float64Constant(0.0)), 455 GotoIf(Float64LessThan(Float64Constant(0.0), x_value), &if_xispositive);
521 &if_xisnegative); 456 Return(ChangeFloat64ToTagged(x_value));
522 assembler.GotoIf(
523 assembler.Float64LessThan(assembler.Float64Constant(0.0), x_value),
524 &if_xispositive);
525 assembler.Return(assembler.ChangeFloat64ToTagged(x_value));
526 457
527 assembler.Bind(&if_xisnegative); 458 Bind(&if_xisnegative);
528 assembler.Return(assembler.SmiConstant(Smi::FromInt(-1))); 459 Return(SmiConstant(Smi::FromInt(-1)));
529 460
530 assembler.Bind(&if_xispositive); 461 Bind(&if_xispositive);
531 assembler.Return(assembler.SmiConstant(Smi::FromInt(1))); 462 Return(SmiConstant(Smi::FromInt(1)));
532 } 463 }
533 464
534 // ES6 section 20.2.2.30 Math.sin ( x ) 465 // ES6 section 20.2.2.30 Math.sin ( x )
535 void Builtins::Generate_MathSin(compiler::CodeAssemblerState* state) { 466 TF_BUILTIN(MathSin, MathBuiltinsAssembler) {
536 CodeStubAssembler assembler(state); 467 MathUnaryOperation(&CodeStubAssembler::Float64Sin);
537 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Sin);
538 } 468 }
539 469
540 // ES6 section 20.2.2.31 Math.sinh ( x ) 470 // ES6 section 20.2.2.31 Math.sinh ( x )
541 void Builtins::Generate_MathSinh(compiler::CodeAssemblerState* state) { 471 TF_BUILTIN(MathSinh, MathBuiltinsAssembler) {
542 CodeStubAssembler assembler(state); 472 MathUnaryOperation(&CodeStubAssembler::Float64Sinh);
543 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Sinh);
544 } 473 }
545 474
546 // ES6 section 20.2.2.32 Math.sqrt ( x ) 475 // ES6 section 20.2.2.32 Math.sqrt ( x )
547 void Builtins::Generate_MathSqrt(compiler::CodeAssemblerState* state) { 476 TF_BUILTIN(MathSqrt, MathBuiltinsAssembler) {
548 CodeStubAssembler assembler(state); 477 MathUnaryOperation(&CodeStubAssembler::Float64Sqrt);
549 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Sqrt);
550 } 478 }
551 479
552 // ES6 section 20.2.2.33 Math.tan ( x ) 480 // ES6 section 20.2.2.33 Math.tan ( x )
553 void Builtins::Generate_MathTan(compiler::CodeAssemblerState* state) { 481 TF_BUILTIN(MathTan, MathBuiltinsAssembler) {
554 CodeStubAssembler assembler(state); 482 MathUnaryOperation(&CodeStubAssembler::Float64Tan);
555 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Tan);
556 } 483 }
557 484
558 // ES6 section 20.2.2.34 Math.tanh ( x ) 485 // ES6 section 20.2.2.34 Math.tanh ( x )
559 void Builtins::Generate_MathTanh(compiler::CodeAssemblerState* state) { 486 TF_BUILTIN(MathTanh, MathBuiltinsAssembler) {
560 CodeStubAssembler assembler(state); 487 MathUnaryOperation(&CodeStubAssembler::Float64Tanh);
561 Generate_MathUnaryOperation(&assembler, &CodeStubAssembler::Float64Tanh);
562 } 488 }
563 489
564 // ES6 section 20.2.2.35 Math.trunc ( x ) 490 // ES6 section 20.2.2.35 Math.trunc ( x )
565 void Builtins::Generate_MathTrunc(compiler::CodeAssemblerState* state) { 491 TF_BUILTIN(MathTrunc, MathBuiltinsAssembler) {
566 CodeStubAssembler assembler(state); 492 MathRoundingOperation(&CodeStubAssembler::Float64Trunc);
567 Generate_MathRoundingOperation(&assembler, &CodeStubAssembler::Float64Trunc);
568 } 493 }
569 494
570 void Builtins::Generate_MathMax(MacroAssembler* masm) { 495 void Builtins::Generate_MathMax(MacroAssembler* masm) {
571 Generate_MathMaxMin(masm, MathMaxMinKind::kMax); 496 Generate_MathMaxMin(masm, MathMaxMinKind::kMax);
572 } 497 }
573 498
574 void Builtins::Generate_MathMin(MacroAssembler* masm) { 499 void Builtins::Generate_MathMin(MacroAssembler* masm) {
575 Generate_MathMaxMin(masm, MathMaxMinKind::kMin); 500 Generate_MathMaxMin(masm, MathMaxMinKind::kMin);
576 } 501 }
577 502
578 } // namespace internal 503 } // namespace internal
579 } // namespace v8 504 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698