OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/builtins/builtins.h" |
| 6 #include "src/builtins/builtins-utils.h" |
| 7 |
| 8 #include "src/code-factory.h" |
| 9 |
| 10 namespace v8 { |
| 11 namespace internal { |
| 12 |
| 13 // ----------------------------------------------------------------------------- |
| 14 // ES6 section 20.2.2 Function Properties of the Math Object |
| 15 |
| 16 // ES6 section - 20.2.2.1 Math.abs ( x ) |
| 17 void Builtins::Generate_MathAbs(CodeStubAssembler* assembler) { |
| 18 using compiler::Node; |
| 19 Node* x = assembler->Parameter(1); |
| 20 Node* context = assembler->Parameter(4); |
| 21 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 22 Node* value = assembler->Float64Abs(x_value); |
| 23 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 24 assembler->Return(result); |
| 25 } |
| 26 |
| 27 // ES6 section 20.2.2.2 Math.acos ( x ) |
| 28 void Builtins::Generate_MathAcos(CodeStubAssembler* assembler) { |
| 29 using compiler::Node; |
| 30 |
| 31 Node* x = assembler->Parameter(1); |
| 32 Node* context = assembler->Parameter(4); |
| 33 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 34 Node* value = assembler->Float64Acos(x_value); |
| 35 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 36 assembler->Return(result); |
| 37 } |
| 38 |
| 39 // ES6 section 20.2.2.3 Math.acosh ( x ) |
| 40 void Builtins::Generate_MathAcosh(CodeStubAssembler* assembler) { |
| 41 using compiler::Node; |
| 42 |
| 43 Node* x = assembler->Parameter(1); |
| 44 Node* context = assembler->Parameter(4); |
| 45 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 46 Node* value = assembler->Float64Acosh(x_value); |
| 47 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 48 assembler->Return(result); |
| 49 } |
| 50 |
| 51 // ES6 section 20.2.2.4 Math.asin ( x ) |
| 52 void Builtins::Generate_MathAsin(CodeStubAssembler* assembler) { |
| 53 using compiler::Node; |
| 54 |
| 55 Node* x = assembler->Parameter(1); |
| 56 Node* context = assembler->Parameter(4); |
| 57 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 58 Node* value = assembler->Float64Asin(x_value); |
| 59 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 60 assembler->Return(result); |
| 61 } |
| 62 |
| 63 // ES6 section 20.2.2.5 Math.asinh ( x ) |
| 64 void Builtins::Generate_MathAsinh(CodeStubAssembler* assembler) { |
| 65 using compiler::Node; |
| 66 |
| 67 Node* x = assembler->Parameter(1); |
| 68 Node* context = assembler->Parameter(4); |
| 69 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 70 Node* value = assembler->Float64Asinh(x_value); |
| 71 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 72 assembler->Return(result); |
| 73 } |
| 74 |
| 75 // ES6 section 20.2.2.6 Math.atan ( x ) |
| 76 void Builtins::Generate_MathAtan(CodeStubAssembler* assembler) { |
| 77 using compiler::Node; |
| 78 |
| 79 Node* x = assembler->Parameter(1); |
| 80 Node* context = assembler->Parameter(4); |
| 81 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 82 Node* value = assembler->Float64Atan(x_value); |
| 83 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 84 assembler->Return(result); |
| 85 } |
| 86 |
| 87 // ES6 section 20.2.2.7 Math.atanh ( x ) |
| 88 void Builtins::Generate_MathAtanh(CodeStubAssembler* assembler) { |
| 89 using compiler::Node; |
| 90 |
| 91 Node* x = assembler->Parameter(1); |
| 92 Node* context = assembler->Parameter(4); |
| 93 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 94 Node* value = assembler->Float64Atanh(x_value); |
| 95 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 96 assembler->Return(result); |
| 97 } |
| 98 |
| 99 // ES6 section 20.2.2.8 Math.atan2 ( y, x ) |
| 100 void Builtins::Generate_MathAtan2(CodeStubAssembler* assembler) { |
| 101 using compiler::Node; |
| 102 |
| 103 Node* y = assembler->Parameter(1); |
| 104 Node* x = assembler->Parameter(2); |
| 105 Node* context = assembler->Parameter(5); |
| 106 Node* y_value = assembler->TruncateTaggedToFloat64(context, y); |
| 107 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 108 Node* value = assembler->Float64Atan2(y_value, x_value); |
| 109 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 110 assembler->Return(result); |
| 111 } |
| 112 |
| 113 namespace { |
| 114 |
| 115 void Generate_MathRoundingOperation( |
| 116 CodeStubAssembler* assembler, |
| 117 compiler::Node* (CodeStubAssembler::*float64op)(compiler::Node*)) { |
| 118 typedef CodeStubAssembler::Label Label; |
| 119 typedef compiler::Node Node; |
| 120 typedef CodeStubAssembler::Variable Variable; |
| 121 |
| 122 Node* context = assembler->Parameter(4); |
| 123 |
| 124 // We might need to loop once for ToNumber conversion. |
| 125 Variable var_x(assembler, MachineRepresentation::kTagged); |
| 126 Label loop(assembler, &var_x); |
| 127 var_x.Bind(assembler->Parameter(1)); |
| 128 assembler->Goto(&loop); |
| 129 assembler->Bind(&loop); |
| 130 { |
| 131 // Load the current {x} value. |
| 132 Node* x = var_x.value(); |
| 133 |
| 134 // Check if {x} is a Smi or a HeapObject. |
| 135 Label if_xissmi(assembler), if_xisnotsmi(assembler); |
| 136 assembler->Branch(assembler->WordIsSmi(x), &if_xissmi, &if_xisnotsmi); |
| 137 |
| 138 assembler->Bind(&if_xissmi); |
| 139 { |
| 140 // Nothing to do when {x} is a Smi. |
| 141 assembler->Return(x); |
| 142 } |
| 143 |
| 144 assembler->Bind(&if_xisnotsmi); |
| 145 { |
| 146 // Check if {x} is a HeapNumber. |
| 147 Label if_xisheapnumber(assembler), |
| 148 if_xisnotheapnumber(assembler, Label::kDeferred); |
| 149 assembler->Branch( |
| 150 assembler->WordEqual(assembler->LoadMap(x), |
| 151 assembler->HeapNumberMapConstant()), |
| 152 &if_xisheapnumber, &if_xisnotheapnumber); |
| 153 |
| 154 assembler->Bind(&if_xisheapnumber); |
| 155 { |
| 156 Node* x_value = assembler->LoadHeapNumberValue(x); |
| 157 Node* value = (assembler->*float64op)(x_value); |
| 158 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 159 assembler->Return(result); |
| 160 } |
| 161 |
| 162 assembler->Bind(&if_xisnotheapnumber); |
| 163 { |
| 164 // Need to convert {x} to a Number first. |
| 165 Callable callable = |
| 166 CodeFactory::NonNumberToNumber(assembler->isolate()); |
| 167 var_x.Bind(assembler->CallStub(callable, context, x)); |
| 168 assembler->Goto(&loop); |
| 169 } |
| 170 } |
| 171 } |
| 172 } |
| 173 |
| 174 } // namespace |
| 175 |
| 176 // ES6 section 20.2.2.10 Math.ceil ( x ) |
| 177 void Builtins::Generate_MathCeil(CodeStubAssembler* assembler) { |
| 178 Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Ceil); |
| 179 } |
| 180 |
| 181 // ES6 section 20.2.2.9 Math.cbrt ( x ) |
| 182 void Builtins::Generate_MathCbrt(CodeStubAssembler* assembler) { |
| 183 using compiler::Node; |
| 184 |
| 185 Node* x = assembler->Parameter(1); |
| 186 Node* context = assembler->Parameter(4); |
| 187 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 188 Node* value = assembler->Float64Cbrt(x_value); |
| 189 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 190 assembler->Return(result); |
| 191 } |
| 192 |
| 193 // ES6 section 20.2.2.11 Math.clz32 ( x ) |
| 194 void Builtins::Generate_MathClz32(CodeStubAssembler* assembler) { |
| 195 typedef CodeStubAssembler::Label Label; |
| 196 typedef compiler::Node Node; |
| 197 typedef CodeStubAssembler::Variable Variable; |
| 198 |
| 199 Node* context = assembler->Parameter(4); |
| 200 |
| 201 // Shared entry point for the clz32 operation. |
| 202 Variable var_clz32_x(assembler, MachineRepresentation::kWord32); |
| 203 Label do_clz32(assembler); |
| 204 |
| 205 // We might need to loop once for ToNumber conversion. |
| 206 Variable var_x(assembler, MachineRepresentation::kTagged); |
| 207 Label loop(assembler, &var_x); |
| 208 var_x.Bind(assembler->Parameter(1)); |
| 209 assembler->Goto(&loop); |
| 210 assembler->Bind(&loop); |
| 211 { |
| 212 // Load the current {x} value. |
| 213 Node* x = var_x.value(); |
| 214 |
| 215 // Check if {x} is a Smi or a HeapObject. |
| 216 Label if_xissmi(assembler), if_xisnotsmi(assembler); |
| 217 assembler->Branch(assembler->WordIsSmi(x), &if_xissmi, &if_xisnotsmi); |
| 218 |
| 219 assembler->Bind(&if_xissmi); |
| 220 { |
| 221 var_clz32_x.Bind(assembler->SmiToWord32(x)); |
| 222 assembler->Goto(&do_clz32); |
| 223 } |
| 224 |
| 225 assembler->Bind(&if_xisnotsmi); |
| 226 { |
| 227 // Check if {x} is a HeapNumber. |
| 228 Label if_xisheapnumber(assembler), |
| 229 if_xisnotheapnumber(assembler, Label::kDeferred); |
| 230 assembler->Branch( |
| 231 assembler->WordEqual(assembler->LoadMap(x), |
| 232 assembler->HeapNumberMapConstant()), |
| 233 &if_xisheapnumber, &if_xisnotheapnumber); |
| 234 |
| 235 assembler->Bind(&if_xisheapnumber); |
| 236 { |
| 237 var_clz32_x.Bind(assembler->TruncateHeapNumberValueToWord32(x)); |
| 238 assembler->Goto(&do_clz32); |
| 239 } |
| 240 |
| 241 assembler->Bind(&if_xisnotheapnumber); |
| 242 { |
| 243 // Need to convert {x} to a Number first. |
| 244 Callable callable = |
| 245 CodeFactory::NonNumberToNumber(assembler->isolate()); |
| 246 var_x.Bind(assembler->CallStub(callable, context, x)); |
| 247 assembler->Goto(&loop); |
| 248 } |
| 249 } |
| 250 } |
| 251 |
| 252 assembler->Bind(&do_clz32); |
| 253 { |
| 254 Node* x_value = var_clz32_x.value(); |
| 255 Node* value = assembler->Word32Clz(x_value); |
| 256 Node* result = assembler->ChangeInt32ToTagged(value); |
| 257 assembler->Return(result); |
| 258 } |
| 259 } |
| 260 |
| 261 // ES6 section 20.2.2.12 Math.cos ( x ) |
| 262 void Builtins::Generate_MathCos(CodeStubAssembler* assembler) { |
| 263 using compiler::Node; |
| 264 |
| 265 Node* x = assembler->Parameter(1); |
| 266 Node* context = assembler->Parameter(4); |
| 267 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 268 Node* value = assembler->Float64Cos(x_value); |
| 269 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 270 assembler->Return(result); |
| 271 } |
| 272 |
| 273 // ES6 section 20.2.2.13 Math.cosh ( x ) |
| 274 void Builtins::Generate_MathCosh(CodeStubAssembler* assembler) { |
| 275 using compiler::Node; |
| 276 |
| 277 Node* x = assembler->Parameter(1); |
| 278 Node* context = assembler->Parameter(4); |
| 279 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 280 Node* value = assembler->Float64Cosh(x_value); |
| 281 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 282 assembler->Return(result); |
| 283 } |
| 284 |
| 285 // ES6 section 20.2.2.14 Math.exp ( x ) |
| 286 void Builtins::Generate_MathExp(CodeStubAssembler* assembler) { |
| 287 using compiler::Node; |
| 288 |
| 289 Node* x = assembler->Parameter(1); |
| 290 Node* context = assembler->Parameter(4); |
| 291 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 292 Node* value = assembler->Float64Exp(x_value); |
| 293 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 294 assembler->Return(result); |
| 295 } |
| 296 |
| 297 // ES6 section 20.2.2.16 Math.floor ( x ) |
| 298 void Builtins::Generate_MathFloor(CodeStubAssembler* assembler) { |
| 299 Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Floor); |
| 300 } |
| 301 |
| 302 // ES6 section 20.2.2.17 Math.fround ( x ) |
| 303 void Builtins::Generate_MathFround(CodeStubAssembler* assembler) { |
| 304 using compiler::Node; |
| 305 |
| 306 Node* x = assembler->Parameter(1); |
| 307 Node* context = assembler->Parameter(4); |
| 308 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 309 Node* value32 = assembler->TruncateFloat64ToFloat32(x_value); |
| 310 Node* value = assembler->ChangeFloat32ToFloat64(value32); |
| 311 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 312 assembler->Return(result); |
| 313 } |
| 314 |
| 315 // ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values ) |
| 316 BUILTIN(MathHypot) { |
| 317 HandleScope scope(isolate); |
| 318 int const length = args.length() - 1; |
| 319 if (length == 0) return Smi::FromInt(0); |
| 320 DCHECK_LT(0, length); |
| 321 double max = 0; |
| 322 bool one_arg_is_nan = false; |
| 323 List<double> abs_values(length); |
| 324 for (int i = 0; i < length; i++) { |
| 325 Handle<Object> x = args.at<Object>(i + 1); |
| 326 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x)); |
| 327 double abs_value = std::abs(x->Number()); |
| 328 |
| 329 if (std::isnan(abs_value)) { |
| 330 one_arg_is_nan = true; |
| 331 } else { |
| 332 abs_values.Add(abs_value); |
| 333 if (max < abs_value) { |
| 334 max = abs_value; |
| 335 } |
| 336 } |
| 337 } |
| 338 |
| 339 if (max == V8_INFINITY) { |
| 340 return *isolate->factory()->NewNumber(V8_INFINITY); |
| 341 } |
| 342 |
| 343 if (one_arg_is_nan) { |
| 344 return *isolate->factory()->nan_value(); |
| 345 } |
| 346 |
| 347 if (max == 0) { |
| 348 return Smi::FromInt(0); |
| 349 } |
| 350 DCHECK_GT(max, 0); |
| 351 |
| 352 // Kahan summation to avoid rounding errors. |
| 353 // Normalize the numbers to the largest one to avoid overflow. |
| 354 double sum = 0; |
| 355 double compensation = 0; |
| 356 for (int i = 0; i < length; i++) { |
| 357 double n = abs_values.at(i) / max; |
| 358 double summand = n * n - compensation; |
| 359 double preliminary = sum + summand; |
| 360 compensation = (preliminary - sum) - summand; |
| 361 sum = preliminary; |
| 362 } |
| 363 |
| 364 return *isolate->factory()->NewNumber(std::sqrt(sum) * max); |
| 365 } |
| 366 |
| 367 // ES6 section 20.2.2.19 Math.imul ( x, y ) |
| 368 void Builtins::Generate_MathImul(CodeStubAssembler* assembler) { |
| 369 using compiler::Node; |
| 370 |
| 371 Node* x = assembler->Parameter(1); |
| 372 Node* y = assembler->Parameter(2); |
| 373 Node* context = assembler->Parameter(5); |
| 374 Node* x_value = assembler->TruncateTaggedToWord32(context, x); |
| 375 Node* y_value = assembler->TruncateTaggedToWord32(context, y); |
| 376 Node* value = assembler->Int32Mul(x_value, y_value); |
| 377 Node* result = assembler->ChangeInt32ToTagged(value); |
| 378 assembler->Return(result); |
| 379 } |
| 380 |
| 381 // ES6 section 20.2.2.20 Math.log ( x ) |
| 382 void Builtins::Generate_MathLog(CodeStubAssembler* assembler) { |
| 383 using compiler::Node; |
| 384 |
| 385 Node* x = assembler->Parameter(1); |
| 386 Node* context = assembler->Parameter(4); |
| 387 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 388 Node* value = assembler->Float64Log(x_value); |
| 389 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 390 assembler->Return(result); |
| 391 } |
| 392 |
| 393 // ES6 section 20.2.2.21 Math.log1p ( x ) |
| 394 void Builtins::Generate_MathLog1p(CodeStubAssembler* assembler) { |
| 395 using compiler::Node; |
| 396 |
| 397 Node* x = assembler->Parameter(1); |
| 398 Node* context = assembler->Parameter(4); |
| 399 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 400 Node* value = assembler->Float64Log1p(x_value); |
| 401 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 402 assembler->Return(result); |
| 403 } |
| 404 |
| 405 // ES6 section 20.2.2.22 Math.log10 ( x ) |
| 406 void Builtins::Generate_MathLog10(CodeStubAssembler* assembler) { |
| 407 using compiler::Node; |
| 408 |
| 409 Node* x = assembler->Parameter(1); |
| 410 Node* context = assembler->Parameter(4); |
| 411 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 412 Node* value = assembler->Float64Log10(x_value); |
| 413 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 414 assembler->Return(result); |
| 415 } |
| 416 |
| 417 // ES6 section 20.2.2.23 Math.log2 ( x ) |
| 418 void Builtins::Generate_MathLog2(CodeStubAssembler* assembler) { |
| 419 using compiler::Node; |
| 420 |
| 421 Node* x = assembler->Parameter(1); |
| 422 Node* context = assembler->Parameter(4); |
| 423 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 424 Node* value = assembler->Float64Log2(x_value); |
| 425 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 426 assembler->Return(result); |
| 427 } |
| 428 |
| 429 // ES6 section 20.2.2.15 Math.expm1 ( x ) |
| 430 void Builtins::Generate_MathExpm1(CodeStubAssembler* assembler) { |
| 431 using compiler::Node; |
| 432 |
| 433 Node* x = assembler->Parameter(1); |
| 434 Node* context = assembler->Parameter(4); |
| 435 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 436 Node* value = assembler->Float64Expm1(x_value); |
| 437 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 438 assembler->Return(result); |
| 439 } |
| 440 |
| 441 // ES6 section 20.2.2.26 Math.pow ( x, y ) |
| 442 void Builtins::Generate_MathPow(CodeStubAssembler* assembler) { |
| 443 using compiler::Node; |
| 444 |
| 445 Node* x = assembler->Parameter(1); |
| 446 Node* y = assembler->Parameter(2); |
| 447 Node* context = assembler->Parameter(5); |
| 448 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 449 Node* y_value = assembler->TruncateTaggedToFloat64(context, y); |
| 450 Node* value = assembler->Float64Pow(x_value, y_value); |
| 451 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 452 assembler->Return(result); |
| 453 } |
| 454 |
| 455 // ES6 section 20.2.2.28 Math.round ( x ) |
| 456 void Builtins::Generate_MathRound(CodeStubAssembler* assembler) { |
| 457 Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Round); |
| 458 } |
| 459 |
| 460 // ES6 section 20.2.2.29 Math.sign ( x ) |
| 461 void Builtins::Generate_MathSign(CodeStubAssembler* assembler) { |
| 462 typedef CodeStubAssembler::Label Label; |
| 463 using compiler::Node; |
| 464 |
| 465 // Convert the {x} value to a Number. |
| 466 Node* x = assembler->Parameter(1); |
| 467 Node* context = assembler->Parameter(4); |
| 468 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 469 |
| 470 // Return -1 if {x} is negative, 1 if {x} is positive, or {x} itself. |
| 471 Label if_xisnegative(assembler), if_xispositive(assembler); |
| 472 assembler->GotoIf( |
| 473 assembler->Float64LessThan(x_value, assembler->Float64Constant(0.0)), |
| 474 &if_xisnegative); |
| 475 assembler->GotoIf( |
| 476 assembler->Float64LessThan(assembler->Float64Constant(0.0), x_value), |
| 477 &if_xispositive); |
| 478 assembler->Return(assembler->ChangeFloat64ToTagged(x_value)); |
| 479 |
| 480 assembler->Bind(&if_xisnegative); |
| 481 assembler->Return(assembler->SmiConstant(Smi::FromInt(-1))); |
| 482 |
| 483 assembler->Bind(&if_xispositive); |
| 484 assembler->Return(assembler->SmiConstant(Smi::FromInt(1))); |
| 485 } |
| 486 |
| 487 // ES6 section 20.2.2.30 Math.sin ( x ) |
| 488 void Builtins::Generate_MathSin(CodeStubAssembler* assembler) { |
| 489 using compiler::Node; |
| 490 |
| 491 Node* x = assembler->Parameter(1); |
| 492 Node* context = assembler->Parameter(4); |
| 493 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 494 Node* value = assembler->Float64Sin(x_value); |
| 495 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 496 assembler->Return(result); |
| 497 } |
| 498 |
| 499 // ES6 section 20.2.2.31 Math.sinh ( x ) |
| 500 void Builtins::Generate_MathSinh(CodeStubAssembler* assembler) { |
| 501 using compiler::Node; |
| 502 |
| 503 Node* x = assembler->Parameter(1); |
| 504 Node* context = assembler->Parameter(4); |
| 505 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 506 Node* value = assembler->Float64Sinh(x_value); |
| 507 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 508 assembler->Return(result); |
| 509 } |
| 510 |
| 511 // ES6 section 20.2.2.32 Math.sqrt ( x ) |
| 512 void Builtins::Generate_MathSqrt(CodeStubAssembler* assembler) { |
| 513 using compiler::Node; |
| 514 |
| 515 Node* x = assembler->Parameter(1); |
| 516 Node* context = assembler->Parameter(4); |
| 517 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 518 Node* value = assembler->Float64Sqrt(x_value); |
| 519 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 520 assembler->Return(result); |
| 521 } |
| 522 |
| 523 // ES6 section 20.2.2.33 Math.tan ( x ) |
| 524 void Builtins::Generate_MathTan(CodeStubAssembler* assembler) { |
| 525 using compiler::Node; |
| 526 |
| 527 Node* x = assembler->Parameter(1); |
| 528 Node* context = assembler->Parameter(4); |
| 529 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 530 Node* value = assembler->Float64Tan(x_value); |
| 531 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 532 assembler->Return(result); |
| 533 } |
| 534 |
| 535 // ES6 section 20.2.2.34 Math.tanh ( x ) |
| 536 void Builtins::Generate_MathTanh(CodeStubAssembler* assembler) { |
| 537 using compiler::Node; |
| 538 |
| 539 Node* x = assembler->Parameter(1); |
| 540 Node* context = assembler->Parameter(4); |
| 541 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
| 542 Node* value = assembler->Float64Tanh(x_value); |
| 543 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 544 assembler->Return(result); |
| 545 } |
| 546 |
| 547 // ES6 section 20.2.2.35 Math.trunc ( x ) |
| 548 void Builtins::Generate_MathTrunc(CodeStubAssembler* assembler) { |
| 549 Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Trunc); |
| 550 } |
| 551 |
| 552 void Builtins::Generate_MathMax(MacroAssembler* masm) { |
| 553 Generate_MathMaxMin(masm, MathMaxMinKind::kMax); |
| 554 } |
| 555 |
| 556 void Builtins::Generate_MathMin(MacroAssembler* masm) { |
| 557 Generate_MathMaxMin(masm, MathMaxMinKind::kMin); |
| 558 } |
| 559 |
| 560 } // namespace internal |
| 561 } // namespace v8 |
OLD | NEW |