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 |