Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 153773002: A64: Synchronize with r16679. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/debug-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 // xmm1 : untagged double input argument 1129 // xmm1 : untagged double input argument
1130 // Output: 1130 // Output:
1131 // xmm1 : untagged double result. 1131 // xmm1 : untagged double result.
1132 1132
1133 Label runtime_call; 1133 Label runtime_call;
1134 Label runtime_call_clear_stack; 1134 Label runtime_call_clear_stack;
1135 Label skip_cache; 1135 Label skip_cache;
1136 const bool tagged = (argument_type_ == TAGGED); 1136 const bool tagged = (argument_type_ == TAGGED);
1137 if (tagged) { 1137 if (tagged) {
1138 Label input_not_smi, loaded; 1138 Label input_not_smi, loaded;
1139
1139 // Test that rax is a number. 1140 // Test that rax is a number.
1140 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); 1141 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
1141 __ movq(rax, args.GetArgumentOperand(0)); 1142 __ movq(rax, args.GetArgumentOperand(0));
1142 __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear); 1143 __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear);
1143 // Input is a smi. Untag and load it onto the FPU stack. 1144 // Input is a smi. Untag and load it onto the FPU stack.
1144 // Then load the bits of the double into rbx. 1145 // Then load the bits of the double into rbx.
1145 __ SmiToInteger32(rax, rax); 1146 __ SmiToInteger32(rax, rax);
1146 __ subq(rsp, Immediate(kDoubleSize)); 1147 __ subq(rsp, Immediate(kDoubleSize));
1147 __ cvtlsi2sd(xmm1, rax); 1148 __ cvtlsi2sd(xmm1, rax);
1148 __ movsd(Operand(rsp, 0), xmm1); 1149 __ movsd(Operand(rsp, 0), xmm1);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); 1193 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize));
1193 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1)); 1194 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1));
1194 1195
1195 // ST[0] == double value. 1196 // ST[0] == double value.
1196 // rbx = bits of double value. 1197 // rbx = bits of double value.
1197 // rcx = TranscendentalCache::hash(double value). 1198 // rcx = TranscendentalCache::hash(double value).
1198 ExternalReference cache_array = 1199 ExternalReference cache_array =
1199 ExternalReference::transcendental_cache_array_address(masm->isolate()); 1200 ExternalReference::transcendental_cache_array_address(masm->isolate());
1200 __ movq(rax, cache_array); 1201 __ movq(rax, cache_array);
1201 int cache_array_index = 1202 int cache_array_index =
1202 type_ * sizeof(Isolate::Current()->transcendental_cache()->caches_[0]); 1203 type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]);
1203 __ movq(rax, Operand(rax, cache_array_index)); 1204 __ movq(rax, Operand(rax, cache_array_index));
1204 // rax points to the cache for the type type_. 1205 // rax points to the cache for the type type_.
1205 // If NULL, the cache hasn't been initialized yet, so go through runtime. 1206 // If NULL, the cache hasn't been initialized yet, so go through runtime.
1206 __ testq(rax, rax); 1207 __ testq(rax, rax);
1207 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED. 1208 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED.
1208 #ifdef DEBUG 1209 #ifdef DEBUG
1209 // Check that the layout of cache elements match expectations. 1210 // Check that the layout of cache elements match expectations.
1210 { // NOLINT - doesn't like a single brace on a line. 1211 { // NOLINT - doesn't like a single brace on a line.
1211 TranscendentalCache::SubCache::Element test_elem[2]; 1212 TranscendentalCache::SubCache::Element test_elem[2];
1212 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); 1213 char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). 1440 // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
1440 __ bind(&check_undefined_arg1); 1441 __ bind(&check_undefined_arg1);
1441 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); 1442 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
1442 __ j(not_equal, conversion_failure); 1443 __ j(not_equal, conversion_failure);
1443 __ Set(r8, 0); 1444 __ Set(r8, 0);
1444 __ jmp(&load_arg2); 1445 __ jmp(&load_arg2);
1445 1446
1446 __ bind(&arg1_is_object); 1447 __ bind(&arg1_is_object);
1447 __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), heap_number_map); 1448 __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), heap_number_map);
1448 __ j(not_equal, &check_undefined_arg1); 1449 __ j(not_equal, &check_undefined_arg1);
1449 // Get the untagged integer version of the rdx heap number in rcx. 1450 // Get the untagged integer version of the rdx heap number in r8.
1450 DoubleToIStub stub1(rdx, r8, HeapNumber::kValueOffset - kHeapObjectTag, 1451 __ TruncateHeapNumberToI(r8, rdx);
1451 true);
1452 __ call(stub1.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
1453 1452
1454 // Here r8 has the untagged integer, rax has a Smi or a heap number. 1453 // Here r8 has the untagged integer, rax has a Smi or a heap number.
1455 __ bind(&load_arg2); 1454 __ bind(&load_arg2);
1456 // Test if arg2 is a Smi. 1455 // Test if arg2 is a Smi.
1457 __ JumpIfNotSmi(rax, &arg2_is_object); 1456 __ JumpIfNotSmi(rax, &arg2_is_object);
1458 __ SmiToInteger32(rcx, rax); 1457 __ SmiToInteger32(rcx, rax);
1459 __ jmp(&done); 1458 __ jmp(&done);
1460 1459
1461 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). 1460 // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
1462 __ bind(&check_undefined_arg2); 1461 __ bind(&check_undefined_arg2);
1463 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 1462 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
1464 __ j(not_equal, conversion_failure); 1463 __ j(not_equal, conversion_failure);
1465 __ Set(rcx, 0); 1464 __ Set(rcx, 0);
1466 __ jmp(&done); 1465 __ jmp(&done);
1467 1466
1468 __ bind(&arg2_is_object); 1467 __ bind(&arg2_is_object);
1469 __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), heap_number_map); 1468 __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), heap_number_map);
1470 __ j(not_equal, &check_undefined_arg2); 1469 __ j(not_equal, &check_undefined_arg2);
1471 // Get the untagged integer version of the rax heap number in rcx. 1470 // Get the untagged integer version of the rax heap number in rcx.
1472 DoubleToIStub stub2(rax, rcx, HeapNumber::kValueOffset - kHeapObjectTag, 1471 __ TruncateHeapNumberToI(rcx, rax);
1473 true);
1474 __ call(stub2.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
1475 1472
1476 __ bind(&done); 1473 __ bind(&done);
1477 __ movl(rax, r8); 1474 __ movl(rax, r8);
1478 } 1475 }
1479 1476
1480 1477
1481 void FloatingPointHelper::LoadSSE2SmiOperands(MacroAssembler* masm) { 1478 void FloatingPointHelper::LoadSSE2SmiOperands(MacroAssembler* masm) {
1482 __ SmiToInteger32(kScratchRegister, rdx); 1479 __ SmiToInteger32(kScratchRegister, rdx);
1483 __ cvtlsi2sd(xmm0, kScratchRegister); 1480 __ cvtlsi2sd(xmm0, kScratchRegister);
1484 __ SmiToInteger32(kScratchRegister, rax); 1481 __ SmiToInteger32(kScratchRegister, rax);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 } else if (exponent_type_ == TAGGED) { 1638 } else if (exponent_type_ == TAGGED) {
1642 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); 1639 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
1643 __ SmiToInteger32(exponent, exponent); 1640 __ SmiToInteger32(exponent, exponent);
1644 __ jmp(&int_exponent); 1641 __ jmp(&int_exponent);
1645 1642
1646 __ bind(&exponent_not_smi); 1643 __ bind(&exponent_not_smi);
1647 __ movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset)); 1644 __ movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
1648 } 1645 }
1649 1646
1650 if (exponent_type_ != INTEGER) { 1647 if (exponent_type_ != INTEGER) {
1651 Label fast_power; 1648 Label fast_power, try_arithmetic_simplification;
1652 // Detect integer exponents stored as double. 1649 // Detect integer exponents stored as double.
1650 __ DoubleToI(exponent, double_exponent, double_scratch,
1651 TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification);
1652 __ jmp(&int_exponent);
1653
1654 __ bind(&try_arithmetic_simplification);
1653 __ cvttsd2si(exponent, double_exponent); 1655 __ cvttsd2si(exponent, double_exponent);
1654 // Skip to runtime if possibly NaN (indicated by the indefinite integer). 1656 // Skip to runtime if possibly NaN (indicated by the indefinite integer).
1655 __ cmpl(exponent, Immediate(0x80000000u)); 1657 __ cmpl(exponent, Immediate(0x80000000u));
1656 __ j(equal, &call_runtime); 1658 __ j(equal, &call_runtime);
1657 __ cvtlsi2sd(double_scratch, exponent);
1658 // Already ruled out NaNs for exponent.
1659 __ ucomisd(double_exponent, double_scratch);
1660 __ j(equal, &int_exponent);
1661 1659
1662 if (exponent_type_ == ON_STACK) { 1660 if (exponent_type_ == ON_STACK) {
1663 // Detect square root case. Crankshaft detects constant +/-0.5 at 1661 // Detect square root case. Crankshaft detects constant +/-0.5 at
1664 // compile time and uses DoMathPowHalf instead. We then skip this check 1662 // compile time and uses DoMathPowHalf instead. We then skip this check
1665 // for non-constant cases of +/-0.5 as these hardly occur. 1663 // for non-constant cases of +/-0.5 as these hardly occur.
1666 Label continue_sqrt, continue_rsqrt, not_plus_half; 1664 Label continue_sqrt, continue_rsqrt, not_plus_half;
1667 // Test for 0.5. 1665 // Test for 0.5.
1668 // Load double_scratch with 0.5. 1666 // Load double_scratch with 0.5.
1669 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000), RelocInfo::NONE64); 1667 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000), RelocInfo::NONE64);
1670 __ movq(double_scratch, scratch); 1668 __ movq(double_scratch, scratch);
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after
3485 3483
3486 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead 3484 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
3487 // of the original receiver from the call site). 3485 // of the original receiver from the call site).
3488 __ bind(&non_function); 3486 __ bind(&non_function);
3489 __ movq(args.GetReceiverOperand(), rdi); 3487 __ movq(args.GetReceiverOperand(), rdi);
3490 __ Set(rax, argc_); 3488 __ Set(rax, argc_);
3491 __ Set(rbx, 0); 3489 __ Set(rbx, 0);
3492 __ SetCallKind(rcx, CALL_AS_METHOD); 3490 __ SetCallKind(rcx, CALL_AS_METHOD);
3493 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); 3491 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
3494 Handle<Code> adaptor = 3492 Handle<Code> adaptor =
3495 Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline(); 3493 isolate->builtins()->ArgumentsAdaptorTrampoline();
3496 __ Jump(adaptor, RelocInfo::CODE_TARGET); 3494 __ Jump(adaptor, RelocInfo::CODE_TARGET);
3497 } 3495 }
3498 3496
3499 3497
3500 void CallConstructStub::Generate(MacroAssembler* masm) { 3498 void CallConstructStub::Generate(MacroAssembler* masm) {
3501 // rax : number of arguments 3499 // rax : number of arguments
3502 // rbx : cache cell for call target 3500 // rbx : cache cell for call target
3503 // rdi : constructor function 3501 // rdi : constructor function
3504 Label slow, non_function_call; 3502 Label slow, non_function_call;
3505 3503
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3540 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3538 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3541 RelocInfo::CODE_TARGET); 3539 RelocInfo::CODE_TARGET);
3542 } 3540 }
3543 3541
3544 3542
3545 bool CEntryStub::NeedsImmovableCode() { 3543 bool CEntryStub::NeedsImmovableCode() {
3546 return false; 3544 return false;
3547 } 3545 }
3548 3546
3549 3547
3550 bool CEntryStub::IsPregenerated() { 3548 bool CEntryStub::IsPregenerated(Isolate* isolate) {
3551 #ifdef _WIN64 3549 #ifdef _WIN64
3552 return result_size_ == 1; 3550 return result_size_ == 1;
3553 #else 3551 #else
3554 return true; 3552 return true;
3555 #endif 3553 #endif
3556 } 3554 }
3557 3555
3558 3556
3559 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { 3557 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
3560 CEntryStub::GenerateAheadOfTime(isolate); 3558 CEntryStub::GenerateAheadOfTime(isolate);
(...skipping 2333 matching lines...) Expand 10 before | Expand all | Expand 10 after
5894 }; 5892 };
5895 5893
5896 5894
5897 #define REG(Name) { kRegister_ ## Name ## _Code } 5895 #define REG(Name) { kRegister_ ## Name ## _Code }
5898 5896
5899 struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { 5897 struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
5900 // Used in RegExpExecStub. 5898 // Used in RegExpExecStub.
5901 { REG(rbx), REG(rax), REG(rdi), EMIT_REMEMBERED_SET }, 5899 { REG(rbx), REG(rax), REG(rdi), EMIT_REMEMBERED_SET },
5902 // Used in CompileArrayPushCall. 5900 // Used in CompileArrayPushCall.
5903 { REG(rbx), REG(rcx), REG(rdx), EMIT_REMEMBERED_SET }, 5901 { REG(rbx), REG(rcx), REG(rdx), EMIT_REMEMBERED_SET },
5904 // Used in CompileStoreGlobal.
5905 { REG(rbx), REG(rcx), REG(rdx), OMIT_REMEMBERED_SET },
5906 // Used in StoreStubCompiler::CompileStoreField and 5902 // Used in StoreStubCompiler::CompileStoreField and
5907 // KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField. 5903 // KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField.
5908 { REG(rdx), REG(rcx), REG(rbx), EMIT_REMEMBERED_SET }, 5904 { REG(rdx), REG(rcx), REG(rbx), EMIT_REMEMBERED_SET },
5909 // GenerateStoreField calls the stub with two different permutations of 5905 // GenerateStoreField calls the stub with two different permutations of
5910 // registers. This is the second. 5906 // registers. This is the second.
5911 { REG(rbx), REG(rcx), REG(rdx), EMIT_REMEMBERED_SET }, 5907 { REG(rbx), REG(rcx), REG(rdx), EMIT_REMEMBERED_SET },
5912 // StoreIC::GenerateNormal via GenerateDictionaryStore. 5908 // StoreIC::GenerateNormal via GenerateDictionaryStore.
5913 { REG(rbx), REG(r8), REG(r9), EMIT_REMEMBERED_SET }, 5909 { REG(rbx), REG(r8), REG(r9), EMIT_REMEMBERED_SET },
5914 // KeyedStoreIC::GenerateGeneric. 5910 // KeyedStoreIC::GenerateGeneric.
5915 { REG(rbx), REG(rdx), REG(rcx), EMIT_REMEMBERED_SET}, 5911 { REG(rbx), REG(rdx), REG(rcx), EMIT_REMEMBERED_SET},
(...skipping 16 matching lines...) Expand all
5932 // StringAddStub::Generate 5928 // StringAddStub::Generate
5933 { REG(rcx), REG(rdx), REG(rbx), EMIT_REMEMBERED_SET}, 5929 { REG(rcx), REG(rdx), REG(rbx), EMIT_REMEMBERED_SET},
5934 // StringAddStub::Generate 5930 // StringAddStub::Generate
5935 { REG(rcx), REG(rax), REG(rbx), EMIT_REMEMBERED_SET}, 5931 { REG(rcx), REG(rax), REG(rbx), EMIT_REMEMBERED_SET},
5936 // Null termination. 5932 // Null termination.
5937 { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET} 5933 { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET}
5938 }; 5934 };
5939 5935
5940 #undef REG 5936 #undef REG
5941 5937
5942 bool RecordWriteStub::IsPregenerated() { 5938 bool RecordWriteStub::IsPregenerated(Isolate* isolate) {
5943 for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; 5939 for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime;
5944 !entry->object.is(no_reg); 5940 !entry->object.is(no_reg);
5945 entry++) { 5941 entry++) {
5946 if (object_.is(entry->object) && 5942 if (object_.is(entry->object) &&
5947 value_.is(entry->value) && 5943 value_.is(entry->value) &&
5948 address_.is(entry->address) && 5944 address_.is(entry->address) &&
5949 remembered_set_action_ == entry->action && 5945 remembered_set_action_ == entry->action &&
5950 save_fp_regs_mode_ == kDontSaveFPRegs) { 5946 save_fp_regs_mode_ == kDontSaveFPRegs) {
5951 return true; 5947 return true;
5952 } 5948 }
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
6623 __ bind(&fast_elements_case); 6619 __ bind(&fast_elements_case);
6624 GenerateCase(masm, FAST_ELEMENTS); 6620 GenerateCase(masm, FAST_ELEMENTS);
6625 } 6621 }
6626 6622
6627 6623
6628 #undef __ 6624 #undef __
6629 6625
6630 } } // namespace v8::internal 6626 } } // namespace v8::internal
6631 6627
6632 #endif // V8_TARGET_ARCH_X64 6628 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/debug-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698