5 #include "src/builtins/builtins-math-gen.h" 7 #include "src/builtins/builtins-utils-gen.h" 8 #include "src/builtins/builtins.h" 9 #include "src/code-factory.h" 10 #include "src/code-stub-assembler.h" 19 TF_BUILTIN(MathAbs, CodeStubAssembler) {
20 Node* context = Parameter(Descriptor::kContext);
23 VARIABLE(var_x, MachineRepresentation::kTagged);
24 Label loop(
this, &var_x);
25 var_x.Bind(Parameter(Descriptor::kX));
30 Node* x = var_x.value();
33 Label if_xissmi(
this), if_xisnotsmi(
this);
34 Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
38 Label if_overflow(
this, Label::kDeferred);
41 if (IsIntPtrAbsWithOverflowSupported()) {
42 Node* pair = IntPtrAbsWithOverflow(x);
43 Node* overflow = Projection(1, pair);
44 GotoIf(overflow, &if_overflow);
47 Node* result = Projection(0, pair);
48 Return(BitcastWordToTagged(result));
52 Label if_xispositive(
this), if_xisnotpositive(
this);
53 BranchIfSmiLessThanOrEqual(SmiConstant(0), CAST(x), &if_xispositive,
56 BIND(&if_xispositive);
62 BIND(&if_xisnotpositive);
65 TNode<Smi> result = TrySmiSub(SmiConstant(0), CAST(x), &if_overflow);
71 { Return(NumberConstant(0.0 - Smi::kMinValue)); }
77 Label if_xisheapnumber(
this), if_xisnotheapnumber(
this, Label::kDeferred);
78 Branch(IsHeapNumber(x), &if_xisheapnumber, &if_xisnotheapnumber);
80 BIND(&if_xisheapnumber);
82 Node* x_value = LoadHeapNumberValue(x);
83 Node* value = Float64Abs(x_value);
84 Node* result = AllocateHeapNumberWithValue(value);
88 BIND(&if_xisnotheapnumber);
91 var_x.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, x));
98 void MathBuiltinsAssembler::MathRoundingOperation(
99 Node* context, Node* x,
100 TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>)) {
102 VARIABLE(var_x, MachineRepresentation::kTagged, x);
103 Label loop(
this, &var_x);
108 Node* x = var_x.value();
111 Label if_xissmi(
this), if_xisnotsmi(
this);
112 Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
123 Label if_xisheapnumber(
this), if_xisnotheapnumber(
this, Label::kDeferred);
124 Branch(IsHeapNumber(x), &if_xisheapnumber, &if_xisnotheapnumber);
126 BIND(&if_xisheapnumber);
128 Node* x_value = LoadHeapNumberValue(x);
129 Node* value = (this->*float64op)(x_value);
130 Node* result = ChangeFloat64ToTagged(value);
134 BIND(&if_xisnotheapnumber);
137 var_x.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, x));
144 void MathBuiltinsAssembler::MathUnaryOperation(
145 Node* context, Node* x,
146 TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>)) {
147 Node* x_value = TruncateTaggedToFloat64(context, x);
148 Node* value = (this->*float64op)(x_value);
149 Node* result = AllocateHeapNumberWithValue(value);
153 void MathBuiltinsAssembler::MathMaxMin(
154 Node* context, Node* argc,
155 TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>,
156 SloppyTNode<Float64T>),
157 double default_val) {
158 CodeStubArguments arguments(
this, ChangeInt32ToIntPtr(argc));
159 argc = arguments.GetLength(INTPTR_PARAMETERS);
161 VARIABLE(result, MachineRepresentation::kFloat64);
162 result.Bind(Float64Constant(default_val));
164 CodeStubAssembler::VariableList vars({&result}, zone());
165 arguments.ForEach(vars, [=, &result](Node* arg) {
166 Node* float_value = TruncateTaggedToFloat64(context, arg);
167 result.Bind((this->*float64op)(result.value(), float_value));
170 arguments.PopAndReturn(ChangeFloat64ToTagged(result.value()));
174 TF_BUILTIN(MathAcos, MathBuiltinsAssembler) {
175 Node* context = Parameter(Descriptor::kContext);
176 Node* x = Parameter(Descriptor::kX);
177 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Acos);
181 TF_BUILTIN(MathAcosh, MathBuiltinsAssembler) {
182 Node* context = Parameter(Descriptor::kContext);
183 Node* x = Parameter(Descriptor::kX);
184 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Acosh);
188 TF_BUILTIN(MathAsin, MathBuiltinsAssembler) {
189 Node* context = Parameter(Descriptor::kContext);
190 Node* x = Parameter(Descriptor::kX);
191 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Asin);
195 TF_BUILTIN(MathAsinh, MathBuiltinsAssembler) {
196 Node* context = Parameter(Descriptor::kContext);
197 Node* x = Parameter(Descriptor::kX);
198 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Asinh);
202 TF_BUILTIN(MathAtan, MathBuiltinsAssembler) {
203 Node* context = Parameter(Descriptor::kContext);
204 Node* x = Parameter(Descriptor::kX);
205 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Atan);
209 TF_BUILTIN(MathAtanh, MathBuiltinsAssembler) {
210 Node* context = Parameter(Descriptor::kContext);
211 Node* x = Parameter(Descriptor::kX);
212 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Atanh);
216 TF_BUILTIN(MathAtan2, CodeStubAssembler) {
217 Node* context = Parameter(Descriptor::kContext);
218 Node* y = Parameter(Descriptor::kY);
219 Node* x = Parameter(Descriptor::kX);
221 Node* y_value = TruncateTaggedToFloat64(context, y);
222 Node* x_value = TruncateTaggedToFloat64(context, x);
223 Node* value = Float64Atan2(y_value, x_value);
224 Node* result = AllocateHeapNumberWithValue(value);
229 TF_BUILTIN(MathCeil, MathBuiltinsAssembler) {
230 Node* context = Parameter(Descriptor::kContext);
231 Node* x = Parameter(Descriptor::kX);
232 MathRoundingOperation(context, x, &CodeStubAssembler::Float64Ceil);
236 TF_BUILTIN(MathCbrt, MathBuiltinsAssembler) {
237 Node* context = Parameter(Descriptor::kContext);
238 Node* x = Parameter(Descriptor::kX);
239 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Cbrt);
243 TF_BUILTIN(MathClz32, CodeStubAssembler) {
244 Node* context = Parameter(Descriptor::kContext);
247 VARIABLE(var_clz32_x, MachineRepresentation::kWord32);
248 Label do_clz32(
this);
251 VARIABLE(var_x, MachineRepresentation::kTagged);
252 Label loop(
this, &var_x);
253 var_x.Bind(Parameter(Descriptor::kX));
258 Node* x = var_x.value();
261 Label if_xissmi(
this), if_xisnotsmi(
this);
262 Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
266 var_clz32_x.Bind(SmiToInt32(x));
273 Label if_xisheapnumber(
this), if_xisnotheapnumber(
this, Label::kDeferred);
274 Branch(IsHeapNumber(x), &if_xisheapnumber, &if_xisnotheapnumber);
276 BIND(&if_xisheapnumber);
278 var_clz32_x.Bind(TruncateHeapNumberValueToWord32(x));
282 BIND(&if_xisnotheapnumber);
285 var_x.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, x));
293 Node* x_value = var_clz32_x.value();
294 Node* value = Word32Clz(x_value);
295 Node* result = ChangeInt32ToTagged(value);
301 TF_BUILTIN(MathCos, MathBuiltinsAssembler) {
302 Node* context = Parameter(Descriptor::kContext);
303 Node* x = Parameter(Descriptor::kX);
304 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Cos);
308 TF_BUILTIN(MathCosh, MathBuiltinsAssembler) {
309 Node* context = Parameter(Descriptor::kContext);
310 Node* x = Parameter(Descriptor::kX);
311 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Cosh);
315 TF_BUILTIN(MathExp, MathBuiltinsAssembler) {
316 Node* context = Parameter(Descriptor::kContext);
317 Node* x = Parameter(Descriptor::kX);
318 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Exp);
322 TF_BUILTIN(MathExpm1, MathBuiltinsAssembler) {
323 Node* context = Parameter(Descriptor::kContext);
324 Node* x = Parameter(Descriptor::kX);
325 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Expm1);
329 TF_BUILTIN(MathFloor, MathBuiltinsAssembler) {
330 Node* context = Parameter(Descriptor::kContext);
331 Node* x = Parameter(Descriptor::kX);
332 MathRoundingOperation(context, x, &CodeStubAssembler::Float64Floor);
336 TF_BUILTIN(MathFround, CodeStubAssembler) {
337 Node* context = Parameter(Descriptor::kContext);
338 Node* x = Parameter(Descriptor::kX);
339 Node* x_value = TruncateTaggedToFloat64(context, x);
340 Node* value32 = TruncateFloat64ToFloat32(x_value);
341 Node* value = ChangeFloat32ToFloat64(value32);
342 Node* result = AllocateHeapNumberWithValue(value);
347 TF_BUILTIN(MathImul, CodeStubAssembler) {
348 Node* context = Parameter(Descriptor::kContext);
349 Node* x = Parameter(Descriptor::kX);
350 Node* y = Parameter(Descriptor::kY);
351 Node* x_value = TruncateTaggedToWord32(context, x);
352 Node* y_value = TruncateTaggedToWord32(context, y);
353 Node* value = Int32Mul(x_value, y_value);
354 Node* result = ChangeInt32ToTagged(value);
359 TF_BUILTIN(MathLog, MathBuiltinsAssembler) {
360 Node* context = Parameter(Descriptor::kContext);
361 Node* x = Parameter(Descriptor::kX);
362 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Log);
366 TF_BUILTIN(MathLog1p, MathBuiltinsAssembler) {
367 Node* context = Parameter(Descriptor::kContext);
368 Node* x = Parameter(Descriptor::kX);
369 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Log1p);
373 TF_BUILTIN(MathLog10, MathBuiltinsAssembler) {
374 Node* context = Parameter(Descriptor::kContext);
375 Node* x = Parameter(Descriptor::kX);
376 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Log10);
380 TF_BUILTIN(MathLog2, MathBuiltinsAssembler) {
381 Node* context = Parameter(Descriptor::kContext);
382 Node* x = Parameter(Descriptor::kX);
383 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Log2);
386 CodeStubAssembler::Node* MathBuiltinsAssembler::MathPow(Node* context,
389 Node* base_value = TruncateTaggedToFloat64(context, base);
390 Node* exponent_value = TruncateTaggedToFloat64(context, exponent);
391 Node* value = Float64Pow(base_value, exponent_value);
392 return ChangeFloat64ToTagged(value);
396 TF_BUILTIN(MathPow, MathBuiltinsAssembler) {
397 Return(MathPow(Parameter(Descriptor::kContext), Parameter(Descriptor::kBase),
398 Parameter(Descriptor::kExponent)));
402 TF_BUILTIN(MathRandom, CodeStubAssembler) {
403 Node* context = Parameter(Descriptor::kContext);
404 Node* native_context = LoadNativeContext(context);
407 TVARIABLE(Smi, smi_index);
409 LoadContextElement(native_context, Context::MATH_RANDOM_INDEX_INDEX));
412 Label if_cached(
this);
413 GotoIf(SmiAbove(smi_index.value(), SmiConstant(0)), &if_cached);
416 Node*
const refill_math_random =
417 ExternalConstant(ExternalReference::refill_math_random());
418 Node*
const isolate_ptr =
419 ExternalConstant(ExternalReference::isolate_address(isolate()));
420 MachineType type_tagged = MachineType::AnyTagged();
421 MachineType type_ptr = MachineType::Pointer();
424 CAST(CallCFunction2(type_tagged, type_ptr, type_tagged,
425 refill_math_random, isolate_ptr, native_context));
430 TNode<Smi> new_smi_index = SmiSub(smi_index.value(), SmiConstant(1));
431 StoreContextElement(native_context, Context::MATH_RANDOM_INDEX_INDEX,
436 LoadContextElement(native_context, Context::MATH_RANDOM_CACHE_INDEX);
437 Node* random = LoadFixedDoubleArrayElement(
438 array, new_smi_index, MachineType::Float64(), 0, SMI_PARAMETERS);
439 Return(AllocateHeapNumberWithValue(random));
443 TF_BUILTIN(MathRound, MathBuiltinsAssembler) {
444 Node* context = Parameter(Descriptor::kContext);
445 Node* x = Parameter(Descriptor::kX);
446 MathRoundingOperation(context, x, &CodeStubAssembler::Float64Round);
450 TF_BUILTIN(MathSign, CodeStubAssembler) {
452 Node* context = Parameter(Descriptor::kContext);
453 Node* x = Parameter(Descriptor::kX);
454 Node* x_value = TruncateTaggedToFloat64(context, x);
457 Label if_xisnegative(
this), if_xispositive(
this);
458 GotoIf(Float64LessThan(x_value, Float64Constant(0.0)), &if_xisnegative);
459 GotoIf(Float64LessThan(Float64Constant(0.0), x_value), &if_xispositive);
460 Return(ChangeFloat64ToTagged(x_value));
462 BIND(&if_xisnegative);
463 Return(SmiConstant(-1));
465 BIND(&if_xispositive);
466 Return(SmiConstant(1));
470 TF_BUILTIN(MathSin, MathBuiltinsAssembler) {
471 Node* context = Parameter(Descriptor::kContext);
472 Node* x = Parameter(Descriptor::kX);
473 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Sin);
477 TF_BUILTIN(MathSinh, MathBuiltinsAssembler) {
478 Node* context = Parameter(Descriptor::kContext);
479 Node* x = Parameter(Descriptor::kX);
480 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Sinh);
484 TF_BUILTIN(MathSqrt, MathBuiltinsAssembler) {
485 Node* context = Parameter(Descriptor::kContext);
486 Node* x = Parameter(Descriptor::kX);
487 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Sqrt);
491 TF_BUILTIN(MathTan, MathBuiltinsAssembler) {
492 Node* context = Parameter(Descriptor::kContext);
493 Node* x = Parameter(Descriptor::kX);
494 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Tan);
498 TF_BUILTIN(MathTanh, MathBuiltinsAssembler) {
499 Node* context = Parameter(Descriptor::kContext);
500 Node* x = Parameter(Descriptor::kX);
501 MathUnaryOperation(context, x, &CodeStubAssembler::Float64Tanh);
505 TF_BUILTIN(MathTrunc, MathBuiltinsAssembler) {
506 Node* context = Parameter(Descriptor::kContext);
507 Node* x = Parameter(Descriptor::kX);
508 MathRoundingOperation(context, x, &CodeStubAssembler::Float64Trunc);
512 TF_BUILTIN(MathMax, MathBuiltinsAssembler) {
515 Node* context = Parameter(Descriptor::kContext);
516 Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);
517 MathMaxMin(context, argc, &CodeStubAssembler::Float64Max, -1.0 * V8_INFINITY);
521 TF_BUILTIN(MathMin, MathBuiltinsAssembler) {
524 Node* context = Parameter(Descriptor::kContext);
525 Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);
526 MathMaxMin(context, argc, &CodeStubAssembler::Float64Min, V8_INFINITY);