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/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 FrameScope scope(masm(), StackFrame::MANUAL); \ | 405 FrameScope scope(masm(), StackFrame::MANUAL); \ |
406 __ PrepareCallCFunction(0, 2, kScratchReg); \ | 406 __ PrepareCallCFunction(0, 2, kScratchReg); \ |
407 __ MovToFloatParameters(i.InputDoubleRegister(0), \ | 407 __ MovToFloatParameters(i.InputDoubleRegister(0), \ |
408 i.InputDoubleRegister(1)); \ | 408 i.InputDoubleRegister(1)); \ |
409 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ | 409 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ |
410 0, 2); \ | 410 0, 2); \ |
411 /* Move the result in the double result register. */ \ | 411 /* Move the result in the double result register. */ \ |
412 __ MovFromFloatResult(i.OutputDoubleRegister()); \ | 412 __ MovFromFloatResult(i.OutputDoubleRegister()); \ |
413 } while (0) | 413 } while (0) |
414 | 414 |
415 #define ASSEMBLE_FLOAT_MAX(double_scratch_reg, general_scratch_reg) \ | 415 #define ASSEMBLE_FLOAT_MAX() \ |
416 do { \ | 416 do { \ |
417 Label ge, done; \ | 417 DoubleRegister left_reg = i.InputDoubleRegister(0); \ |
418 __ cdbr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \ | 418 DoubleRegister right_reg = i.InputDoubleRegister(1); \ |
419 __ bge(&ge, Label::kNear); \ | 419 DoubleRegister result_reg = i.OutputDoubleRegister(); \ |
420 __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); \ | 420 Label check_nan_left, check_zero, return_left, return_right, done; \ |
421 __ b(&done, Label::kNear); \ | 421 __ cdbr(left_reg, right_reg); \ |
422 __ bind(&ge); \ | 422 __ bunordered(&check_nan_left, Label::kNear); \ |
423 __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 423 __ beq(&check_zero); \ |
424 __ bind(&done); \ | 424 __ bge(&return_left, Label::kNear); \ |
425 } while (0) | 425 __ b(&return_right, Label::kNear); \ |
| 426 \ |
| 427 __ bind(&check_zero); \ |
| 428 __ lzdr(kDoubleRegZero); \ |
| 429 __ cdbr(left_reg, kDoubleRegZero); \ |
| 430 /* left == right != 0. */ \ |
| 431 __ bne(&return_left, Label::kNear); \ |
| 432 /* At this point, both left and right are either 0 or -0. */ \ |
| 433 /* N.B. The following works because +0 + -0 == +0 */ \ |
| 434 /* For max we want logical-and of sign bit: (L + R) */ \ |
| 435 __ ldr(result_reg, left_reg); \ |
| 436 __ adbr(result_reg, right_reg); \ |
| 437 __ b(&done, Label::kNear); \ |
| 438 \ |
| 439 __ bind(&check_nan_left); \ |
| 440 __ cdbr(left_reg, left_reg); \ |
| 441 /* left == NaN. */ \ |
| 442 __ bunordered(&return_left, Label::kNear); \ |
| 443 \ |
| 444 __ bind(&return_right); \ |
| 445 if (!right_reg.is(result_reg)) { \ |
| 446 __ ldr(result_reg, right_reg); \ |
| 447 } \ |
| 448 __ b(&done, Label::kNear); \ |
| 449 \ |
| 450 __ bind(&return_left); \ |
| 451 if (!left_reg.is(result_reg)) { \ |
| 452 __ ldr(result_reg, left_reg); \ |
| 453 } \ |
| 454 __ bind(&done); \ |
| 455 } while (0) \ |
426 | 456 |
427 #define ASSEMBLE_FLOAT_MIN(double_scratch_reg, general_scratch_reg) \ | 457 #define ASSEMBLE_FLOAT_MIN() \ |
428 do { \ | 458 do { \ |
429 Label ge, done; \ | 459 DoubleRegister left_reg = i.InputDoubleRegister(0); \ |
430 __ cdbr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \ | 460 DoubleRegister right_reg = i.InputDoubleRegister(1); \ |
431 __ bge(&ge, Label::kNear); \ | 461 DoubleRegister result_reg = i.OutputDoubleRegister(); \ |
432 __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 462 Label check_nan_left, check_zero, return_left, return_right, done; \ |
433 __ b(&done, Label::kNear); \ | 463 __ cdbr(left_reg, right_reg); \ |
434 __ bind(&ge); \ | 464 __ bunordered(&check_nan_left, Label::kNear); \ |
435 __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); \ | 465 __ beq(&check_zero); \ |
436 __ bind(&done); \ | 466 __ ble(&return_left, Label::kNear); \ |
| 467 __ b(&return_right, Label::kNear); \ |
| 468 \ |
| 469 __ bind(&check_zero); \ |
| 470 __ lzdr(kDoubleRegZero); \ |
| 471 __ cdbr(left_reg, kDoubleRegZero); \ |
| 472 /* left == right != 0. */ \ |
| 473 __ bne(&return_left, Label::kNear); \ |
| 474 /* At this point, both left and right are either 0 or -0. */ \ |
| 475 /* N.B. The following works because +0 + -0 == +0 */ \ |
| 476 /* For min we want logical-or of sign bit: -(-L + -R) */ \ |
| 477 __ lcdbr(left_reg, left_reg); \ |
| 478 __ ldr(result_reg, left_reg); \ |
| 479 if (left_reg.is(right_reg)) { \ |
| 480 __ adbr(result_reg, right_reg); \ |
| 481 } else { \ |
| 482 __ sdbr(result_reg, right_reg); \ |
| 483 } \ |
| 484 __ lcdbr(result_reg, result_reg); \ |
| 485 __ b(&done, Label::kNear); \ |
| 486 \ |
| 487 __ bind(&check_nan_left); \ |
| 488 __ cdbr(left_reg, left_reg); \ |
| 489 /* left == NaN. */ \ |
| 490 __ bunordered(&return_left, Label::kNear); \ |
| 491 \ |
| 492 __ bind(&return_right); \ |
| 493 if (!right_reg.is(result_reg)) { \ |
| 494 __ ldr(result_reg, right_reg); \ |
| 495 } \ |
| 496 __ b(&done, Label::kNear); \ |
| 497 \ |
| 498 __ bind(&return_left); \ |
| 499 if (!left_reg.is(result_reg)) { \ |
| 500 __ ldr(result_reg, left_reg); \ |
| 501 } \ |
| 502 __ bind(&done); \ |
437 } while (0) | 503 } while (0) |
438 | 504 |
439 // Only MRI mode for these instructions available | 505 // Only MRI mode for these instructions available |
440 #define ASSEMBLE_LOAD_FLOAT(asm_instr) \ | 506 #define ASSEMBLE_LOAD_FLOAT(asm_instr) \ |
441 do { \ | 507 do { \ |
442 DoubleRegister result = i.OutputDoubleRegister(); \ | 508 DoubleRegister result = i.OutputDoubleRegister(); \ |
443 AddressingMode mode = kMode_None; \ | 509 AddressingMode mode = kMode_None; \ |
444 MemOperand operand = i.MemoryOperand(&mode); \ | 510 MemOperand operand = i.MemoryOperand(&mode); \ |
445 __ asm_instr(result, operand); \ | 511 __ asm_instr(result, operand); \ |
446 } while (0) | 512 } while (0) |
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 case kIeee754Float64Pow: { | 1478 case kIeee754Float64Pow: { |
1413 MathPowStub stub(isolate(), MathPowStub::DOUBLE); | 1479 MathPowStub stub(isolate(), MathPowStub::DOUBLE); |
1414 __ CallStub(&stub); | 1480 __ CallStub(&stub); |
1415 __ Move(d1, d3); | 1481 __ Move(d1, d3); |
1416 break; | 1482 break; |
1417 } | 1483 } |
1418 case kS390_Neg: | 1484 case kS390_Neg: |
1419 __ LoadComplementRR(i.OutputRegister(), i.InputRegister(0)); | 1485 __ LoadComplementRR(i.OutputRegister(), i.InputRegister(0)); |
1420 break; | 1486 break; |
1421 case kS390_MaxDouble: | 1487 case kS390_MaxDouble: |
1422 ASSEMBLE_FLOAT_MAX(kScratchDoubleReg, kScratchReg); | 1488 ASSEMBLE_FLOAT_MAX(); |
1423 break; | 1489 break; |
1424 case kS390_MinDouble: | 1490 case kS390_MinDouble: |
1425 ASSEMBLE_FLOAT_MIN(kScratchDoubleReg, kScratchReg); | 1491 ASSEMBLE_FLOAT_MIN(); |
1426 break; | 1492 break; |
1427 case kS390_AbsDouble: | 1493 case kS390_AbsDouble: |
1428 __ lpdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1494 __ lpdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1429 break; | 1495 break; |
1430 case kS390_SqrtDouble: | 1496 case kS390_SqrtDouble: |
1431 ASSEMBLE_FLOAT_UNOP(sqdbr); | 1497 ASSEMBLE_FLOAT_UNOP(sqdbr); |
1432 break; | 1498 break; |
1433 case kS390_FloorDouble: | 1499 case kS390_FloorDouble: |
1434 __ fidbra(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 1500 __ fidbra(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
1435 v8::internal::Assembler::FIDBRA_ROUND_TOWARD_NEG_INF); | 1501 v8::internal::Assembler::FIDBRA_ROUND_TOWARD_NEG_INF); |
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2361 padding_size -= 2; | 2427 padding_size -= 2; |
2362 } | 2428 } |
2363 } | 2429 } |
2364 } | 2430 } |
2365 | 2431 |
2366 #undef __ | 2432 #undef __ |
2367 | 2433 |
2368 } // namespace compiler | 2434 } // namespace compiler |
2369 } // namespace internal | 2435 } // namespace internal |
2370 } // namespace v8 | 2436 } // namespace v8 |
OLD | NEW |