| OLD | NEW |
| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 } | 155 } |
| 156 | 156 |
| 157 | 157 |
| 158 const char* LArithmeticT::Mnemonic() const { | 158 const char* LArithmeticT::Mnemonic() const { |
| 159 switch (op()) { | 159 switch (op()) { |
| 160 case Token::ADD: return "add-t"; | 160 case Token::ADD: return "add-t"; |
| 161 case Token::SUB: return "sub-t"; | 161 case Token::SUB: return "sub-t"; |
| 162 case Token::MUL: return "mul-t"; | 162 case Token::MUL: return "mul-t"; |
| 163 case Token::MOD: return "mod-t"; | 163 case Token::MOD: return "mod-t"; |
| 164 case Token::DIV: return "div-t"; | 164 case Token::DIV: return "div-t"; |
| 165 case Token::BIT_AND: return "bit-and-t"; |
| 166 case Token::BIT_OR: return "bit-or-t"; |
| 167 case Token::BIT_XOR: return "bit-xor-t"; |
| 168 case Token::SHL: return "sal-t"; |
| 169 case Token::SAR: return "sar-t"; |
| 170 case Token::SHR: return "shr-t"; |
| 165 default: | 171 default: |
| 166 UNREACHABLE(); | 172 UNREACHABLE(); |
| 167 return NULL; | 173 return NULL; |
| 168 } | 174 } |
| 169 } | 175 } |
| 170 | 176 |
| 171 | 177 |
| 172 void LGoto::PrintDataTo(StringStream* stream) { | 178 void LGoto::PrintDataTo(StringStream* stream) { |
| 173 stream->Add("B%d", block_id()); | 179 stream->Add("B%d", block_id()); |
| 174 } | 180 } |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 } | 738 } |
| 733 | 739 |
| 734 | 740 |
| 735 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 741 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 736 return AssignEnvironment(new LDeoptimize); | 742 return AssignEnvironment(new LDeoptimize); |
| 737 } | 743 } |
| 738 | 744 |
| 739 | 745 |
| 740 LInstruction* LChunkBuilder::DoBit(Token::Value op, | 746 LInstruction* LChunkBuilder::DoBit(Token::Value op, |
| 741 HBitwiseBinaryOperation* instr) { | 747 HBitwiseBinaryOperation* instr) { |
| 742 ASSERT(instr->representation().IsInteger32()); | 748 if (instr->representation().IsInteger32()) { |
| 743 ASSERT(instr->left()->representation().IsInteger32()); | 749 ASSERT(instr->left()->representation().IsInteger32()); |
| 744 ASSERT(instr->right()->representation().IsInteger32()); | 750 ASSERT(instr->right()->representation().IsInteger32()); |
| 745 | 751 |
| 746 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); | 752 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 747 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); | 753 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); |
| 748 return DefineSameAsFirst(new LBitI(op, left, right)); | 754 return DefineSameAsFirst(new LBitI(op, left, right)); |
| 755 } else { |
| 756 ASSERT(instr->representation().IsTagged()); |
| 757 ASSERT(instr->left()->representation().IsTagged()); |
| 758 ASSERT(instr->right()->representation().IsTagged()); |
| 759 |
| 760 LOperand* left = UseFixed(instr->left(), edx); |
| 761 LOperand* right = UseFixed(instr->right(), eax); |
| 762 LArithmeticT* result = new LArithmeticT(op, left, right); |
| 763 return MarkAsCall(DefineFixed(result, eax), instr); |
| 764 } |
| 749 } | 765 } |
| 750 | 766 |
| 751 | 767 |
| 752 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 768 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 753 HBitwiseBinaryOperation* instr) { | 769 HBitwiseBinaryOperation* instr) { |
| 770 if (instr->representation().IsTagged()) { |
| 771 ASSERT(instr->left()->representation().IsTagged()); |
| 772 ASSERT(instr->right()->representation().IsTagged()); |
| 773 |
| 774 LOperand* left = UseFixed(instr->left(), edx); |
| 775 LOperand* right = UseFixed(instr->right(), eax); |
| 776 LArithmeticT* result = new LArithmeticT(op, left, right); |
| 777 return MarkAsCall(DefineFixed(result, eax), instr); |
| 778 } |
| 779 |
| 754 ASSERT(instr->representation().IsInteger32()); | 780 ASSERT(instr->representation().IsInteger32()); |
| 755 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); | 781 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); |
| 756 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); | 782 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); |
| 757 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); | 783 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); |
| 758 | 784 |
| 759 HValue* right_value = instr->OperandAt(1); | 785 HValue* right_value = instr->OperandAt(1); |
| 760 LOperand* right = NULL; | 786 LOperand* right = NULL; |
| 761 int constant_value = 0; | 787 int constant_value = 0; |
| 762 if (right_value->IsConstant()) { | 788 if (right_value->IsConstant()) { |
| 763 HConstant* constant = HConstant::cast(right_value); | 789 HConstant* constant = HConstant::cast(right_value); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 if (current->has_position()) position_ = current->position(); | 913 if (current->has_position()) position_ = current->position(); |
| 888 LInstruction* instr = current->CompileToLithium(this); | 914 LInstruction* instr = current->CompileToLithium(this); |
| 889 | 915 |
| 890 if (instr != NULL) { | 916 if (instr != NULL) { |
| 891 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 917 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 892 instr = AssignPointerMap(instr); | 918 instr = AssignPointerMap(instr); |
| 893 } | 919 } |
| 894 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 920 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 895 instr = AssignEnvironment(instr); | 921 instr = AssignEnvironment(instr); |
| 896 } | 922 } |
| 897 if (current->IsBranch() && !instr->IsGoto()) { | 923 if (current->IsTest() && !instr->IsGoto()) { |
| 898 // TODO(fschneider): Handle branch instructions uniformly like | |
| 899 // other instructions. This requires us to generate the right | |
| 900 // branch instruction already at the HIR level. | |
| 901 ASSERT(instr->IsControl()); | 924 ASSERT(instr->IsControl()); |
| 902 HBranch* branch = HBranch::cast(current); | 925 HTest* test = HTest::cast(current); |
| 903 instr->set_hydrogen_value(branch->value()); | 926 instr->set_hydrogen_value(test->value()); |
| 904 HBasicBlock* first = branch->FirstSuccessor(); | 927 HBasicBlock* first = test->FirstSuccessor(); |
| 905 HBasicBlock* second = branch->SecondSuccessor(); | 928 HBasicBlock* second = test->SecondSuccessor(); |
| 906 ASSERT(first != NULL && second != NULL); | 929 ASSERT(first != NULL && second != NULL); |
| 907 instr->SetBranchTargets(first->block_id(), second->block_id()); | 930 instr->SetBranchTargets(first->block_id(), second->block_id()); |
| 908 } else { | 931 } else { |
| 909 instr->set_hydrogen_value(current); | 932 instr->set_hydrogen_value(current); |
| 910 } | 933 } |
| 911 | 934 |
| 912 int index = chunk_->AddInstruction(instr, current_block_); | 935 int index = chunk_->AddInstruction(instr, current_block_); |
| 913 allocator_->SummarizeInstruction(index); | 936 allocator_->SummarizeInstruction(index); |
| 914 } else { | 937 } else { |
| 915 // This instruction should be omitted. | 938 // This instruction should be omitted. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 | 975 |
| 953 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 976 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
| 954 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), | 977 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), |
| 955 instr->include_stack_check()); | 978 instr->include_stack_check()); |
| 956 return (instr->include_stack_check()) | 979 return (instr->include_stack_check()) |
| 957 ? AssignPointerMap(result) | 980 ? AssignPointerMap(result) |
| 958 : result; | 981 : result; |
| 959 } | 982 } |
| 960 | 983 |
| 961 | 984 |
| 962 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 985 LInstruction* LChunkBuilder::DoTest(HTest* instr) { |
| 963 HValue* v = instr->value(); | 986 HValue* v = instr->value(); |
| 964 if (v->EmitAtUses()) { | 987 if (v->EmitAtUses()) { |
| 965 if (v->IsClassOfTest()) { | 988 if (v->IsClassOfTest()) { |
| 966 HClassOfTest* compare = HClassOfTest::cast(v); | 989 HClassOfTest* compare = HClassOfTest::cast(v); |
| 967 ASSERT(compare->value()->representation().IsTagged()); | 990 ASSERT(compare->value()->representation().IsTagged()); |
| 968 | 991 |
| 969 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), | 992 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), |
| 970 TempRegister(), | 993 TempRegister(), |
| 971 TempRegister()); | 994 TempRegister()); |
| 972 } else if (v->IsCompare()) { | 995 } else if (v->IsCompare()) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 } | 1077 } |
| 1055 } | 1078 } |
| 1056 Abort("Undefined compare before branch"); | 1079 Abort("Undefined compare before branch"); |
| 1057 return NULL; | 1080 return NULL; |
| 1058 } | 1081 } |
| 1059 } | 1082 } |
| 1060 return new LBranch(UseRegisterAtStart(v)); | 1083 return new LBranch(UseRegisterAtStart(v)); |
| 1061 } | 1084 } |
| 1062 | 1085 |
| 1063 | 1086 |
| 1064 LInstruction* LChunkBuilder::DoCompareMapAndBranch( | 1087 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 1065 HCompareMapAndBranch* instr) { | |
| 1066 ASSERT(instr->value()->representation().IsTagged()); | 1088 ASSERT(instr->value()->representation().IsTagged()); |
| 1067 LOperand* value = UseRegisterAtStart(instr->value()); | 1089 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1068 return new LCmpMapAndBranch(value); | 1090 return new LCmpMapAndBranch(value); |
| 1069 } | 1091 } |
| 1070 | 1092 |
| 1071 | 1093 |
| 1072 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 1094 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
| 1073 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); | 1095 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); |
| 1074 } | 1096 } |
| 1075 | 1097 |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1734 | 1756 |
| 1735 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 1757 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 1736 LOperand* obj = UseFixed(instr->object(), edx); | 1758 LOperand* obj = UseFixed(instr->object(), edx); |
| 1737 LOperand* val = UseFixed(instr->value(), eax); | 1759 LOperand* val = UseFixed(instr->value(), eax); |
| 1738 | 1760 |
| 1739 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, val); | 1761 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, val); |
| 1740 return MarkAsCall(result, instr); | 1762 return MarkAsCall(result, instr); |
| 1741 } | 1763 } |
| 1742 | 1764 |
| 1743 | 1765 |
| 1766 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 1767 LOperand* string = UseRegister(instr->string()); |
| 1768 LOperand* index = UseRegisterOrConstant(instr->index()); |
| 1769 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); |
| 1770 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 1771 } |
| 1772 |
| 1773 |
| 1774 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 1775 LOperand* string = UseRegisterAtStart(instr->value()); |
| 1776 return DefineAsRegister(new LStringLength(string)); |
| 1777 } |
| 1778 |
| 1779 |
| 1744 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1780 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 1745 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); | 1781 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); |
| 1746 } | 1782 } |
| 1747 | 1783 |
| 1748 | 1784 |
| 1749 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1785 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
| 1750 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); | 1786 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); |
| 1751 } | 1787 } |
| 1752 | 1788 |
| 1753 | 1789 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1872 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 1908 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 1873 HEnvironment* outer = current_block_->last_environment()->outer(); | 1909 HEnvironment* outer = current_block_->last_environment()->outer(); |
| 1874 current_block_->UpdateEnvironment(outer); | 1910 current_block_->UpdateEnvironment(outer); |
| 1875 return NULL; | 1911 return NULL; |
| 1876 } | 1912 } |
| 1877 | 1913 |
| 1878 | 1914 |
| 1879 } } // namespace v8::internal | 1915 } } // namespace v8::internal |
| 1880 | 1916 |
| 1881 #endif // V8_TARGET_ARCH_IA32 | 1917 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |