Chromium Code Reviews| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 token_index(), | 235 token_index(), |
| 236 try_index(), | 236 try_index(), |
| 237 operator_name, | 237 operator_name, |
| 238 kNumberOfArguments, | 238 kNumberOfArguments, |
| 239 kNoArgumentNames, | 239 kNoArgumentNames, |
| 240 kNumArgumentsChecked); | 240 kNumArgumentsChecked); |
| 241 __ Bind(&done); | 241 __ Bind(&done); |
| 242 } | 242 } |
| 243 | 243 |
| 244 | 244 |
| 245 static Condition TokenKindToSmiCondition(Token::Kind kind) { | |
| 246 switch (kind) { | |
| 247 case Token::kEQ: return EQUAL; | |
| 248 case Token::kNE: return NOT_EQUAL; | |
| 249 case Token::kLT: return LESS; | |
| 250 case Token::kGT: return GREATER; | |
| 251 case Token::kLTE: return LESS_EQUAL; | |
| 252 case Token::kGTE: return GREATER_EQUAL; | |
| 253 default: | |
| 254 UNREACHABLE(); | |
| 255 return OVERFLOW; | |
| 256 } | |
| 257 } | |
| 258 | |
| 259 | |
| 260 static void EmitSmiRelationalOp(FlowGraphCompiler* compiler, | |
| 261 RelationalOpComp* comp) { | |
| 262 Register left = comp->locs()->in(0).reg(); | |
| 263 Register right = comp->locs()->in(1).reg(); | |
| 264 Register result = comp->locs()->out().reg(); | |
| 265 Label* deopt = compiler->AddDeoptStub(comp->cid(), | |
| 266 comp->token_index(), | |
| 267 comp->try_index(), | |
| 268 kDeoptSmiCompareSmis, | |
| 269 left, | |
| 270 right); | |
| 271 __ movq(TMP, left); | |
| 272 __ orq(TMP, right); | |
| 273 __ testq(TMP, Immediate(kSmiTagMask)); | |
| 274 __ j(NOT_ZERO, deopt); | |
| 275 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 276 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 277 Condition condition = TokenKindToSmiCondition(comp->kind()); | |
| 278 | |
| 279 Label done, is_true; | |
| 280 __ cmpq(left, right); | |
| 281 __ j(condition, &is_true); | |
| 282 __ LoadObject(result, bool_false); | |
| 283 __ jmp(&done); | |
| 284 __ Bind(&is_true); | |
| 285 __ LoadObject(result, bool_true); | |
| 286 __ Bind(&done); | |
| 287 } | |
| 288 | |
| 289 | |
| 290 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | |
| 291 if (operands_class_id() == kSmi) { | |
| 292 const intptr_t kNumInputs = 2; | |
| 293 const intptr_t kNumTemps = 0; | |
| 294 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | |
| 295 summary->set_in(0, Location::RequiresRegister()); | |
| 296 summary->set_in(1, Location::RequiresRegister()); | |
| 297 summary->set_out(Location::RequiresRegister()); | |
| 298 return summary; | |
| 299 } | |
| 300 if (operands_class_id() == kDouble) { | |
| 301 const intptr_t kNumInputs = 2; | |
| 302 const intptr_t kNumTemps = 1; | |
| 303 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | |
| 304 summary->set_in(0, Location::RequiresRegister()); | |
| 305 summary->set_in(1, Location::RequiresRegister()); | |
| 306 summary->set_out(Location::RequiresRegister()); | |
| 307 summary->set_temp(0, Location::RequiresRegister()); | |
| 308 return summary; | |
| 309 } | |
| 310 ASSERT(operands_class_id() == kObject); | |
| 311 return MakeCallSummary(); | |
| 312 } | |
| 313 | |
| 314 | |
| 315 | |
| 316 static Condition TokenKindToDoubleCondition(Token::Kind kind) { | |
| 317 switch (kind) { | |
| 318 case Token::kEQ: return EQUAL; | |
| 319 case Token::kLT: return BELOW; | |
| 320 case Token::kGT: return ABOVE; | |
| 321 case Token::kLTE: return BELOW_EQUAL; | |
| 322 default: | |
| 323 UNREACHABLE(); | |
| 324 return OVERFLOW; | |
| 325 } | |
| 326 } | |
| 327 | |
| 328 | |
| 329 static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler, | |
| 330 RelationalOpComp* comp) { | |
| 331 Register left = comp->locs()->in(0).reg(); | |
| 332 Register right = comp->locs()->in(1).reg(); | |
| 333 Register result = comp->locs()->out().reg(); | |
| 334 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs. | |
| 335 Register temp = comp->locs()->temp(0).reg(); | |
| 336 Label* deopt = compiler->AddDeoptStub(comp->cid(), | |
| 337 comp->token_index(), | |
| 338 comp->try_index(), | |
| 339 kDeoptDoubleComparison, | |
| 340 left, | |
| 341 right); | |
| 342 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); | |
| 343 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); | |
| 344 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 345 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 346 Condition true_condition = TokenKindToDoubleCondition(comp->kind()); | |
| 347 Label is_false, is_true, done; | |
| 348 __ comisd(XMM0, XMM1); | |
| 349 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false; | |
| 350 __ j(true_condition, &is_true, Assembler::kNearJump); | |
| 351 __ Bind(&is_false); | |
| 352 __ LoadObject(result, bool_false); | |
| 353 __ jmp(&done); | |
| 354 __ Bind(&is_true); | |
| 355 __ LoadObject(result, bool_true); | |
| 356 __ Bind(&done); | |
| 357 } | |
| 358 | |
| 359 | |
| 360 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 361 if (operands_class_id() == kSmi) { | |
| 362 EmitSmiRelationalOp(compiler, this); | |
| 363 return; | |
| 364 } | |
| 365 if (operands_class_id() == kDouble) { | |
| 366 EmitDoubleRelationalOp(compiler, this); | |
| 367 return; | |
| 368 } | |
| 369 const String& function_name = | |
| 370 String::ZoneHandle(String::NewSymbol(Token::Str(kind()))); | |
| 371 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | |
| 372 cid(), | |
| 373 token_index(), | |
| 374 try_index()); | |
| 375 const intptr_t kNumArguments = 2; | |
| 376 const intptr_t kNumArgsChecked = 2; // Type-feedback. | |
| 377 compiler->GenerateInstanceCall(cid(), | |
| 378 token_index(), | |
| 379 try_index(), | |
| 380 function_name, | |
| 381 kNumArguments, | |
| 382 Array::ZoneHandle(), // No optional arguments. | |
| 383 kNumArgsChecked); | |
| 384 ASSERT(locs()->out().reg() == RAX); | |
| 385 } | |
| 386 | |
| 387 | |
| 245 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 388 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
| 246 LocationSummary* locs = new LocationSummary(0, 3); | 389 LocationSummary* locs = new LocationSummary(0, 3); |
| 247 locs->set_temp(0, Location::RegisterLocation(RAX)); | 390 locs->set_temp(0, Location::RegisterLocation(RAX)); |
| 248 locs->set_temp(1, Location::RegisterLocation(RBX)); | 391 locs->set_temp(1, Location::RegisterLocation(RBX)); |
| 249 locs->set_temp(2, Location::RegisterLocation(R10)); | 392 locs->set_temp(2, Location::RegisterLocation(R10)); |
| 250 locs->set_out(Location::RequiresRegister()); | 393 locs->set_out(Location::RequiresRegister()); |
| 251 return locs; | 394 return locs; |
| 252 } | 395 } |
| 253 | 396 |
| 254 | 397 |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 | 1000 |
| 858 ASSERT(!exception_var().is_captured()); | 1001 ASSERT(!exception_var().is_captured()); |
| 859 ASSERT(!stacktrace_var().is_captured()); | 1002 ASSERT(!stacktrace_var().is_captured()); |
| 860 __ movq(Address(RBP, exception_var().index() * kWordSize), | 1003 __ movq(Address(RBP, exception_var().index() * kWordSize), |
| 861 kExceptionObjectReg); | 1004 kExceptionObjectReg); |
| 862 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), | 1005 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), |
| 863 kStackTraceObjectReg); | 1006 kStackTraceObjectReg); |
| 864 } | 1007 } |
| 865 | 1008 |
| 866 | 1009 |
| 1010 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { | |
| 1011 return LocationSummary::Make(0, Location::NoLocation()); | |
| 1012 } | |
| 1013 | |
| 1014 | |
| 1015 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 1016 // Generate stack overflow check. | |
| 1017 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address())); | |
|
Vyacheslav Egorov (Google)
2012/06/11 12:51:21
I though we can use TMP only in the assembler itse
srdjan
2012/06/11 16:00:50
Yes, unfortunately, we are using TMP outside in se
| |
| 1018 __ cmpq(RSP, Address(TMP, 0)); | |
| 1019 Label no_stack_overflow; | |
| 1020 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); | |
| 1021 compiler->GenerateCallRuntime(cid(), | |
| 1022 token_index(), | |
| 1023 try_index(), | |
| 1024 kStackOverflowRuntimeEntry); | |
| 1025 __ Bind(&no_stack_overflow); | |
| 1026 } | |
| 1027 | |
| 1028 | |
| 867 LocationSummary* BinaryOpComp::MakeLocationSummary() const { | 1029 LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
| 868 const intptr_t kNumInputs = 2; | 1030 const intptr_t kNumInputs = 2; |
| 869 | 1031 |
| 870 if (operands_type() == kDoubleOperands) { | 1032 if (operands_type() == kDoubleOperands) { |
| 871 const intptr_t kNumTemps = 1; | 1033 const intptr_t kNumTemps = 1; |
| 872 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1034 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 873 summary->set_in(0, Location::RequiresRegister()); | 1035 summary->set_in(0, Location::RequiresRegister()); |
| 874 summary->set_in(1, Location::RequiresRegister()); | 1036 summary->set_in(1, Location::RequiresRegister()); |
| 875 summary->set_out(Location::RegisterLocation(RAX)); | 1037 summary->set_out(Location::RegisterLocation(RAX)); |
| 876 summary->set_temp(0, Location::RequiresRegister()); | 1038 summary->set_temp(0, Location::RequiresRegister()); |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1221 } else { | 1383 } else { |
| 1222 UNREACHABLE(); | 1384 UNREACHABLE(); |
| 1223 } | 1385 } |
| 1224 } | 1386 } |
| 1225 | 1387 |
| 1226 } // namespace dart | 1388 } // namespace dart |
| 1227 | 1389 |
| 1228 #undef __ | 1390 #undef __ |
| 1229 | 1391 |
| 1230 #endif // defined TARGET_ARCH_X64 | 1392 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |