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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 5437002: Add generated code to calculate Math.log and to search Transcendental cache f... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years 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/ia32/assembler-ia32.cc ('k') | src/ia32/codegen-ia32.h » ('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 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 __ bind(&runtime_call); 1323 __ bind(&runtime_call);
1324 __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1); 1324 __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1);
1325 } 1325 }
1326 1326
1327 1327
1328 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { 1328 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
1329 switch (type_) { 1329 switch (type_) {
1330 // Add more cases when necessary. 1330 // Add more cases when necessary.
1331 case TranscendentalCache::SIN: return Runtime::kMath_sin; 1331 case TranscendentalCache::SIN: return Runtime::kMath_sin;
1332 case TranscendentalCache::COS: return Runtime::kMath_cos; 1332 case TranscendentalCache::COS: return Runtime::kMath_cos;
1333 case TranscendentalCache::LOG: return Runtime::kMath_log;
1333 default: 1334 default:
1334 UNIMPLEMENTED(); 1335 UNIMPLEMENTED();
1335 return Runtime::kAbort; 1336 return Runtime::kAbort;
1336 } 1337 }
1337 } 1338 }
1338 1339
1339 1340
1340 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { 1341 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
1341 // Only free register is edi. 1342 // Only free register is edi.
1343 // Input value is on FP stack, and also in ebx/edx. Address of result
1344 // (a newly allocated HeapNumber) is in eax.
1342 NearLabel done; 1345 NearLabel done;
1343 ASSERT(type_ == TranscendentalCache::SIN || 1346 if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) {
1344 type_ == TranscendentalCache::COS); 1347 // Both fsin and fcos require arguments in the range +/-2^63 and
1345 // More transcendental types can be added later. 1348 // return NaN for infinities and NaN. They can share all code except
1349 // the actual fsin/fcos operation.
1350 NearLabel in_range;
1351 // If argument is outside the range -2^63..2^63, fsin/cos doesn't
1352 // work. We must reduce it to the appropriate range.
1353 __ mov(edi, edx);
1354 __ and_(Operand(edi), Immediate(0x7ff00000)); // Exponent only.
1355 int supported_exponent_limit =
1356 (63 + HeapNumber::kExponentBias) << HeapNumber::kExponentShift;
1357 __ cmp(Operand(edi), Immediate(supported_exponent_limit));
1358 __ j(below, &in_range, taken);
1359 // Check for infinity and NaN. Both return NaN for sin.
1360 __ cmp(Operand(edi), Immediate(0x7ff00000));
1361 NearLabel non_nan_result;
1362 __ j(not_equal, &non_nan_result, taken);
1363 // Input is +/-Infinity or NaN. Result is NaN.
1364 __ fstp(0);
1365 // NaN is represented by 0x7ff8000000000000.
1366 __ push(Immediate(0x7ff80000));
1367 __ push(Immediate(0));
1368 __ fld_d(Operand(esp, 0));
1369 __ add(Operand(esp), Immediate(2 * kPointerSize));
1370 __ jmp(&done);
1346 1371
1347 // Both fsin and fcos require arguments in the range +/-2^63 and 1372 __ bind(&non_nan_result);
1348 // return NaN for infinities and NaN. They can share all code except
1349 // the actual fsin/fcos operation.
1350 NearLabel in_range;
1351 // If argument is outside the range -2^63..2^63, fsin/cos doesn't
1352 // work. We must reduce it to the appropriate range.
1353 __ mov(edi, edx);
1354 __ and_(Operand(edi), Immediate(0x7ff00000)); // Exponent only.
1355 int supported_exponent_limit =
1356 (63 + HeapNumber::kExponentBias) << HeapNumber::kExponentShift;
1357 __ cmp(Operand(edi), Immediate(supported_exponent_limit));
1358 __ j(below, &in_range, taken);
1359 // Check for infinity and NaN. Both return NaN for sin.
1360 __ cmp(Operand(edi), Immediate(0x7ff00000));
1361 NearLabel non_nan_result;
1362 __ j(not_equal, &non_nan_result, taken);
1363 // Input is +/-Infinity or NaN. Result is NaN.
1364 __ fstp(0);
1365 // NaN is represented by 0x7ff8000000000000.
1366 __ push(Immediate(0x7ff80000));
1367 __ push(Immediate(0));
1368 __ fld_d(Operand(esp, 0));
1369 __ add(Operand(esp), Immediate(2 * kPointerSize));
1370 __ jmp(&done);
1371 1373
1372 __ bind(&non_nan_result); 1374 // Use fpmod to restrict argument to the range +/-2*PI.
1375 __ mov(edi, eax); // Save eax before using fnstsw_ax.
1376 __ fldpi();
1377 __ fadd(0);
1378 __ fld(1);
1379 // FPU Stack: input, 2*pi, input.
1380 {
1381 NearLabel no_exceptions;
1382 __ fwait();
1383 __ fnstsw_ax();
1384 // Clear if Illegal Operand or Zero Division exceptions are set.
1385 __ test(Operand(eax), Immediate(5));
1386 __ j(zero, &no_exceptions);
1387 __ fnclex();
1388 __ bind(&no_exceptions);
1389 }
1373 1390
1374 // Use fpmod to restrict argument to the range +/-2*PI. 1391 // Compute st(0) % st(1)
1375 __ mov(edi, eax); // Save eax before using fnstsw_ax. 1392 {
1376 __ fldpi(); 1393 NearLabel partial_remainder_loop;
1377 __ fadd(0); 1394 __ bind(&partial_remainder_loop);
1378 __ fld(1); 1395 __ fprem1();
1379 // FPU Stack: input, 2*pi, input. 1396 __ fwait();
1380 { 1397 __ fnstsw_ax();
1381 NearLabel no_exceptions; 1398 __ test(Operand(eax), Immediate(0x400 /* C2 */));
1382 __ fwait(); 1399 // If C2 is set, computation only has partial result. Loop to
1383 __ fnstsw_ax(); 1400 // continue computation.
1384 // Clear if Illegal Operand or Zero Division exceptions are set. 1401 __ j(not_zero, &partial_remainder_loop);
1385 __ test(Operand(eax), Immediate(5)); 1402 }
1386 __ j(zero, &no_exceptions); 1403 // FPU Stack: input, 2*pi, input % 2*pi
1387 __ fnclex(); 1404 __ fstp(2);
1388 __ bind(&no_exceptions); 1405 __ fstp(0);
1406 __ mov(eax, edi); // Restore eax (allocated HeapNumber pointer).
1407
1408 // FPU Stack: input % 2*pi
1409 __ bind(&in_range);
1410 switch (type_) {
1411 case TranscendentalCache::SIN:
1412 __ fsin();
1413 break;
1414 case TranscendentalCache::COS:
1415 __ fcos();
1416 break;
1417 default:
1418 UNREACHABLE();
1419 }
1420 __ bind(&done);
1421 } else {
1422 ASSERT(type_ == TranscendentalCache::LOG);
1423 __ fldln2();
1424 __ fxch();
1425 __ fyl2x();
1389 } 1426 }
1390
1391 // Compute st(0) % st(1)
1392 {
1393 NearLabel partial_remainder_loop;
1394 __ bind(&partial_remainder_loop);
1395 __ fprem1();
1396 __ fwait();
1397 __ fnstsw_ax();
1398 __ test(Operand(eax), Immediate(0x400 /* C2 */));
1399 // If C2 is set, computation only has partial result. Loop to
1400 // continue computation.
1401 __ j(not_zero, &partial_remainder_loop);
1402 }
1403 // FPU Stack: input, 2*pi, input % 2*pi
1404 __ fstp(2);
1405 __ fstp(0);
1406 __ mov(eax, edi); // Restore eax (allocated HeapNumber pointer).
1407
1408 // FPU Stack: input % 2*pi
1409 __ bind(&in_range);
1410 switch (type_) {
1411 case TranscendentalCache::SIN:
1412 __ fsin();
1413 break;
1414 case TranscendentalCache::COS:
1415 __ fcos();
1416 break;
1417 default:
1418 UNREACHABLE();
1419 }
1420 __ bind(&done);
1421 } 1427 }
1422 1428
1423 1429
1424 // Get the integer part of a heap number. Surprisingly, all this bit twiddling 1430 // Get the integer part of a heap number. Surprisingly, all this bit twiddling
1425 // is faster than using the built-in instructions on floating point registers. 1431 // is faster than using the built-in instructions on floating point registers.
1426 // Trashes edi and ebx. Dest is ecx. Source cannot be ecx or one of the 1432 // Trashes edi and ebx. Dest is ecx. Source cannot be ecx or one of the
1427 // trashed registers. 1433 // trashed registers.
1428 void IntegerConvert(MacroAssembler* masm, 1434 void IntegerConvert(MacroAssembler* masm,
1429 Register source, 1435 Register source,
1430 TypeInfo type_info, 1436 TypeInfo type_info,
(...skipping 3140 matching lines...) Expand 10 before | Expand all | Expand 10 after
4571 // tagged as a small integer. 4577 // tagged as a small integer.
4572 __ bind(&runtime); 4578 __ bind(&runtime);
4573 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 4579 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
4574 } 4580 }
4575 4581
4576 #undef __ 4582 #undef __
4577 4583
4578 } } // namespace v8::internal 4584 } } // namespace v8::internal
4579 4585
4580 #endif // V8_TARGET_ARCH_IA32 4586 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32.cc ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698