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 4273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4284 ASSERT(args->length() == 2); | 4284 ASSERT(args->length() == 2); |
4285 Load(args->at(0)); | 4285 Load(args->at(0)); |
4286 Load(args->at(1)); | 4286 Load(args->at(1)); |
4287 | 4287 |
4288 if (!CpuFeatures::IsSupported(VFP3)) { | 4288 if (!CpuFeatures::IsSupported(VFP3)) { |
4289 frame_->CallRuntime(Runtime::kMath_pow, 2); | 4289 frame_->CallRuntime(Runtime::kMath_pow, 2); |
4290 frame_->EmitPush(r0); | 4290 frame_->EmitPush(r0); |
4291 } else { | 4291 } else { |
4292 CpuFeatures::Scope scope(VFP3); | 4292 CpuFeatures::Scope scope(VFP3); |
4293 JumpTarget runtime, done; | 4293 JumpTarget runtime, done; |
4294 Label not_minus_half, allocate_return; | 4294 Label exponent_nonsmi, base_nonsmi, powi, not_minus_half, allocate_return; |
4295 | 4295 |
4296 Register scratch1 = VirtualFrame::scratch0(); | 4296 Register scratch1 = VirtualFrame::scratch0(); |
4297 Register scratch2 = VirtualFrame::scratch1(); | 4297 Register scratch2 = VirtualFrame::scratch1(); |
4298 | 4298 |
4299 // Get base and exponent to registers. | 4299 // Get base and exponent to registers. |
4300 Register exponent = frame_->PopToRegister(); | 4300 Register exponent = frame_->PopToRegister(); |
4301 Register base = frame_->PopToRegister(exponent); | 4301 Register base = frame_->PopToRegister(exponent); |
| 4302 Register heap_number_map = no_reg; |
4302 | 4303 |
4303 // Set the frame for the runtime jump target. The code below jumps to the | 4304 // Set the frame for the runtime jump target. The code below jumps to the |
4304 // jump target label so the frame needs to be established before that. | 4305 // jump target label so the frame needs to be established before that. |
4305 ASSERT(runtime.entry_frame() == NULL); | 4306 ASSERT(runtime.entry_frame() == NULL); |
4306 runtime.set_entry_frame(frame_); | 4307 runtime.set_entry_frame(frame_); |
4307 | 4308 |
4308 __ BranchOnSmi(exponent, runtime.entry_label()); | 4309 __ BranchOnNotSmi(exponent, &exponent_nonsmi); |
| 4310 __ BranchOnNotSmi(base, &base_nonsmi); |
4309 | 4311 |
| 4312 heap_number_map = r6; |
| 4313 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
| 4314 |
| 4315 // Exponent is a smi and base is a smi. Get the smi value into vfp register |
| 4316 // d1. |
| 4317 __ SmiToDoubleVFPRegister(base, d1, scratch1, s0); |
| 4318 __ b(&powi); |
| 4319 |
| 4320 __ bind(&base_nonsmi); |
| 4321 // Exponent is smi and base is non smi. Get the double value from the base |
| 4322 // into vfp register d1. |
| 4323 __ ObjectToDoubleVFPRegister(base, d1, |
| 4324 scratch1, scratch2, heap_number_map, s0, |
| 4325 runtime.entry_label()); |
| 4326 |
| 4327 __ bind(&powi); |
| 4328 |
| 4329 // Load 1.0 into d0. |
| 4330 __ mov(scratch2, Operand(0x3ff00000)); |
| 4331 __ mov(scratch1, Operand(0)); |
| 4332 __ vmov(d0, scratch1, scratch2); |
| 4333 |
| 4334 // Get the absolute untagged value of the exponent and use that for the |
| 4335 // calculation. |
| 4336 __ mov(scratch1, Operand(exponent, ASR, kSmiTagSize), SetCC); |
| 4337 __ rsb(scratch1, scratch1, Operand(0), LeaveCC, mi); // Negate if negative. |
| 4338 __ vmov(d2, d0, mi); // 1.0 needed in d2 later if exponent is negative. |
| 4339 |
| 4340 // Run through all the bits in the exponent. The result is calculated in d0 |
| 4341 // and d1 holds base^(bit^2). |
| 4342 Label more_bits; |
| 4343 __ bind(&more_bits); |
| 4344 __ mov(scratch1, Operand(scratch1, LSR, 1), SetCC); |
| 4345 __ vmul(d0, d0, d1, cs); // Multiply with base^(bit^2) if bit is set. |
| 4346 __ vmul(d1, d1, d1, ne); // Don't bother calculating next d1 if done. |
| 4347 __ b(ne, &more_bits); |
| 4348 |
| 4349 // If exponent is negative result is 1/result (d2 already holds 1.0 in that |
| 4350 // case). |
| 4351 __ cmp(exponent, Operand(0)); |
| 4352 __ vdiv(d0, d2, d0, mi); |
| 4353 __ b(&allocate_return); |
| 4354 |
| 4355 __ bind(&exponent_nonsmi); |
4310 // Special handling of raising to the power of -0.5 and 0.5. First check | 4356 // Special handling of raising to the power of -0.5 and 0.5. First check |
4311 // that the value is a heap number and that the lower bits (which for both | 4357 // that the value is a heap number and that the lower bits (which for both |
4312 // values are zero). | 4358 // values are zero). |
4313 Register heap_number_map = r6; | 4359 heap_number_map = r6; |
4314 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); | 4360 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
4315 __ ldr(scratch1, FieldMemOperand(exponent, HeapObject::kMapOffset)); | 4361 __ ldr(scratch1, FieldMemOperand(exponent, HeapObject::kMapOffset)); |
4316 __ ldr(scratch2, FieldMemOperand(exponent, HeapNumber::kMantissaOffset)); | 4362 __ ldr(scratch2, FieldMemOperand(exponent, HeapNumber::kMantissaOffset)); |
4317 __ cmp(scratch1, heap_number_map); | 4363 __ cmp(scratch1, heap_number_map); |
4318 runtime.Branch(ne); | 4364 runtime.Branch(ne); |
4319 __ tst(scratch2, scratch2); | 4365 __ tst(scratch2, scratch2); |
4320 runtime.Branch(ne); | 4366 runtime.Branch(ne); |
4321 | 4367 |
4322 // Load the e | 4368 // Load the higher bits (which contains the floating point exponent). |
4323 __ ldr(scratch1, FieldMemOperand(exponent, HeapNumber::kExponentOffset)); | 4369 __ ldr(scratch1, FieldMemOperand(exponent, HeapNumber::kExponentOffset)); |
4324 | 4370 |
4325 // Compare exponent with -0.5. | 4371 // Compare exponent with -0.5. |
4326 __ cmp(scratch1, Operand(0xbfe00000)); | 4372 __ cmp(scratch1, Operand(0xbfe00000)); |
4327 __ b(ne, ¬_minus_half); | 4373 __ b(ne, ¬_minus_half); |
4328 | 4374 |
4329 // Get the double value from the base into vfp register d0. | 4375 // Get the double value from the base into vfp register d0. |
4330 __ ObjectToDoubleVFPRegister(base, d0, | 4376 __ ObjectToDoubleVFPRegister(base, d0, |
4331 scratch1, scratch2, heap_number_map, s0, | 4377 scratch1, scratch2, heap_number_map, s0, |
4332 runtime.entry_label(), | 4378 runtime.entry_label(), |
(...skipping 6709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11042 __ bind(&string_add_runtime); | 11088 __ bind(&string_add_runtime); |
11043 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 11089 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
11044 } | 11090 } |
11045 | 11091 |
11046 | 11092 |
11047 #undef __ | 11093 #undef __ |
11048 | 11094 |
11049 } } // namespace v8::internal | 11095 } } // namespace v8::internal |
11050 | 11096 |
11051 #endif // V8_TARGET_ARCH_ARM | 11097 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |