| OLD | NEW |
| 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 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2246 // jssp[1]: Base (as a tagged value). | 2246 // jssp[1]: Base (as a tagged value). |
| 2247 // | 2247 // |
| 2248 // The (tagged) result will be returned in x0, as a heap number. | 2248 // The (tagged) result will be returned in x0, as a heap number. |
| 2249 | 2249 |
| 2250 Register result_tagged = x0; | 2250 Register result_tagged = x0; |
| 2251 Register base_tagged = x10; | 2251 Register base_tagged = x10; |
| 2252 Register exponent_tagged = x11; | 2252 Register exponent_tagged = x11; |
| 2253 Register exponent_integer = x12; | 2253 Register exponent_integer = x12; |
| 2254 Register scratch1 = x14; | 2254 Register scratch1 = x14; |
| 2255 Register scratch0 = x15; | 2255 Register scratch0 = x15; |
| 2256 Register saved_lr = x19; |
| 2256 FPRegister result_double = d0; | 2257 FPRegister result_double = d0; |
| 2257 FPRegister base_double = d1; | 2258 FPRegister base_double = d0; |
| 2258 FPRegister exponent_double = d2; | 2259 FPRegister exponent_double = d1; |
| 2260 FPRegister base_double_copy = d2; |
| 2259 FPRegister scratch1_double = d6; | 2261 FPRegister scratch1_double = d6; |
| 2260 FPRegister scratch0_double = d7; | 2262 FPRegister scratch0_double = d7; |
| 2261 | 2263 |
| 2262 // A fast-path for integer exponents. | 2264 // A fast-path for integer exponents. |
| 2263 Label exponent_is_smi, exponent_is_integer; | 2265 Label exponent_is_smi, exponent_is_integer; |
| 2264 // Bail out to runtime. | 2266 // Bail out to runtime. |
| 2265 Label call_runtime; | 2267 Label call_runtime; |
| 2266 // Allocate a heap number for the result, and return it. | 2268 // Allocate a heap number for the result, and return it. |
| 2267 Label done; | 2269 Label done; |
| 2268 | 2270 |
| 2269 // TODO(all): Cases other than ON_STACK are only used by Lithium, and we do | |
| 2270 // not yet support them. | |
| 2271 ASSERT(exponent_type_ == ON_STACK); | |
| 2272 | |
| 2273 // Unpack the inputs. | 2271 // Unpack the inputs. |
| 2274 if (exponent_type_ == ON_STACK) { | 2272 if (exponent_type_ == ON_STACK) { |
| 2275 Label base_is_smi; | 2273 Label base_is_smi; |
| 2276 Label unpack_exponent; | 2274 Label unpack_exponent; |
| 2277 | 2275 |
| 2278 __ Pop(exponent_tagged, base_tagged); | 2276 __ Pop(exponent_tagged, base_tagged); |
| 2279 | 2277 |
| 2280 __ JumpIfSmi(base_tagged, &base_is_smi); | 2278 __ JumpIfSmi(base_tagged, &base_is_smi); |
| 2281 __ JumpIfNotHeapNumber(base_tagged, &call_runtime); | 2279 __ JumpIfNotHeapNumber(base_tagged, &call_runtime); |
| 2282 // base_tagged is a heap number, so load its double value. | 2280 // base_tagged is a heap number, so load its double value. |
| 2283 __ Ldr(base_double, FieldMemOperand(base_tagged, HeapNumber::kValueOffset)); | 2281 __ Ldr(base_double, FieldMemOperand(base_tagged, HeapNumber::kValueOffset)); |
| 2284 __ B(&unpack_exponent); | 2282 __ B(&unpack_exponent); |
| 2285 __ Bind(&base_is_smi); | 2283 __ Bind(&base_is_smi); |
| 2286 // base_tagged is a SMI, so untag it and convert it to a double. | 2284 // base_tagged is a SMI, so untag it and convert it to a double. |
| 2287 __ SmiUntagToDouble(base_double, base_tagged); | 2285 __ SmiUntagToDouble(base_double, base_tagged); |
| 2288 | 2286 |
| 2289 __ Bind(&unpack_exponent); | 2287 __ Bind(&unpack_exponent); |
| 2290 // x10 base_tagged The tagged base (input). | 2288 // x10 base_tagged The tagged base (input). |
| 2291 // x11 exponent_tagged The tagged exponent (input). | 2289 // x11 exponent_tagged The tagged exponent (input). |
| 2292 // d1 base_double The base as a double. | 2290 // d1 base_double The base as a double. |
| 2293 __ JumpIfSmi(exponent_tagged, &exponent_is_smi); | 2291 __ JumpIfSmi(exponent_tagged, &exponent_is_smi); |
| 2294 __ JumpIfNotHeapNumber(exponent_tagged, &call_runtime); | 2292 __ JumpIfNotHeapNumber(exponent_tagged, &call_runtime); |
| 2295 // exponent_tagged is a heap number, so load its double value. | 2293 // exponent_tagged is a heap number, so load its double value. |
| 2296 __ Ldr(exponent_double, | 2294 __ Ldr(exponent_double, |
| 2297 FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset)); | 2295 FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset)); |
| 2298 } else { | 2296 } else if (exponent_type_ == TAGGED) { |
| 2299 UNIMPLEMENTED_M("MathPowStub types other than ON_STACK are unimplemented."); | 2297 __ JumpIfSmi(exponent_tagged, &exponent_is_smi); |
| 2298 __ Ldr(exponent_double, |
| 2299 FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset)); |
| 2300 } | 2300 } |
| 2301 | 2301 |
| 2302 // Handle double (heap number) exponents. | 2302 // Handle double (heap number) exponents. |
| 2303 if (exponent_type_ != INTEGER) { | 2303 if (exponent_type_ != INTEGER) { |
| 2304 // Detect integer exponents stored as doubles and handle those in the | 2304 // Detect integer exponents stored as doubles and handle those in the |
| 2305 // integer fast-path. | 2305 // integer fast-path. |
| 2306 __ TryConvertDoubleToInt64(exponent_integer, exponent_double, | 2306 __ TryConvertDoubleToInt64(exponent_integer, exponent_double, |
| 2307 scratch0_double, &exponent_is_integer); | 2307 scratch0_double, &exponent_is_integer); |
| 2308 | 2308 |
| 2309 if (exponent_type_ == ON_STACK) { | 2309 if (exponent_type_ == ON_STACK) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2376 __ Fcsel(base_double, scratch1_double, base_double, vs); | 2376 __ Fcsel(base_double, scratch1_double, base_double, vs); |
| 2377 | 2377 |
| 2378 // Calculate the square root of base. | 2378 // Calculate the square root of base. |
| 2379 __ Fsqrt(result_double, base_double); | 2379 __ Fsqrt(result_double, base_double); |
| 2380 __ Fcmp(exponent_double, 0.0); | 2380 __ Fcmp(exponent_double, 0.0); |
| 2381 __ B(ge, &done); // Finish now for exponents of 0.5. | 2381 __ B(ge, &done); // Finish now for exponents of 0.5. |
| 2382 // Find the inverse for exponents of -0.5. | 2382 // Find the inverse for exponents of -0.5. |
| 2383 __ Fmov(scratch0_double, 1.0); | 2383 __ Fmov(scratch0_double, 1.0); |
| 2384 __ Fdiv(result_double, scratch0_double, result_double); | 2384 __ Fdiv(result_double, scratch0_double, result_double); |
| 2385 __ B(&done); | 2385 __ B(&done); |
| 2386 } else { | |
| 2387 UNIMPLEMENTED_M( | |
| 2388 "MathPowStub types other than ON_STACK are unimplemented."); | |
| 2389 } | 2386 } |
| 2390 | 2387 |
| 2391 // TODO(all): From here, call the C power function for non-ON_STACK types. | 2388 { |
| 2392 // ON_STACK types should not be able to reach this point. | 2389 AllowExternalCallThatCantCauseGC scope(masm); |
| 2393 ASM_UNIMPLEMENTED_BREAK( | 2390 __ Mov(saved_lr, lr); |
| 2394 "MathPowStub types other than ON_STACK are unimplemented."); | 2391 __ CallCFunction( |
| 2395 } else { | 2392 ExternalReference::power_double_double_function(masm->isolate()), |
| 2396 UNIMPLEMENTED_M("MathPowStub types other than ON_STACK are unimplemented."); | 2393 0, 2); |
| 2394 __ Mov(lr, saved_lr); |
| 2395 __ B(&done); |
| 2396 } |
| 2397 } | 2397 } |
| 2398 | 2398 |
| 2399 // Handle integer (and SMI) exponents. | 2399 // Handle integer (and SMI) exponents. |
| 2400 __ Bind(&exponent_is_smi); | 2400 __ Bind(&exponent_is_smi); |
| 2401 // x10 base_tagged The tagged base (input). | 2401 // x10 base_tagged The tagged base (input). |
| 2402 // x11 exponent_tagged The tagged exponent (input). | 2402 // x11 exponent_tagged The tagged exponent (input). |
| 2403 // d1 base_double The base as a double. | 2403 // d1 base_double The base as a double. |
| 2404 __ SmiUntag(exponent_integer, exponent_tagged); | 2404 __ SmiUntag(exponent_integer, exponent_tagged); |
| 2405 __ Bind(&exponent_is_integer); | 2405 __ Bind(&exponent_is_integer); |
| 2406 // x10 base_tagged The tagged base (input). | 2406 // x10 base_tagged The tagged base (input). |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2420 // if (exponent_integer{n}) { | 2420 // if (exponent_integer{n}) { |
| 2421 // result *= base; | 2421 // result *= base; |
| 2422 // } | 2422 // } |
| 2423 // base *= base; | 2423 // base *= base; |
| 2424 // if (remaining bits in exponent_integer are all zero) { | 2424 // if (remaining bits in exponent_integer are all zero) { |
| 2425 // break; | 2425 // break; |
| 2426 // } | 2426 // } |
| 2427 // } | 2427 // } |
| 2428 Label power_loop, power_loop_entry, power_loop_exit; | 2428 Label power_loop, power_loop_entry, power_loop_exit; |
| 2429 __ Fmov(scratch1_double, base_double); | 2429 __ Fmov(scratch1_double, base_double); |
| 2430 __ Fmov(base_double_copy, base_double); |
| 2430 __ Fmov(result_double, 1.0); | 2431 __ Fmov(result_double, 1.0); |
| 2431 __ B(&power_loop_entry); | 2432 __ B(&power_loop_entry); |
| 2432 | 2433 |
| 2433 __ Bind(&power_loop); | 2434 __ Bind(&power_loop); |
| 2434 __ Fmul(scratch1_double, scratch1_double, scratch1_double); | 2435 __ Fmul(scratch1_double, scratch1_double, scratch1_double); |
| 2435 __ Lsr(exponent_abs, exponent_abs, 1); | 2436 __ Lsr(exponent_abs, exponent_abs, 1); |
| 2436 __ Cbz(exponent_abs, &power_loop_exit); | 2437 __ Cbz(exponent_abs, &power_loop_exit); |
| 2437 | 2438 |
| 2438 __ Bind(&power_loop_entry); | 2439 __ Bind(&power_loop_entry); |
| 2439 __ Tbz(exponent_abs, 0, &power_loop); | 2440 __ Tbz(exponent_abs, 0, &power_loop); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2467 // Return. | 2468 // Return. |
| 2468 __ Bind(&done); | 2469 __ Bind(&done); |
| 2469 __ AllocateHeapNumber(result_tagged, &call_runtime, scratch0, scratch1); | 2470 __ AllocateHeapNumber(result_tagged, &call_runtime, scratch0, scratch1); |
| 2470 __ Str(result_double, | 2471 __ Str(result_double, |
| 2471 FieldMemOperand(result_tagged, HeapNumber::kValueOffset)); | 2472 FieldMemOperand(result_tagged, HeapNumber::kValueOffset)); |
| 2472 ASSERT(result_tagged.is(x0)); | 2473 ASSERT(result_tagged.is(x0)); |
| 2473 __ IncrementCounter( | 2474 __ IncrementCounter( |
| 2474 masm->isolate()->counters()->math_pow(), 1, scratch0, scratch1); | 2475 masm->isolate()->counters()->math_pow(), 1, scratch0, scratch1); |
| 2475 __ Ret(); | 2476 __ Ret(); |
| 2476 } else { | 2477 } else { |
| 2477 UNIMPLEMENTED_M("MathPowStub types other than ON_STACK are unimplemented."); | 2478 AllowExternalCallThatCantCauseGC scope(masm); |
| 2479 __ Mov(saved_lr, lr); |
| 2480 __ Fmov(base_double, base_double_copy); |
| 2481 __ Scvtf(exponent_double, exponent_integer); |
| 2482 __ CallCFunction( |
| 2483 ExternalReference::power_double_double_function(masm->isolate()), |
| 2484 0, 2); |
| 2485 __ Mov(lr, saved_lr); |
| 2486 __ Bind(&done); |
| 2487 __ IncrementCounter( |
| 2488 masm->isolate()->counters()->math_pow(), 1, scratch0, scratch1); |
| 2489 __ Ret(); |
| 2478 } | 2490 } |
| 2479 } | 2491 } |
| 2480 | 2492 |
| 2481 | 2493 |
| 2482 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 2494 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 2483 // It is important that the following stubs are generated in this order | 2495 // It is important that the following stubs are generated in this order |
| 2484 // because pregenerated stubs can only call other pregenerated stubs. | 2496 // because pregenerated stubs can only call other pregenerated stubs. |
| 2485 // RecordWriteStub uses StoreBufferOverflowStub, which in turn uses | 2497 // RecordWriteStub uses StoreBufferOverflowStub, which in turn uses |
| 2486 // CEntryStub. | 2498 // CEntryStub. |
| 2487 CEntryStub::GenerateAheadOfTime(isolate); | 2499 CEntryStub::GenerateAheadOfTime(isolate); |
| (...skipping 4840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7328 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 7340 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 7329 } | 7341 } |
| 7330 } | 7342 } |
| 7331 | 7343 |
| 7332 | 7344 |
| 7333 #undef __ | 7345 #undef __ |
| 7334 | 7346 |
| 7335 } } // namespace v8::internal | 7347 } } // namespace v8::internal |
| 7336 | 7348 |
| 7337 #endif // V8_TARGET_ARCH_A64 | 7349 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |