Revision: 6083
Author: [email protected]
Date: Mon Dec 20 05:52:14 2010
Log: Add untagged double versions of Math.sin and Math.cos. Merge classes
TranscendentalCacheStub and TranscendentalCacheSSE2Stub.
Review URL: http://codereview.chromium.org/5996002
http://code.google.com/p/v8/source/detail?r=6083
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/heap.h
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
/branches/bleeding_edge/src/ia32/code-stubs-ia32.h
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Wed Dec 15 04:32:19 2010
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Mon Dec 20 05:52:14 2010
@@ -1375,6 +1375,12 @@
case kMathLog:
Abort("MathLog LUnaryMathOperation not implemented");
return NULL;
+ case kMathCos:
+ Abort("MathCos LUnaryMathOperation not implemented");
+ return NULL;
+ case kMathSin:
+ Abort("MathSin LUnaryMathOperation not implemented");
+ return NULL;
default:
UNREACHABLE();
return NULL;
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Dec 15
04:32:19 2010
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Dec 20
05:52:14 2010
@@ -1547,7 +1547,7 @@
void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
- Abort("LUnaryMathOperation unimplemented.");
+ Abort("DoMathAbs unimplemented.");
}
@@ -1562,9 +1562,6 @@
void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
- ASSERT(instr->op() == kMathFloor ||
- instr->op() == kMathAbs);
-
switch (instr->op()) {
case kMathAbs:
DoMathAbs(instr);
@@ -1576,6 +1573,7 @@
DoMathSqrt(instr);
break;
default:
+ Abort("Unimplemented type of LUnaryMathOperation.");
UNREACHABLE();
}
}
=======================================
--- /branches/bleeding_edge/src/heap.h Tue Dec 14 05:21:29 2010
+++ /branches/bleeding_edge/src/heap.h Mon Dec 20 05:52:14 2010
@@ -1968,6 +1968,8 @@
class TranscendentalCache {
public:
enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches};
+ static const int kTranscendentalTypeBits = 3;
+ STATIC_ASSERT((1 << kTranscendentalTypeBits) >= kNumberOfCaches);
explicit TranscendentalCache(Type t);
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri Dec 17 05:44:19
2010
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Mon Dec 20 05:52:14
2010
@@ -1389,6 +1389,8 @@
case kMathSqrt:
case kMathPowHalf:
case kMathLog:
+ case kMathSin:
+ case kMathCos:
set_representation(Representation::Double());
break;
default:
@@ -1411,6 +1413,8 @@
case kMathSqrt:
case kMathPowHalf:
case kMathLog:
+ case kMathSin:
+ case kMathCos:
return Representation::Double();
break;
case kMathAbs:
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Mon Dec 20 05:18:47 2010
+++ /branches/bleeding_edge/src/hydrogen.cc Mon Dec 20 05:52:14 2010
@@ -4097,6 +4097,8 @@
case kMathAbs:
case kMathSqrt:
case kMathLog:
+ case kMathSin:
+ case kMathCos:
if (argument_count == 2) {
HValue* argument = Pop();
Drop(1); // Receiver.
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Dec 16 00:58:42
2010
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Mon Dec 20 05:52:14
2010
@@ -2472,41 +2472,66 @@
void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
- // Input on stack:
- // esp[4]: argument (should be number).
- // esp[0]: return address.
- // Test that eax is a number.
+ // TAGGED case:
+ // Input:
+ // esp[4]: tagged number input argument (should be number).
+ // esp[0]: return address.
+ // Output:
+ // eax: tagged double result.
+ // UNTAGGED case:
+ // Input::
+ // esp[0]: return address.
+ // xmm1: untagged double input argument
+ // Output:
+ // xmm1: untagged double result.
+
Label runtime_call;
Label runtime_call_clear_stack;
- NearLabel input_not_smi;
- NearLabel loaded;
- __ mov(eax, Operand(esp, kPointerSize));
- __ test(eax, Immediate(kSmiTagMask));
- __ j(not_zero, &input_not_smi);
- // Input is a smi. Untag and load it onto the FPU stack.
- // Then load the low and high words of the double into ebx, edx.
- STATIC_ASSERT(kSmiTagSize == 1);
- __ sar(eax, 1);
- __ sub(Operand(esp), Immediate(2 * kPointerSize));
- __ mov(Operand(esp, 0), eax);
- __ fild_s(Operand(esp, 0));
- __ fst_d(Operand(esp, 0));
- __ pop(edx);
- __ pop(ebx);
- __ jmp(&loaded);
- __ bind(&input_not_smi);
- // Check if input is a HeapNumber.
- __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- __ cmp(Operand(ebx), Immediate(Factory::heap_number_map()));
- __ j(not_equal, &runtime_call);
- // Input is a HeapNumber. Push it on the FPU stack and load its
- // low and high words into ebx, edx.
- __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
- __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
- __ mov(ebx, FieldOperand(eax, HeapNumber::kMantissaOffset));
-
- __ bind(&loaded);
- // ST[0] == double value
+ Label skip_cache;
+ Label call_runtime;
+ const bool tagged = (argument_type_ == TAGGED);
+ if (tagged) {
+ // Test that eax is a number.
+ NearLabel input_not_smi;
+ NearLabel loaded;
+ __ mov(eax, Operand(esp, kPointerSize));
+ __ test(eax, Immediate(kSmiTagMask));
+ __ j(not_zero, &input_not_smi);
+ // Input is a smi. Untag and load it onto the FPU stack.
+ // Then load the low and high words of the double into ebx, edx.
+ STATIC_ASSERT(kSmiTagSize == 1);
+ __ sar(eax, 1);
+ __ sub(Operand(esp), Immediate(2 * kPointerSize));
+ __ mov(Operand(esp, 0), eax);
+ __ fild_s(Operand(esp, 0));
+ __ fst_d(Operand(esp, 0));
+ __ pop(edx);
+ __ pop(ebx);
+ __ jmp(&loaded);
+ __ bind(&input_not_smi);
+ // Check if input is a HeapNumber.
+ __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
+ __ cmp(Operand(ebx), Immediate(Factory::heap_number_map()));
+ __ j(not_equal, &runtime_call);
+ // Input is a HeapNumber. Push it on the FPU stack and load its
+ // low and high words into ebx, edx.
+ __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
+ __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
+ __ mov(ebx, FieldOperand(eax, HeapNumber::kMantissaOffset));
+
+ __ bind(&loaded);
+ } else { // UNTAGGED.
+ if (CpuFeatures::IsSupported(SSE4_1)) {
+ CpuFeatures::Scope sse4_scope(SSE4_1);
+ __ pextrd(Operand(edx), xmm1, 0x1); // copy xmm1[63..32] to edx.
+ } else {
+ __ pshufd(xmm0, xmm1, 0x1);
+ __ movd(Operand(edx), xmm0);
+ }
+ __ movd(Operand(ebx), xmm1);
+ }
+
+ // ST[0] or xmm1 == double value
// ebx = low 32 bits of double value
// edx = high 32 bits of double value
// Compute hash (the shifts are arithmetic):
@@ -2522,7 +2547,7 @@
ASSERT(IsPowerOf2(TranscendentalCache::kCacheSize));
__ and_(Operand(ecx), Immediate(TranscendentalCache::kCacheSize - 1));
- // ST[0] == double value.
+ // ST[0] or xmm1 == double value.
// ebx = low 32 bits of double value.
// edx = high 32 bits of double value.
// ecx = TranscendentalCache::hash(double value).
@@ -2559,31 +2584,72 @@
__ j(not_equal, &cache_miss);
// Cache hit!
__ mov(eax, Operand(ecx, 2 * kIntSize));
- __ fstp(0);
- __ ret(kPointerSize);
+ if (tagged) {
+ __ fstp(0);
+ __ ret(kPointerSize);
+ } else { // UNTAGGED.
+ __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
+ __ Ret();
+ }
__ bind(&cache_miss);
// Update cache with new value.
// We are short on registers, so use no_reg as scratch.
// This gives slightly larger code.
- __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack);
+ if (tagged) {
+ __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack);
+ } else { // UNTAGGED.
+ __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
+ __ sub(Operand(esp), Immediate(kDoubleSize));
+ __ movdbl(Operand(esp, 0), xmm1);
+ __ fld_d(Operand(esp, 0));
+ __ add(Operand(esp), Immediate(kDoubleSize));
+ }
GenerateOperation(masm);
__ mov(Operand(ecx, 0), ebx);
__ mov(Operand(ecx, kIntSize), edx);
__ mov(Operand(ecx, 2 * kIntSize), eax);
__ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
- __ ret(kPointerSize);
-
- __ bind(&runtime_call_clear_stack);
- __ fstp(0);
- __ bind(&runtime_call);
- __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1);
+ if (tagged) {
+ __ ret(kPointerSize);
+ } else { // UNTAGGED.
+ __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
+ __ Ret();
+
+ // Skip cache and return answer directly, only in untagged case.
+ __ bind(&skip_cache);
+ __ sub(Operand(esp), Immediate(kDoubleSize));
+ __ movdbl(Operand(esp, 0), xmm1);
+ __ fld_d(Operand(esp, 0));
+ GenerateOperation(masm);
+ __ fstp_d(Operand(esp, 0));
+ __ movdbl(xmm1, Operand(esp, 0));
+ __ add(Operand(esp), Immediate(kDoubleSize));
+ __ Ret();
+ }
+
+ // Call runtime, doing whatever allocation and cleanup is necessary.
+ if (tagged) {
+ __ bind(&runtime_call_clear_stack);
+ __ fstp(0);
+ __ bind(&runtime_call);
+ __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1,
1);
+ } else { // UNTAGGED.
+ __ bind(&call_runtime);
+ __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
+ __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1);
+ __ EnterInternalFrame();
+ __ push(eax);
+ __ CallRuntime(RuntimeFunction(), 1);
+ __ LeaveInternalFrame();
+ __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
+ __ Ret();
+ }
}
Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
switch (type_) {
- // Add more cases when necessary.
case TranscendentalCache::SIN: return Runtime::kMath_sin;
case TranscendentalCache::COS: return Runtime::kMath_cos;
case TranscendentalCache::LOG: return Runtime::kMath_log;
@@ -2596,14 +2662,14 @@
void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
// Only free register is edi.
- // Input value is on FP stack, and also in ebx/edx. Address of result
- // (a newly allocated HeapNumber) is in eax.
- NearLabel done;
+ // Input value is on FP stack, and also in ebx/edx.
+ // Input value is possibly in xmm1.
+ // Address of result (a newly allocated HeapNumber) may be in eax.
if (type_ == TranscendentalCache::SIN || type_ ==
TranscendentalCache::COS) {
// Both fsin and fcos require arguments in the range +/-2^63 and
// return NaN for infinities and NaN. They can share all code except
// the actual fsin/fcos operation.
- NearLabel in_range;
+ NearLabel in_range, done;
// If argument is outside the range -2^63..2^63, fsin/cos doesn't
// work. We must reduce it to the appropriate range.
__ mov(edi, edx);
@@ -2681,145 +2747,6 @@
__ fyl2x();
}
}
-
-
-void TranscendentalCacheSSE2Stub::Generate(MacroAssembler* masm) {
- // Input on stack:
- // esp[0]: return address.
- // Input in registers:
- // xmm1: untagged double input argument.
- // Output:
- // xmm1: untagged double result.
- Label skip_cache;
- Label call_runtime;
-
- // Input is an untagged double in xmm1.
- // Compute hash (the shifts are arithmetic):
- // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize -
1);
- if (CpuFeatures::IsSupported(SSE4_1)) {
- CpuFeatures::Scope sse4_scope(SSE4_1);
- __ pextrd(Operand(edx), xmm1, 0x1); // copy xmm1[63..32] to edx.
- } else {
- __ pshufd(xmm0, xmm1, 0x1);
- __ movd(Operand(edx), xmm0);
- }
- __ movd(Operand(ebx), xmm1);
-
- // xmm1 = double value
- // ebx = low 32 bits of double value
- // edx = high 32 bits of double value
- // Compute hash (the shifts are arithmetic):
- // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize -
1);
- __ mov(ecx, ebx);
- __ xor_(ecx, Operand(edx));
- __ mov(eax, ecx);
- __ sar(eax, 16);
- __ xor_(ecx, Operand(eax));
- __ mov(eax, ecx);
- __ sar(eax, 8);
- __ xor_(ecx, Operand(eax));
- ASSERT(IsPowerOf2(TranscendentalCache::kCacheSize));
- __ and_(Operand(ecx), Immediate(TranscendentalCache::kCacheSize - 1));
-
- // xmm1 = double value.
- // ebx = low 32 bits of double value.
- // edx = high 32 bits of double value.
- // ecx = TranscendentalCache::hash(double value).
- __ mov(eax,
-
Immediate(ExternalReference::transcendental_cache_array_address()));
- // Eax points to cache array.
- __ mov(eax, Operand(eax, type_ *
sizeof(TranscendentalCache::caches_[0])));
- // Eax points to the cache for the type type_.
- // If NULL, the cache hasn't been initialized yet, so go through runtime.
- __ test(eax, Operand(eax));
- __ j(zero, &call_runtime);
-#ifdef DEBUG
- // Check that the layout of cache elements match expectations.
- { TranscendentalCache::Element test_elem[2];
- char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
- char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
- char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0]));
- char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1]));
- char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
- CHECK_EQ(12, elem2_start - elem_start); // Two uint_32's and a
pointer.
- CHECK_EQ(0, elem_in0 - elem_start);
- CHECK_EQ(kIntSize, elem_in1 - elem_start);
- CHECK_EQ(2 * kIntSize, elem_out - elem_start);
- }
-#endif
- // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12].
- __ lea(ecx, Operand(ecx, ecx, times_2, 0));
- __ lea(ecx, Operand(eax, ecx, times_4, 0));
- // Check if cache matches: Double value is stored in uint32_t[2] array.
- NearLabel cache_miss;
- __ cmp(ebx, Operand(ecx, 0));
- __ j(not_equal, &cache_miss);
- __ cmp(edx, Operand(ecx, kIntSize));
- __ j(not_equal, &cache_miss);
- // Cache hit!
- __ mov(eax, Operand(ecx, 2 * kIntSize));
- __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
- __ Ret();
-
- __ bind(&cache_miss);
- // Update cache with new value.
- // We are short on registers, so use no_reg as scratch.
- // This gives slightly larger code.
- __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
- __ sub(Operand(esp), Immediate(kDoubleSize));
- __ movdbl(Operand(esp, 0), xmm1);
- __ fld_d(Operand(esp, 0));
- __ add(Operand(esp), Immediate(kDoubleSize));
- GenerateOperation(masm);
- __ mov(Operand(ecx, 0), ebx);
- __ mov(Operand(ecx, kIntSize), edx);
- __ mov(Operand(ecx, 2 * kIntSize), eax);
- __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
- __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
- __ Ret();
-
- __ bind(&skip_cache);
- __ sub(Operand(esp), Immediate(kDoubleSize));
- __ movdbl(Operand(esp, 0), xmm1);
- __ fld_d(Operand(esp, 0));
- GenerateOperation(masm);
- __ fstp_d(Operand(esp, 0));
- __ movdbl(xmm1, Operand(esp, 0));
- __ add(Operand(esp), Immediate(kDoubleSize));
- __ Ret();
-
- __ bind(&call_runtime);
- __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
- __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1);
- __ EnterInternalFrame();
- __ push(eax);
- __ CallRuntime(RuntimeFunction(), 1);
- __ LeaveInternalFrame();
- __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
- __ Ret();
-}
-
-
-Runtime::FunctionId TranscendentalCacheSSE2Stub::RuntimeFunction() {
- switch (type_) {
- // Add more cases when necessary.
- case TranscendentalCache::LOG: return Runtime::kMath_log;
- default:
- UNIMPLEMENTED();
- return Runtime::kAbort;
- }
-}
-
-
-void TranscendentalCacheSSE2Stub::GenerateOperation(MacroAssembler* masm) {
- // Only free register is edi.
- // Input value is on FP stack and in xmm1.
-
- ASSERT(type_ == TranscendentalCache::LOG);
- __ fldln2();
- __ fxch();
- __ fyl2x();
-}
// Get the integer part of a heap number. Surprisingly, all this bit
twiddling
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.h Wed Dec 15 05:56:41
2010
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.h Mon Dec 20 05:52:14
2010
@@ -40,32 +40,21 @@
// TranscendentalCache runtime function.
class TranscendentalCacheStub: public CodeStub {
public:
- explicit TranscendentalCacheStub(TranscendentalCache::Type type)
- : type_(type) {}
- void Generate(MacroAssembler* masm);
- private:
- TranscendentalCache::Type type_;
-
- Major MajorKey() { return TranscendentalCache; }
- int MinorKey() { return type_; }
- Runtime::FunctionId RuntimeFunction();
- void GenerateOperation(MacroAssembler* masm);
-};
-
-
-// Check the transcendental cache, or generate the result, using SSE2.
-// The argument and result will be in xmm1.
-// Only supports TranscendentalCache::LOG at this point.
-class TranscendentalCacheSSE2Stub: public CodeStub {
- public:
- explicit TranscendentalCacheSSE2Stub(TranscendentalCache::Type type)
- : type_(type) {}
+ enum ArgumentType {
+ TAGGED = 0,
+ UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
+ };
+
+ explicit TranscendentalCacheStub(TranscendentalCache::Type type,
+ ArgumentType argument_type)
+ : type_(type), argument_type_(argument_type) {}
void Generate(MacroAssembler* masm);
private:
TranscendentalCache::Type type_;
-
- Major MajorKey() { return TranscendentalCacheSSE2; }
- int MinorKey() { return type_; }
+ ArgumentType argument_type_;
+
+ Major MajorKey() { return TranscendentalCache; }
+ int MinorKey() { return type_ | argument_type_; }
Runtime::FunctionId RuntimeFunction();
void GenerateOperation(MacroAssembler* masm);
};
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Thu Dec 16 00:58:42
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Dec 20 05:52:14
2010
@@ -7912,7 +7912,8 @@
void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
Load(args->at(0));
- TranscendentalCacheStub stub(TranscendentalCache::SIN);
+ TranscendentalCacheStub stub(TranscendentalCache::SIN,
+ TranscendentalCacheStub::TAGGED);
Result result = frame_->CallStub(&stub, 1);
frame_->Push(&result);
}
@@ -7921,7 +7922,8 @@
void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
Load(args->at(0));
- TranscendentalCacheStub stub(TranscendentalCache::COS);
+ TranscendentalCacheStub stub(TranscendentalCache::COS,
+ TranscendentalCacheStub::TAGGED);
Result result = frame_->CallStub(&stub, 1);
frame_->Push(&result);
}
@@ -7930,7 +7932,8 @@
void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
Load(args->at(0));
- TranscendentalCacheStub stub(TranscendentalCache::LOG);
+ TranscendentalCacheStub stub(TranscendentalCache::LOG,
+ TranscendentalCacheStub::TAGGED);
Result result = frame_->CallStub(&stub, 1);
frame_->Push(&result);
}
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu Dec 16
00:58:42 2010
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Mon Dec 20
05:52:14 2010
@@ -3067,7 +3067,8 @@
void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the stub.
- TranscendentalCacheStub stub(TranscendentalCache::SIN);
+ TranscendentalCacheStub stub(TranscendentalCache::SIN,
+ TranscendentalCacheStub::TAGGED);
ASSERT(args->length() == 1);
VisitForStackValue(args->at(0));
__ CallStub(&stub);
@@ -3077,7 +3078,8 @@
void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the stub.
- TranscendentalCacheStub stub(TranscendentalCache::COS);
+ TranscendentalCacheStub stub(TranscendentalCache::COS,
+ TranscendentalCacheStub::TAGGED);
ASSERT(args->length() == 1);
VisitForStackValue(args->at(0));
__ CallStub(&stub);
@@ -3087,7 +3089,8 @@
void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the stub.
- TranscendentalCacheStub stub(TranscendentalCache::LOG);
+ TranscendentalCacheStub stub(TranscendentalCache::LOG,
+ TranscendentalCacheStub::TAGGED);
ASSERT(args->length() == 1);
VisitForStackValue(args->at(0));
__ CallStub(&stub);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu Dec 16
00:58:42 2010
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Dec 20
05:52:14 2010
@@ -686,7 +686,8 @@
break;
}
case CodeStub::TranscendentalCache: {
- TranscendentalCacheStub stub(instr->transcendental_type());
+ TranscendentalCacheStub stub(instr->transcendental_type(),
+ TranscendentalCacheStub::TAGGED);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
@@ -2314,9 +2315,26 @@
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
- TranscendentalCacheSSE2Stub stub(TranscendentalCache::LOG);
+ TranscendentalCacheStub stub(TranscendentalCache::LOG,
+ TranscendentalCacheStub::UNTAGGED);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
+
+
+void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+ TranscendentalCacheStub stub(TranscendentalCache::COS,
+ TranscendentalCacheStub::UNTAGGED);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoMathSin(LUnaryMathOperation* instr) {
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+ TranscendentalCacheStub stub(TranscendentalCache::SIN,
+ TranscendentalCacheStub::UNTAGGED);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
@@ -2336,6 +2354,12 @@
case kMathPowHalf:
DoMathPowHalf(instr);
break;
+ case kMathCos:
+ DoMathCos(instr);
+ break;
+ case kMathSin:
+ DoMathSin(instr);
+ break;
case kMathLog:
DoMathLog(instr);
break;
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Wed Dec 15
04:32:19 2010
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Mon Dec 20
05:52:14 2010
@@ -177,6 +177,8 @@
void DoMathSqrt(LUnaryMathOperation* instr);
void DoMathPowHalf(LUnaryMathOperation* instr);
void DoMathLog(LUnaryMathOperation* instr);
+ void DoMathCos(LUnaryMathOperation* instr);
+ void DoMathSin(LUnaryMathOperation* instr);
// Support for recording safepoint and position information.
void RecordSafepoint(LPointerMap* pointers, int deoptimization_index);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Dec 16 08:56:45
2010
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Mon Dec 20 05:52:14
2010
@@ -1361,7 +1361,7 @@
LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation*
instr) {
BuiltinFunctionId op = instr->op();
- if (op == kMathLog) {
+ if (op == kMathLog || op == kMathSin || op == kMathCos) {
LOperand* input = UseFixedDouble(instr->value(), xmm1);
LInstruction* result = new LUnaryMathOperation(input);
return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev