OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 | 1409 |
1410 // Run the native code for the Array function called as a normal function. | 1410 // Run the native code for the Array function called as a normal function. |
1411 // tail call a stub | 1411 // tail call a stub |
1412 __ mov(ebx, masm->isolate()->factory()->undefined_value()); | 1412 __ mov(ebx, masm->isolate()->factory()->undefined_value()); |
1413 ArrayConstructorStub stub(masm->isolate()); | 1413 ArrayConstructorStub stub(masm->isolate()); |
1414 __ TailCallStub(&stub); | 1414 __ TailCallStub(&stub); |
1415 } | 1415 } |
1416 | 1416 |
1417 | 1417 |
1418 // static | 1418 // static |
| 1419 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { |
| 1420 // ----------- S t a t e ------------- |
| 1421 // -- eax : number of arguments |
| 1422 // -- esp[0] : return address |
| 1423 // -- esp[(argc - n) * 8] : arg[n] (zero-based) |
| 1424 // -- esp[(argc + 1) * 8] : receiver |
| 1425 // ----------------------------------- |
| 1426 Condition const cc = (kind == MathMaxMinKind::kMin) ? below : above; |
| 1427 Heap::RootListIndex const root_index = |
| 1428 (kind == MathMaxMinKind::kMin) ? Heap::kInfinityValueRootIndex |
| 1429 : Heap::kMinusInfinityValueRootIndex; |
| 1430 const int reg_sel = (kind == MathMaxMinKind::kMin) ? 1 : 0; |
| 1431 |
| 1432 // Load the accumulator with the default return value (either -Infinity or |
| 1433 // +Infinity), with the tagged value in edx and the double value in stx_0. |
| 1434 __ LoadRoot(edx, root_index); |
| 1435 __ fld_d(FieldOperand(edx, HeapNumber::kValueOffset)); |
| 1436 __ Move(ecx, eax); |
| 1437 |
| 1438 Label done_loop, loop; |
| 1439 __ bind(&loop); |
| 1440 { |
| 1441 // Check if all parameters done. |
| 1442 __ test(ecx, ecx); |
| 1443 __ j(zero, &done_loop); |
| 1444 |
| 1445 // Load the next parameter tagged value into ebx. |
| 1446 __ mov(ebx, Operand(esp, ecx, times_pointer_size, 0)); |
| 1447 |
| 1448 // Load the double value of the parameter into stx_1, maybe converting the |
| 1449 // parameter to a number first using the ToNumberStub if necessary. |
| 1450 Label convert, convert_smi, convert_number, done_convert; |
| 1451 __ bind(&convert); |
| 1452 __ JumpIfSmi(ebx, &convert_smi); |
| 1453 __ JumpIfRoot(FieldOperand(ebx, HeapObject::kMapOffset), |
| 1454 Heap::kHeapNumberMapRootIndex, &convert_number); |
| 1455 { |
| 1456 // Parameter is not a Number, use the ToNumberStub to convert it. |
| 1457 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1458 __ SmiTag(eax); |
| 1459 __ SmiTag(ecx); |
| 1460 __ Push(eax); |
| 1461 __ Push(ecx); |
| 1462 __ Push(edx); |
| 1463 __ mov(eax, ebx); |
| 1464 ToNumberStub stub(masm->isolate()); |
| 1465 __ CallStub(&stub); |
| 1466 __ mov(ebx, eax); |
| 1467 __ Pop(edx); |
| 1468 __ Pop(ecx); |
| 1469 __ Pop(eax); |
| 1470 { |
| 1471 // Restore the double accumulator value (stX_0). |
| 1472 Label restore_smi, done_restore; |
| 1473 __ JumpIfSmi(edx, &restore_smi, Label::kNear); |
| 1474 __ fld_d(FieldOperand(edx, HeapNumber::kValueOffset)); |
| 1475 __ jmp(&done_restore, Label::kNear); |
| 1476 __ bind(&restore_smi); |
| 1477 __ SmiUntag(edx); |
| 1478 __ push(edx); |
| 1479 __ fild_s(Operand(esp, 0)); |
| 1480 __ pop(edx); |
| 1481 __ SmiTag(edx); |
| 1482 __ bind(&done_restore); |
| 1483 } |
| 1484 __ SmiUntag(ecx); |
| 1485 __ SmiUntag(eax); |
| 1486 } |
| 1487 __ jmp(&convert); |
| 1488 __ bind(&convert_number); |
| 1489 // Load another value into stx_1 |
| 1490 __ fld_d(FieldOperand(ebx, HeapNumber::kValueOffset)); |
| 1491 __ fxch(); |
| 1492 __ jmp(&done_convert, Label::kNear); |
| 1493 __ bind(&convert_smi); |
| 1494 __ SmiUntag(ebx); |
| 1495 __ push(ebx); |
| 1496 __ fild_s(Operand(esp, 0)); |
| 1497 __ pop(ebx); |
| 1498 __ fxch(); |
| 1499 __ SmiTag(ebx); |
| 1500 __ bind(&done_convert); |
| 1501 |
| 1502 // Perform the actual comparison with the accumulator value on the left hand |
| 1503 // side (stx_0) and the next parameter value on the right hand side (stx_1). |
| 1504 Label compare_equal, compare_nan, compare_swap, done_compare; |
| 1505 |
| 1506 // Duplicates the 2 float data for FCmp |
| 1507 __ fld(1); |
| 1508 __ fld(1); |
| 1509 __ FCmp(); |
| 1510 __ j(parity_even, &compare_nan, Label::kNear); |
| 1511 __ j(cc, &done_compare, Label::kNear); |
| 1512 __ j(equal, &compare_equal, Label::kNear); |
| 1513 |
| 1514 // Result is on the right hand side(stx_0). |
| 1515 __ bind(&compare_swap); |
| 1516 __ fxch(); |
| 1517 __ mov(edx, ebx); |
| 1518 __ jmp(&done_compare, Label::kNear); |
| 1519 |
| 1520 // At least one side is NaN, which means that the result will be NaN too. |
| 1521 __ bind(&compare_nan); |
| 1522 // Set the result on the right hand side (stx_0) to nan |
| 1523 __ fstp(0); |
| 1524 __ LoadRoot(edx, Heap::kNanValueRootIndex); |
| 1525 __ fld_d(FieldOperand(edx, HeapNumber::kValueOffset)); |
| 1526 __ jmp(&done_compare, Label::kNear); |
| 1527 |
| 1528 // Left and right hand side are equal, check for -0 vs. +0. |
| 1529 __ bind(&compare_equal); |
| 1530 // Check the sign of the value in reg_sel |
| 1531 __ fld(reg_sel); |
| 1532 __ FXamSign(); |
| 1533 __ j(not_zero, &compare_swap); |
| 1534 |
| 1535 __ bind(&done_compare); |
| 1536 // The right result is on the right hand side(stx_0) |
| 1537 // and can remove the useless stx_1 now. |
| 1538 __ fxch(); |
| 1539 __ fstp(0); |
| 1540 __ dec(ecx); |
| 1541 __ jmp(&loop); |
| 1542 } |
| 1543 |
| 1544 __ bind(&done_loop); |
| 1545 __ PopReturnAddressTo(ecx); |
| 1546 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize)); |
| 1547 __ PushReturnAddressFrom(ecx); |
| 1548 __ mov(eax, edx); |
| 1549 __ Ret(); |
| 1550 } |
| 1551 |
| 1552 // static |
1419 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { | 1553 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { |
1420 // ----------- S t a t e ------------- | 1554 // ----------- S t a t e ------------- |
1421 // -- eax : number of arguments | 1555 // -- eax : number of arguments |
1422 // -- edi : constructor function | 1556 // -- edi : constructor function |
1423 // -- esp[0] : return address | 1557 // -- esp[0] : return address |
1424 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1558 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1425 // -- esp[(argc + 1) * 4] : receiver | 1559 // -- esp[(argc + 1) * 4] : receiver |
1426 // ----------------------------------- | 1560 // ----------------------------------- |
1427 | 1561 |
1428 // 1. Load the first argument into eax and get rid of the rest (including the | 1562 // 1. Load the first argument into eax and get rid of the rest (including the |
(...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2682 | 2816 |
2683 __ bind(&ok); | 2817 __ bind(&ok); |
2684 __ ret(0); | 2818 __ ret(0); |
2685 } | 2819 } |
2686 | 2820 |
2687 #undef __ | 2821 #undef __ |
2688 } // namespace internal | 2822 } // namespace internal |
2689 } // namespace v8 | 2823 } // namespace v8 |
2690 | 2824 |
2691 #endif // V8_TARGET_ARCH_X87 | 2825 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |