Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 } | 644 } |
| 645 | 645 |
| 646 | 646 |
| 647 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 647 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 648 BranchLabels labels) { | 648 BranchLabels labels) { |
| 649 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); | 649 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); |
| 650 Register val_reg = locs()->in(0).reg(); | 650 Register val_reg = locs()->in(0).reg(); |
| 651 Register cid_reg = locs()->temp(0).reg(); | 651 Register cid_reg = locs()->temp(0).reg(); |
| 652 | 652 |
| 653 Label* deopt = CanDeoptimize() ? | 653 Label* deopt = CanDeoptimize() ? |
| 654 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL; | 654 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL; |
| 655 | 655 |
| 656 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; | 656 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; |
| 657 const ZoneGrowableArray<intptr_t>& data = cid_results(); | 657 const ZoneGrowableArray<intptr_t>& data = cid_results(); |
| 658 ASSERT(data[0] == kSmiCid); | 658 ASSERT(data[0] == kSmiCid); |
| 659 bool result = data[1] == true_result; | 659 bool result = data[1] == true_result; |
| 660 __ testl(val_reg, Immediate(kSmiTagMask)); | 660 __ testl(val_reg, Immediate(kSmiTagMask)); |
| 661 __ j(ZERO, result ? labels.true_label : labels.false_label); | 661 __ j(ZERO, result ? labels.true_label : labels.false_label); |
| 662 __ LoadClassId(cid_reg, val_reg); | 662 __ LoadClassId(cid_reg, val_reg); |
| 663 for (intptr_t i = 2; i < data.length(); i += 2) { | 663 for (intptr_t i = 2; i < data.length(); i += 2) { |
| 664 const intptr_t test_cid = data[i]; | 664 const intptr_t test_cid = data[i]; |
| (...skipping 5174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5839 __ Bind(&done); | 5839 __ Bind(&done); |
| 5840 } | 5840 } |
| 5841 | 5841 |
| 5842 | 5842 |
| 5843 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, | 5843 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
| 5844 bool opt) const { | 5844 bool opt) const { |
| 5845 const intptr_t kNumInputs = 2; | 5845 const intptr_t kNumInputs = 2; |
| 5846 switch (op_kind()) { | 5846 switch (op_kind()) { |
| 5847 case Token::kBIT_AND: | 5847 case Token::kBIT_AND: |
| 5848 case Token::kBIT_OR: | 5848 case Token::kBIT_OR: |
| 5849 case Token::kBIT_XOR: { | 5849 case Token::kBIT_XOR: |
| 5850 const intptr_t kNumTemps = 0; | 5850 case Token::kADD: |
| 5851 case Token::kSUB: | |
| 5852 case Token::kMUL: { | |
| 5853 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0; | |
| 5851 LocationSummary* summary = new(isolate) LocationSummary( | 5854 LocationSummary* summary = new(isolate) LocationSummary( |
| 5852 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5855 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5853 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 5856 summary->set_in(0, (op_kind() == Token::kMUL) |
| 5854 Location::RequiresRegister())); | 5857 ? Location::Pair(Location::RegisterLocation(EAX), |
| 5858 Location::RegisterLocation(EDX)) | |
| 5859 : Location::Pair(Location::RequiresRegister(), | |
| 5860 Location::RequiresRegister())); | |
| 5855 summary->set_in(1, Location::Pair(Location::RequiresRegister(), | 5861 summary->set_in(1, Location::Pair(Location::RequiresRegister(), |
| 5856 Location::RequiresRegister())); | 5862 Location::RequiresRegister())); |
| 5857 summary->set_out(0, Location::SameAsFirstInput()); | 5863 summary->set_out(0, Location::SameAsFirstInput()); |
| 5858 return summary; | 5864 if (kNumTemps > 0) { |
| 5859 } | 5865 summary->set_temp(0, Location::RequiresRegister()); |
| 5860 case Token::kADD: | 5866 } |
| 5861 case Token::kSUB: { | |
| 5862 const intptr_t kNumTemps = 0; | |
| 5863 LocationSummary* summary = new(isolate) LocationSummary( | |
| 5864 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 5865 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | |
| 5866 Location::RequiresRegister())); | |
| 5867 summary->set_in(1, Location::Pair(Location::RequiresRegister(), | |
| 5868 Location::RequiresRegister())); | |
| 5869 summary->set_out(0, Location::SameAsFirstInput()); | |
| 5870 return summary; | 5867 return summary; |
| 5871 } | 5868 } |
| 5872 default: | 5869 default: |
| 5873 UNREACHABLE(); | 5870 UNREACHABLE(); |
| 5874 return NULL; | 5871 return NULL; |
| 5875 } | 5872 } |
| 5876 } | 5873 } |
| 5877 | 5874 |
| 5878 | 5875 |
| 5879 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5876 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5913 __ adcl(left_hi, right_hi); | 5910 __ adcl(left_hi, right_hi); |
| 5914 } else { | 5911 } else { |
| 5915 __ subl(left_lo, right_lo); | 5912 __ subl(left_lo, right_lo); |
| 5916 __ sbbl(left_hi, right_hi); | 5913 __ sbbl(left_hi, right_hi); |
| 5917 } | 5914 } |
| 5918 if (can_overflow()) { | 5915 if (can_overflow()) { |
| 5919 __ j(OVERFLOW, deopt); | 5916 __ j(OVERFLOW, deopt); |
| 5920 } | 5917 } |
| 5921 break; | 5918 break; |
| 5922 } | 5919 } |
| 5923 default: UNREACHABLE(); | 5920 case Token::kMUL: { |
| 5921 // The product of two signed 32-bit integers fits in a signed 64-bit | |
| 5922 // result without causing overflow. | |
| 5923 // We deopt on larger inputs. | |
| 5924 Register temp = locs()->temp(0).reg(); | |
|
Vyacheslav Egorov (Google)
2014/07/18 11:15:35
Please add TODO here and in another place use rang
regis
2014/07/18 17:59:43
Done.
| |
| 5925 __ movl(temp, left_lo); | |
| 5926 __ sarl(temp, Immediate(31)); | |
| 5927 __ cmpl(temp, left_hi); | |
| 5928 __ j(NOT_EQUAL, deopt); | |
| 5929 __ movl(temp, right_lo); | |
| 5930 __ sarl(temp, Immediate(31)); | |
| 5931 __ cmpl(temp, right_hi); | |
| 5932 __ j(NOT_EQUAL, deopt); | |
| 5933 ASSERT(left_lo == EAX); | |
| 5934 __ imull(right_lo); // Result in EDX:EAX. | |
| 5935 ASSERT(out_lo == EAX); | |
| 5936 ASSERT(out_hi == EDX); | |
| 5937 break; | |
| 5938 } | |
| 5939 default: | |
| 5940 UNREACHABLE(); | |
| 5924 } | 5941 } |
| 5925 if (FLAG_throw_on_javascript_int_overflow) { | 5942 if (FLAG_throw_on_javascript_int_overflow) { |
| 5926 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | 5943 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
| 5927 } | 5944 } |
| 5928 } | 5945 } |
| 5929 | 5946 |
| 5930 | 5947 |
| 5931 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, | 5948 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, |
| 5932 bool opt) const { | 5949 bool opt) const { |
| 5933 const intptr_t kNumInputs = 2; | 5950 const intptr_t kNumInputs = 2; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6106 __ Bind(&large_shift); | 6123 __ Bind(&large_shift); |
| 6107 // No need to subtract 32 from CL, only 5 bits used by shll. | 6124 // No need to subtract 32 from CL, only 5 bits used by shll. |
| 6108 __ movl(left_hi, left_lo); // Shift by 32. | 6125 __ movl(left_hi, left_lo); // Shift by 32. |
| 6109 __ xorl(left_lo, left_lo); // Zero left_lo. | 6126 __ xorl(left_lo, left_lo); // Zero left_lo. |
| 6110 __ shll(left_hi, ECX); // Shift count: CL % 32. | 6127 __ shll(left_hi, ECX); // Shift count: CL % 32. |
| 6111 } | 6128 } |
| 6112 break; | 6129 break; |
| 6113 } | 6130 } |
| 6114 default: | 6131 default: |
| 6115 UNREACHABLE(); | 6132 UNREACHABLE(); |
| 6116 break; | |
| 6117 } | 6133 } |
| 6118 __ Bind(&done); | 6134 __ Bind(&done); |
| 6119 } | 6135 } |
| 6120 if (FLAG_throw_on_javascript_int_overflow) { | 6136 if (FLAG_throw_on_javascript_int_overflow) { |
| 6121 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | 6137 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
| 6122 } | 6138 } |
| 6123 } | 6139 } |
| 6124 | 6140 |
| 6125 | 6141 |
| 6126 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, | 6142 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6185 | 6201 |
| 6186 | 6202 |
| 6187 CompileType UnboxUint32Instr::ComputeType() const { | 6203 CompileType UnboxUint32Instr::ComputeType() const { |
| 6188 return CompileType::Int(); | 6204 return CompileType::Int(); |
| 6189 } | 6205 } |
| 6190 | 6206 |
| 6191 | 6207 |
| 6192 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | 6208 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
| 6193 bool opt) const { | 6209 bool opt) const { |
| 6194 const intptr_t kNumInputs = 2; | 6210 const intptr_t kNumInputs = 2; |
| 6195 const intptr_t kNumTemps = 0; | 6211 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0; |
| 6196 LocationSummary* summary = new(isolate) LocationSummary( | 6212 LocationSummary* summary = new(isolate) LocationSummary( |
| 6197 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6213 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6198 summary->set_in(0, Location::RequiresRegister()); | 6214 if (op_kind() == Token::kMUL) { |
| 6215 summary->set_in(0, Location::RegisterLocation(EAX)); | |
| 6216 summary->set_temp(0, Location::RegisterLocation(EDX)); | |
| 6217 } else { | |
| 6218 summary->set_in(0, Location::RequiresRegister()); | |
| 6219 } | |
| 6199 summary->set_in(1, Location::RequiresRegister()); | 6220 summary->set_in(1, Location::RequiresRegister()); |
| 6200 summary->set_out(0, Location::SameAsFirstInput()); | 6221 summary->set_out(0, Location::SameAsFirstInput()); |
| 6201 return summary; | 6222 return summary; |
| 6202 } | 6223 } |
| 6203 | 6224 |
| 6204 | 6225 |
| 6205 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6226 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6206 Register left = locs()->in(0).reg(); | 6227 Register left = locs()->in(0).reg(); |
| 6207 Register right = locs()->in(1).reg(); | 6228 Register right = locs()->in(1).reg(); |
| 6208 Register out = locs()->out(0).reg(); | 6229 Register out = locs()->out(0).reg(); |
| 6209 ASSERT(out == left); | 6230 ASSERT(out == left); |
| 6210 switch (op_kind()) { | 6231 switch (op_kind()) { |
| 6211 case Token::kBIT_AND: | 6232 case Token::kBIT_AND: |
| 6212 __ andl(out, right); | 6233 __ andl(out, right); |
| 6213 break; | 6234 break; |
| 6214 case Token::kBIT_OR: | 6235 case Token::kBIT_OR: |
| 6215 __ orl(out, right); | 6236 __ orl(out, right); |
| 6216 break; | 6237 break; |
| 6217 case Token::kBIT_XOR: | 6238 case Token::kBIT_XOR: |
| 6218 __ xorl(out, right); | 6239 __ xorl(out, right); |
| 6219 break; | 6240 break; |
| 6220 case Token::kADD: | 6241 case Token::kADD: |
| 6221 __ addl(out, right); | 6242 __ addl(out, right); |
| 6222 break; | 6243 break; |
| 6223 case Token::kSUB: | 6244 case Token::kSUB: |
| 6224 __ subl(out, right); | 6245 __ subl(out, right); |
| 6225 break; | 6246 break; |
| 6247 case Token::kMUL: | |
| 6248 __ mull(right); // Result in EDX:EAX. | |
| 6249 ASSERT(out == EAX); | |
| 6250 ASSERT(locs()->temp(0).reg() == EDX); | |
| 6251 break; | |
| 6226 default: | 6252 default: |
| 6227 UNREACHABLE(); | 6253 UNREACHABLE(); |
| 6228 } | 6254 } |
| 6229 } | 6255 } |
| 6230 | 6256 |
| 6231 | 6257 |
| 6232 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, | 6258 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
| 6233 bool opt) const { | 6259 bool opt) const { |
| 6234 const intptr_t kNumInputs = 2; | 6260 const intptr_t kNumInputs = 2; |
| 6235 const intptr_t kNumTemps = 0; | 6261 const intptr_t kNumTemps = 0; |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6830 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6856 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6831 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6857 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6832 #endif | 6858 #endif |
| 6833 } | 6859 } |
| 6834 | 6860 |
| 6835 } // namespace dart | 6861 } // namespace dart |
| 6836 | 6862 |
| 6837 #undef __ | 6863 #undef __ |
| 6838 | 6864 |
| 6839 #endif // defined TARGET_ARCH_IA32 | 6865 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |