Commit 001f020d authored by lrn@chromium.org's avatar lrn@chromium.org

X64: Minor change of control flow in inline transcendental cache.

Move NaN-handling away from main code path.

Review URL: http://codereview.chromium.org/1851002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4577 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 852cebb1
...@@ -43,8 +43,6 @@ namespace internal { ...@@ -43,8 +43,6 @@ namespace internal {
#define __ ACCESS_MASM(masm_) #define __ ACCESS_MASM(masm_)
static int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Platform-specific DeferredCode functions. // Platform-specific DeferredCode functions.
...@@ -7725,8 +7723,9 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { ...@@ -7725,8 +7723,9 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
__ bind(&cache_miss); __ bind(&cache_miss);
// Update cache with new value. // Update cache with new value.
Label nan_result;
GenerateOperation(masm, &nan_result);
__ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack); __ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack);
GenerateOperation(masm);
__ movq(Operand(rcx, 0), rbx); __ movq(Operand(rcx, 0), rbx);
__ movq(Operand(rcx, 2 * kIntSize), rax); __ movq(Operand(rcx, 2 * kIntSize), rax);
__ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset));
...@@ -7736,6 +7735,13 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { ...@@ -7736,6 +7735,13 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
__ fstp(0); __ fstp(0);
__ bind(&runtime_call); __ bind(&runtime_call);
__ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1); __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1);
__ bind(&nan_result);
__ fstp(0); // Remove argument from FPU stack.
__ LoadRoot(rax, Heap::kNanValueRootIndex);
__ movq(Operand(rcx, 0), rbx);
__ movq(Operand(rcx, 2 * kIntSize), rax);
__ ret(kPointerSize);
} }
...@@ -7751,8 +7757,12 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { ...@@ -7751,8 +7757,12 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
} }
void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm,
// Only free register is rdi. Label* on_nan_result) {
// Registers:
// rbx: Bits of input double. Must be preserved.
// rcx: Pointer to cache entry. Must be preserved.
// st(0): Input double
Label done; Label done;
ASSERT(type_ == TranscendentalCache::SIN || ASSERT(type_ == TranscendentalCache::SIN ||
type_ == TranscendentalCache::COS); type_ == TranscendentalCache::COS);
...@@ -7774,21 +7784,9 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { ...@@ -7774,21 +7784,9 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
__ j(below, &in_range); __ j(below, &in_range);
// Check for infinity and NaN. Both return NaN for sin. // Check for infinity and NaN. Both return NaN for sin.
__ cmpl(rdi, Immediate(0x7ff)); __ cmpl(rdi, Immediate(0x7ff));
Label non_nan_result; __ j(equal, on_nan_result);
__ j(not_equal, &non_nan_result);
// Input is +/-Infinity or NaN. Result is NaN.
__ fstp(0); // Clear fpu stack.
// NaN is represented by 0x7ff8000000000000.
__ movq(rdi, kNaNValue, RelocInfo::NONE);
__ push(rdi);
__ fld_d(Operand(rsp, 0));
__ addq(rsp, Immediate(kPointerSize));
__ jmp(&done);
__ bind(&non_nan_result);
// Use fpmod to restrict argument to the range +/-2*PI. // Use fpmod to restrict argument to the range +/-2*PI.
__ movq(rdi, rax); // Save rax before using fnstsw_ax.
__ fldpi(); __ fldpi();
__ fadd(0); __ fadd(0);
__ fld(1); __ fld(1);
...@@ -7798,7 +7796,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { ...@@ -7798,7 +7796,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
__ fwait(); __ fwait();
__ fnstsw_ax(); __ fnstsw_ax();
// Clear if Illegal Operand or Zero Division exceptions are set. // Clear if Illegal Operand or Zero Division exceptions are set.
__ testl(rax, Immediate(5)); __ testl(rax, Immediate(5)); // #IO and #ZD flags of FPU status word.
__ j(zero, &no_exceptions); __ j(zero, &no_exceptions);
__ fnclex(); __ fnclex();
__ bind(&no_exceptions); __ bind(&no_exceptions);
...@@ -7820,9 +7818,6 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { ...@@ -7820,9 +7818,6 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
__ fstp(2); __ fstp(2);
// FPU Stack: input % 2*pi, 2*pi, // FPU Stack: input % 2*pi, 2*pi,
__ fstp(0); __ fstp(0);
// FPU Stack: input % 2*pi
__ movq(rax, rdi); // Restore rax (allocated HeapNumber pointer).
// FPU Stack: input % 2*pi // FPU Stack: input % 2*pi
__ bind(&in_range); __ bind(&in_range);
switch (type_) { switch (type_) {
...@@ -11379,6 +11374,7 @@ ModuloFunction CreateModuloFunction() { ...@@ -11379,6 +11374,7 @@ ModuloFunction CreateModuloFunction() {
__ testb(rax, Immediate(5)); __ testb(rax, Immediate(5));
__ j(zero, &valid_result); __ j(zero, &valid_result);
__ fstp(0); // Drop result in st(0). __ fstp(0); // Drop result in st(0).
int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
__ movq(rcx, kNaNValue, RelocInfo::NONE); __ movq(rcx, kNaNValue, RelocInfo::NONE);
__ movq(Operand(rsp, kPointerSize), rcx); __ movq(Operand(rsp, kPointerSize), rcx);
__ movsd(xmm0, Operand(rsp, kPointerSize)); __ movsd(xmm0, Operand(rsp, kPointerSize));
......
...@@ -686,7 +686,7 @@ class TranscendentalCacheStub: public CodeStub { ...@@ -686,7 +686,7 @@ class TranscendentalCacheStub: public CodeStub {
Major MajorKey() { return TranscendentalCache; } Major MajorKey() { return TranscendentalCache; }
int MinorKey() { return type_; } int MinorKey() { return type_; }
Runtime::FunctionId RuntimeFunction(); Runtime::FunctionId RuntimeFunction();
void GenerateOperation(MacroAssembler* masm); void GenerateOperation(MacroAssembler* masm, Label* on_nan_result);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment