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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 6460038: Version 3.1.3.... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 10 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.h ('k') | src/x64/lithium-x64.h » ('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 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 } 586 }
587 } 587 }
588 588
589 589
590 void LCodeGen::DoParameter(LParameter* instr) { 590 void LCodeGen::DoParameter(LParameter* instr) {
591 // Nothing to do. 591 // Nothing to do.
592 } 592 }
593 593
594 594
595 void LCodeGen::DoCallStub(LCallStub* instr) { 595 void LCodeGen::DoCallStub(LCallStub* instr) {
596 Abort("Unimplemented: %s", "DoCallStub"); 596 ASSERT(ToRegister(instr->result()).is(rax));
597 switch (instr->hydrogen()->major_key()) {
598 case CodeStub::RegExpConstructResult: {
599 RegExpConstructResultStub stub;
600 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
601 break;
602 }
603 case CodeStub::RegExpExec: {
604 RegExpExecStub stub;
605 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
606 break;
607 }
608 case CodeStub::SubString: {
609 SubStringStub stub;
610 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
611 break;
612 }
613 case CodeStub::StringCharAt: {
614 // TODO(1116): Add StringCharAt stub to x64.
615 Abort("Unimplemented: %s", "StringCharAt Stub");
616 break;
617 }
618 case CodeStub::MathPow: {
619 // TODO(1115): Add MathPow stub to x64.
620 Abort("Unimplemented: %s", "MathPow Stub");
621 break;
622 }
623 case CodeStub::NumberToString: {
624 NumberToStringStub stub;
625 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
626 break;
627 }
628 case CodeStub::StringAdd: {
629 StringAddStub stub(NO_STRING_ADD_FLAGS);
630 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
631 break;
632 }
633 case CodeStub::StringCompare: {
634 StringCompareStub stub;
635 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
636 break;
637 }
638 case CodeStub::TranscendentalCache: {
639 TranscendentalCacheStub stub(instr->transcendental_type());
640 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
641 break;
642 }
643 default:
644 UNREACHABLE();
645 }
597 } 646 }
598 647
599 648
600 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 649 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
601 // Nothing to do. 650 // Nothing to do.
602 } 651 }
603 652
604 653
605 void LCodeGen::DoModI(LModI* instr) { 654 void LCodeGen::DoModI(LModI* instr) {
606 Abort("Unimplemented: %s", "DoModI"); 655 Abort("Unimplemented: %s", "DoModI");
607 } 656 }
608 657
609 658
610 void LCodeGen::DoDivI(LDivI* instr) { 659 void LCodeGen::DoDivI(LDivI* instr) {
611 Abort("Unimplemented: %s", "DoDivI");} 660 LOperand* right = instr->InputAt(1);
661 ASSERT(ToRegister(instr->result()).is(rax));
662 ASSERT(ToRegister(instr->InputAt(0)).is(rax));
663 ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
664 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
665
666 Register left_reg = rax;
667
668 // Check for x / 0.
669 Register right_reg = ToRegister(right);
670 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
671 __ testl(right_reg, right_reg);
672 DeoptimizeIf(zero, instr->environment());
673 }
674
675 // Check for (0 / -x) that will produce negative zero.
676 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
677 NearLabel left_not_zero;
678 __ testl(left_reg, left_reg);
679 __ j(not_zero, &left_not_zero);
680 __ testl(right_reg, right_reg);
681 DeoptimizeIf(sign, instr->environment());
682 __ bind(&left_not_zero);
683 }
684
685 // Check for (-kMinInt / -1).
686 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
687 NearLabel left_not_min_int;
688 __ cmpl(left_reg, Immediate(kMinInt));
689 __ j(not_zero, &left_not_min_int);
690 __ cmpl(right_reg, Immediate(-1));
691 DeoptimizeIf(zero, instr->environment());
692 __ bind(&left_not_min_int);
693 }
694
695 // Sign extend to rdx.
696 __ cdq();
697 __ idivl(right_reg);
698
699 // Deoptimize if remainder is not 0.
700 __ testl(rdx, rdx);
701 DeoptimizeIf(not_zero, instr->environment());
702 }
612 703
613 704
614 void LCodeGen::DoMulI(LMulI* instr) { 705 void LCodeGen::DoMulI(LMulI* instr) {
615 Abort("Unimplemented: %s", "DoMultI");} 706 Register left = ToRegister(instr->InputAt(0));
707 LOperand* right = instr->InputAt(1);
708
709 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
710 __ movl(kScratchRegister, left);
711 }
712
713 if (right->IsConstantOperand()) {
714 int right_value = ToInteger32(LConstantOperand::cast(right));
715 __ imull(left, left, Immediate(right_value));
716 } else if (right->IsStackSlot()) {
717 __ imull(left, ToOperand(right));
718 } else {
719 __ imull(left, ToRegister(right));
720 }
721
722 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
723 DeoptimizeIf(overflow, instr->environment());
724 }
725
726 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
727 // Bail out if the result is supposed to be negative zero.
728 NearLabel done;
729 __ testl(left, left);
730 __ j(not_zero, &done);
731 if (right->IsConstantOperand()) {
732 if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
733 DeoptimizeIf(no_condition, instr->environment());
734 }
735 } else if (right->IsStackSlot()) {
736 __ or_(kScratchRegister, ToOperand(right));
737 DeoptimizeIf(sign, instr->environment());
738 } else {
739 // Test the non-zero operand for negative sign.
740 __ or_(kScratchRegister, ToRegister(right));
741 DeoptimizeIf(sign, instr->environment());
742 }
743 __ bind(&done);
744 }
745 }
616 746
617 747
618 void LCodeGen::DoBitI(LBitI* instr) { 748 void LCodeGen::DoBitI(LBitI* instr) {
619 LOperand* left = instr->InputAt(0); 749 LOperand* left = instr->InputAt(0);
620 LOperand* right = instr->InputAt(1); 750 LOperand* right = instr->InputAt(1);
621 ASSERT(left->Equals(instr->result())); 751 ASSERT(left->Equals(instr->result()));
622 ASSERT(left->IsRegister()); 752 ASSERT(left->IsRegister());
623 753
624 if (right->IsConstantOperand()) { 754 if (right->IsConstantOperand()) {
625 int right_operand = ToInteger32(LConstantOperand::cast(right)); 755 int right_operand = ToInteger32(LConstantOperand::cast(right));
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 933
804 934
805 void LCodeGen::DoBitNotI(LBitNotI* instr) { 935 void LCodeGen::DoBitNotI(LBitNotI* instr) {
806 LOperand* input = instr->InputAt(0); 936 LOperand* input = instr->InputAt(0);
807 ASSERT(input->Equals(instr->result())); 937 ASSERT(input->Equals(instr->result()));
808 __ not_(ToRegister(input)); 938 __ not_(ToRegister(input));
809 } 939 }
810 940
811 941
812 void LCodeGen::DoThrow(LThrow* instr) { 942 void LCodeGen::DoThrow(LThrow* instr) {
813 Abort("Unimplemented: %s", "DoThrow"); 943 __ push(ToRegister(instr->InputAt(0)));
944 CallRuntime(Runtime::kThrow, 1, instr);
945
946 if (FLAG_debug_code) {
947 Comment("Unreachable code.");
948 __ int3();
949 }
814 } 950 }
815 951
816 952
817 void LCodeGen::DoAddI(LAddI* instr) { 953 void LCodeGen::DoAddI(LAddI* instr) {
818 LOperand* left = instr->InputAt(0); 954 LOperand* left = instr->InputAt(0);
819 LOperand* right = instr->InputAt(1); 955 LOperand* right = instr->InputAt(1);
820 ASSERT(left->Equals(instr->result())); 956 ASSERT(left->Equals(instr->result()));
821 957
822 if (right->IsConstantOperand()) { 958 if (right->IsConstantOperand()) {
823 __ addl(ToRegister(left), 959 __ addl(ToRegister(left),
(...skipping 13 matching lines...) Expand all
837 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 973 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
838 Abort("Unimplemented: %s", "DoArithmeticD"); 974 Abort("Unimplemented: %s", "DoArithmeticD");
839 } 975 }
840 976
841 977
842 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 978 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
843 ASSERT(ToRegister(instr->InputAt(0)).is(rdx)); 979 ASSERT(ToRegister(instr->InputAt(0)).is(rdx));
844 ASSERT(ToRegister(instr->InputAt(1)).is(rax)); 980 ASSERT(ToRegister(instr->InputAt(1)).is(rax));
845 ASSERT(ToRegister(instr->result()).is(rax)); 981 ASSERT(ToRegister(instr->result()).is(rax));
846 982
847 GenericBinaryOpStub stub(instr->op(), NO_OVERWRITE, NO_GENERIC_BINARY_FLAGS); 983 TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
848 stub.SetArgsInRegisters();
849 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 984 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
850 } 985 }
851 986
852 987
853 int LCodeGen::GetNextEmittedBlock(int block) { 988 int LCodeGen::GetNextEmittedBlock(int block) {
854 for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 989 for (int i = block + 1; i < graph()->blocks()->length(); ++i) {
855 LLabel* label = chunk_->GetLabel(i); 990 LLabel* label = chunk_->GetLabel(i);
856 if (!label->HasReplacement()) return i; 991 if (!label->HasReplacement()) return i;
857 } 992 }
858 return -1; 993 return -1;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 __ jmp(deferred_stack_check->entry()); 1091 __ jmp(deferred_stack_check->entry());
957 deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block)); 1092 deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block));
958 } else { 1093 } else {
959 __ jmp(chunk_->GetAssemblyLabel(block)); 1094 __ jmp(chunk_->GetAssemblyLabel(block));
960 } 1095 }
961 } 1096 }
962 } 1097 }
963 1098
964 1099
965 void LCodeGen::DoDeferredStackCheck(LGoto* instr) { 1100 void LCodeGen::DoDeferredStackCheck(LGoto* instr) {
966 Abort("Unimplemented: %s", "DoDeferredStackCheck"); 1101 __ Pushad();
1102 __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
1103 RecordSafepointWithRegisters(
1104 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
1105 __ Popad();
967 } 1106 }
968 1107
969 1108
970 void LCodeGen::DoGoto(LGoto* instr) { 1109 void LCodeGen::DoGoto(LGoto* instr) {
971 class DeferredStackCheck: public LDeferredCode { 1110 class DeferredStackCheck: public LDeferredCode {
972 public: 1111 public:
973 DeferredStackCheck(LCodeGen* codegen, LGoto* instr) 1112 DeferredStackCheck(LCodeGen* codegen, LGoto* instr)
974 : LDeferredCode(codegen), instr_(instr) { } 1113 : LDeferredCode(codegen), instr_(instr) { }
975 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 1114 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
976 private: 1115 private:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 1154
1016 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { 1155 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) {
1017 if (right->IsConstantOperand()) { 1156 if (right->IsConstantOperand()) {
1018 int32_t value = ToInteger32(LConstantOperand::cast(right)); 1157 int32_t value = ToInteger32(LConstantOperand::cast(right));
1019 if (left->IsRegister()) { 1158 if (left->IsRegister()) {
1020 __ cmpl(ToRegister(left), Immediate(value)); 1159 __ cmpl(ToRegister(left), Immediate(value));
1021 } else { 1160 } else {
1022 __ cmpl(ToOperand(left), Immediate(value)); 1161 __ cmpl(ToOperand(left), Immediate(value));
1023 } 1162 }
1024 } else if (right->IsRegister()) { 1163 } else if (right->IsRegister()) {
1025 __ cmpq(ToRegister(left), ToRegister(right)); 1164 __ cmpl(ToRegister(left), ToRegister(right));
1026 } else { 1165 } else {
1027 __ cmpq(ToRegister(left), ToOperand(right)); 1166 __ cmpl(ToRegister(left), ToOperand(right));
1028 } 1167 }
1029 } 1168 }
1030 1169
1031 1170
1032 void LCodeGen::DoCmpID(LCmpID* instr) { 1171 void LCodeGen::DoCmpID(LCmpID* instr) {
1033 LOperand* left = instr->InputAt(0); 1172 LOperand* left = instr->InputAt(0);
1034 LOperand* right = instr->InputAt(1); 1173 LOperand* right = instr->InputAt(1);
1035 LOperand* result = instr->result(); 1174 LOperand* result = instr->result();
1036 1175
1037 NearLabel unordered; 1176 NearLabel unordered;
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 1643
1505 void LCodeGen::DoReturn(LReturn* instr) { 1644 void LCodeGen::DoReturn(LReturn* instr) {
1506 if (FLAG_trace) { 1645 if (FLAG_trace) {
1507 // Preserve the return value on the stack and rely on the runtime 1646 // Preserve the return value on the stack and rely on the runtime
1508 // call to return the value in the same register. 1647 // call to return the value in the same register.
1509 __ push(rax); 1648 __ push(rax);
1510 __ CallRuntime(Runtime::kTraceExit, 1); 1649 __ CallRuntime(Runtime::kTraceExit, 1);
1511 } 1650 }
1512 __ movq(rsp, rbp); 1651 __ movq(rsp, rbp);
1513 __ pop(rbp); 1652 __ pop(rbp);
1514 __ ret((ParameterCount() + 1) * kPointerSize); 1653 __ Ret((ParameterCount() + 1) * kPointerSize, rcx);
1515 } 1654 }
1516 1655
1517 1656
1518 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { 1657 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) {
1519 Abort("Unimplemented: %s", "DoLoadGlobal"); 1658 Register result = ToRegister(instr->result());
1659 if (result.is(rax)) {
1660 __ load_rax(instr->hydrogen()->cell().location(),
1661 RelocInfo::GLOBAL_PROPERTY_CELL);
1662 } else {
1663 __ movq(result, instr->hydrogen()->cell(), RelocInfo::GLOBAL_PROPERTY_CELL);
1664 __ movq(result, Operand(result, 0));
1665 }
1666 if (instr->hydrogen()->check_hole_value()) {
1667 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
1668 DeoptimizeIf(equal, instr->environment());
1669 }
1520 } 1670 }
1521 1671
1522 1672
1523 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { 1673 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
1524 Register value = ToRegister(instr->InputAt(0)); 1674 Register value = ToRegister(instr->InputAt(0));
1525 Register temp = ToRegister(instr->TempAt(0)); 1675 Register temp = ToRegister(instr->TempAt(0));
1526 ASSERT(!value.is(temp)); 1676 ASSERT(!value.is(temp));
1527 bool check_hole = instr->hydrogen()->check_hole_value(); 1677 bool check_hole = instr->hydrogen()->check_hole_value();
1528 if (!check_hole && value.is(rax)) { 1678 if (!check_hole && value.is(rax)) {
1529 __ store_rax(instr->hydrogen()->cell().location(), 1679 __ store_rax(instr->hydrogen()->cell().location(),
1530 RelocInfo::GLOBAL_PROPERTY_CELL); 1680 RelocInfo::GLOBAL_PROPERTY_CELL);
1531 return; 1681 return;
1532 } 1682 }
1533 // If the cell we are storing to contains the hole it could have 1683 // If the cell we are storing to contains the hole it could have
1534 // been deleted from the property dictionary. In that case, we need 1684 // been deleted from the property dictionary. In that case, we need
1535 // to update the property details in the property dictionary to mark 1685 // to update the property details in the property dictionary to mark
1536 // it as no longer deleted. We deoptimize in that case. 1686 // it as no longer deleted. We deoptimize in that case.
1537 __ movq(temp, 1687 __ movq(temp, instr->hydrogen()->cell(), RelocInfo::GLOBAL_PROPERTY_CELL);
1538 Handle<Object>::cast(instr->hydrogen()->cell()),
1539 RelocInfo::GLOBAL_PROPERTY_CELL);
1540 if (check_hole) { 1688 if (check_hole) {
1541 __ CompareRoot(Operand(temp, 0), Heap::kTheHoleValueRootIndex); 1689 __ CompareRoot(Operand(temp, 0), Heap::kTheHoleValueRootIndex);
1542 DeoptimizeIf(equal, instr->environment()); 1690 DeoptimizeIf(equal, instr->environment());
1543 } 1691 }
1544 __ movq(Operand(temp, 0), value); 1692 __ movq(Operand(temp, 0), value);
1545 } 1693 }
1546 1694
1547 1695
1548 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 1696 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
1549 Abort("Unimplemented: %s", "DoLoadContextSlot"); 1697 Abort("Unimplemented: %s", "DoLoadContextSlot");
1550 } 1698 }
1551 1699
1552 1700
1553 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 1701 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
1554 Register object = ToRegister(instr->InputAt(0)); 1702 Register object = ToRegister(instr->InputAt(0));
1555 Register result = ToRegister(instr->result()); 1703 Register result = ToRegister(instr->result());
1556 if (instr->hydrogen()->is_in_object()) { 1704 if (instr->hydrogen()->is_in_object()) {
1557 __ movq(result, FieldOperand(object, instr->hydrogen()->offset())); 1705 __ movq(result, FieldOperand(object, instr->hydrogen()->offset()));
1558 } else { 1706 } else {
1559 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); 1707 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
1560 __ movq(result, FieldOperand(result, instr->hydrogen()->offset())); 1708 __ movq(result, FieldOperand(result, instr->hydrogen()->offset()));
1561 } 1709 }
1562 } 1710 }
1563 1711
1564 1712
1565 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 1713 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
1566 Abort("Unimplemented: %s", "DoLoadNamedGeneric"); 1714 ASSERT(ToRegister(instr->object()).is(rax));
1715 ASSERT(ToRegister(instr->result()).is(rax));
1716
1717 __ Move(rcx, instr->name());
1718 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1719 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1567 } 1720 }
1568 1721
1569 1722
1570 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 1723 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
1571 Abort("Unimplemented: %s", "DoLoadFunctionPrototype"); 1724 Abort("Unimplemented: %s", "DoLoadFunctionPrototype");
1572 } 1725 }
1573 1726
1574 1727
1575 void LCodeGen::DoLoadElements(LLoadElements* instr) { 1728 void LCodeGen::DoLoadElements(LLoadElements* instr) {
1576 ASSERT(instr->result()->Equals(instr->InputAt(0))); 1729 ASSERT(instr->result()->Equals(instr->InputAt(0)));
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 if (instr->length()->IsRegister()) { 2001 if (instr->length()->IsRegister()) {
1849 __ cmpq(ToRegister(instr->index()), ToRegister(instr->length())); 2002 __ cmpq(ToRegister(instr->index()), ToRegister(instr->length()));
1850 } else { 2003 } else {
1851 __ cmpq(ToRegister(instr->index()), ToOperand(instr->length())); 2004 __ cmpq(ToRegister(instr->index()), ToOperand(instr->length()));
1852 } 2005 }
1853 DeoptimizeIf(above_equal, instr->environment()); 2006 DeoptimizeIf(above_equal, instr->environment());
1854 } 2007 }
1855 2008
1856 2009
1857 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 2010 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
1858 Abort("Unimplemented: %s", "DoStoreKeyedFastElement"); 2011 Register value = ToRegister(instr->value());
2012 Register elements = ToRegister(instr->object());
2013 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
2014
2015 // Do the store.
2016 if (instr->key()->IsConstantOperand()) {
2017 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
2018 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
2019 int offset =
2020 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize;
2021 __ movq(FieldOperand(elements, offset), value);
2022 } else {
2023 __ movq(FieldOperand(elements,
2024 key,
2025 times_pointer_size,
2026 FixedArray::kHeaderSize),
2027 value);
2028 }
2029
2030 if (instr->hydrogen()->NeedsWriteBarrier()) {
2031 // Compute address of modified element and store it into key register.
2032 __ lea(key, FieldOperand(elements,
2033 key,
2034 times_pointer_size,
2035 FixedArray::kHeaderSize));
2036 __ RecordWrite(elements, key, value);
2037 }
1859 } 2038 }
1860 2039
1861 2040
1862 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 2041 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
1863 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); 2042 Abort("Unimplemented: %s", "DoStoreKeyedGeneric");
1864 } 2043 }
1865 2044
1866 2045
1867 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 2046 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
1868 LOperand* input = instr->InputAt(0); 2047 LOperand* input = instr->InputAt(0);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 RecordSafepointWithRegisters( 2098 RecordSafepointWithRegisters(
1920 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); 2099 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
1921 // Ensure that value in rax survives popping registers. 2100 // Ensure that value in rax survives popping registers.
1922 __ movq(kScratchRegister, rax); 2101 __ movq(kScratchRegister, rax);
1923 __ PopSafepointRegisters(); 2102 __ PopSafepointRegisters();
1924 __ movq(reg, kScratchRegister); 2103 __ movq(reg, kScratchRegister);
1925 } 2104 }
1926 2105
1927 2106
1928 void LCodeGen::DoSmiTag(LSmiTag* instr) { 2107 void LCodeGen::DoSmiTag(LSmiTag* instr) {
1929 Abort("Unimplemented: %s", "DoSmiTag"); 2108 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2109 Register input = ToRegister(instr->InputAt(0));
2110 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
2111 __ Integer32ToSmi(input, input);
1930 } 2112 }
1931 2113
1932 2114
1933 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 2115 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
1934 Abort("Unimplemented: %s", "DoSmiUntag"); 2116 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2117 Register input = ToRegister(instr->InputAt(0));
2118 if (instr->needs_check()) {
2119 Condition is_smi = __ CheckSmi(input);
2120 DeoptimizeIf(NegateCondition(is_smi), instr->environment());
2121 }
2122 __ SmiToInteger32(input, input);
1935 } 2123 }
1936 2124
1937 2125
1938 void LCodeGen::EmitNumberUntagD(Register input_reg, 2126 void LCodeGen::EmitNumberUntagD(Register input_reg,
1939 XMMRegister result_reg, 2127 XMMRegister result_reg,
1940 LEnvironment* env) { 2128 LEnvironment* env) {
1941 NearLabel load_smi, heap_number, done; 2129 NearLabel load_smi, heap_number, done;
1942 2130
1943 // Smi check. 2131 // Smi check.
1944 __ JumpIfSmi(input_reg, &load_smi); 2132 __ JumpIfSmi(input_reg, &load_smi);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 LOperand* input = instr->InputAt(0); 2291 LOperand* input = instr->InputAt(0);
2104 ASSERT(input->IsRegister()); 2292 ASSERT(input->IsRegister());
2105 Register reg = ToRegister(input); 2293 Register reg = ToRegister(input);
2106 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), 2294 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset),
2107 instr->hydrogen()->map()); 2295 instr->hydrogen()->map());
2108 DeoptimizeIf(not_equal, instr->environment()); 2296 DeoptimizeIf(not_equal, instr->environment());
2109 } 2297 }
2110 2298
2111 2299
2112 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { 2300 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) {
2113 Abort("Unimplemented: %s", "LoadHeapObject"); 2301 if (Heap::InNewSpace(*object)) {
2302 Handle<JSGlobalPropertyCell> cell =
2303 Factory::NewJSGlobalPropertyCell(object);
2304 __ movq(result, cell, RelocInfo::GLOBAL_PROPERTY_CELL);
2305 __ movq(result, Operand(result, 0));
2306 } else {
2307 __ Move(result, object);
2308 }
2114 } 2309 }
2115 2310
2116 2311
2117 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 2312 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
2118 Register reg = ToRegister(instr->TempAt(0)); 2313 Register reg = ToRegister(instr->TempAt(0));
2119 2314
2120 Handle<JSObject> holder = instr->holder(); 2315 Handle<JSObject> holder = instr->holder();
2121 Handle<JSObject> current_prototype = instr->prototype(); 2316 Handle<JSObject> current_prototype = instr->prototype();
2122 2317
2123 // Load prototype object. 2318 // Load prototype object.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2212 void LCodeGen::DoTypeof(LTypeof* instr) { 2407 void LCodeGen::DoTypeof(LTypeof* instr) {
2213 Abort("Unimplemented: %s", "DoTypeof"); 2408 Abort("Unimplemented: %s", "DoTypeof");
2214 } 2409 }
2215 2410
2216 2411
2217 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { 2412 void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
2218 Abort("Unimplemented: %s", "DoTypeofIs"); 2413 Abort("Unimplemented: %s", "DoTypeofIs");
2219 } 2414 }
2220 2415
2221 2416
2417 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
2418 Register result = ToRegister(instr->result());
2419 NearLabel true_label;
2420 NearLabel false_label;
2421 NearLabel done;
2422
2423 EmitIsConstructCall(result);
2424 __ j(equal, &true_label);
2425
2426 __ LoadRoot(result, Heap::kFalseValueRootIndex);
2427 __ jmp(&done);
2428
2429 __ bind(&true_label);
2430 __ LoadRoot(result, Heap::kTrueValueRootIndex);
2431
2432
2433 __ bind(&done);
2434 }
2435
2436
2437 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
2438 Register temp = ToRegister(instr->TempAt(0));
2439 int true_block = chunk_->LookupDestination(instr->true_block_id());
2440 int false_block = chunk_->LookupDestination(instr->false_block_id());
2441
2442 EmitIsConstructCall(temp);
2443 EmitBranch(true_block, false_block, equal);
2444 }
2445
2446
2447 void LCodeGen::EmitIsConstructCall(Register temp) {
2448 // Get the frame pointer for the calling frame.
2449 __ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2450
2451 // Skip the arguments adaptor frame if it exists.
2452 NearLabel check_frame_marker;
2453 __ SmiCompare(Operand(temp, StandardFrameConstants::kContextOffset),
2454 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2455 __ j(not_equal, &check_frame_marker);
2456 __ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset));
2457
2458 // Check the marker in the calling frame.
2459 __ bind(&check_frame_marker);
2460 __ SmiCompare(Operand(temp, StandardFrameConstants::kMarkerOffset),
2461 Smi::FromInt(StackFrame::CONSTRUCT));
2462 }
2463
2464
2222 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 2465 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
2223 Register input = ToRegister(instr->InputAt(0)); 2466 Register input = ToRegister(instr->InputAt(0));
2224 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2467 int true_block = chunk_->LookupDestination(instr->true_block_id());
2225 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2468 int false_block = chunk_->LookupDestination(instr->false_block_id());
2226 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2469 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2227 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2470 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2228 2471
2229 Condition final_branch_condition = EmitTypeofIs(true_label, 2472 Condition final_branch_condition = EmitTypeofIs(true_label,
2230 false_label, 2473 false_label,
2231 input, 2474 input,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 2572
2330 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 2573 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
2331 Abort("Unimplemented: %s", "DoOsrEntry"); 2574 Abort("Unimplemented: %s", "DoOsrEntry");
2332 } 2575 }
2333 2576
2334 #undef __ 2577 #undef __
2335 2578
2336 } } // namespace v8::internal 2579 } } // namespace v8::internal
2337 2580
2338 #endif // V8_TARGET_ARCH_X64 2581 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698