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

Side by Side Diff: src/arm/codegen-arm.cc

Issue 2804033: ARM: Special code for raising to the power of an integer... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 5 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/arm/assembler-arm.cc ('k') | src/arm/disasm-arm.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 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
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, &not_minus_half); 4373 __ b(ne, &not_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
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
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.cc ('k') | src/arm/disasm-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698