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

Side by Side Diff: src/x64/macro-assembler-x64.h

Issue 6928060: Merge Label and NearLabel (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: address comments Created 9 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-codegen-x64.cc ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 void MacroAssembler::SmiMul(Register dst, 1362 void MacroAssembler::SmiMul(Register dst,
1363 Register src1, 1363 Register src1,
1364 Register src2, 1364 Register src2,
1365 LabelType* on_not_smi_result) { 1365 LabelType* on_not_smi_result) {
1366 ASSERT(!dst.is(src2)); 1366 ASSERT(!dst.is(src2));
1367 ASSERT(!dst.is(kScratchRegister)); 1367 ASSERT(!dst.is(kScratchRegister));
1368 ASSERT(!src1.is(kScratchRegister)); 1368 ASSERT(!src1.is(kScratchRegister));
1369 ASSERT(!src2.is(kScratchRegister)); 1369 ASSERT(!src2.is(kScratchRegister));
1370 1370
1371 if (dst.is(src1)) { 1371 if (dst.is(src1)) {
1372 NearLabel failure, zero_correct_result; 1372 Label failure, zero_correct_result;
1373 movq(kScratchRegister, src1); // Create backup for later testing. 1373 movq(kScratchRegister, src1); // Create backup for later testing.
1374 SmiToInteger64(dst, src1); 1374 SmiToInteger64(dst, src1);
1375 imul(dst, src2); 1375 imul(dst, src2);
1376 j(overflow, &failure); 1376 j(overflow, &failure, Label::kNear);
1377 1377
1378 // Check for negative zero result. If product is zero, and one 1378 // Check for negative zero result. If product is zero, and one
1379 // argument is negative, go to slow case. 1379 // argument is negative, go to slow case.
1380 NearLabel correct_result; 1380 Label correct_result;
1381 testq(dst, dst); 1381 testq(dst, dst);
1382 j(not_zero, &correct_result); 1382 j(not_zero, &correct_result, Label::kNear);
1383 1383
1384 movq(dst, kScratchRegister); 1384 movq(dst, kScratchRegister);
1385 xor_(dst, src2); 1385 xor_(dst, src2);
1386 j(positive, &zero_correct_result); // Result was positive zero. 1386 // Result was positive zero.
1387 j(positive, &zero_correct_result, Label::kNear);
1387 1388
1388 bind(&failure); // Reused failure exit, restores src1. 1389 bind(&failure); // Reused failure exit, restores src1.
1389 movq(src1, kScratchRegister); 1390 movq(src1, kScratchRegister);
1390 jmp(on_not_smi_result); 1391 jmp(on_not_smi_result);
1391 1392
1392 bind(&zero_correct_result); 1393 bind(&zero_correct_result);
1393 Set(dst, 0); 1394 Set(dst, 0);
1394 1395
1395 bind(&correct_result); 1396 bind(&correct_result);
1396 } else { 1397 } else {
1397 SmiToInteger64(dst, src1); 1398 SmiToInteger64(dst, src1);
1398 imul(dst, src2); 1399 imul(dst, src2);
1399 j(overflow, on_not_smi_result); 1400 j(overflow, on_not_smi_result);
1400 // Check for negative zero result. If product is zero, and one 1401 // Check for negative zero result. If product is zero, and one
1401 // argument is negative, go to slow case. 1402 // argument is negative, go to slow case.
1402 NearLabel correct_result; 1403 Label correct_result;
1403 testq(dst, dst); 1404 testq(dst, dst);
1404 j(not_zero, &correct_result); 1405 j(not_zero, &correct_result, Label::kNear);
1405 // One of src1 and src2 is zero, the check whether the other is 1406 // One of src1 and src2 is zero, the check whether the other is
1406 // negative. 1407 // negative.
1407 movq(kScratchRegister, src1); 1408 movq(kScratchRegister, src1);
1408 xor_(kScratchRegister, src2); 1409 xor_(kScratchRegister, src2);
1409 j(negative, on_not_smi_result); 1410 j(negative, on_not_smi_result);
1410 bind(&correct_result); 1411 bind(&correct_result);
1411 } 1412 }
1412 } 1413 }
1413 1414
1414 1415
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 Register src2, 1510 Register src2,
1510 LabelType* on_not_smi_result) { 1511 LabelType* on_not_smi_result) {
1511 ASSERT(!src1.is(kScratchRegister)); 1512 ASSERT(!src1.is(kScratchRegister));
1512 ASSERT(!src2.is(kScratchRegister)); 1513 ASSERT(!src2.is(kScratchRegister));
1513 ASSERT(!dst.is(kScratchRegister)); 1514 ASSERT(!dst.is(kScratchRegister));
1514 ASSERT(!src2.is(rax)); 1515 ASSERT(!src2.is(rax));
1515 ASSERT(!src2.is(rdx)); 1516 ASSERT(!src2.is(rdx));
1516 ASSERT(!src1.is(rdx)); 1517 ASSERT(!src1.is(rdx));
1517 1518
1518 // Check for 0 divisor (result is +/-Infinity). 1519 // Check for 0 divisor (result is +/-Infinity).
1519 NearLabel positive_divisor;
1520 testq(src2, src2); 1520 testq(src2, src2);
1521 j(zero, on_not_smi_result); 1521 j(zero, on_not_smi_result);
1522 1522
1523 if (src1.is(rax)) { 1523 if (src1.is(rax)) {
1524 movq(kScratchRegister, src1); 1524 movq(kScratchRegister, src1);
1525 } 1525 }
1526 SmiToInteger32(rax, src1); 1526 SmiToInteger32(rax, src1);
1527 // We need to rule out dividing Smi::kMinValue by -1, since that would 1527 // We need to rule out dividing Smi::kMinValue by -1, since that would
1528 // overflow in idiv and raise an exception. 1528 // overflow in idiv and raise an exception.
1529 // We combine this with negative zero test (negative zero only happens 1529 // We combine this with negative zero test (negative zero only happens
1530 // when dividing zero by a negative number). 1530 // when dividing zero by a negative number).
1531 1531
1532 // We overshoot a little and go to slow case if we divide min-value 1532 // We overshoot a little and go to slow case if we divide min-value
1533 // by any negative value, not just -1. 1533 // by any negative value, not just -1.
1534 NearLabel safe_div; 1534 Label safe_div;
1535 testl(rax, Immediate(0x7fffffff)); 1535 testl(rax, Immediate(0x7fffffff));
1536 j(not_zero, &safe_div); 1536 j(not_zero, &safe_div, Label::kNear);
1537 testq(src2, src2); 1537 testq(src2, src2);
1538 if (src1.is(rax)) { 1538 if (src1.is(rax)) {
1539 j(positive, &safe_div); 1539 j(positive, &safe_div, Label::kNear);
1540 movq(src1, kScratchRegister); 1540 movq(src1, kScratchRegister);
1541 jmp(on_not_smi_result); 1541 jmp(on_not_smi_result);
1542 } else { 1542 } else {
1543 j(negative, on_not_smi_result); 1543 j(negative, on_not_smi_result);
1544 } 1544 }
1545 bind(&safe_div); 1545 bind(&safe_div);
1546 1546
1547 SmiToInteger32(src2, src2); 1547 SmiToInteger32(src2, src2);
1548 // Sign extend src1 into edx:eax. 1548 // Sign extend src1 into edx:eax.
1549 cdq(); 1549 cdq();
1550 idivl(src2); 1550 idivl(src2);
1551 Integer32ToSmi(src2, src2); 1551 Integer32ToSmi(src2, src2);
1552 // Check that the remainder is zero. 1552 // Check that the remainder is zero.
1553 testl(rdx, rdx); 1553 testl(rdx, rdx);
1554 if (src1.is(rax)) { 1554 if (src1.is(rax)) {
1555 NearLabel smi_result; 1555 Label smi_result;
1556 j(zero, &smi_result); 1556 j(zero, &smi_result, Label::kNear);
1557 movq(src1, kScratchRegister); 1557 movq(src1, kScratchRegister);
1558 jmp(on_not_smi_result); 1558 jmp(on_not_smi_result);
1559 bind(&smi_result); 1559 bind(&smi_result);
1560 } else { 1560 } else {
1561 j(not_zero, on_not_smi_result); 1561 j(not_zero, on_not_smi_result);
1562 } 1562 }
1563 if (!dst.is(src1) && src1.is(rax)) { 1563 if (!dst.is(src1) && src1.is(rax)) {
1564 movq(src1, kScratchRegister); 1564 movq(src1, kScratchRegister);
1565 } 1565 }
1566 Integer32ToSmi(dst, rax); 1566 Integer32ToSmi(dst, rax);
(...skipping 16 matching lines...) Expand all
1583 testq(src2, src2); 1583 testq(src2, src2);
1584 j(zero, on_not_smi_result); 1584 j(zero, on_not_smi_result);
1585 1585
1586 if (src1.is(rax)) { 1586 if (src1.is(rax)) {
1587 movq(kScratchRegister, src1); 1587 movq(kScratchRegister, src1);
1588 } 1588 }
1589 SmiToInteger32(rax, src1); 1589 SmiToInteger32(rax, src1);
1590 SmiToInteger32(src2, src2); 1590 SmiToInteger32(src2, src2);
1591 1591
1592 // Test for the edge case of dividing Smi::kMinValue by -1 (will overflow). 1592 // Test for the edge case of dividing Smi::kMinValue by -1 (will overflow).
1593 NearLabel safe_div; 1593 Label safe_div;
1594 cmpl(rax, Immediate(Smi::kMinValue)); 1594 cmpl(rax, Immediate(Smi::kMinValue));
1595 j(not_equal, &safe_div); 1595 j(not_equal, &safe_div, Label::kNear);
1596 cmpl(src2, Immediate(-1)); 1596 cmpl(src2, Immediate(-1));
1597 j(not_equal, &safe_div); 1597 j(not_equal, &safe_div, Label::kNear);
1598 // Retag inputs and go slow case. 1598 // Retag inputs and go slow case.
1599 Integer32ToSmi(src2, src2); 1599 Integer32ToSmi(src2, src2);
1600 if (src1.is(rax)) { 1600 if (src1.is(rax)) {
1601 movq(src1, kScratchRegister); 1601 movq(src1, kScratchRegister);
1602 } 1602 }
1603 jmp(on_not_smi_result); 1603 jmp(on_not_smi_result);
1604 bind(&safe_div); 1604 bind(&safe_div);
1605 1605
1606 // Sign extend eax into edx:eax. 1606 // Sign extend eax into edx:eax.
1607 cdq(); 1607 cdq();
1608 idivl(src2); 1608 idivl(src2);
1609 // Restore smi tags on inputs. 1609 // Restore smi tags on inputs.
1610 Integer32ToSmi(src2, src2); 1610 Integer32ToSmi(src2, src2);
1611 if (src1.is(rax)) { 1611 if (src1.is(rax)) {
1612 movq(src1, kScratchRegister); 1612 movq(src1, kScratchRegister);
1613 } 1613 }
1614 // Check for a negative zero result. If the result is zero, and the 1614 // Check for a negative zero result. If the result is zero, and the
1615 // dividend is negative, go slow to return a floating point negative zero. 1615 // dividend is negative, go slow to return a floating point negative zero.
1616 NearLabel smi_result; 1616 Label smi_result;
1617 testl(rdx, rdx); 1617 testl(rdx, rdx);
1618 j(not_zero, &smi_result); 1618 j(not_zero, &smi_result, Label::kNear);
1619 testq(src1, src1); 1619 testq(src1, src1);
1620 j(negative, on_not_smi_result); 1620 j(negative, on_not_smi_result);
1621 bind(&smi_result); 1621 bind(&smi_result);
1622 Integer32ToSmi(dst, rdx); 1622 Integer32ToSmi(dst, rdx);
1623 } 1623 }
1624 1624
1625 1625
1626 template <typename LabelType> 1626 template <typename LabelType>
1627 void MacroAssembler::SmiShiftLogicalRightConstant( 1627 void MacroAssembler::SmiShiftLogicalRightConstant(
1628 Register dst, Register src, int shift_value, LabelType* on_not_smi_result) { 1628 Register dst, Register src, int shift_value, LabelType* on_not_smi_result) {
(...skipping 16 matching lines...) Expand all
1645 void MacroAssembler::SmiShiftLogicalRight(Register dst, 1645 void MacroAssembler::SmiShiftLogicalRight(Register dst,
1646 Register src1, 1646 Register src1,
1647 Register src2, 1647 Register src2,
1648 LabelType* on_not_smi_result) { 1648 LabelType* on_not_smi_result) {
1649 ASSERT(!dst.is(kScratchRegister)); 1649 ASSERT(!dst.is(kScratchRegister));
1650 ASSERT(!src1.is(kScratchRegister)); 1650 ASSERT(!src1.is(kScratchRegister));
1651 ASSERT(!src2.is(kScratchRegister)); 1651 ASSERT(!src2.is(kScratchRegister));
1652 ASSERT(!dst.is(rcx)); 1652 ASSERT(!dst.is(rcx));
1653 // dst and src1 can be the same, because the one case that bails out 1653 // dst and src1 can be the same, because the one case that bails out
1654 // is a shift by 0, which leaves dst, and therefore src1, unchanged. 1654 // is a shift by 0, which leaves dst, and therefore src1, unchanged.
1655 NearLabel result_ok;
1656 if (src1.is(rcx) || src2.is(rcx)) { 1655 if (src1.is(rcx) || src2.is(rcx)) {
1657 movq(kScratchRegister, rcx); 1656 movq(kScratchRegister, rcx);
1658 } 1657 }
1659 if (!dst.is(src1)) { 1658 if (!dst.is(src1)) {
1660 movq(dst, src1); 1659 movq(dst, src1);
1661 } 1660 }
1662 SmiToInteger32(rcx, src2); 1661 SmiToInteger32(rcx, src2);
1663 orl(rcx, Immediate(kSmiShift)); 1662 orl(rcx, Immediate(kSmiShift));
1664 shr_cl(dst); // Shift is rcx modulo 0x1f + 32. 1663 shr_cl(dst); // Shift is rcx modulo 0x1f + 32.
1665 shl(dst, Immediate(kSmiShift)); 1664 shl(dst, Immediate(kSmiShift));
1666 testq(dst, dst); 1665 testq(dst, dst);
1667 if (src1.is(rcx) || src2.is(rcx)) { 1666 if (src1.is(rcx) || src2.is(rcx)) {
1668 NearLabel positive_result; 1667 Label positive_result;
1669 j(positive, &positive_result); 1668 j(positive, &positive_result, Label::kNear);
1670 if (src1.is(rcx)) { 1669 if (src1.is(rcx)) {
1671 movq(src1, kScratchRegister); 1670 movq(src1, kScratchRegister);
1672 } else { 1671 } else {
1673 movq(src2, kScratchRegister); 1672 movq(src2, kScratchRegister);
1674 } 1673 }
1675 jmp(on_not_smi_result); 1674 jmp(on_not_smi_result);
1676 bind(&positive_result); 1675 bind(&positive_result);
1677 } else { 1676 } else {
1678 j(negative, on_not_smi_result); // src2 was zero and src1 negative. 1677 j(negative, on_not_smi_result); // src2 was zero and src1 negative.
1679 } 1678 }
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1931 1930
1932 template <typename LabelType> 1931 template <typename LabelType>
1933 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 1932 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
1934 const ParameterCount& actual, 1933 const ParameterCount& actual,
1935 Handle<Code> code_constant, 1934 Handle<Code> code_constant,
1936 Register code_register, 1935 Register code_register,
1937 LabelType* done, 1936 LabelType* done,
1938 InvokeFlag flag, 1937 InvokeFlag flag,
1939 const CallWrapper& call_wrapper) { 1938 const CallWrapper& call_wrapper) {
1940 bool definitely_matches = false; 1939 bool definitely_matches = false;
1941 NearLabel invoke; 1940 Label invoke;
1942 if (expected.is_immediate()) { 1941 if (expected.is_immediate()) {
1943 ASSERT(actual.is_immediate()); 1942 ASSERT(actual.is_immediate());
1944 if (expected.immediate() == actual.immediate()) { 1943 if (expected.immediate() == actual.immediate()) {
1945 definitely_matches = true; 1944 definitely_matches = true;
1946 } else { 1945 } else {
1947 Set(rax, actual.immediate()); 1946 Set(rax, actual.immediate());
1948 if (expected.immediate() == 1947 if (expected.immediate() ==
1949 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 1948 SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
1950 // Don't worry about adapting arguments for built-ins that 1949 // Don't worry about adapting arguments for built-ins that
1951 // don't want that done. Skip adaption code by making it look 1950 // don't want that done. Skip adaption code by making it look
1952 // like we have a match between expected and actual number of 1951 // like we have a match between expected and actual number of
1953 // arguments. 1952 // arguments.
1954 definitely_matches = true; 1953 definitely_matches = true;
1955 } else { 1954 } else {
1956 Set(rbx, expected.immediate()); 1955 Set(rbx, expected.immediate());
1957 } 1956 }
1958 } 1957 }
1959 } else { 1958 } else {
1960 if (actual.is_immediate()) { 1959 if (actual.is_immediate()) {
1961 // Expected is in register, actual is immediate. This is the 1960 // Expected is in register, actual is immediate. This is the
1962 // case when we invoke function values without going through the 1961 // case when we invoke function values without going through the
1963 // IC mechanism. 1962 // IC mechanism.
1964 cmpq(expected.reg(), Immediate(actual.immediate())); 1963 cmpq(expected.reg(), Immediate(actual.immediate()));
1965 j(equal, &invoke); 1964 j(equal, &invoke, Label::kNear);
1966 ASSERT(expected.reg().is(rbx)); 1965 ASSERT(expected.reg().is(rbx));
1967 Set(rax, actual.immediate()); 1966 Set(rax, actual.immediate());
1968 } else if (!expected.reg().is(actual.reg())) { 1967 } else if (!expected.reg().is(actual.reg())) {
1969 // Both expected and actual are in (different) registers. This 1968 // Both expected and actual are in (different) registers. This
1970 // is the case when we invoke functions using call and apply. 1969 // is the case when we invoke functions using call and apply.
1971 cmpq(expected.reg(), actual.reg()); 1970 cmpq(expected.reg(), actual.reg());
1972 j(equal, &invoke); 1971 j(equal, &invoke, Label::kNear);
1973 ASSERT(actual.reg().is(rax)); 1972 ASSERT(actual.reg().is(rax));
1974 ASSERT(expected.reg().is(rbx)); 1973 ASSERT(expected.reg().is(rbx));
1975 } 1974 }
1976 } 1975 }
1977 1976
1978 if (!definitely_matches) { 1977 if (!definitely_matches) {
1979 Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); 1978 Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
1980 if (!code_constant.is_null()) { 1979 if (!code_constant.is_null()) {
1981 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); 1980 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT);
1982 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 1981 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
(...skipping 10 matching lines...) Expand all
1993 Jump(adaptor, RelocInfo::CODE_TARGET); 1992 Jump(adaptor, RelocInfo::CODE_TARGET);
1994 } 1993 }
1995 bind(&invoke); 1994 bind(&invoke);
1996 } 1995 }
1997 } 1996 }
1998 1997
1999 1998
2000 } } // namespace v8::internal 1999 } } // namespace v8::internal
2001 2000
2002 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ 2001 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.cc ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698