Commit f54aa8b6 authored by haitao.feng@intel.com's avatar haitao.feng@intel.com

tweak of Math.abs in its x64 stub

R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/22285003

Patch from Weiliang Lin <weiliang.lin@intel.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16113 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent bbbf78e7
...@@ -2479,6 +2479,8 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall( ...@@ -2479,6 +2479,8 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall(
STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTag == 0);
__ JumpIfNotSmi(eax, &not_smi); __ JumpIfNotSmi(eax, &not_smi);
// Branchless abs implementation, refer to below:
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
// Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
// otherwise. // otherwise.
__ mov(ebx, eax); __ mov(ebx, eax);
......
...@@ -3449,7 +3449,7 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { ...@@ -3449,7 +3449,7 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
} }
void LCodeGen::EmitInteger64MathAbs(LMathAbs* instr) { void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) {
Register input_reg = ToRegister(instr->value()); Register input_reg = ToRegister(instr->value());
__ testq(input_reg, input_reg); __ testq(input_reg, input_reg);
Label is_positive; Label is_positive;
...@@ -3486,16 +3486,14 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) { ...@@ -3486,16 +3486,14 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) {
} else if (r.IsInteger32()) { } else if (r.IsInteger32()) {
EmitIntegerMathAbs(instr); EmitIntegerMathAbs(instr);
} else if (r.IsSmi()) { } else if (r.IsSmi()) {
EmitInteger64MathAbs(instr); EmitSmiMathAbs(instr);
} else { // Tagged case. } else { // Tagged case.
DeferredMathAbsTaggedHeapNumber* deferred = DeferredMathAbsTaggedHeapNumber* deferred =
new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
Register input_reg = ToRegister(instr->value()); Register input_reg = ToRegister(instr->value());
// Smi check. // Smi check.
__ JumpIfNotSmi(input_reg, deferred->entry()); __ JumpIfNotSmi(input_reg, deferred->entry());
__ SmiToInteger32(input_reg, input_reg); EmitSmiMathAbs(instr);
EmitIntegerMathAbs(instr);
__ Integer32ToSmi(input_reg, input_reg);
__ bind(deferred->exit()); __ bind(deferred->exit());
} }
} }
......
...@@ -269,7 +269,7 @@ class LCodeGen BASE_EMBEDDED { ...@@ -269,7 +269,7 @@ class LCodeGen BASE_EMBEDDED {
uint32_t additional_index = 0); uint32_t additional_index = 0);
void EmitIntegerMathAbs(LMathAbs* instr); void EmitIntegerMathAbs(LMathAbs* instr);
void EmitInteger64MathAbs(LMathAbs* instr); void EmitSmiMathAbs(LMathAbs* instr);
// Support for recording safepoint and position information. // Support for recording safepoint and position information.
void RecordSafepoint(LPointerMap* pointers, void RecordSafepoint(LPointerMap* pointers,
......
...@@ -2246,26 +2246,25 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall( ...@@ -2246,26 +2246,25 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall(
Label not_smi; Label not_smi;
STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTag == 0);
__ JumpIfNotSmi(rax, &not_smi); __ JumpIfNotSmi(rax, &not_smi);
__ SmiToInteger32(rax, rax);
// Branchless abs implementation, refer to below:
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
// Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
// otherwise. // otherwise.
__ movl(rbx, rax); __ movq(rbx, rax);
__ sarl(rbx, Immediate(kBitsPerInt - 1)); __ sar(rbx, Immediate(kBitsPerPointer - 1));
// Do bitwise not or do nothing depending on ebx. // Do bitwise not or do nothing depending on ebx.
__ xorl(rax, rbx); __ xor_(rax, rbx);
// Add 1 or do nothing depending on ebx. // Add 1 or do nothing depending on ebx.
__ subl(rax, rbx); __ subq(rax, rbx);
// If the result is still negative, go to the slow case. // If the result is still negative, go to the slow case.
// This only happens for the most negative smi. // This only happens for the most negative smi.
Label slow; Label slow;
__ j(negative, &slow); __ j(negative, &slow);
// Smi case done.
__ Integer32ToSmi(rax, rax);
__ ret(2 * kPointerSize); __ ret(2 * kPointerSize);
// Check if the argument is a heap number and load its value. // Check if the argument is a heap number and load its value.
......
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