Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 5095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5106 } | 5106 } |
| 5107 Load(args->at(n_args + 1)); // function | 5107 Load(args->at(n_args + 1)); // function |
| 5108 frame_->CallJSFunction(n_args); | 5108 frame_->CallJSFunction(n_args); |
| 5109 frame_->EmitPush(r0); | 5109 frame_->EmitPush(r0); |
| 5110 } | 5110 } |
| 5111 | 5111 |
| 5112 | 5112 |
| 5113 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) { | 5113 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) { |
| 5114 ASSERT_EQ(args->length(), 1); | 5114 ASSERT_EQ(args->length(), 1); |
| 5115 Load(args->at(0)); | 5115 Load(args->at(0)); |
| 5116 if (CpuFeatures::IsSupported(VFP3)) { | 5116 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { |
|
Erik Corry
2010/06/17 07:00:16
If one isolate has VFP then they all have VFP, so
| |
| 5117 TranscendentalCacheStub stub(TranscendentalCache::SIN); | 5117 TranscendentalCacheStub stub(TranscendentalCache::SIN); |
| 5118 frame_->SpillAllButCopyTOSToR0(); | 5118 frame_->SpillAllButCopyTOSToR0(); |
| 5119 frame_->CallStub(&stub, 1); | 5119 frame_->CallStub(&stub, 1); |
| 5120 } else { | 5120 } else { |
| 5121 frame_->CallRuntime(Runtime::kMath_sin, 1); | 5121 frame_->CallRuntime(Runtime::kMath_sin, 1); |
| 5122 } | 5122 } |
| 5123 frame_->EmitPush(r0); | 5123 frame_->EmitPush(r0); |
| 5124 } | 5124 } |
| 5125 | 5125 |
| 5126 | 5126 |
| 5127 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { | 5127 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { |
| 5128 ASSERT_EQ(args->length(), 1); | 5128 ASSERT_EQ(args->length(), 1); |
| 5129 Load(args->at(0)); | 5129 Load(args->at(0)); |
| 5130 if (CpuFeatures::IsSupported(VFP3)) { | 5130 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { |
| 5131 TranscendentalCacheStub stub(TranscendentalCache::COS); | 5131 TranscendentalCacheStub stub(TranscendentalCache::COS); |
| 5132 frame_->SpillAllButCopyTOSToR0(); | 5132 frame_->SpillAllButCopyTOSToR0(); |
| 5133 frame_->CallStub(&stub, 1); | 5133 frame_->CallStub(&stub, 1); |
| 5134 } else { | 5134 } else { |
| 5135 frame_->CallRuntime(Runtime::kMath_cos, 1); | 5135 frame_->CallRuntime(Runtime::kMath_cos, 1); |
| 5136 } | 5136 } |
| 5137 frame_->EmitPush(r0); | 5137 frame_->EmitPush(r0); |
| 5138 } | 5138 } |
| 5139 | 5139 |
| 5140 | 5140 |
| (...skipping 3161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8302 return stub.GetCode(); | 8302 return stub.GetCode(); |
| 8303 } | 8303 } |
| 8304 | 8304 |
| 8305 | 8305 |
| 8306 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { | 8306 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { |
| 8307 // Argument is a number and is on stack and in r0. | 8307 // Argument is a number and is on stack and in r0. |
| 8308 Label runtime_call; | 8308 Label runtime_call; |
| 8309 Label input_not_smi; | 8309 Label input_not_smi; |
| 8310 Label loaded; | 8310 Label loaded; |
| 8311 | 8311 |
| 8312 if (CpuFeatures::IsSupported(VFP3)) { | 8312 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { |
| 8313 // Load argument and check if it is a smi. | 8313 // Load argument and check if it is a smi. |
| 8314 __ BranchOnNotSmi(r0, &input_not_smi); | 8314 __ BranchOnNotSmi(r0, &input_not_smi); |
| 8315 | 8315 |
| 8316 CpuFeatures::Scope scope(VFP3); | 8316 CpuFeatures::Scope scope(VFP3); |
| 8317 // Input is a smi. Convert to double and load the low and high words | 8317 // Input is a smi. Convert to double and load the low and high words |
| 8318 // of the double into r2, r3. | 8318 // of the double into r2, r3. |
| 8319 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); | 8319 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); |
| 8320 __ b(&loaded); | 8320 __ b(&loaded); |
| 8321 | 8321 |
| 8322 __ bind(&input_not_smi); | 8322 __ bind(&input_not_smi); |
| 8323 // Check if input is a HeapNumber. | 8323 // Check if input is a HeapNumber. |
| 8324 __ CheckMap(r0, | 8324 __ CheckMap(r0, |
| 8325 r1, | 8325 r1, |
| 8326 Heap::kHeapNumberMapRootIndex, | 8326 Heap::kHeapNumberMapRootIndex, |
| 8327 &runtime_call, | 8327 &runtime_call, |
| 8328 true); | 8328 true); |
| 8329 // Input is a HeapNumber. Load it to a double register and store the | 8329 // Input is a HeapNumber. Load it to a double register and store the |
| 8330 // low and high words into r2, r3. | 8330 // low and high words into r2, r3. |
| 8331 __ Ldrd(r2, r3, FieldMemOperand(r0, HeapNumber::kValueOffset)); | 8331 __ Ldrd(r2, r3, FieldMemOperand(r0, HeapNumber::kValueOffset)); |
| 8332 | 8332 |
| 8333 __ bind(&loaded); | 8333 __ bind(&loaded); |
| 8334 // r2 = low 32 bits of double value | 8334 // r2 = low 32 bits of double value |
| 8335 // r3 = high 32 bits of double value | 8335 // r3 = high 32 bits of double value |
| 8336 // Compute hash (the shifts are arithmetic): | 8336 // Compute hash (the shifts are arithmetic): |
| 8337 // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1); | 8337 // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1); |
| 8338 __ eor(r1, r2, Operand(r3)); | 8338 __ eor(r1, r2, Operand(r3)); |
| 8339 __ eor(r1, r1, Operand(r1, ASR, 16)); | 8339 __ eor(r1, r1, Operand(r1, ASR, 16)); |
| 8340 __ eor(r1, r1, Operand(r1, ASR, 8)); | 8340 __ eor(r1, r1, Operand(r1, ASR, 8)); |
| 8341 ASSERT(IsPowerOf2(TranscendentalCache::kCacheSize)); | 8341 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); |
| 8342 __ And(r1, r1, Operand(TranscendentalCache::kCacheSize - 1)); | 8342 __ And(r1, r1, Operand(TranscendentalCache::SubCache::kCacheSize - 1)); |
| 8343 | 8343 |
| 8344 // r2 = low 32 bits of double value. | 8344 // r2 = low 32 bits of double value. |
| 8345 // r3 = high 32 bits of double value. | 8345 // r3 = high 32 bits of double value. |
| 8346 // r1 = TranscendentalCache::hash(double value). | 8346 // r1 = TranscendentalCache::hash(double value). |
| 8347 __ mov(r0, | 8347 __ mov(r0, |
| 8348 Operand(ExternalReference::transcendental_cache_array_address())); | 8348 Operand(ExternalReference::transcendental_cache_array_address())); |
| 8349 // r0 points to cache array. | 8349 // r0 points to cache array. |
| 8350 __ ldr(r0, MemOperand(r0, type_ * sizeof(TranscendentalCache::caches_[0]))); | 8350 __ ldr(r0, MemOperand(r0, type_ * sizeof( |
| 8351 Isolate::Current()->transcendental_cache()->caches_[0]))); | |
| 8351 // r0 points to the cache for the type type_. | 8352 // r0 points to the cache for the type type_. |
| 8352 // If NULL, the cache hasn't been initialized yet, so go through runtime. | 8353 // If NULL, the cache hasn't been initialized yet, so go through runtime. |
| 8353 __ cmp(r0, Operand(0)); | 8354 __ cmp(r0, Operand(0)); |
| 8354 __ b(eq, &runtime_call); | 8355 __ b(eq, &runtime_call); |
| 8355 | 8356 |
| 8356 #ifdef DEBUG | 8357 #ifdef DEBUG |
| 8357 // Check that the layout of cache elements match expectations. | 8358 // Check that the layout of cache elements match expectations. |
| 8358 { TranscendentalCache::Element test_elem[2]; | 8359 { TranscendentalCache::SubCache::Element test_elem[2]; |
| 8359 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); | 8360 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); |
| 8360 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); | 8361 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); |
| 8361 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); | 8362 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); |
| 8362 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); | 8363 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); |
| 8363 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); | 8364 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); |
| 8364 CHECK_EQ(12, elem2_start - elem_start); // Two uint_32's and a pointer. | 8365 CHECK_EQ(12, elem2_start - elem_start); // Two uint_32's and a pointer. |
| 8365 CHECK_EQ(0, elem_in0 - elem_start); | 8366 CHECK_EQ(0, elem_in0 - elem_start); |
| 8366 CHECK_EQ(kIntSize, elem_in1 - elem_start); | 8367 CHECK_EQ(kIntSize, elem_in1 - elem_start); |
| 8367 CHECK_EQ(2 * kIntSize, elem_out - elem_start); | 8368 CHECK_EQ(2 * kIntSize, elem_out - elem_start); |
| 8368 } | 8369 } |
| (...skipping 2328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10697 __ bind(&string_add_runtime); | 10698 __ bind(&string_add_runtime); |
| 10698 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 10699 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
| 10699 } | 10700 } |
| 10700 | 10701 |
| 10701 | 10702 |
| 10702 #undef __ | 10703 #undef __ |
| 10703 | 10704 |
| 10704 } } // namespace v8::internal | 10705 } } // namespace v8::internal |
| 10705 | 10706 |
| 10706 #endif // V8_TARGET_ARCH_ARM | 10707 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |