| 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 case Token::kADD: |
| 5851 case Token::kSUB: |
| 5852 case Token::kMUL: { |
| 5850 const intptr_t kNumTemps = 0; | 5853 const intptr_t kNumTemps = 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; | |
| 5859 } | |
| 5860 case Token::kADD: | |
| 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; | 5864 return summary; |
| 5871 } | 5865 } |
| 5872 default: | 5866 default: |
| 5873 UNREACHABLE(); | 5867 UNREACHABLE(); |
| 5874 return NULL; | 5868 return NULL; |
| 5875 } | 5869 } |
| 5876 } | 5870 } |
| 5877 | 5871 |
| 5878 | 5872 |
| 5879 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5873 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5913 __ adcl(left_hi, right_hi); | 5907 __ adcl(left_hi, right_hi); |
| 5914 } else { | 5908 } else { |
| 5915 __ subl(left_lo, right_lo); | 5909 __ subl(left_lo, right_lo); |
| 5916 __ sbbl(left_hi, right_hi); | 5910 __ sbbl(left_hi, right_hi); |
| 5917 } | 5911 } |
| 5918 if (can_overflow()) { | 5912 if (can_overflow()) { |
| 5919 __ j(OVERFLOW, deopt); | 5913 __ j(OVERFLOW, deopt); |
| 5920 } | 5914 } |
| 5921 break; | 5915 break; |
| 5922 } | 5916 } |
| 5923 default: UNREACHABLE(); | 5917 case Token::kMUL: { |
| 5918 ASSERT(left_lo == EAX); |
| 5919 __ mull(right_lo); // Result in EDX:EAX. |
| 5920 ASSERT(out_lo == EAX); |
| 5921 ASSERT(out_hi == EDX); |
| 5922 if (can_overflow()) { |
| 5923 __ testl(out_hi, Immediate(0xc0000000)); |
| 5924 __ j(NOT_ZERO, deopt); |
| 5925 } |
| 5926 break; |
| 5927 } |
| 5928 default: |
| 5929 UNREACHABLE(); |
| 5924 } | 5930 } |
| 5925 if (FLAG_throw_on_javascript_int_overflow) { | 5931 if (FLAG_throw_on_javascript_int_overflow) { |
| 5926 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | 5932 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
| 5927 } | 5933 } |
| 5928 } | 5934 } |
| 5929 | 5935 |
| 5930 | 5936 |
| 5931 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, | 5937 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, |
| 5932 bool opt) const { | 5938 bool opt) const { |
| 5933 const intptr_t kNumInputs = 2; | 5939 const intptr_t kNumInputs = 2; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6031 } | 6037 } |
| 6032 } else { | 6038 } else { |
| 6033 __ shld(left_hi, left_lo, Immediate(shift)); | 6039 __ shld(left_hi, left_lo, Immediate(shift)); |
| 6034 __ shll(left_lo, Immediate(shift)); | 6040 __ shll(left_lo, Immediate(shift)); |
| 6035 } | 6041 } |
| 6036 } | 6042 } |
| 6037 break; | 6043 break; |
| 6038 } | 6044 } |
| 6039 default: | 6045 default: |
| 6040 UNREACHABLE(); | 6046 UNREACHABLE(); |
| 6041 break; | |
| 6042 } | 6047 } |
| 6043 } else { | 6048 } else { |
| 6044 // Code for a variable shift amount. | 6049 // Code for a variable shift amount. |
| 6045 // Deoptimize if shift count is > 63. | 6050 // Deoptimize if shift count is > 63. |
| 6046 // sarl operation masks the count to 5 bits and | 6051 // sarl operation masks the count to 5 bits and |
| 6047 // shrd is undefined with count > operand size (32) | 6052 // shrd is undefined with count > operand size (32) |
| 6048 __ SmiUntag(ECX); | 6053 __ SmiUntag(ECX); |
| 6049 if (has_shift_count_check()) { | 6054 if (has_shift_count_check()) { |
| 6050 __ cmpl(ECX, Immediate(kMintShiftCountLimit)); | 6055 __ cmpl(ECX, Immediate(kMintShiftCountLimit)); |
| 6051 __ j(ABOVE, deopt); | 6056 __ j(ABOVE, deopt); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6107 __ Bind(&large_shift); | 6112 __ Bind(&large_shift); |
| 6108 __ subl(ECX, Immediate(32)); | 6113 __ subl(ECX, Immediate(32)); |
| 6109 __ movl(left_hi, left_lo); // Shift by 32. | 6114 __ movl(left_hi, left_lo); // Shift by 32. |
| 6110 __ xorl(left_lo, left_lo); // Zero left_lo. | 6115 __ xorl(left_lo, left_lo); // Zero left_lo. |
| 6111 __ shll(left_hi, ECX); // Shift count in CL. | 6116 __ shll(left_hi, ECX); // Shift count in CL. |
| 6112 } | 6117 } |
| 6113 break; | 6118 break; |
| 6114 } | 6119 } |
| 6115 default: | 6120 default: |
| 6116 UNREACHABLE(); | 6121 UNREACHABLE(); |
| 6117 break; | |
| 6118 } | 6122 } |
| 6119 __ Bind(&done); | 6123 __ Bind(&done); |
| 6120 } | 6124 } |
| 6121 if (FLAG_throw_on_javascript_int_overflow) { | 6125 if (FLAG_throw_on_javascript_int_overflow) { |
| 6122 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | 6126 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
| 6123 } | 6127 } |
| 6124 } | 6128 } |
| 6125 | 6129 |
| 6126 | 6130 |
| 6127 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, | 6131 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6186 | 6190 |
| 6187 | 6191 |
| 6188 CompileType UnboxUint32Instr::ComputeType() const { | 6192 CompileType UnboxUint32Instr::ComputeType() const { |
| 6189 return CompileType::Int(); | 6193 return CompileType::Int(); |
| 6190 } | 6194 } |
| 6191 | 6195 |
| 6192 | 6196 |
| 6193 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | 6197 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
| 6194 bool opt) const { | 6198 bool opt) const { |
| 6195 const intptr_t kNumInputs = 2; | 6199 const intptr_t kNumInputs = 2; |
| 6196 const intptr_t kNumTemps = 0; | 6200 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0; |
| 6197 LocationSummary* summary = new(isolate) LocationSummary( | 6201 LocationSummary* summary = new(isolate) LocationSummary( |
| 6198 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6202 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6199 summary->set_in(0, Location::RequiresRegister()); | 6203 if (op_kind() == Token::kMUL) { |
| 6204 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 6205 summary->set_temp(0, Location::RegisterLocation(EDX)); |
| 6206 } else { |
| 6207 summary->set_in(0, Location::RequiresRegister()); |
| 6208 } |
| 6200 summary->set_in(1, Location::RequiresRegister()); | 6209 summary->set_in(1, Location::RequiresRegister()); |
| 6201 summary->set_out(0, Location::SameAsFirstInput()); | 6210 summary->set_out(0, Location::SameAsFirstInput()); |
| 6202 return summary; | 6211 return summary; |
| 6203 } | 6212 } |
| 6204 | 6213 |
| 6205 | 6214 |
| 6206 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6215 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6207 Register left = locs()->in(0).reg(); | 6216 Register left = locs()->in(0).reg(); |
| 6208 Register right = locs()->in(1).reg(); | 6217 Register right = locs()->in(1).reg(); |
| 6209 Register out = locs()->out(0).reg(); | 6218 Register out = locs()->out(0).reg(); |
| 6210 ASSERT(out == left); | 6219 ASSERT(out == left); |
| 6211 switch (op_kind()) { | 6220 switch (op_kind()) { |
| 6212 case Token::kBIT_AND: | 6221 case Token::kBIT_AND: |
| 6213 __ andl(out, right); | 6222 __ andl(out, right); |
| 6214 break; | 6223 break; |
| 6215 case Token::kBIT_OR: | 6224 case Token::kBIT_OR: |
| 6216 __ orl(out, right); | 6225 __ orl(out, right); |
| 6217 break; | 6226 break; |
| 6218 case Token::kBIT_XOR: | 6227 case Token::kBIT_XOR: |
| 6219 __ xorl(out, right); | 6228 __ xorl(out, right); |
| 6220 break; | 6229 break; |
| 6221 case Token::kADD: | 6230 case Token::kADD: |
| 6222 __ addl(out, right); | 6231 __ addl(out, right); |
| 6223 break; | 6232 break; |
| 6224 case Token::kSUB: | 6233 case Token::kSUB: |
| 6225 __ subl(out, right); | 6234 __ subl(out, right); |
| 6226 break; | 6235 break; |
| 6236 case Token::kMUL: |
| 6237 __ mull(right); // Result in EDX:EAX. |
| 6238 ASSERT(out == EAX); |
| 6239 ASSERT(locs()->temp(0).reg() == EDX); |
| 6240 break; |
| 6227 default: | 6241 default: |
| 6228 UNREACHABLE(); | 6242 UNREACHABLE(); |
| 6229 } | 6243 } |
| 6230 } | 6244 } |
| 6231 | 6245 |
| 6232 | 6246 |
| 6233 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, | 6247 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
| 6234 bool opt) const { | 6248 bool opt) const { |
| 6235 const intptr_t kNumInputs = 2; | 6249 const intptr_t kNumInputs = 2; |
| 6236 const intptr_t kNumTemps = 0; | 6250 const intptr_t kNumTemps = 0; |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6831 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6845 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6832 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6846 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6833 #endif | 6847 #endif |
| 6834 } | 6848 } |
| 6835 | 6849 |
| 6836 } // namespace dart | 6850 } // namespace dart |
| 6837 | 6851 |
| 6838 #undef __ | 6852 #undef __ |
| 6839 | 6853 |
| 6840 #endif // defined TARGET_ARCH_IA32 | 6854 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |