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

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

Issue 196893003: Introduce addp, idivp, imulp and subp for x64 port (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 Label ok; 229 Label ok;
230 JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear); 230 JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear);
231 int3(); 231 int3();
232 bind(&ok); 232 bind(&ok);
233 } 233 }
234 // Load store buffer top. 234 // Load store buffer top.
235 LoadRoot(scratch, Heap::kStoreBufferTopRootIndex); 235 LoadRoot(scratch, Heap::kStoreBufferTopRootIndex);
236 // Store pointer to buffer. 236 // Store pointer to buffer.
237 movp(Operand(scratch, 0), addr); 237 movp(Operand(scratch, 0), addr);
238 // Increment buffer top. 238 // Increment buffer top.
239 addq(scratch, Immediate(kPointerSize)); 239 addp(scratch, Immediate(kPointerSize));
240 // Write back new top of buffer. 240 // Write back new top of buffer.
241 StoreRoot(scratch, Heap::kStoreBufferTopRootIndex); 241 StoreRoot(scratch, Heap::kStoreBufferTopRootIndex);
242 // Call stub on end of buffer. 242 // Call stub on end of buffer.
243 Label done; 243 Label done;
244 // Check for end of buffer. 244 // Check for end of buffer.
245 testq(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit)); 245 testq(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit));
246 if (and_then == kReturnAtEnd) { 246 if (and_then == kReturnAtEnd) {
247 Label buffer_overflowed; 247 Label buffer_overflowed;
248 j(not_equal, &buffer_overflowed, Label::kNear); 248 j(not_equal, &buffer_overflowed, Label::kNear);
249 ret(0); 249 ret(0);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 Move(kScratchRegister, ExternalReference::new_space_start(isolate())); 284 Move(kScratchRegister, ExternalReference::new_space_start(isolate()));
285 cmpq(scratch, kScratchRegister); 285 cmpq(scratch, kScratchRegister);
286 j(cc, branch, distance); 286 j(cc, branch, distance);
287 } else { 287 } else {
288 ASSERT(is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask()))); 288 ASSERT(is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask())));
289 intptr_t new_space_start = 289 intptr_t new_space_start =
290 reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart()); 290 reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart());
291 Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start), 291 Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start),
292 Assembler::RelocInfoNone()); 292 Assembler::RelocInfoNone());
293 if (scratch.is(object)) { 293 if (scratch.is(object)) {
294 addq(scratch, kScratchRegister); 294 addp(scratch, kScratchRegister);
295 } else { 295 } else {
296 lea(scratch, Operand(object, kScratchRegister, times_1, 0)); 296 lea(scratch, Operand(object, kScratchRegister, times_1, 0));
297 } 297 }
298 and_(scratch, 298 and_(scratch,
299 Immediate(static_cast<int32_t>(isolate()->heap()->NewSpaceMask()))); 299 Immediate(static_cast<int32_t>(isolate()->heap()->NewSpaceMask())));
300 j(cc, branch, distance); 300 j(cc, branch, distance);
301 } 301 }
302 } 302 }
303 303
304 304
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 } 553 }
554 554
555 555
556 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 556 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
557 return has_frame_ || !stub->SometimesSetsUpAFrame(); 557 return has_frame_ || !stub->SometimesSetsUpAFrame();
558 } 558 }
559 559
560 560
561 void MacroAssembler::IllegalOperation(int num_arguments) { 561 void MacroAssembler::IllegalOperation(int num_arguments) {
562 if (num_arguments > 0) { 562 if (num_arguments > 0) {
563 addq(rsp, Immediate(num_arguments * kPointerSize)); 563 addp(rsp, Immediate(num_arguments * kPointerSize));
564 } 564 }
565 LoadRoot(rax, Heap::kUndefinedValueRootIndex); 565 LoadRoot(rax, Heap::kUndefinedValueRootIndex);
566 } 566 }
567 567
568 568
569 void MacroAssembler::IndexFromHash(Register hash, Register index) { 569 void MacroAssembler::IndexFromHash(Register hash, Register index) {
570 // The assert checks that the constants for the maximum number of digits 570 // The assert checks that the constants for the maximum number of digits
571 // for an array index cached in the hash field and the number of bits 571 // for an array index cached in the hash field and the number of bits
572 // reserved for it does not conflict. 572 // reserved for it does not conflict.
573 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 573 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 // store the registers in any particular way, but we do have to store and 879 // store the registers in any particular way, but we do have to store and
880 // restore them. 880 // restore them.
881 for (int i = 0; i < kNumberOfSavedRegs; i++) { 881 for (int i = 0; i < kNumberOfSavedRegs; i++) {
882 Register reg = saved_regs[i]; 882 Register reg = saved_regs[i];
883 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 883 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
884 pushq(reg); 884 pushq(reg);
885 } 885 }
886 } 886 }
887 // R12 to r15 are callee save on all platforms. 887 // R12 to r15 are callee save on all platforms.
888 if (fp_mode == kSaveFPRegs) { 888 if (fp_mode == kSaveFPRegs) {
889 subq(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 889 subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
890 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 890 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
891 XMMRegister reg = XMMRegister::from_code(i); 891 XMMRegister reg = XMMRegister::from_code(i);
892 movsd(Operand(rsp, i * kDoubleSize), reg); 892 movsd(Operand(rsp, i * kDoubleSize), reg);
893 } 893 }
894 } 894 }
895 } 895 }
896 896
897 897
898 void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, 898 void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode,
899 Register exclusion1, 899 Register exclusion1,
900 Register exclusion2, 900 Register exclusion2,
901 Register exclusion3) { 901 Register exclusion3) {
902 if (fp_mode == kSaveFPRegs) { 902 if (fp_mode == kSaveFPRegs) {
903 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 903 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
904 XMMRegister reg = XMMRegister::from_code(i); 904 XMMRegister reg = XMMRegister::from_code(i);
905 movsd(reg, Operand(rsp, i * kDoubleSize)); 905 movsd(reg, Operand(rsp, i * kDoubleSize));
906 } 906 }
907 addq(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 907 addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
908 } 908 }
909 for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { 909 for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) {
910 Register reg = saved_regs[i]; 910 Register reg = saved_regs[i];
911 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 911 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
912 popq(reg); 912 popq(reg);
913 } 913 }
914 } 914 }
915 } 915 }
916 916
917 917
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { 1442 void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) {
1443 if (constant->value() == 0) { 1443 if (constant->value() == 0) {
1444 if (!dst.is(src)) { 1444 if (!dst.is(src)) {
1445 movp(dst, src); 1445 movp(dst, src);
1446 } 1446 }
1447 return; 1447 return;
1448 } else if (dst.is(src)) { 1448 } else if (dst.is(src)) {
1449 ASSERT(!dst.is(kScratchRegister)); 1449 ASSERT(!dst.is(kScratchRegister));
1450 switch (constant->value()) { 1450 switch (constant->value()) {
1451 case 1: 1451 case 1:
1452 addq(dst, kSmiConstantRegister); 1452 addp(dst, kSmiConstantRegister);
1453 return; 1453 return;
1454 case 2: 1454 case 2:
1455 lea(dst, Operand(src, kSmiConstantRegister, times_2, 0)); 1455 lea(dst, Operand(src, kSmiConstantRegister, times_2, 0));
1456 return; 1456 return;
1457 case 4: 1457 case 4:
1458 lea(dst, Operand(src, kSmiConstantRegister, times_4, 0)); 1458 lea(dst, Operand(src, kSmiConstantRegister, times_4, 0));
1459 return; 1459 return;
1460 case 8: 1460 case 8:
1461 lea(dst, Operand(src, kSmiConstantRegister, times_8, 0)); 1461 lea(dst, Operand(src, kSmiConstantRegister, times_8, 0));
1462 return; 1462 return;
1463 default: 1463 default:
1464 Register constant_reg = GetSmiConstant(constant); 1464 Register constant_reg = GetSmiConstant(constant);
1465 addq(dst, constant_reg); 1465 addp(dst, constant_reg);
1466 return; 1466 return;
1467 } 1467 }
1468 } else { 1468 } else {
1469 switch (constant->value()) { 1469 switch (constant->value()) {
1470 case 1: 1470 case 1:
1471 lea(dst, Operand(src, kSmiConstantRegister, times_1, 0)); 1471 lea(dst, Operand(src, kSmiConstantRegister, times_1, 0));
1472 return; 1472 return;
1473 case 2: 1473 case 2:
1474 lea(dst, Operand(src, kSmiConstantRegister, times_2, 0)); 1474 lea(dst, Operand(src, kSmiConstantRegister, times_2, 0));
1475 return; 1475 return;
1476 case 4: 1476 case 4:
1477 lea(dst, Operand(src, kSmiConstantRegister, times_4, 0)); 1477 lea(dst, Operand(src, kSmiConstantRegister, times_4, 0));
1478 return; 1478 return;
1479 case 8: 1479 case 8:
1480 lea(dst, Operand(src, kSmiConstantRegister, times_8, 0)); 1480 lea(dst, Operand(src, kSmiConstantRegister, times_8, 0));
1481 return; 1481 return;
1482 default: 1482 default:
1483 LoadSmiConstant(dst, constant); 1483 LoadSmiConstant(dst, constant);
1484 addq(dst, src); 1484 addp(dst, src);
1485 return; 1485 return;
1486 } 1486 }
1487 } 1487 }
1488 } 1488 }
1489 1489
1490 1490
1491 void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) { 1491 void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) {
1492 if (constant->value() != 0) { 1492 if (constant->value() != 0) {
1493 addl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(constant->value())); 1493 addl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(constant->value()));
1494 } 1494 }
1495 } 1495 }
1496 1496
1497 1497
1498 void MacroAssembler::SmiAddConstant(Register dst, 1498 void MacroAssembler::SmiAddConstant(Register dst,
1499 Register src, 1499 Register src,
1500 Smi* constant, 1500 Smi* constant,
1501 SmiOperationExecutionMode mode, 1501 SmiOperationExecutionMode mode,
1502 Label* bailout_label, 1502 Label* bailout_label,
1503 Label::Distance near_jump) { 1503 Label::Distance near_jump) {
1504 if (constant->value() == 0) { 1504 if (constant->value() == 0) {
1505 if (!dst.is(src)) { 1505 if (!dst.is(src)) {
1506 movp(dst, src); 1506 movp(dst, src);
1507 } 1507 }
1508 } else if (dst.is(src)) { 1508 } else if (dst.is(src)) {
1509 ASSERT(!dst.is(kScratchRegister)); 1509 ASSERT(!dst.is(kScratchRegister));
1510 LoadSmiConstant(kScratchRegister, constant); 1510 LoadSmiConstant(kScratchRegister, constant);
1511 addq(dst, kScratchRegister); 1511 addp(dst, kScratchRegister);
1512 if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) { 1512 if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) {
1513 j(no_overflow, bailout_label, near_jump); 1513 j(no_overflow, bailout_label, near_jump);
1514 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1514 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER));
1515 subq(dst, kScratchRegister); 1515 subp(dst, kScratchRegister);
1516 } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) { 1516 } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) {
1517 if (mode.Contains(PRESERVE_SOURCE_REGISTER)) { 1517 if (mode.Contains(PRESERVE_SOURCE_REGISTER)) {
1518 Label done; 1518 Label done;
1519 j(no_overflow, &done, Label::kNear); 1519 j(no_overflow, &done, Label::kNear);
1520 subq(dst, kScratchRegister); 1520 subp(dst, kScratchRegister);
1521 jmp(bailout_label, near_jump); 1521 jmp(bailout_label, near_jump);
1522 bind(&done); 1522 bind(&done);
1523 } else { 1523 } else {
1524 // Bailout if overflow without reserving src. 1524 // Bailout if overflow without reserving src.
1525 j(overflow, bailout_label, near_jump); 1525 j(overflow, bailout_label, near_jump);
1526 } 1526 }
1527 } else { 1527 } else {
1528 CHECK(mode.IsEmpty()); 1528 CHECK(mode.IsEmpty());
1529 } 1529 }
1530 } else { 1530 } else {
1531 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1531 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER));
1532 ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW)); 1532 ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW));
1533 LoadSmiConstant(dst, constant); 1533 LoadSmiConstant(dst, constant);
1534 addq(dst, src); 1534 addp(dst, src);
1535 j(overflow, bailout_label, near_jump); 1535 j(overflow, bailout_label, near_jump);
1536 } 1536 }
1537 } 1537 }
1538 1538
1539 1539
1540 void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) { 1540 void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) {
1541 if (constant->value() == 0) { 1541 if (constant->value() == 0) {
1542 if (!dst.is(src)) { 1542 if (!dst.is(src)) {
1543 movp(dst, src); 1543 movp(dst, src);
1544 } 1544 }
1545 } else if (dst.is(src)) { 1545 } else if (dst.is(src)) {
1546 ASSERT(!dst.is(kScratchRegister)); 1546 ASSERT(!dst.is(kScratchRegister));
1547 Register constant_reg = GetSmiConstant(constant); 1547 Register constant_reg = GetSmiConstant(constant);
1548 subq(dst, constant_reg); 1548 subp(dst, constant_reg);
1549 } else { 1549 } else {
1550 if (constant->value() == Smi::kMinValue) { 1550 if (constant->value() == Smi::kMinValue) {
1551 LoadSmiConstant(dst, constant); 1551 LoadSmiConstant(dst, constant);
1552 // Adding and subtracting the min-value gives the same result, it only 1552 // Adding and subtracting the min-value gives the same result, it only
1553 // differs on the overflow bit, which we don't check here. 1553 // differs on the overflow bit, which we don't check here.
1554 addq(dst, src); 1554 addp(dst, src);
1555 } else { 1555 } else {
1556 // Subtract by adding the negation. 1556 // Subtract by adding the negation.
1557 LoadSmiConstant(dst, Smi::FromInt(-constant->value())); 1557 LoadSmiConstant(dst, Smi::FromInt(-constant->value()));
1558 addq(dst, src); 1558 addp(dst, src);
1559 } 1559 }
1560 } 1560 }
1561 } 1561 }
1562 1562
1563 1563
1564 void MacroAssembler::SmiSubConstant(Register dst, 1564 void MacroAssembler::SmiSubConstant(Register dst,
1565 Register src, 1565 Register src,
1566 Smi* constant, 1566 Smi* constant,
1567 SmiOperationExecutionMode mode, 1567 SmiOperationExecutionMode mode,
1568 Label* bailout_label, 1568 Label* bailout_label,
1569 Label::Distance near_jump) { 1569 Label::Distance near_jump) {
1570 if (constant->value() == 0) { 1570 if (constant->value() == 0) {
1571 if (!dst.is(src)) { 1571 if (!dst.is(src)) {
1572 movp(dst, src); 1572 movp(dst, src);
1573 } 1573 }
1574 } else if (dst.is(src)) { 1574 } else if (dst.is(src)) {
1575 ASSERT(!dst.is(kScratchRegister)); 1575 ASSERT(!dst.is(kScratchRegister));
1576 LoadSmiConstant(kScratchRegister, constant); 1576 LoadSmiConstant(kScratchRegister, constant);
1577 subq(dst, kScratchRegister); 1577 subp(dst, kScratchRegister);
1578 if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) { 1578 if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) {
1579 j(no_overflow, bailout_label, near_jump); 1579 j(no_overflow, bailout_label, near_jump);
1580 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1580 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER));
1581 addq(dst, kScratchRegister); 1581 addp(dst, kScratchRegister);
1582 } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) { 1582 } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) {
1583 if (mode.Contains(PRESERVE_SOURCE_REGISTER)) { 1583 if (mode.Contains(PRESERVE_SOURCE_REGISTER)) {
1584 Label done; 1584 Label done;
1585 j(no_overflow, &done, Label::kNear); 1585 j(no_overflow, &done, Label::kNear);
1586 addq(dst, kScratchRegister); 1586 addp(dst, kScratchRegister);
1587 jmp(bailout_label, near_jump); 1587 jmp(bailout_label, near_jump);
1588 bind(&done); 1588 bind(&done);
1589 } else { 1589 } else {
1590 // Bailout if overflow without reserving src. 1590 // Bailout if overflow without reserving src.
1591 j(overflow, bailout_label, near_jump); 1591 j(overflow, bailout_label, near_jump);
1592 } 1592 }
1593 } else { 1593 } else {
1594 CHECK(mode.IsEmpty()); 1594 CHECK(mode.IsEmpty());
1595 } 1595 }
1596 } else { 1596 } else {
1597 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1597 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER));
1598 ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW)); 1598 ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW));
1599 if (constant->value() == Smi::kMinValue) { 1599 if (constant->value() == Smi::kMinValue) {
1600 ASSERT(!dst.is(kScratchRegister)); 1600 ASSERT(!dst.is(kScratchRegister));
1601 movp(dst, src); 1601 movp(dst, src);
1602 LoadSmiConstant(kScratchRegister, constant); 1602 LoadSmiConstant(kScratchRegister, constant);
1603 subq(dst, kScratchRegister); 1603 subp(dst, kScratchRegister);
1604 j(overflow, bailout_label, near_jump); 1604 j(overflow, bailout_label, near_jump);
1605 } else { 1605 } else {
1606 // Subtract by adding the negation. 1606 // Subtract by adding the negation.
1607 LoadSmiConstant(dst, Smi::FromInt(-(constant->value()))); 1607 LoadSmiConstant(dst, Smi::FromInt(-(constant->value())));
1608 addq(dst, src); 1608 addp(dst, src);
1609 j(overflow, bailout_label, near_jump); 1609 j(overflow, bailout_label, near_jump);
1610 } 1610 }
1611 } 1611 }
1612 } 1612 }
1613 1613
1614 1614
1615 void MacroAssembler::SmiNeg(Register dst, 1615 void MacroAssembler::SmiNeg(Register dst,
1616 Register src, 1616 Register src,
1617 Label* on_smi_result, 1617 Label* on_smi_result,
1618 Label::Distance near_jump) { 1618 Label::Distance near_jump) {
(...skipping 17 matching lines...) Expand all
1636 1636
1637 template<class T> 1637 template<class T>
1638 static void SmiAddHelper(MacroAssembler* masm, 1638 static void SmiAddHelper(MacroAssembler* masm,
1639 Register dst, 1639 Register dst,
1640 Register src1, 1640 Register src1,
1641 T src2, 1641 T src2,
1642 Label* on_not_smi_result, 1642 Label* on_not_smi_result,
1643 Label::Distance near_jump) { 1643 Label::Distance near_jump) {
1644 if (dst.is(src1)) { 1644 if (dst.is(src1)) {
1645 Label done; 1645 Label done;
1646 masm->addq(dst, src2); 1646 masm->addp(dst, src2);
1647 masm->j(no_overflow, &done, Label::kNear); 1647 masm->j(no_overflow, &done, Label::kNear);
1648 // Restore src1. 1648 // Restore src1.
1649 masm->subq(dst, src2); 1649 masm->subp(dst, src2);
1650 masm->jmp(on_not_smi_result, near_jump); 1650 masm->jmp(on_not_smi_result, near_jump);
1651 masm->bind(&done); 1651 masm->bind(&done);
1652 } else { 1652 } else {
1653 masm->movp(dst, src1); 1653 masm->movp(dst, src1);
1654 masm->addq(dst, src2); 1654 masm->addp(dst, src2);
1655 masm->j(overflow, on_not_smi_result, near_jump); 1655 masm->j(overflow, on_not_smi_result, near_jump);
1656 } 1656 }
1657 } 1657 }
1658 1658
1659 1659
1660 void MacroAssembler::SmiAdd(Register dst, 1660 void MacroAssembler::SmiAdd(Register dst,
1661 Register src1, 1661 Register src1,
1662 Register src2, 1662 Register src2,
1663 Label* on_not_smi_result, 1663 Label* on_not_smi_result,
1664 Label::Distance near_jump) { 1664 Label::Distance near_jump) {
(...skipping 15 matching lines...) Expand all
1680 1680
1681 1681
1682 void MacroAssembler::SmiAdd(Register dst, 1682 void MacroAssembler::SmiAdd(Register dst,
1683 Register src1, 1683 Register src1,
1684 Register src2) { 1684 Register src2) {
1685 // No overflow checking. Use only when it's known that 1685 // No overflow checking. Use only when it's known that
1686 // overflowing is impossible. 1686 // overflowing is impossible.
1687 if (!dst.is(src1)) { 1687 if (!dst.is(src1)) {
1688 if (emit_debug_code()) { 1688 if (emit_debug_code()) {
1689 movp(kScratchRegister, src1); 1689 movp(kScratchRegister, src1);
1690 addq(kScratchRegister, src2); 1690 addp(kScratchRegister, src2);
1691 Check(no_overflow, kSmiAdditionOverflow); 1691 Check(no_overflow, kSmiAdditionOverflow);
1692 } 1692 }
1693 lea(dst, Operand(src1, src2, times_1, 0)); 1693 lea(dst, Operand(src1, src2, times_1, 0));
1694 } else { 1694 } else {
1695 addq(dst, src2); 1695 addp(dst, src2);
1696 Assert(no_overflow, kSmiAdditionOverflow); 1696 Assert(no_overflow, kSmiAdditionOverflow);
1697 } 1697 }
1698 } 1698 }
1699 1699
1700 1700
1701 template<class T> 1701 template<class T>
1702 static void SmiSubHelper(MacroAssembler* masm, 1702 static void SmiSubHelper(MacroAssembler* masm,
1703 Register dst, 1703 Register dst,
1704 Register src1, 1704 Register src1,
1705 T src2, 1705 T src2,
1706 Label* on_not_smi_result, 1706 Label* on_not_smi_result,
1707 Label::Distance near_jump) { 1707 Label::Distance near_jump) {
1708 if (dst.is(src1)) { 1708 if (dst.is(src1)) {
1709 Label done; 1709 Label done;
1710 masm->subq(dst, src2); 1710 masm->subp(dst, src2);
1711 masm->j(no_overflow, &done, Label::kNear); 1711 masm->j(no_overflow, &done, Label::kNear);
1712 // Restore src1. 1712 // Restore src1.
1713 masm->addq(dst, src2); 1713 masm->addp(dst, src2);
1714 masm->jmp(on_not_smi_result, near_jump); 1714 masm->jmp(on_not_smi_result, near_jump);
1715 masm->bind(&done); 1715 masm->bind(&done);
1716 } else { 1716 } else {
1717 masm->movp(dst, src1); 1717 masm->movp(dst, src1);
1718 masm->subq(dst, src2); 1718 masm->subp(dst, src2);
1719 masm->j(overflow, on_not_smi_result, near_jump); 1719 masm->j(overflow, on_not_smi_result, near_jump);
1720 } 1720 }
1721 } 1721 }
1722 1722
1723 1723
1724 void MacroAssembler::SmiSub(Register dst, 1724 void MacroAssembler::SmiSub(Register dst,
1725 Register src1, 1725 Register src1,
1726 Register src2, 1726 Register src2,
1727 Label* on_not_smi_result, 1727 Label* on_not_smi_result,
1728 Label::Distance near_jump) { 1728 Label::Distance near_jump) {
(...skipping 17 matching lines...) Expand all
1746 template<class T> 1746 template<class T>
1747 static void SmiSubNoOverflowHelper(MacroAssembler* masm, 1747 static void SmiSubNoOverflowHelper(MacroAssembler* masm,
1748 Register dst, 1748 Register dst,
1749 Register src1, 1749 Register src1,
1750 T src2) { 1750 T src2) {
1751 // No overflow checking. Use only when it's known that 1751 // No overflow checking. Use only when it's known that
1752 // overflowing is impossible (e.g., subtracting two positive smis). 1752 // overflowing is impossible (e.g., subtracting two positive smis).
1753 if (!dst.is(src1)) { 1753 if (!dst.is(src1)) {
1754 masm->movp(dst, src1); 1754 masm->movp(dst, src1);
1755 } 1755 }
1756 masm->subq(dst, src2); 1756 masm->subp(dst, src2);
1757 masm->Assert(no_overflow, kSmiSubtractionOverflow); 1757 masm->Assert(no_overflow, kSmiSubtractionOverflow);
1758 } 1758 }
1759 1759
1760 1760
1761 void MacroAssembler::SmiSub(Register dst, Register src1, Register src2) { 1761 void MacroAssembler::SmiSub(Register dst, Register src1, Register src2) {
1762 ASSERT(!dst.is(src2)); 1762 ASSERT(!dst.is(src2));
1763 SmiSubNoOverflowHelper<Register>(this, dst, src1, src2); 1763 SmiSubNoOverflowHelper<Register>(this, dst, src1, src2);
1764 } 1764 }
1765 1765
1766 1766
(...skipping 11 matching lines...) Expand all
1778 Label::Distance near_jump) { 1778 Label::Distance near_jump) {
1779 ASSERT(!dst.is(src2)); 1779 ASSERT(!dst.is(src2));
1780 ASSERT(!dst.is(kScratchRegister)); 1780 ASSERT(!dst.is(kScratchRegister));
1781 ASSERT(!src1.is(kScratchRegister)); 1781 ASSERT(!src1.is(kScratchRegister));
1782 ASSERT(!src2.is(kScratchRegister)); 1782 ASSERT(!src2.is(kScratchRegister));
1783 1783
1784 if (dst.is(src1)) { 1784 if (dst.is(src1)) {
1785 Label failure, zero_correct_result; 1785 Label failure, zero_correct_result;
1786 movp(kScratchRegister, src1); // Create backup for later testing. 1786 movp(kScratchRegister, src1); // Create backup for later testing.
1787 SmiToInteger64(dst, src1); 1787 SmiToInteger64(dst, src1);
1788 imul(dst, src2); 1788 imulp(dst, src2);
1789 j(overflow, &failure, Label::kNear); 1789 j(overflow, &failure, Label::kNear);
1790 1790
1791 // Check for negative zero result. If product is zero, and one 1791 // Check for negative zero result. If product is zero, and one
1792 // argument is negative, go to slow case. 1792 // argument is negative, go to slow case.
1793 Label correct_result; 1793 Label correct_result;
1794 testq(dst, dst); 1794 testq(dst, dst);
1795 j(not_zero, &correct_result, Label::kNear); 1795 j(not_zero, &correct_result, Label::kNear);
1796 1796
1797 movp(dst, kScratchRegister); 1797 movp(dst, kScratchRegister);
1798 xor_(dst, src2); 1798 xor_(dst, src2);
1799 // Result was positive zero. 1799 // Result was positive zero.
1800 j(positive, &zero_correct_result, Label::kNear); 1800 j(positive, &zero_correct_result, Label::kNear);
1801 1801
1802 bind(&failure); // Reused failure exit, restores src1. 1802 bind(&failure); // Reused failure exit, restores src1.
1803 movp(src1, kScratchRegister); 1803 movp(src1, kScratchRegister);
1804 jmp(on_not_smi_result, near_jump); 1804 jmp(on_not_smi_result, near_jump);
1805 1805
1806 bind(&zero_correct_result); 1806 bind(&zero_correct_result);
1807 Set(dst, 0); 1807 Set(dst, 0);
1808 1808
1809 bind(&correct_result); 1809 bind(&correct_result);
1810 } else { 1810 } else {
1811 SmiToInteger64(dst, src1); 1811 SmiToInteger64(dst, src1);
1812 imul(dst, src2); 1812 imulp(dst, src2);
1813 j(overflow, on_not_smi_result, near_jump); 1813 j(overflow, on_not_smi_result, near_jump);
1814 // Check for negative zero result. If product is zero, and one 1814 // Check for negative zero result. If product is zero, and one
1815 // argument is negative, go to slow case. 1815 // argument is negative, go to slow case.
1816 Label correct_result; 1816 Label correct_result;
1817 testq(dst, dst); 1817 testq(dst, dst);
1818 j(not_zero, &correct_result, Label::kNear); 1818 j(not_zero, &correct_result, Label::kNear);
1819 // One of src1 and src2 is zero, the check whether the other is 1819 // One of src1 and src2 is zero, the check whether the other is
1820 // negative. 1820 // negative.
1821 movp(kScratchRegister, src1); 1821 movp(kScratchRegister, src1);
1822 xor_(kScratchRegister, src2); 1822 xor_(kScratchRegister, src2);
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
2169 ASSERT_EQ(0, Smi::FromInt(0)); 2169 ASSERT_EQ(0, Smi::FromInt(0));
2170 movl(kScratchRegister, Immediate(kSmiTagMask)); 2170 movl(kScratchRegister, Immediate(kSmiTagMask));
2171 and_(kScratchRegister, src1); 2171 and_(kScratchRegister, src1);
2172 testl(kScratchRegister, src2); 2172 testl(kScratchRegister, src2);
2173 // If non-zero then both are smis. 2173 // If non-zero then both are smis.
2174 j(not_zero, on_not_smis, near_jump); 2174 j(not_zero, on_not_smis, near_jump);
2175 2175
2176 // Exactly one operand is a smi. 2176 // Exactly one operand is a smi.
2177 ASSERT_EQ(1, static_cast<int>(kSmiTagMask)); 2177 ASSERT_EQ(1, static_cast<int>(kSmiTagMask));
2178 // kScratchRegister still holds src1 & kSmiTag, which is either zero or one. 2178 // kScratchRegister still holds src1 & kSmiTag, which is either zero or one.
2179 subq(kScratchRegister, Immediate(1)); 2179 subp(kScratchRegister, Immediate(1));
2180 // If src1 is a smi, then scratch register all 1s, else it is all 0s. 2180 // If src1 is a smi, then scratch register all 1s, else it is all 0s.
2181 movp(dst, src1); 2181 movp(dst, src1);
2182 xor_(dst, src2); 2182 xor_(dst, src2);
2183 and_(dst, kScratchRegister); 2183 and_(dst, kScratchRegister);
2184 // If src1 is a smi, dst holds src1 ^ src2, else it is zero. 2184 // If src1 is a smi, dst holds src1 ^ src2, else it is zero.
2185 xor_(dst, src1); 2185 xor_(dst, src1);
2186 // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi. 2186 // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi.
2187 } 2187 }
2188 2188
2189 2189
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2282 Register scratch = scratch2; 2282 Register scratch = scratch2;
2283 2283
2284 // Load the number string cache. 2284 // Load the number string cache.
2285 LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); 2285 LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
2286 2286
2287 // Make the hash mask from the length of the number string cache. It 2287 // Make the hash mask from the length of the number string cache. It
2288 // contains two elements (number and string) for each cache entry. 2288 // contains two elements (number and string) for each cache entry.
2289 SmiToInteger32( 2289 SmiToInteger32(
2290 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 2290 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
2291 shrl(mask, Immediate(1)); 2291 shrl(mask, Immediate(1));
2292 subq(mask, Immediate(1)); // Make mask. 2292 subp(mask, Immediate(1)); // Make mask.
2293 2293
2294 // Calculate the entry in the number string cache. The hash value in the 2294 // Calculate the entry in the number string cache. The hash value in the
2295 // number string cache for smis is just the smi value, and the hash for 2295 // number string cache for smis is just the smi value, and the hash for
2296 // doubles is the xor of the upper and lower words. See 2296 // doubles is the xor of the upper and lower words. See
2297 // Heap::GetNumberStringCache. 2297 // Heap::GetNumberStringCache.
2298 Label is_smi; 2298 Label is_smi;
2299 Label load_result_from_cache; 2299 Label load_result_from_cache;
2300 JumpIfSmi(object, &is_smi); 2300 JumpIfSmi(object, &is_smi);
2301 CheckMap(object, 2301 CheckMap(object,
2302 isolate()->factory()->heap_number_map(), 2302 isolate()->factory()->heap_number_map(),
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
2560 load_rax(cell.location(), RelocInfo::CELL); 2560 load_rax(cell.location(), RelocInfo::CELL);
2561 } else { 2561 } else {
2562 Move(dst, cell, RelocInfo::CELL); 2562 Move(dst, cell, RelocInfo::CELL);
2563 movp(dst, Operand(dst, 0)); 2563 movp(dst, Operand(dst, 0));
2564 } 2564 }
2565 } 2565 }
2566 2566
2567 2567
2568 void MacroAssembler::Drop(int stack_elements) { 2568 void MacroAssembler::Drop(int stack_elements) {
2569 if (stack_elements > 0) { 2569 if (stack_elements > 0) {
2570 addq(rsp, Immediate(stack_elements * kPointerSize)); 2570 addp(rsp, Immediate(stack_elements * kPointerSize));
2571 } 2571 }
2572 } 2572 }
2573 2573
2574 2574
2575 void MacroAssembler::Push(Register src) { 2575 void MacroAssembler::Push(Register src) {
2576 if (kPointerSize == kInt64Size) { 2576 if (kPointerSize == kInt64Size) {
2577 pushq(src); 2577 pushq(src);
2578 } else { 2578 } else {
2579 ASSERT(kPointerSize == kInt32Size); 2579 ASSERT(kPointerSize == kInt32Size);
2580 // x32 uses 64-bit push for rbp in the prologue. 2580 // x32 uses 64-bit push for rbp in the prologue.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2637 popq(dst); 2637 popq(dst);
2638 } else { 2638 } else {
2639 ASSERT(kPointerSize == kInt32Size); 2639 ASSERT(kPointerSize == kInt32Size);
2640 Register scratch = dst.AddressUsesRegister(kScratchRegister) 2640 Register scratch = dst.AddressUsesRegister(kScratchRegister)
2641 ? kSmiConstantRegister : kScratchRegister; 2641 ? kSmiConstantRegister : kScratchRegister;
2642 movp(scratch, Operand(rsp, 0)); 2642 movp(scratch, Operand(rsp, 0));
2643 movp(dst, scratch); 2643 movp(dst, scratch);
2644 leal(rsp, Operand(rsp, 4)); 2644 leal(rsp, Operand(rsp, 4));
2645 if (scratch.is(kSmiConstantRegister)) { 2645 if (scratch.is(kSmiConstantRegister)) {
2646 // Restore kSmiConstantRegister. 2646 // Restore kSmiConstantRegister.
2647 movp(kSmiConstantRegister, Smi::FromInt(kSmiConstantRegisterValue), 2647 movp(kSmiConstantRegister,
2648 reinterpret_cast<void*>(Smi::FromInt(kSmiConstantRegisterValue)),
2648 Assembler::RelocInfoNone()); 2649 Assembler::RelocInfoNone());
2649 } 2650 }
2650 } 2651 }
2651 } 2652 }
2652 2653
2653 2654
2654 void MacroAssembler::TestBit(const Operand& src, int bits) { 2655 void MacroAssembler::TestBit(const Operand& src, int bits) {
2655 int byte_offset = bits / kBitsPerByte; 2656 int byte_offset = bits / kBitsPerByte;
2656 int bit_in_byte = bits & (kBitsPerByte - 1); 2657 int bit_in_byte = bits & (kBitsPerByte - 1);
2657 testb(Operand(src, byte_offset), Immediate(1 << bit_in_byte)); 2658 testb(Operand(src, byte_offset), Immediate(1 << bit_in_byte));
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2781 Pop(rdi); 2782 Pop(rdi);
2782 Pop(rsi); 2783 Pop(rsi);
2783 Pop(rbx); 2784 Pop(rbx);
2784 Pop(rdx); 2785 Pop(rdx);
2785 Pop(rcx); 2786 Pop(rcx);
2786 Pop(rax); 2787 Pop(rax);
2787 } 2788 }
2788 2789
2789 2790
2790 void MacroAssembler::Dropad() { 2791 void MacroAssembler::Dropad() {
2791 addq(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); 2792 addp(rsp, Immediate(kNumSafepointRegisters * kPointerSize));
2792 } 2793 }
2793 2794
2794 2795
2795 // Order general registers are pushed by Pushad: 2796 // Order general registers are pushed by Pushad:
2796 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. 2797 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
2797 const int 2798 const int
2798 MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { 2799 MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = {
2799 0, 2800 0,
2800 1, 2801 1,
2801 2, 2802 2,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2872 Push(ExternalOperand(handler_address)); 2873 Push(ExternalOperand(handler_address));
2873 // Set this new handler as the current one. 2874 // Set this new handler as the current one.
2874 movp(ExternalOperand(handler_address), rsp); 2875 movp(ExternalOperand(handler_address), rsp);
2875 } 2876 }
2876 2877
2877 2878
2878 void MacroAssembler::PopTryHandler() { 2879 void MacroAssembler::PopTryHandler() {
2879 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 2880 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
2880 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 2881 ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
2881 Pop(ExternalOperand(handler_address)); 2882 Pop(ExternalOperand(handler_address));
2882 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 2883 addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
2883 } 2884 }
2884 2885
2885 2886
2886 void MacroAssembler::JumpToHandlerEntry() { 2887 void MacroAssembler::JumpToHandlerEntry() {
2887 // Compute the handler entry address and jump to it. The handler table is 2888 // Compute the handler entry address and jump to it. The handler table is
2888 // a fixed array of (smi-tagged) code offsets. 2889 // a fixed array of (smi-tagged) code offsets.
2889 // rax = exception, rdi = code object, rdx = state. 2890 // rax = exception, rdi = code object, rdx = state.
2890 movp(rbx, FieldOperand(rdi, Code::kHandlerTableOffset)); 2891 movp(rbx, FieldOperand(rdi, Code::kHandlerTableOffset));
2891 shr(rdx, Immediate(StackHandler::kKindWidth)); 2892 shr(rdx, Immediate(StackHandler::kKindWidth));
2892 movp(rdx, 2893 movp(rdx,
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2986 void MacroAssembler::Ret() { 2987 void MacroAssembler::Ret() {
2987 ret(0); 2988 ret(0);
2988 } 2989 }
2989 2990
2990 2991
2991 void MacroAssembler::Ret(int bytes_dropped, Register scratch) { 2992 void MacroAssembler::Ret(int bytes_dropped, Register scratch) {
2992 if (is_uint16(bytes_dropped)) { 2993 if (is_uint16(bytes_dropped)) {
2993 ret(bytes_dropped); 2994 ret(bytes_dropped);
2994 } else { 2995 } else {
2995 PopReturnAddressTo(scratch); 2996 PopReturnAddressTo(scratch);
2996 addq(rsp, Immediate(bytes_dropped)); 2997 addp(rsp, Immediate(bytes_dropped));
2997 PushReturnAddressFrom(scratch); 2998 PushReturnAddressFrom(scratch);
2998 ret(0); 2999 ret(0);
2999 } 3000 }
3000 } 3001 }
3001 3002
3002 3003
3003 void MacroAssembler::FCmp() { 3004 void MacroAssembler::FCmp() {
3004 fucomip(); 3005 fucomip();
3005 fstp(0); 3006 fstp(0);
3006 } 3007 }
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
3192 Register input_reg) { 3193 Register input_reg) {
3193 Label done; 3194 Label done;
3194 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3195 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
3195 cvttsd2siq(result_reg, xmm0); 3196 cvttsd2siq(result_reg, xmm0);
3196 Set(kScratchRegister, V8_UINT64_C(0x8000000000000000)); 3197 Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
3197 cmpq(result_reg, kScratchRegister); 3198 cmpq(result_reg, kScratchRegister);
3198 j(not_equal, &done, Label::kNear); 3199 j(not_equal, &done, Label::kNear);
3199 3200
3200 // Slow case. 3201 // Slow case.
3201 if (input_reg.is(result_reg)) { 3202 if (input_reg.is(result_reg)) {
3202 subq(rsp, Immediate(kDoubleSize)); 3203 subp(rsp, Immediate(kDoubleSize));
3203 movsd(MemOperand(rsp, 0), xmm0); 3204 movsd(MemOperand(rsp, 0), xmm0);
3204 SlowTruncateToI(result_reg, rsp, 0); 3205 SlowTruncateToI(result_reg, rsp, 0);
3205 addq(rsp, Immediate(kDoubleSize)); 3206 addp(rsp, Immediate(kDoubleSize));
3206 } else { 3207 } else {
3207 SlowTruncateToI(result_reg, input_reg); 3208 SlowTruncateToI(result_reg, input_reg);
3208 } 3209 }
3209 3210
3210 bind(&done); 3211 bind(&done);
3211 } 3212 }
3212 3213
3213 3214
3214 void MacroAssembler::TruncateDoubleToI(Register result_reg, 3215 void MacroAssembler::TruncateDoubleToI(Register result_reg,
3215 XMMRegister input_reg) { 3216 XMMRegister input_reg) {
3216 Label done; 3217 Label done;
3217 cvttsd2siq(result_reg, input_reg); 3218 cvttsd2siq(result_reg, input_reg);
3218 movq(kScratchRegister, V8_INT64_C(0x8000000000000000)); 3219 movq(kScratchRegister, V8_INT64_C(0x8000000000000000));
3219 cmpq(result_reg, kScratchRegister); 3220 cmpq(result_reg, kScratchRegister);
3220 j(not_equal, &done, Label::kNear); 3221 j(not_equal, &done, Label::kNear);
3221 3222
3222 subq(rsp, Immediate(kDoubleSize)); 3223 subp(rsp, Immediate(kDoubleSize));
3223 movsd(MemOperand(rsp, 0), input_reg); 3224 movsd(MemOperand(rsp, 0), input_reg);
3224 SlowTruncateToI(result_reg, rsp, 0); 3225 SlowTruncateToI(result_reg, rsp, 0);
3225 addq(rsp, Immediate(kDoubleSize)); 3226 addp(rsp, Immediate(kDoubleSize));
3226 3227
3227 bind(&done); 3228 bind(&done);
3228 } 3229 }
3229 3230
3230 3231
3231 void MacroAssembler::DoubleToI(Register result_reg, 3232 void MacroAssembler::DoubleToI(Register result_reg,
3232 XMMRegister input_reg, 3233 XMMRegister input_reg,
3233 XMMRegister scratch, 3234 XMMRegister scratch,
3234 MinusZeroMode minus_zero_mode, 3235 MinusZeroMode minus_zero_mode,
3235 Label* conversion_failed, 3236 Label* conversion_failed,
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
3709 j(equal, &invoke, Label::kNear); 3710 j(equal, &invoke, Label::kNear);
3710 ASSERT(actual.reg().is(rax)); 3711 ASSERT(actual.reg().is(rax));
3711 ASSERT(expected.reg().is(rbx)); 3712 ASSERT(expected.reg().is(rbx));
3712 } 3713 }
3713 } 3714 }
3714 3715
3715 if (!definitely_matches) { 3716 if (!definitely_matches) {
3716 Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); 3717 Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
3717 if (!code_constant.is_null()) { 3718 if (!code_constant.is_null()) {
3718 Move(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); 3719 Move(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT);
3719 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 3720 addp(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
3720 } else if (!code_register.is(rdx)) { 3721 } else if (!code_register.is(rdx)) {
3721 movp(rdx, code_register); 3722 movp(rdx, code_register);
3722 } 3723 }
3723 3724
3724 if (flag == CALL_FUNCTION) { 3725 if (flag == CALL_FUNCTION) {
3725 call_wrapper.BeforeCall(CallSize(adaptor)); 3726 call_wrapper.BeforeCall(CallSize(adaptor));
3726 Call(adaptor, RelocInfo::CODE_TARGET); 3727 Call(adaptor, RelocInfo::CODE_TARGET);
3727 call_wrapper.AfterCall(); 3728 call_wrapper.AfterCall();
3728 if (!*definitely_mismatches) { 3729 if (!*definitely_mismatches) {
3729 jmp(done, near_jump); 3730 jmp(done, near_jump);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
3817 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, 3818 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
3818 bool save_doubles) { 3819 bool save_doubles) {
3819 #ifdef _WIN64 3820 #ifdef _WIN64
3820 const int kShadowSpace = 4; 3821 const int kShadowSpace = 4;
3821 arg_stack_space += kShadowSpace; 3822 arg_stack_space += kShadowSpace;
3822 #endif 3823 #endif
3823 // Optionally save all XMM registers. 3824 // Optionally save all XMM registers.
3824 if (save_doubles) { 3825 if (save_doubles) {
3825 int space = XMMRegister::kMaxNumAllocatableRegisters * kDoubleSize + 3826 int space = XMMRegister::kMaxNumAllocatableRegisters * kDoubleSize +
3826 arg_stack_space * kRegisterSize; 3827 arg_stack_space * kRegisterSize;
3827 subq(rsp, Immediate(space)); 3828 subp(rsp, Immediate(space));
3828 int offset = -2 * kPointerSize; 3829 int offset = -2 * kPointerSize;
3829 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { 3830 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) {
3830 XMMRegister reg = XMMRegister::FromAllocationIndex(i); 3831 XMMRegister reg = XMMRegister::FromAllocationIndex(i);
3831 movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); 3832 movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg);
3832 } 3833 }
3833 } else if (arg_stack_space > 0) { 3834 } else if (arg_stack_space > 0) {
3834 subq(rsp, Immediate(arg_stack_space * kRegisterSize)); 3835 subp(rsp, Immediate(arg_stack_space * kRegisterSize));
3835 } 3836 }
3836 3837
3837 // Get the required frame alignment for the OS. 3838 // Get the required frame alignment for the OS.
3838 const int kFrameAlignment = OS::ActivationFrameAlignment(); 3839 const int kFrameAlignment = OS::ActivationFrameAlignment();
3839 if (kFrameAlignment > 0) { 3840 if (kFrameAlignment > 0) {
3840 ASSERT(IsPowerOf2(kFrameAlignment)); 3841 ASSERT(IsPowerOf2(kFrameAlignment));
3841 ASSERT(is_int8(kFrameAlignment)); 3842 ASSERT(is_int8(kFrameAlignment));
3842 and_(rsp, Immediate(-kFrameAlignment)); 3843 and_(rsp, Immediate(-kFrameAlignment));
3843 } 3844 }
3844 3845
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
4186 4187
4187 // Calculate new top and bail out if new space is exhausted. 4188 // Calculate new top and bail out if new space is exhausted.
4188 ExternalReference allocation_limit = 4189 ExternalReference allocation_limit =
4189 AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4190 AllocationUtils::GetAllocationLimitReference(isolate(), flags);
4190 4191
4191 Register top_reg = result_end.is_valid() ? result_end : result; 4192 Register top_reg = result_end.is_valid() ? result_end : result;
4192 4193
4193 if (!top_reg.is(result)) { 4194 if (!top_reg.is(result)) {
4194 movp(top_reg, result); 4195 movp(top_reg, result);
4195 } 4196 }
4196 addq(top_reg, Immediate(object_size)); 4197 addp(top_reg, Immediate(object_size));
4197 j(carry, gc_required); 4198 j(carry, gc_required);
4198 Operand limit_operand = ExternalOperand(allocation_limit); 4199 Operand limit_operand = ExternalOperand(allocation_limit);
4199 cmpq(top_reg, limit_operand); 4200 cmpq(top_reg, limit_operand);
4200 j(above, gc_required); 4201 j(above, gc_required);
4201 4202
4202 // Update allocation top. 4203 // Update allocation top.
4203 UpdateAllocationTopHelper(top_reg, scratch, flags); 4204 UpdateAllocationTopHelper(top_reg, scratch, flags);
4204 4205
4205 bool tag_result = (flags & TAG_OBJECT) != 0; 4206 bool tag_result = (flags & TAG_OBJECT) != 0;
4206 if (top_reg.is(result)) { 4207 if (top_reg.is(result)) {
4207 if (tag_result) { 4208 if (tag_result) {
4208 subq(result, Immediate(object_size - kHeapObjectTag)); 4209 subp(result, Immediate(object_size - kHeapObjectTag));
4209 } else { 4210 } else {
4210 subq(result, Immediate(object_size)); 4211 subp(result, Immediate(object_size));
4211 } 4212 }
4212 } else if (tag_result) { 4213 } else if (tag_result) {
4213 // Tag the result if requested. 4214 // Tag the result if requested.
4214 ASSERT(kHeapObjectTag == 1); 4215 ASSERT(kHeapObjectTag == 1);
4215 incq(result); 4216 incq(result);
4216 } 4217 }
4217 } 4218 }
4218 4219
4219 4220
4220 void MacroAssembler::Allocate(int header_size, 4221 void MacroAssembler::Allocate(int header_size,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4262 testq(result, Immediate(kDoubleAlignmentMask)); 4263 testq(result, Immediate(kDoubleAlignmentMask));
4263 Check(zero, kAllocationIsNotDoubleAligned); 4264 Check(zero, kAllocationIsNotDoubleAligned);
4264 } 4265 }
4265 4266
4266 // Calculate new top and bail out if new space is exhausted. 4267 // Calculate new top and bail out if new space is exhausted.
4267 ExternalReference allocation_limit = 4268 ExternalReference allocation_limit =
4268 AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4269 AllocationUtils::GetAllocationLimitReference(isolate(), flags);
4269 if (!object_size.is(result_end)) { 4270 if (!object_size.is(result_end)) {
4270 movp(result_end, object_size); 4271 movp(result_end, object_size);
4271 } 4272 }
4272 addq(result_end, result); 4273 addp(result_end, result);
4273 j(carry, gc_required); 4274 j(carry, gc_required);
4274 Operand limit_operand = ExternalOperand(allocation_limit); 4275 Operand limit_operand = ExternalOperand(allocation_limit);
4275 cmpq(result_end, limit_operand); 4276 cmpq(result_end, limit_operand);
4276 j(above, gc_required); 4277 j(above, gc_required);
4277 4278
4278 // Update allocation top. 4279 // Update allocation top.
4279 UpdateAllocationTopHelper(result_end, scratch, flags); 4280 UpdateAllocationTopHelper(result_end, scratch, flags);
4280 4281
4281 // Tag the result if requested. 4282 // Tag the result if requested.
4282 if ((flags & TAG_OBJECT) != 0) { 4283 if ((flags & TAG_OBJECT) != 0) {
4283 addq(result, Immediate(kHeapObjectTag)); 4284 addp(result, Immediate(kHeapObjectTag));
4284 } 4285 }
4285 } 4286 }
4286 4287
4287 4288
4288 void MacroAssembler::UndoAllocationInNewSpace(Register object) { 4289 void MacroAssembler::UndoAllocationInNewSpace(Register object) {
4289 ExternalReference new_space_allocation_top = 4290 ExternalReference new_space_allocation_top =
4290 ExternalReference::new_space_allocation_top_address(isolate()); 4291 ExternalReference::new_space_allocation_top_address(isolate());
4291 4292
4292 // Make sure the object has no tag before resetting top. 4293 // Make sure the object has no tag before resetting top.
4293 and_(object, Immediate(~kHeapObjectTagMask)); 4294 and_(object, Immediate(~kHeapObjectTagMask));
(...skipping 27 matching lines...) Expand all
4321 // Calculate the number of bytes needed for the characters in the string while 4322 // Calculate the number of bytes needed for the characters in the string while
4322 // observing object alignment. 4323 // observing object alignment.
4323 const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & 4324 const int kHeaderAlignment = SeqTwoByteString::kHeaderSize &
4324 kObjectAlignmentMask; 4325 kObjectAlignmentMask;
4325 ASSERT(kShortSize == 2); 4326 ASSERT(kShortSize == 2);
4326 // scratch1 = length * 2 + kObjectAlignmentMask. 4327 // scratch1 = length * 2 + kObjectAlignmentMask.
4327 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + 4328 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask +
4328 kHeaderAlignment)); 4329 kHeaderAlignment));
4329 and_(scratch1, Immediate(~kObjectAlignmentMask)); 4330 and_(scratch1, Immediate(~kObjectAlignmentMask));
4330 if (kHeaderAlignment > 0) { 4331 if (kHeaderAlignment > 0) {
4331 subq(scratch1, Immediate(kHeaderAlignment)); 4332 subp(scratch1, Immediate(kHeaderAlignment));
4332 } 4333 }
4333 4334
4334 // Allocate two byte string in new space. 4335 // Allocate two byte string in new space.
4335 Allocate(SeqTwoByteString::kHeaderSize, 4336 Allocate(SeqTwoByteString::kHeaderSize,
4336 times_1, 4337 times_1,
4337 scratch1, 4338 scratch1,
4338 result, 4339 result,
4339 scratch2, 4340 scratch2,
4340 scratch3, 4341 scratch3,
4341 gc_required, 4342 gc_required,
(...skipping 14 matching lines...) Expand all
4356 Register scratch1, 4357 Register scratch1,
4357 Register scratch2, 4358 Register scratch2,
4358 Register scratch3, 4359 Register scratch3,
4359 Label* gc_required) { 4360 Label* gc_required) {
4360 // Calculate the number of bytes needed for the characters in the string while 4361 // Calculate the number of bytes needed for the characters in the string while
4361 // observing object alignment. 4362 // observing object alignment.
4362 const int kHeaderAlignment = SeqOneByteString::kHeaderSize & 4363 const int kHeaderAlignment = SeqOneByteString::kHeaderSize &
4363 kObjectAlignmentMask; 4364 kObjectAlignmentMask;
4364 movl(scratch1, length); 4365 movl(scratch1, length);
4365 ASSERT(kCharSize == 1); 4366 ASSERT(kCharSize == 1);
4366 addq(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); 4367 addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment));
4367 and_(scratch1, Immediate(~kObjectAlignmentMask)); 4368 and_(scratch1, Immediate(~kObjectAlignmentMask));
4368 if (kHeaderAlignment > 0) { 4369 if (kHeaderAlignment > 0) {
4369 subq(scratch1, Immediate(kHeaderAlignment)); 4370 subp(scratch1, Immediate(kHeaderAlignment));
4370 } 4371 }
4371 4372
4372 // Allocate ASCII string in new space. 4373 // Allocate ASCII string in new space.
4373 Allocate(SeqOneByteString::kHeaderSize, 4374 Allocate(SeqOneByteString::kHeaderSize,
4374 times_1, 4375 times_1,
4375 scratch1, 4376 scratch1,
4376 result, 4377 result,
4377 scratch2, 4378 scratch2,
4378 scratch3, 4379 scratch3,
4379 gc_required, 4380 gc_required,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
4510 // Because source is 8-byte aligned in our uses of this function, 4511 // Because source is 8-byte aligned in our uses of this function,
4511 // we keep source aligned for the rep movs operation by copying the odd bytes 4512 // we keep source aligned for the rep movs operation by copying the odd bytes
4512 // at the end of the ranges. 4513 // at the end of the ranges.
4513 movp(scratch, length); 4514 movp(scratch, length);
4514 shrl(length, Immediate(kPointerSizeLog2)); 4515 shrl(length, Immediate(kPointerSizeLog2));
4515 repmovsq(); 4516 repmovsq();
4516 // Move remaining bytes of length. 4517 // Move remaining bytes of length.
4517 andl(scratch, Immediate(kPointerSize - 1)); 4518 andl(scratch, Immediate(kPointerSize - 1));
4518 movp(length, Operand(source, scratch, times_1, -kPointerSize)); 4519 movp(length, Operand(source, scratch, times_1, -kPointerSize));
4519 movp(Operand(destination, scratch, times_1, -kPointerSize), length); 4520 movp(Operand(destination, scratch, times_1, -kPointerSize), length);
4520 addq(destination, scratch); 4521 addp(destination, scratch);
4521 4522
4522 if (min_length <= kLongStringLimit) { 4523 if (min_length <= kLongStringLimit) {
4523 jmp(&done, Label::kNear); 4524 jmp(&done, Label::kNear);
4524 bind(&len24); 4525 bind(&len24);
4525 movp(scratch, Operand(source, 2 * kPointerSize)); 4526 movp(scratch, Operand(source, 2 * kPointerSize));
4526 movp(Operand(destination, 2 * kPointerSize), scratch); 4527 movp(Operand(destination, 2 * kPointerSize), scratch);
4527 bind(&len16); 4528 bind(&len16);
4528 movp(scratch, Operand(source, kPointerSize)); 4529 movp(scratch, Operand(source, kPointerSize));
4529 movp(Operand(destination, kPointerSize), scratch); 4530 movp(Operand(destination, kPointerSize), scratch);
4530 bind(&len8); 4531 bind(&len8);
4531 movp(scratch, Operand(source, 0)); 4532 movp(scratch, Operand(source, 0));
4532 movp(Operand(destination, 0), scratch); 4533 movp(Operand(destination, 0), scratch);
4533 // Move remaining bytes of length. 4534 // Move remaining bytes of length.
4534 movp(scratch, Operand(source, length, times_1, -kPointerSize)); 4535 movp(scratch, Operand(source, length, times_1, -kPointerSize));
4535 movp(Operand(destination, length, times_1, -kPointerSize), scratch); 4536 movp(Operand(destination, length, times_1, -kPointerSize), scratch);
4536 addq(destination, length); 4537 addp(destination, length);
4537 jmp(&done, Label::kNear); 4538 jmp(&done, Label::kNear);
4538 4539
4539 bind(&short_string); 4540 bind(&short_string);
4540 if (min_length == 0) { 4541 if (min_length == 0) {
4541 testl(length, length); 4542 testl(length, length);
4542 j(zero, &done, Label::kNear); 4543 j(zero, &done, Label::kNear);
4543 } 4544 }
4544 4545
4545 bind(&short_loop); 4546 bind(&short_loop);
4546 movb(scratch, Operand(source, 0)); 4547 movb(scratch, Operand(source, 0));
4547 movb(Operand(destination, 0), scratch); 4548 movb(Operand(destination, 0), scratch);
4548 incq(source); 4549 incq(source);
4549 incq(destination); 4550 incq(destination);
4550 decl(length); 4551 decl(length);
4551 j(not_zero, &short_loop); 4552 j(not_zero, &short_loop);
4552 } 4553 }
4553 4554
4554 bind(&done); 4555 bind(&done);
4555 } 4556 }
4556 4557
4557 4558
4558 void MacroAssembler::InitializeFieldsWithFiller(Register start_offset, 4559 void MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
4559 Register end_offset, 4560 Register end_offset,
4560 Register filler) { 4561 Register filler) {
4561 Label loop, entry; 4562 Label loop, entry;
4562 jmp(&entry); 4563 jmp(&entry);
4563 bind(&loop); 4564 bind(&loop);
4564 movp(Operand(start_offset, 0), filler); 4565 movp(Operand(start_offset, 0), filler);
4565 addq(start_offset, Immediate(kPointerSize)); 4566 addp(start_offset, Immediate(kPointerSize));
4566 bind(&entry); 4567 bind(&entry);
4567 cmpq(start_offset, end_offset); 4568 cmpq(start_offset, end_offset);
4568 j(less, &loop); 4569 j(less, &loop);
4569 } 4570 }
4570 4571
4571 4572
4572 void MacroAssembler::LoadContext(Register dst, int context_chain_length) { 4573 void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
4573 if (context_chain_length > 0) { 4574 if (context_chain_length > 0) {
4574 // Move up the chain of contexts to the context containing the slot. 4575 // Move up the chain of contexts to the context containing the slot.
4575 movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 4576 movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX)));
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
4709 void MacroAssembler::PrepareCallCFunction(int num_arguments) { 4710 void MacroAssembler::PrepareCallCFunction(int num_arguments) {
4710 int frame_alignment = OS::ActivationFrameAlignment(); 4711 int frame_alignment = OS::ActivationFrameAlignment();
4711 ASSERT(frame_alignment != 0); 4712 ASSERT(frame_alignment != 0);
4712 ASSERT(num_arguments >= 0); 4713 ASSERT(num_arguments >= 0);
4713 4714
4714 // Make stack end at alignment and allocate space for arguments and old rsp. 4715 // Make stack end at alignment and allocate space for arguments and old rsp.
4715 movp(kScratchRegister, rsp); 4716 movp(kScratchRegister, rsp);
4716 ASSERT(IsPowerOf2(frame_alignment)); 4717 ASSERT(IsPowerOf2(frame_alignment));
4717 int argument_slots_on_stack = 4718 int argument_slots_on_stack =
4718 ArgumentStackSlotsForCFunctionCall(num_arguments); 4719 ArgumentStackSlotsForCFunctionCall(num_arguments);
4719 subq(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize)); 4720 subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize));
4720 and_(rsp, Immediate(-frame_alignment)); 4721 and_(rsp, Immediate(-frame_alignment));
4721 movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister); 4722 movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister);
4722 } 4723 }
4723 4724
4724 4725
4725 void MacroAssembler::CallCFunction(ExternalReference function, 4726 void MacroAssembler::CallCFunction(ExternalReference function,
4726 int num_arguments) { 4727 int num_arguments) {
4727 LoadAddress(rax, function); 4728 LoadAddress(rax, function);
4728 CallCFunction(rax, num_arguments); 4729 CallCFunction(rax, num_arguments);
4729 } 4730 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4867 // Sign extended 32 bit immediate. 4868 // Sign extended 32 bit immediate.
4868 and_(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 4869 and_(bitmap_reg, Immediate(~Page::kPageAlignmentMask));
4869 movp(rcx, addr_reg); 4870 movp(rcx, addr_reg);
4870 int shift = 4871 int shift =
4871 Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 4872 Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2;
4872 shrl(rcx, Immediate(shift)); 4873 shrl(rcx, Immediate(shift));
4873 and_(rcx, 4874 and_(rcx,
4874 Immediate((Page::kPageAlignmentMask >> shift) & 4875 Immediate((Page::kPageAlignmentMask >> shift) &
4875 ~(Bitmap::kBytesPerCell - 1))); 4876 ~(Bitmap::kBytesPerCell - 1)));
4876 4877
4877 addq(bitmap_reg, rcx); 4878 addp(bitmap_reg, rcx);
4878 movp(rcx, addr_reg); 4879 movp(rcx, addr_reg);
4879 shrl(rcx, Immediate(kPointerSizeLog2)); 4880 shrl(rcx, Immediate(kPointerSizeLog2));
4880 and_(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 4881 and_(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1));
4881 movl(mask_reg, Immediate(1)); 4882 movl(mask_reg, Immediate(1));
4882 shl_cl(mask_reg); 4883 shl_cl(mask_reg);
4883 } 4884 }
4884 4885
4885 4886
4886 void MacroAssembler::EnsureNotWhite( 4887 void MacroAssembler::EnsureNotWhite(
4887 Register value, 4888 Register value,
(...skipping 15 matching lines...) Expand all
4903 // Since both black and grey have a 1 in the first position and white does 4904 // Since both black and grey have a 1 in the first position and white does
4904 // not have a 1 there we only need to check one bit. 4905 // not have a 1 there we only need to check one bit.
4905 testq(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 4906 testq(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
4906 j(not_zero, &done, Label::kNear); 4907 j(not_zero, &done, Label::kNear);
4907 4908
4908 if (emit_debug_code()) { 4909 if (emit_debug_code()) {
4909 // Check for impossible bit pattern. 4910 // Check for impossible bit pattern.
4910 Label ok; 4911 Label ok;
4911 Push(mask_scratch); 4912 Push(mask_scratch);
4912 // shl. May overflow making the check conservative. 4913 // shl. May overflow making the check conservative.
4913 addq(mask_scratch, mask_scratch); 4914 addp(mask_scratch, mask_scratch);
4914 testq(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 4915 testq(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
4915 j(zero, &ok, Label::kNear); 4916 j(zero, &ok, Label::kNear);
4916 int3(); 4917 int3();
4917 bind(&ok); 4918 bind(&ok);
4918 Pop(mask_scratch); 4919 Pop(mask_scratch);
4919 } 4920 }
4920 4921
4921 // Value is white. We check whether it is data that doesn't need scanning. 4922 // Value is white. We check whether it is data that doesn't need scanning.
4922 // Currently only checks for HeapNumber and non-cons strings. 4923 // Currently only checks for HeapNumber and non-cons strings.
4923 Register map = rcx; // Holds map while checking type. 4924 Register map = rcx; // Holds map while checking type.
(...skipping 29 matching lines...) Expand all
4953 testb(instance_type, Immediate(kExternalStringTag)); 4954 testb(instance_type, Immediate(kExternalStringTag));
4954 j(zero, &not_external, Label::kNear); 4955 j(zero, &not_external, Label::kNear);
4955 movp(length, Immediate(ExternalString::kSize)); 4956 movp(length, Immediate(ExternalString::kSize));
4956 jmp(&is_data_object, Label::kNear); 4957 jmp(&is_data_object, Label::kNear);
4957 4958
4958 bind(&not_external); 4959 bind(&not_external);
4959 // Sequential string, either ASCII or UC16. 4960 // Sequential string, either ASCII or UC16.
4960 ASSERT(kOneByteStringTag == 0x04); 4961 ASSERT(kOneByteStringTag == 0x04);
4961 and_(length, Immediate(kStringEncodingMask)); 4962 and_(length, Immediate(kStringEncodingMask));
4962 xor_(length, Immediate(kStringEncodingMask)); 4963 xor_(length, Immediate(kStringEncodingMask));
4963 addq(length, Immediate(0x04)); 4964 addp(length, Immediate(0x04));
4964 // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2. 4965 // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2.
4965 imul(length, FieldOperand(value, String::kLengthOffset)); 4966 imulp(length, FieldOperand(value, String::kLengthOffset));
4966 shr(length, Immediate(2 + kSmiTagSize + kSmiShiftSize)); 4967 shr(length, Immediate(2 + kSmiTagSize + kSmiShiftSize));
4967 addq(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask)); 4968 addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask));
4968 and_(length, Immediate(~kObjectAlignmentMask)); 4969 and_(length, Immediate(~kObjectAlignmentMask));
4969 4970
4970 bind(&is_data_object); 4971 bind(&is_data_object);
4971 // Value is a data object, and it is white. Mark it black. Since we know 4972 // Value is a data object, and it is white. Mark it black. Since we know
4972 // that the object is white we can make it black by flipping one bit. 4973 // that the object is white we can make it black by flipping one bit.
4973 or_(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 4974 or_(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
4974 4975
4975 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 4976 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask));
4976 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); 4977 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length);
4977 4978
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
5082 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift())); 5083 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift()));
5083 movl(rax, dividend); 5084 movl(rax, dividend);
5084 shrl(rax, Immediate(31)); 5085 shrl(rax, Immediate(31));
5085 addl(rdx, rax); 5086 addl(rdx, rax);
5086 } 5087 }
5087 5088
5088 5089
5089 } } // namespace v8::internal 5090 } } // namespace v8::internal
5090 5091
5091 #endif // V8_TARGET_ARCH_X64 5092 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698