| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 StringAddStub stub(NO_STRING_ADD_FLAGS); | 704 StringAddStub stub(NO_STRING_ADD_FLAGS); |
| 705 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 705 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 706 break; | 706 break; |
| 707 } | 707 } |
| 708 case CodeStub::StringCompare: { | 708 case CodeStub::StringCompare: { |
| 709 StringCompareStub stub; | 709 StringCompareStub stub; |
| 710 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 710 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 711 break; | 711 break; |
| 712 } | 712 } |
| 713 case CodeStub::TranscendentalCache: { | 713 case CodeStub::TranscendentalCache: { |
| 714 TranscendentalCacheStub stub(instr->transcendental_type()); | 714 TranscendentalCacheStub stub(instr->transcendental_type(), |
| 715 TranscendentalCacheStub::TAGGED); |
| 715 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 716 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 716 break; | 717 break; |
| 717 } | 718 } |
| 718 default: | 719 default: |
| 719 UNREACHABLE(); | 720 UNREACHABLE(); |
| 720 } | 721 } |
| 721 } | 722 } |
| 722 | 723 |
| 723 | 724 |
| 724 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 725 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1572 InstanceType to = instr->to(); | 1573 InstanceType to = instr->to(); |
| 1573 if (from == to) return equal; | 1574 if (from == to) return equal; |
| 1574 if (to == LAST_TYPE) return above_equal; | 1575 if (to == LAST_TYPE) return above_equal; |
| 1575 if (from == FIRST_TYPE) return below_equal; | 1576 if (from == FIRST_TYPE) return below_equal; |
| 1576 UNREACHABLE(); | 1577 UNREACHABLE(); |
| 1577 return equal; | 1578 return equal; |
| 1578 } | 1579 } |
| 1579 | 1580 |
| 1580 | 1581 |
| 1581 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { | 1582 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { |
| 1582 Abort("Unimplemented: %s", "DoHasInstanceType"); | 1583 Register input = ToRegister(instr->InputAt(0)); |
| 1584 Register result = ToRegister(instr->result()); |
| 1585 |
| 1586 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
| 1587 __ testl(input, Immediate(kSmiTagMask)); |
| 1588 NearLabel done, is_false; |
| 1589 __ j(zero, &is_false); |
| 1590 __ CmpObjectType(input, TestType(instr->hydrogen()), result); |
| 1591 __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false); |
| 1592 __ LoadRoot(result, Heap::kTrueValueRootIndex); |
| 1593 __ jmp(&done); |
| 1594 __ bind(&is_false); |
| 1595 __ LoadRoot(result, Heap::kFalseValueRootIndex); |
| 1596 __ bind(&done); |
| 1583 } | 1597 } |
| 1584 | 1598 |
| 1585 | 1599 |
| 1586 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 1600 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { |
| 1587 Register input = ToRegister(instr->InputAt(0)); | 1601 Register input = ToRegister(instr->InputAt(0)); |
| 1588 | 1602 |
| 1589 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1603 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1590 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1604 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1591 | 1605 |
| 1592 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1606 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2264 | 2278 |
| 2265 | 2279 |
| 2266 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2280 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
| 2267 ASSERT(ToRegister(instr->result()).is(rax)); | 2281 ASSERT(ToRegister(instr->result()).is(rax)); |
| 2268 __ Move(rdi, instr->function()); | 2282 __ Move(rdi, instr->function()); |
| 2269 CallKnownFunction(instr->function(), instr->arity(), instr); | 2283 CallKnownFunction(instr->function(), instr->arity(), instr); |
| 2270 } | 2284 } |
| 2271 | 2285 |
| 2272 | 2286 |
| 2273 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2287 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
| 2274 Abort("Unimplemented: %s", "DoDeferredMathAbsTaggedHeapNumber"); | 2288 Register input_reg = ToRegister(instr->InputAt(0)); |
| 2289 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 2290 Heap::kHeapNumberMapRootIndex); |
| 2291 DeoptimizeIf(not_equal, instr->environment()); |
| 2292 |
| 2293 Label done; |
| 2294 Register tmp = input_reg.is(rax) ? rcx : rax; |
| 2295 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; |
| 2296 |
| 2297 // Preserve the value of all registers. |
| 2298 __ PushSafepointRegisters(); |
| 2299 |
| 2300 Label negative; |
| 2301 __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); |
| 2302 // Check the sign of the argument. If the argument is positive, just |
| 2303 // return it. We do not need to patch the stack since |input| and |
| 2304 // |result| are the same register and |input| will be restored |
| 2305 // unchanged by popping safepoint registers. |
| 2306 __ testl(tmp, Immediate(HeapNumber::kSignMask)); |
| 2307 __ j(not_zero, &negative); |
| 2308 __ jmp(&done); |
| 2309 |
| 2310 __ bind(&negative); |
| 2311 |
| 2312 Label allocated, slow; |
| 2313 __ AllocateHeapNumber(tmp, tmp2, &slow); |
| 2314 __ jmp(&allocated); |
| 2315 |
| 2316 // Slow case: Call the runtime system to do the number allocation. |
| 2317 __ bind(&slow); |
| 2318 |
| 2319 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 2320 RecordSafepointWithRegisters( |
| 2321 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); |
| 2322 // Set the pointer to the new heap number in tmp. |
| 2323 if (!tmp.is(rax)) { |
| 2324 __ movq(tmp, rax); |
| 2325 } |
| 2326 |
| 2327 // Restore input_reg after call to runtime. |
| 2328 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); |
| 2329 |
| 2330 __ bind(&allocated); |
| 2331 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 2332 __ shl(tmp2, Immediate(1)); |
| 2333 __ shr(tmp2, Immediate(1)); |
| 2334 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); |
| 2335 __ StoreToSafepointRegisterSlot(input_reg, tmp); |
| 2336 |
| 2337 __ bind(&done); |
| 2338 __ PopSafepointRegisters(); |
| 2339 } |
| 2340 |
| 2341 |
| 2342 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { |
| 2343 Register input_reg = ToRegister(instr->InputAt(0)); |
| 2344 __ testl(input_reg, input_reg); |
| 2345 Label is_positive; |
| 2346 __ j(not_sign, &is_positive); |
| 2347 __ negl(input_reg); // Sets flags. |
| 2348 DeoptimizeIf(negative, instr->environment()); |
| 2349 __ bind(&is_positive); |
| 2275 } | 2350 } |
| 2276 | 2351 |
| 2277 | 2352 |
| 2278 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 2353 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
| 2279 Abort("Unimplemented: %s", "DoMathAbs"); | 2354 // Class for deferred case. |
| 2355 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 2356 public: |
| 2357 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
| 2358 LUnaryMathOperation* instr) |
| 2359 : LDeferredCode(codegen), instr_(instr) { } |
| 2360 virtual void Generate() { |
| 2361 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
| 2362 } |
| 2363 private: |
| 2364 LUnaryMathOperation* instr_; |
| 2365 }; |
| 2366 |
| 2367 ASSERT(instr->InputAt(0)->Equals(instr->result())); |
| 2368 Representation r = instr->hydrogen()->value()->representation(); |
| 2369 |
| 2370 if (r.IsDouble()) { |
| 2371 XMMRegister scratch = xmm0; |
| 2372 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| 2373 __ xorpd(scratch, scratch); |
| 2374 __ subsd(scratch, input_reg); |
| 2375 __ andpd(input_reg, scratch); |
| 2376 } else if (r.IsInteger32()) { |
| 2377 EmitIntegerMathAbs(instr); |
| 2378 } else { // Tagged case. |
| 2379 DeferredMathAbsTaggedHeapNumber* deferred = |
| 2380 new DeferredMathAbsTaggedHeapNumber(this, instr); |
| 2381 Register input_reg = ToRegister(instr->InputAt(0)); |
| 2382 // Smi check. |
| 2383 __ JumpIfNotSmi(input_reg, deferred->entry()); |
| 2384 EmitIntegerMathAbs(instr); |
| 2385 __ bind(deferred->exit()); |
| 2386 } |
| 2280 } | 2387 } |
| 2281 | 2388 |
| 2282 | 2389 |
| 2283 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 2390 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
| 2284 XMMRegister xmm_scratch = xmm0; | 2391 XMMRegister xmm_scratch = xmm0; |
| 2285 Register output_reg = ToRegister(instr->result()); | 2392 Register output_reg = ToRegister(instr->result()); |
| 2286 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); | 2393 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| 2287 __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. | 2394 __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. |
| 2288 __ ucomisd(input_reg, xmm_scratch); | 2395 __ ucomisd(input_reg, xmm_scratch); |
| 2289 | 2396 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2353 __ sqrtsd(input_reg, input_reg); | 2460 __ sqrtsd(input_reg, input_reg); |
| 2354 } | 2461 } |
| 2355 | 2462 |
| 2356 | 2463 |
| 2357 void LCodeGen::DoPower(LPower* instr) { | 2464 void LCodeGen::DoPower(LPower* instr) { |
| 2358 Abort("Unimplemented: %s", "DoPower"); | 2465 Abort("Unimplemented: %s", "DoPower"); |
| 2359 } | 2466 } |
| 2360 | 2467 |
| 2361 | 2468 |
| 2362 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { | 2469 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { |
| 2363 Abort("Unimplemented: %s", "DoMathLog"); | 2470 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
| 2471 TranscendentalCacheStub stub(TranscendentalCache::LOG, |
| 2472 TranscendentalCacheStub::UNTAGGED); |
| 2473 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 2364 } | 2474 } |
| 2365 | 2475 |
| 2366 | 2476 |
| 2367 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { | 2477 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { |
| 2368 Abort("Unimplemented: %s", "DoMathCos"); | 2478 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
| 2479 TranscendentalCacheStub stub(TranscendentalCache::LOG, |
| 2480 TranscendentalCacheStub::UNTAGGED); |
| 2481 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 2369 } | 2482 } |
| 2370 | 2483 |
| 2371 | 2484 |
| 2372 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { | 2485 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { |
| 2373 Abort("Unimplemented: %s", "DoMathSin"); | 2486 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
| 2487 TranscendentalCacheStub stub(TranscendentalCache::LOG, |
| 2488 TranscendentalCacheStub::UNTAGGED); |
| 2489 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 2374 } | 2490 } |
| 2375 | 2491 |
| 2376 | 2492 |
| 2377 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { | 2493 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { |
| 2378 switch (instr->op()) { | 2494 switch (instr->op()) { |
| 2379 case kMathAbs: | 2495 case kMathAbs: |
| 2380 DoMathAbs(instr); | 2496 DoMathAbs(instr); |
| 2381 break; | 2497 break; |
| 2382 case kMathFloor: | 2498 case kMathFloor: |
| 2383 DoMathFloor(instr); | 2499 DoMathFloor(instr); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2407 } | 2523 } |
| 2408 | 2524 |
| 2409 | 2525 |
| 2410 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 2526 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
| 2411 ASSERT(ToRegister(instr->key()).is(rcx)); | 2527 ASSERT(ToRegister(instr->key()).is(rcx)); |
| 2412 ASSERT(ToRegister(instr->result()).is(rax)); | 2528 ASSERT(ToRegister(instr->result()).is(rax)); |
| 2413 | 2529 |
| 2414 int arity = instr->arity(); | 2530 int arity = instr->arity(); |
| 2415 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); | 2531 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); |
| 2416 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2532 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2533 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2417 } | 2534 } |
| 2418 | 2535 |
| 2419 | 2536 |
| 2420 void LCodeGen::DoCallNamed(LCallNamed* instr) { | 2537 void LCodeGen::DoCallNamed(LCallNamed* instr) { |
| 2421 ASSERT(ToRegister(instr->result()).is(rax)); | 2538 ASSERT(ToRegister(instr->result()).is(rax)); |
| 2422 | 2539 |
| 2423 int arity = instr->arity(); | 2540 int arity = instr->arity(); |
| 2424 Handle<Code> ic = StubCache::ComputeCallInitialize(arity, NOT_IN_LOOP); | 2541 Handle<Code> ic = StubCache::ComputeCallInitialize(arity, NOT_IN_LOOP); |
| 2425 __ Move(rcx, instr->name()); | 2542 __ Move(rcx, instr->name()); |
| 2426 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2543 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| (...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3435 RegisterEnvironmentForDeoptimization(environment); | 3552 RegisterEnvironmentForDeoptimization(environment); |
| 3436 ASSERT(osr_pc_offset_ == -1); | 3553 ASSERT(osr_pc_offset_ == -1); |
| 3437 osr_pc_offset_ = masm()->pc_offset(); | 3554 osr_pc_offset_ = masm()->pc_offset(); |
| 3438 } | 3555 } |
| 3439 | 3556 |
| 3440 #undef __ | 3557 #undef __ |
| 3441 | 3558 |
| 3442 } } // namespace v8::internal | 3559 } } // namespace v8::internal |
| 3443 | 3560 |
| 3444 #endif // V8_TARGET_ARCH_X64 | 3561 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |