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
This commit is contained in:
parent
852cebb1cb
commit
001f020d04
@ -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) {
|
|||||||
|
|
||||||
__ 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) {
|
|||||||
__ 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() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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) {
|
|||||||
__ 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) {
|
|||||||
__ 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) {
|
|||||||
__ 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() {
|
|||||||
__ 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 {
|
|||||||
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user