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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 } | 358 } |
359 return true_condition; | 359 return true_condition; |
360 } | 360 } |
361 | 361 |
362 | 362 |
363 static void EmitJavascriptIntOverflowCheck(FlowGraphCompiler* compiler, | 363 static void EmitJavascriptIntOverflowCheck(FlowGraphCompiler* compiler, |
364 Label* overflow, | 364 Label* overflow, |
365 XmmRegister result, | 365 XmmRegister result, |
366 Register tmp) { | 366 Register tmp) { |
367 // Compare upper half. | 367 // Compare upper half. |
368 Label check_lower, done; | 368 Label check_lower; |
369 __ pextrd(tmp, result, Immediate(1)); | 369 __ pextrd(tmp, result, Immediate(1)); |
370 __ cmpl(tmp, Immediate(0x00200000)); | 370 __ cmpl(tmp, Immediate(0x00200000)); |
371 __ j(GREATER, overflow); | 371 __ j(GREATER, overflow); |
372 __ j(NOT_EQUAL, &check_lower); | 372 __ j(NOT_EQUAL, &check_lower); |
373 | 373 |
374 __ pextrd(tmp, result, Immediate(0)); | 374 __ pextrd(tmp, result, Immediate(0)); |
375 __ cmpl(tmp, Immediate(0)); | 375 __ cmpl(tmp, Immediate(0)); |
376 __ j(ABOVE, overflow); | 376 __ j(ABOVE, overflow); |
377 | 377 |
378 __ Bind(&check_lower); | 378 __ Bind(&check_lower); |
379 __ pextrd(tmp, result, Immediate(1)); | 379 __ pextrd(tmp, result, Immediate(1)); |
380 __ cmpl(tmp, Immediate(-0x00200000)); | 380 __ cmpl(tmp, Immediate(-0x00200000)); |
381 __ j(LESS, overflow); | 381 __ j(LESS, overflow); |
382 // Anything in the lower part would make the number bigger than the lower | 382 // Anything in the lower part would make the number bigger than the lower |
383 // bound, so we are done. | 383 // bound, so we are done. |
384 | |
385 __ Bind(&done); | |
386 } | 384 } |
387 | 385 |
388 | 386 |
389 static Condition TokenKindToMintCondition(Token::Kind kind) { | 387 static Condition TokenKindToMintCondition(Token::Kind kind) { |
390 switch (kind) { | 388 switch (kind) { |
391 case Token::kEQ: return EQUAL; | 389 case Token::kEQ: return EQUAL; |
392 case Token::kNE: return NOT_EQUAL; | 390 case Token::kNE: return NOT_EQUAL; |
393 case Token::kLT: return LESS; | 391 case Token::kLT: return LESS; |
394 case Token::kGT: return GREATER; | 392 case Token::kGT: return GREATER; |
395 case Token::kLTE: return LESS_EQUAL; | 393 case Token::kLTE: return LESS_EQUAL; |
(...skipping 4774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5170 const intptr_t kNumInputs = 1; | 5168 const intptr_t kNumInputs = 1; |
5171 const intptr_t value_cid = value()->Type()->ToCid(); | 5169 const intptr_t value_cid = value()->Type()->ToCid(); |
5172 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kMintCid)); | 5170 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kMintCid)); |
5173 const bool needs_writable_input = (value_cid == kSmiCid); | 5171 const bool needs_writable_input = (value_cid == kSmiCid); |
5174 const intptr_t kNumTemps = needs_temp ? 1 : 0; | 5172 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
5175 LocationSummary* summary = | 5173 LocationSummary* summary = |
5176 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5174 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5177 summary->set_in(0, needs_writable_input | 5175 summary->set_in(0, needs_writable_input |
5178 ? Location::WritableRegister() | 5176 ? Location::WritableRegister() |
5179 : Location::RequiresRegister()); | 5177 : Location::RequiresRegister()); |
5180 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); | 5178 if (needs_temp) { |
| 5179 summary->set_temp(0, Location::RequiresRegister()); |
| 5180 } |
5181 summary->set_out(0, Location::RequiresFpuRegister()); | 5181 summary->set_out(0, Location::RequiresFpuRegister()); |
5182 return summary; | 5182 return summary; |
5183 } | 5183 } |
5184 | 5184 |
5185 | 5185 |
5186 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5186 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5187 const intptr_t value_cid = value()->Type()->ToCid(); | 5187 const intptr_t value_cid = value()->Type()->ToCid(); |
5188 const Register value = locs()->in(0).reg(); | 5188 const Register value = locs()->in(0).reg(); |
5189 const XmmRegister result = locs()->out(0).fpu_reg(); | 5189 const XmmRegister result = locs()->out(0).fpu_reg(); |
5190 | 5190 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5407 summary->set_out(0, Location::SameAsFirstInput()); | 5407 summary->set_out(0, Location::SameAsFirstInput()); |
5408 return summary; | 5408 return summary; |
5409 } | 5409 } |
5410 | 5410 |
5411 | 5411 |
5412 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5412 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5413 XmmRegister left = locs()->in(0).fpu_reg(); | 5413 XmmRegister left = locs()->in(0).fpu_reg(); |
5414 ASSERT(locs()->in(1).reg() == ECX); | 5414 ASSERT(locs()->in(1).reg() == ECX); |
5415 ASSERT(locs()->out(0).fpu_reg() == left); | 5415 ASSERT(locs()->out(0).fpu_reg() == left); |
5416 | 5416 |
5417 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 5417 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
5418 kDeoptShiftMintOp); | 5418 kDeoptShiftMintOp); |
5419 Label done; | 5419 Label done; |
5420 __ testl(ECX, ECX); | 5420 __ testl(ECX, ECX); |
5421 __ j(ZERO, &done); // Shift by 0 is a nop. | 5421 __ j(ZERO, &done); // Shift by 0 is a nop. |
5422 __ subl(ESP, Immediate(2 * kWordSize)); | 5422 __ subl(ESP, Immediate(2 * kWordSize)); |
5423 __ movq(Address(ESP, 0), left); | 5423 __ movq(Address(ESP, 0), left); |
5424 // Deoptimize if shift count is > 31. | 5424 // Deoptimize if shift count is > 31. |
5425 // sarl operation masks the count to 5 bits and | 5425 // sarl operation masks the count to 5 bits and |
5426 // shrd is undefined with count > operand size (32) | 5426 // shrd is undefined with count > operand size (32) |
5427 // TODO(fschneider): Support shift counts > 31 without deoptimization. | 5427 // TODO(fschneider): Support shift counts > 31 without deoptimization. |
5428 __ SmiUntag(ECX); | 5428 __ SmiUntag(ECX); |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5803 PcDescriptors::kOther, | 5803 PcDescriptors::kOther, |
5804 locs()); | 5804 locs()); |
5805 __ Drop(ArgumentCount()); // Discard arguments. | 5805 __ Drop(ArgumentCount()); // Discard arguments. |
5806 } | 5806 } |
5807 | 5807 |
5808 } // namespace dart | 5808 } // namespace dart |
5809 | 5809 |
5810 #undef __ | 5810 #undef __ |
5811 | 5811 |
5812 #endif // defined TARGET_ARCH_IA32 | 5812 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |