| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 token_index(), | 225 token_index(), |
| 226 try_index(), | 226 try_index(), |
| 227 operator_name, | 227 operator_name, |
| 228 kNumberOfArguments, | 228 kNumberOfArguments, |
| 229 kNoArgumentNames, | 229 kNoArgumentNames, |
| 230 kNumArgumentsChecked); | 230 kNumArgumentsChecked); |
| 231 __ Bind(&done); | 231 __ Bind(&done); |
| 232 } | 232 } |
| 233 | 233 |
| 234 | 234 |
| 235 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 236 if ((operands_class_id() == kSmi) || (operands_class_id() == kDouble)) { |
| 237 const intptr_t kNumInputs = 2; |
| 238 const intptr_t kNumTemps = 1; |
| 239 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 240 summary->set_in(0, Location::RequiresRegister()); |
| 241 summary->set_in(1, Location::RequiresRegister()); |
| 242 summary->set_out(Location::RequiresRegister()); |
| 243 summary->set_temp(0, Location::RequiresRegister()); |
| 244 return summary; |
| 245 } |
| 246 ASSERT(operands_class_id() == kObject); |
| 247 return MakeCallSummary(); |
| 248 } |
| 249 |
| 250 |
| 251 static Condition TokenKindToSmiCondition(Token::Kind kind) { |
| 252 switch (kind) { |
| 253 case Token::kEQ: return EQUAL; |
| 254 case Token::kNE: return NOT_EQUAL; |
| 255 case Token::kLT: return LESS; |
| 256 case Token::kGT: return GREATER; |
| 257 case Token::kLTE: return LESS_EQUAL; |
| 258 case Token::kGTE: return GREATER_EQUAL; |
| 259 default: |
| 260 UNREACHABLE(); |
| 261 return OVERFLOW; |
| 262 } |
| 263 } |
| 264 |
| 265 |
| 266 static void EmitSmiRelationalOp(FlowGraphCompiler* compiler, |
| 267 RelationalOpComp* comp) { |
| 268 Register left = comp->locs()->in(0).reg(); |
| 269 Register right = comp->locs()->in(1).reg(); |
| 270 Register result = comp->locs()->out().reg(); |
| 271 Register temp = comp->locs()->temp(0).reg(); |
| 272 Label* deopt = compiler->AddDeoptStub(comp->cid(), |
| 273 comp->token_index(), |
| 274 comp->try_index(), |
| 275 kDeoptSmiCompareSmis, |
| 276 left, |
| 277 right); |
| 278 __ movl(temp, left); |
| 279 __ orl(temp, right); |
| 280 __ testl(temp, Immediate(kSmiTagMask)); |
| 281 __ j(NOT_ZERO, deopt); |
| 282 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 283 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 284 Condition condition = TokenKindToSmiCondition(comp->kind()); |
| 285 |
| 286 Label done, is_true; |
| 287 __ cmpl(left, right); |
| 288 __ j(condition, &is_true); |
| 289 __ LoadObject(result, bool_false); |
| 290 __ jmp(&done); |
| 291 __ Bind(&is_true); |
| 292 __ LoadObject(result, bool_true); |
| 293 __ Bind(&done); |
| 294 } |
| 295 |
| 296 |
| 297 static Condition TokenKindToDoubleCondition(Token::Kind kind) { |
| 298 switch (kind) { |
| 299 case Token::kEQ: return EQUAL; |
| 300 case Token::kLT: return BELOW; |
| 301 case Token::kGT: return ABOVE; |
| 302 case Token::kLTE: return BELOW_EQUAL; |
| 303 default: |
| 304 UNREACHABLE(); |
| 305 return OVERFLOW; |
| 306 } |
| 307 } |
| 308 |
| 309 |
| 310 static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler, |
| 311 RelationalOpComp* comp) { |
| 312 Register left = comp->locs()->in(0).reg(); |
| 313 Register right = comp->locs()->in(1).reg(); |
| 314 Register result = comp->locs()->out().reg(); |
| 315 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs. |
| 316 Register temp = comp->locs()->temp(0).reg(); |
| 317 Label* deopt = compiler->AddDeoptStub(comp->cid(), |
| 318 comp->token_index(), |
| 319 comp->try_index(), |
| 320 kDeoptDoubleComparison, |
| 321 left, |
| 322 right); |
| 323 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); |
| 324 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); |
| 325 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 326 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 327 Condition true_condition = TokenKindToDoubleCondition(comp->kind()); |
| 328 Label is_false, is_true, done; |
| 329 __ comisd(XMM0, XMM1); |
| 330 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false; |
| 331 __ j(true_condition, &is_true, Assembler::kNearJump); |
| 332 __ Bind(&is_false); |
| 333 __ LoadObject(result, bool_false); |
| 334 __ jmp(&done); |
| 335 __ Bind(&is_true); |
| 336 __ LoadObject(result, bool_true); |
| 337 __ Bind(&done); |
| 338 } |
| 339 |
| 340 |
| 341 |
| 342 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 343 if (operands_class_id() == kSmi) { |
| 344 EmitSmiRelationalOp(compiler, this); |
| 345 return; |
| 346 } |
| 347 if (operands_class_id() == kDouble) { |
| 348 EmitDoubleRelationalOp(compiler, this); |
| 349 return; |
| 350 } |
| 351 const String& function_name = |
| 352 String::ZoneHandle(String::NewSymbol(Token::Str(kind()))); |
| 353 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 354 cid(), |
| 355 token_index(), |
| 356 try_index()); |
| 357 const intptr_t kNumArguments = 2; |
| 358 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 359 compiler->GenerateInstanceCall(cid(), |
| 360 token_index(), |
| 361 try_index(), |
| 362 function_name, |
| 363 kNumArguments, |
| 364 Array::ZoneHandle(), // No optional arguments. |
| 365 kNumArgsChecked); |
| 366 ASSERT(locs()->out().reg() == EAX); |
| 367 } |
| 368 |
| 369 |
| 235 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 370 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
| 236 LocationSummary* locs = new LocationSummary(0, 3); | 371 LocationSummary* locs = new LocationSummary(0, 3); |
| 237 locs->set_temp(0, Location::RegisterLocation(EAX)); | 372 locs->set_temp(0, Location::RegisterLocation(EAX)); |
| 238 locs->set_temp(1, Location::RegisterLocation(ECX)); | 373 locs->set_temp(1, Location::RegisterLocation(ECX)); |
| 239 locs->set_temp(2, Location::RegisterLocation(EDX)); | 374 locs->set_temp(2, Location::RegisterLocation(EDX)); |
| 240 locs->set_out(Location::RequiresRegister()); | 375 locs->set_out(Location::RequiresRegister()); |
| 241 return locs; | 376 return locs; |
| 242 } | 377 } |
| 243 | 378 |
| 244 | 379 |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 | 900 |
| 766 ASSERT(!exception_var().is_captured()); | 901 ASSERT(!exception_var().is_captured()); |
| 767 ASSERT(!stacktrace_var().is_captured()); | 902 ASSERT(!stacktrace_var().is_captured()); |
| 768 __ movl(Address(EBP, exception_var().index() * kWordSize), | 903 __ movl(Address(EBP, exception_var().index() * kWordSize), |
| 769 kExceptionObjectReg); | 904 kExceptionObjectReg); |
| 770 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), | 905 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), |
| 771 kStackTraceObjectReg); | 906 kStackTraceObjectReg); |
| 772 } | 907 } |
| 773 | 908 |
| 774 | 909 |
| 910 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { |
| 911 return LocationSummary::Make(0, Location::NoLocation()); |
| 912 } |
| 913 |
| 914 |
| 915 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 916 __ cmpl(ESP, |
| 917 Address::Absolute(Isolate::Current()->stack_limit_address())); |
| 918 Label no_stack_overflow; |
| 919 __ j(ABOVE, &no_stack_overflow); |
| 920 compiler->GenerateCallRuntime(cid(), |
| 921 token_index(), |
| 922 try_index(), |
| 923 kStackOverflowRuntimeEntry); |
| 924 __ Bind(&no_stack_overflow); |
| 925 } |
| 926 |
| 927 |
| 775 LocationSummary* BinaryOpComp::MakeLocationSummary() const { | 928 LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
| 776 const intptr_t kNumInputs = 2; | 929 const intptr_t kNumInputs = 2; |
| 777 const intptr_t kNumTemps = 0; | 930 const intptr_t kNumTemps = 0; |
| 778 if (operands_type() == kDoubleOperands) { | 931 if (operands_type() == kDoubleOperands) { |
| 779 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 932 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 780 summary->set_in(0, Location::RequiresRegister()); | 933 summary->set_in(0, Location::RequiresRegister()); |
| 781 summary->set_in(1, Location::RequiresRegister()); | 934 summary->set_in(1, Location::RequiresRegister()); |
| 782 summary->set_out(Location::SameAsFirstInput()); | 935 summary->set_out(Location::SameAsFirstInput()); |
| 783 return summary; | 936 return summary; |
| 784 } | 937 } |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1094 UNREACHABLE(); | 1247 UNREACHABLE(); |
| 1095 } | 1248 } |
| 1096 } | 1249 } |
| 1097 | 1250 |
| 1098 | 1251 |
| 1099 } // namespace dart | 1252 } // namespace dart |
| 1100 | 1253 |
| 1101 #undef __ | 1254 #undef __ |
| 1102 | 1255 |
| 1103 #endif // defined TARGET_ARCH_X64 | 1256 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |