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 4261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4272 | 4272 |
4273 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { | 4273 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { |
4274 ASSERT(args->length() == 1); | 4274 ASSERT(args->length() == 1); |
4275 Load(args->at(0)); | 4275 Load(args->at(0)); |
4276 Register reg = frame_->PopToRegister(); | 4276 Register reg = frame_->PopToRegister(); |
4277 __ tst(reg, Operand(kSmiTagMask | 0x80000000u)); | 4277 __ tst(reg, Operand(kSmiTagMask | 0x80000000u)); |
4278 cc_reg_ = eq; | 4278 cc_reg_ = eq; |
4279 } | 4279 } |
4280 | 4280 |
4281 | 4281 |
4282 // Generates the Math.pow method - currently just calls runtime. | 4282 // Generates the Math.pow method. |
4283 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { | 4283 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { |
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 frame_->CallRuntime(Runtime::kMath_pow, 2); | 4287 |
4288 frame_->EmitPush(r0); | 4288 if (!CpuFeatures::IsSupported(VFP3)) { |
| 4289 frame_->CallRuntime(Runtime::kMath_pow, 2); |
| 4290 frame_->EmitPush(r0); |
| 4291 } else { |
| 4292 CpuFeatures::Scope scope(VFP3); |
| 4293 JumpTarget runtime, done; |
| 4294 Label not_minus_half, allocate_return; |
| 4295 |
| 4296 Register scratch1 = VirtualFrame::scratch0(); |
| 4297 Register scratch2 = VirtualFrame::scratch1(); |
| 4298 |
| 4299 // Get base and exponent to registers. |
| 4300 Register exponent = frame_->PopToRegister(); |
| 4301 Register base = frame_->PopToRegister(exponent); |
| 4302 |
| 4303 // 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 ASSERT(runtime.entry_frame() == NULL); |
| 4306 runtime.set_entry_frame(frame_); |
| 4307 |
| 4308 __ BranchOnSmi(exponent, runtime.entry_label()); |
| 4309 |
| 4310 // 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 |
| 4312 // values are zero). |
| 4313 Register heap_number_map = r6; |
| 4314 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
| 4315 __ ldr(scratch1, FieldMemOperand(exponent, HeapObject::kMapOffset)); |
| 4316 __ ldr(scratch2, FieldMemOperand(exponent, HeapNumber::kMantissaOffset)); |
| 4317 __ cmp(scratch1, heap_number_map); |
| 4318 runtime.Branch(ne); |
| 4319 __ tst(scratch2, scratch2); |
| 4320 runtime.Branch(ne); |
| 4321 |
| 4322 // Load the e |
| 4323 __ ldr(scratch1, FieldMemOperand(exponent, HeapNumber::kExponentOffset)); |
| 4324 |
| 4325 // Compare exponent with -0.5. |
| 4326 __ cmp(scratch1, Operand(0xbfe00000)); |
| 4327 __ b(ne, ¬_minus_half); |
| 4328 |
| 4329 // Get the double value from the base into vfp register d0. |
| 4330 __ ObjectToDoubleVFPRegister(base, d0, |
| 4331 scratch1, scratch2, heap_number_map, s0, |
| 4332 runtime.entry_label(), |
| 4333 AVOID_NANS_AND_INFINITIES); |
| 4334 |
| 4335 // Load 1.0 into d2. |
| 4336 __ mov(scratch2, Operand(0x3ff00000)); |
| 4337 __ mov(scratch1, Operand(0)); |
| 4338 __ vmov(d2, scratch1, scratch2); |
| 4339 |
| 4340 // Calculate the reciprocal of the square root. 1/sqrt(x) = sqrt(1/x). |
| 4341 __ vdiv(d0, d2, d0); |
| 4342 __ vsqrt(d0, d0); |
| 4343 |
| 4344 __ b(&allocate_return); |
| 4345 |
| 4346 __ bind(¬_minus_half); |
| 4347 // Compare exponent with 0.5. |
| 4348 __ cmp(scratch1, Operand(0x3fe00000)); |
| 4349 runtime.Branch(ne); |
| 4350 |
| 4351 // Get the double value from the base into vfp register d0. |
| 4352 __ ObjectToDoubleVFPRegister(base, d0, |
| 4353 scratch1, scratch2, heap_number_map, s0, |
| 4354 runtime.entry_label(), |
| 4355 AVOID_NANS_AND_INFINITIES); |
| 4356 __ vsqrt(d0, d0); |
| 4357 |
| 4358 __ bind(&allocate_return); |
| 4359 __ AllocateHeapNumberWithValue( |
| 4360 base, d0, scratch1, scratch2, heap_number_map, runtime.entry_label()); |
| 4361 done.Jump(); |
| 4362 |
| 4363 runtime.Bind(); |
| 4364 |
| 4365 // Push back the arguments again for the runtime call. |
| 4366 frame_->EmitPush(base); |
| 4367 frame_->EmitPush(exponent); |
| 4368 frame_->CallRuntime(Runtime::kMath_pow, 2); |
| 4369 __ Move(base, r0); |
| 4370 |
| 4371 done.Bind(); |
| 4372 frame_->EmitPush(base); |
| 4373 } |
4289 } | 4374 } |
4290 | 4375 |
4291 | 4376 |
4292 // Generates the Math.sqrt method - currently just calls runtime. | 4377 // Generates the Math.sqrt method. |
4293 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { | 4378 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { |
4294 ASSERT(args->length() == 1); | 4379 ASSERT(args->length() == 1); |
4295 Load(args->at(0)); | 4380 Load(args->at(0)); |
4296 frame_->CallRuntime(Runtime::kMath_sqrt, 1); | 4381 |
4297 frame_->EmitPush(r0); | 4382 if (!CpuFeatures::IsSupported(VFP3)) { |
| 4383 frame_->CallRuntime(Runtime::kMath_sqrt, 1); |
| 4384 frame_->EmitPush(r0); |
| 4385 } else { |
| 4386 CpuFeatures::Scope scope(VFP3); |
| 4387 JumpTarget runtime, done; |
| 4388 |
| 4389 Register scratch1 = VirtualFrame::scratch0(); |
| 4390 Register scratch2 = VirtualFrame::scratch1(); |
| 4391 |
| 4392 // Get the value from the frame. |
| 4393 Register tos = frame_->PopToRegister(); |
| 4394 |
| 4395 // Set the frame for the runtime jump target. The code below jumps to the |
| 4396 // jump target label so the frame needs to be established before that. |
| 4397 ASSERT(runtime.entry_frame() == NULL); |
| 4398 runtime.set_entry_frame(frame_); |
| 4399 |
| 4400 Register heap_number_map = r6; |
| 4401 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
| 4402 |
| 4403 // Get the double value from the heap number into vfp register d0. |
| 4404 __ ObjectToDoubleVFPRegister(tos, d0, |
| 4405 scratch1, scratch2, heap_number_map, s0, |
| 4406 runtime.entry_label()); |
| 4407 |
| 4408 // Calculate the square root of d0 and place result in a heap number object. |
| 4409 __ vsqrt(d0, d0); |
| 4410 __ AllocateHeapNumberWithValue( |
| 4411 tos, d0, scratch1, scratch2, heap_number_map, runtime.entry_label()); |
| 4412 done.Jump(); |
| 4413 |
| 4414 runtime.Bind(); |
| 4415 // Push back the argument again for the runtime call. |
| 4416 frame_->EmitPush(tos); |
| 4417 frame_->CallRuntime(Runtime::kMath_sqrt, 1); |
| 4418 __ Move(tos, r0); |
| 4419 |
| 4420 done.Bind(); |
| 4421 frame_->EmitPush(tos); |
| 4422 } |
4298 } | 4423 } |
4299 | 4424 |
4300 | 4425 |
4301 class DeferredStringCharCodeAt : public DeferredCode { | 4426 class DeferredStringCharCodeAt : public DeferredCode { |
4302 public: | 4427 public: |
4303 DeferredStringCharCodeAt(Register object, | 4428 DeferredStringCharCodeAt(Register object, |
4304 Register index, | 4429 Register index, |
4305 Register scratch, | 4430 Register scratch, |
4306 Register result) | 4431 Register result) |
4307 : result_(result), | 4432 : result_(result), |
(...skipping 6609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10917 __ bind(&string_add_runtime); | 11042 __ bind(&string_add_runtime); |
10918 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 11043 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
10919 } | 11044 } |
10920 | 11045 |
10921 | 11046 |
10922 #undef __ | 11047 #undef __ |
10923 | 11048 |
10924 } } // namespace v8::internal | 11049 } } // namespace v8::internal |
10925 | 11050 |
10926 #endif // V8_TARGET_ARCH_ARM | 11051 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |