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(
STATIC_ASSERT(kSmiTag == 0);
__ 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
// otherwise.
__ mov(ebx, eax);
......
......@@ -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());
__ testq(input_reg, input_reg);
Label is_positive;
......@@ -3486,16 +3486,14 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) {
} else if (r.IsInteger32()) {
EmitIntegerMathAbs(instr);
} else if (r.IsSmi()) {
EmitInteger64MathAbs(instr);
EmitSmiMathAbs(instr);
} else { // Tagged case.
DeferredMathAbsTaggedHeapNumber* deferred =
new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
Register input_reg = ToRegister(instr->value());
// Smi check.
__ JumpIfNotSmi(input_reg, deferred->entry());
__ SmiToInteger32(input_reg, input_reg);
EmitIntegerMathAbs(instr);
__ Integer32ToSmi(input_reg, input_reg);
EmitSmiMathAbs(instr);
__ bind(deferred->exit());
}
}
......
......@@ -269,7 +269,7 @@ class LCodeGen BASE_EMBEDDED {
uint32_t additional_index = 0);
void EmitIntegerMathAbs(LMathAbs* instr);
void EmitInteger64MathAbs(LMathAbs* instr);
void EmitSmiMathAbs(LMathAbs* instr);
// Support for recording safepoint and position information.
void RecordSafepoint(LPointerMap* pointers,
......
......@@ -2246,26 +2246,25 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall(
Label not_smi;
STATIC_ASSERT(kSmiTag == 0);
__ 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
// otherwise.
__ movl(rbx, rax);
__ sarl(rbx, Immediate(kBitsPerInt - 1));
__ movq(rbx, rax);
__ sar(rbx, Immediate(kBitsPerPointer - 1));
// Do bitwise not or do nothing depending on ebx.
__ xorl(rax, rbx);
__ xor_(rax, rbx);
// 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.
// This only happens for the most negative smi.
Label slow;
__ j(negative, &slow);
// Smi case done.
__ Integer32ToSmi(rax, rax);
__ ret(2 * kPointerSize);
// 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