| 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 // TODO(regis): Range analysis may eliminate the deopt check. |
| 5925 Register temp = locs()->temp(0).reg(); |
| 5926 __ movl(temp, left_lo); |
| 5927 __ sarl(temp, Immediate(31)); |
| 5928 __ cmpl(temp, left_hi); |
| 5929 __ j(NOT_EQUAL, deopt); |
| 5930 __ movl(temp, right_lo); |
| 5931 __ sarl(temp, Immediate(31)); |
| 5932 __ cmpl(temp, right_hi); |
| 5933 __ j(NOT_EQUAL, deopt); |
| 5934 ASSERT(left_lo == EAX); |
| 5935 __ imull(right_lo); // Result in EDX:EAX. |
| 5936 ASSERT(out_lo == EAX); |
| 5937 ASSERT(out_hi == EDX); |
| 5938 break; |
| 5939 } |
| 5940 default: |
| 5941 UNREACHABLE(); |
| 5924 } | 5942 } |
| 5925 if (FLAG_throw_on_javascript_int_overflow) { | 5943 if (FLAG_throw_on_javascript_int_overflow) { |
| 5926 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | 5944 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
| 5927 } | 5945 } |
| 5928 } | 5946 } |
| 5929 | 5947 |
| 5930 | 5948 |
| 5931 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, | 5949 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, |
| 5932 bool opt) const { | 5950 bool opt) const { |
| 5933 const intptr_t kNumInputs = 2; | 5951 const intptr_t kNumInputs = 2; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6106 __ Bind(&large_shift); | 6124 __ Bind(&large_shift); |
| 6107 // No need to subtract 32 from CL, only 5 bits used by shll. | 6125 // No need to subtract 32 from CL, only 5 bits used by shll. |
| 6108 __ movl(left_hi, left_lo); // Shift by 32. | 6126 __ movl(left_hi, left_lo); // Shift by 32. |
| 6109 __ xorl(left_lo, left_lo); // Zero left_lo. | 6127 __ xorl(left_lo, left_lo); // Zero left_lo. |
| 6110 __ shll(left_hi, ECX); // Shift count: CL % 32. | 6128 __ shll(left_hi, ECX); // Shift count: CL % 32. |
| 6111 } | 6129 } |
| 6112 break; | 6130 break; |
| 6113 } | 6131 } |
| 6114 default: | 6132 default: |
| 6115 UNREACHABLE(); | 6133 UNREACHABLE(); |
| 6116 break; | |
| 6117 } | 6134 } |
| 6118 __ Bind(&done); | 6135 __ Bind(&done); |
| 6119 } | 6136 } |
| 6120 if (FLAG_throw_on_javascript_int_overflow) { | 6137 if (FLAG_throw_on_javascript_int_overflow) { |
| 6121 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | 6138 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
| 6122 } | 6139 } |
| 6123 } | 6140 } |
| 6124 | 6141 |
| 6125 | 6142 |
| 6126 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, | 6143 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6185 | 6202 |
| 6186 | 6203 |
| 6187 CompileType UnboxUint32Instr::ComputeType() const { | 6204 CompileType UnboxUint32Instr::ComputeType() const { |
| 6188 return CompileType::Int(); | 6205 return CompileType::Int(); |
| 6189 } | 6206 } |
| 6190 | 6207 |
| 6191 | 6208 |
| 6192 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | 6209 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
| 6193 bool opt) const { | 6210 bool opt) const { |
| 6194 const intptr_t kNumInputs = 2; | 6211 const intptr_t kNumInputs = 2; |
| 6195 const intptr_t kNumTemps = 0; | 6212 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0; |
| 6196 LocationSummary* summary = new(isolate) LocationSummary( | 6213 LocationSummary* summary = new(isolate) LocationSummary( |
| 6197 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6214 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6198 summary->set_in(0, Location::RequiresRegister()); | 6215 if (op_kind() == Token::kMUL) { |
| 6216 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 6217 summary->set_temp(0, Location::RegisterLocation(EDX)); |
| 6218 } else { |
| 6219 summary->set_in(0, Location::RequiresRegister()); |
| 6220 } |
| 6199 summary->set_in(1, Location::RequiresRegister()); | 6221 summary->set_in(1, Location::RequiresRegister()); |
| 6200 summary->set_out(0, Location::SameAsFirstInput()); | 6222 summary->set_out(0, Location::SameAsFirstInput()); |
| 6201 return summary; | 6223 return summary; |
| 6202 } | 6224 } |
| 6203 | 6225 |
| 6204 | 6226 |
| 6205 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6227 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6206 Register left = locs()->in(0).reg(); | 6228 Register left = locs()->in(0).reg(); |
| 6207 Register right = locs()->in(1).reg(); | 6229 Register right = locs()->in(1).reg(); |
| 6208 Register out = locs()->out(0).reg(); | 6230 Register out = locs()->out(0).reg(); |
| 6209 ASSERT(out == left); | 6231 ASSERT(out == left); |
| 6210 switch (op_kind()) { | 6232 switch (op_kind()) { |
| 6211 case Token::kBIT_AND: | 6233 case Token::kBIT_AND: |
| 6212 __ andl(out, right); | 6234 __ andl(out, right); |
| 6213 break; | 6235 break; |
| 6214 case Token::kBIT_OR: | 6236 case Token::kBIT_OR: |
| 6215 __ orl(out, right); | 6237 __ orl(out, right); |
| 6216 break; | 6238 break; |
| 6217 case Token::kBIT_XOR: | 6239 case Token::kBIT_XOR: |
| 6218 __ xorl(out, right); | 6240 __ xorl(out, right); |
| 6219 break; | 6241 break; |
| 6220 case Token::kADD: | 6242 case Token::kADD: |
| 6221 __ addl(out, right); | 6243 __ addl(out, right); |
| 6222 break; | 6244 break; |
| 6223 case Token::kSUB: | 6245 case Token::kSUB: |
| 6224 __ subl(out, right); | 6246 __ subl(out, right); |
| 6225 break; | 6247 break; |
| 6248 case Token::kMUL: |
| 6249 __ mull(right); // Result in EDX:EAX. |
| 6250 ASSERT(out == EAX); |
| 6251 ASSERT(locs()->temp(0).reg() == EDX); |
| 6252 break; |
| 6226 default: | 6253 default: |
| 6227 UNREACHABLE(); | 6254 UNREACHABLE(); |
| 6228 } | 6255 } |
| 6229 } | 6256 } |
| 6230 | 6257 |
| 6231 | 6258 |
| 6232 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, | 6259 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
| 6233 bool opt) const { | 6260 bool opt) const { |
| 6234 const intptr_t kNumInputs = 2; | 6261 const intptr_t kNumInputs = 2; |
| 6235 const intptr_t kNumTemps = 0; | 6262 const intptr_t kNumTemps = 0; |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6830 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6857 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6831 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6858 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6832 #endif | 6859 #endif |
| 6833 } | 6860 } |
| 6834 | 6861 |
| 6835 } // namespace dart | 6862 } // namespace dart |
| 6836 | 6863 |
| 6837 #undef __ | 6864 #undef __ |
| 6838 | 6865 |
| 6839 #endif // defined TARGET_ARCH_IA32 | 6866 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |