X64 Crankshaft: Implement MathRound, MathFloor, MathSqrt, and MathPowHalf UnaryMathOperations in optimizing code generator. Remove unneeded bailout on Math.pow(-0, 0.5) from ia32 and x64 platforms - we produce the correct value without bailing out.
Review URL: http://codereview.chromium.org/6532054 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6856 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
d00e3225f7
commit
4ac9f20601
@ -2493,11 +2493,6 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
|
||||
XMMRegister xmm_scratch = xmm0;
|
||||
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
|
||||
ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
|
||||
ExternalReference negative_infinity =
|
||||
ExternalReference::address_of_negative_infinity();
|
||||
__ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity));
|
||||
__ ucomisd(xmm_scratch, input_reg);
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
__ xorpd(xmm_scratch, xmm_scratch);
|
||||
__ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
|
||||
__ sqrtsd(input_reg, input_reg);
|
||||
|
@ -1223,7 +1223,7 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
|
||||
case kMathSqrt:
|
||||
return DefineSameAsFirst(result);
|
||||
case kMathPowHalf:
|
||||
return AssignEnvironment(DefineSameAsFirst(result));
|
||||
return DefineSameAsFirst(result);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
|
@ -2097,22 +2097,76 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
|
||||
Abort("Unimplemented: %s", "DoMathFloor");
|
||||
XMMRegister xmm_scratch = xmm0;
|
||||
Register output_reg = ToRegister(instr->result());
|
||||
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
|
||||
__ xorpd(xmm_scratch, xmm_scratch); // Zero the register.
|
||||
__ ucomisd(input_reg, xmm_scratch);
|
||||
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
DeoptimizeIf(below_equal, instr->environment());
|
||||
} else {
|
||||
DeoptimizeIf(below, instr->environment());
|
||||
}
|
||||
|
||||
// Use truncating instruction (OK because input is positive).
|
||||
__ cvttsd2si(output_reg, input_reg);
|
||||
|
||||
// Overflow is signalled with minint.
|
||||
__ cmpl(output_reg, Immediate(0x80000000));
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
|
||||
Abort("Unimplemented: %s", "DoMathRound");
|
||||
const XMMRegister xmm_scratch = xmm0;
|
||||
Register output_reg = ToRegister(instr->result());
|
||||
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
|
||||
|
||||
// xmm_scratch = 0.5
|
||||
__ movq(kScratchRegister, V8_INT64_C(0x3FE0000000000000), RelocInfo::NONE);
|
||||
__ movq(xmm_scratch, kScratchRegister);
|
||||
|
||||
// input = input + 0.5
|
||||
__ addsd(input_reg, xmm_scratch);
|
||||
|
||||
// We need to return -0 for the input range [-0.5, 0[, otherwise
|
||||
// compute Math.floor(value + 0.5).
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
__ ucomisd(input_reg, xmm_scratch);
|
||||
DeoptimizeIf(below_equal, instr->environment());
|
||||
} else {
|
||||
// If we don't need to bailout on -0, we check only bailout
|
||||
// on negative inputs.
|
||||
__ xorpd(xmm_scratch, xmm_scratch); // Zero the register.
|
||||
__ ucomisd(input_reg, xmm_scratch);
|
||||
DeoptimizeIf(below, instr->environment());
|
||||
}
|
||||
|
||||
// Compute Math.floor(value + 0.5).
|
||||
// Use truncating instruction (OK because input is positive).
|
||||
__ cvttsd2si(output_reg, input_reg);
|
||||
|
||||
// Overflow is signalled with minint.
|
||||
__ cmpl(output_reg, Immediate(0x80000000));
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
|
||||
Abort("Unimplemented: %s", "DoMathSqrt");
|
||||
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
|
||||
ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
|
||||
__ sqrtsd(input_reg, input_reg);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
|
||||
Abort("Unimplemented: %s", "DoMathPowHalf");
|
||||
XMMRegister xmm_scratch = xmm0;
|
||||
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
|
||||
ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
|
||||
__ xorpd(xmm_scratch, xmm_scratch);
|
||||
__ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
|
||||
__ sqrtsd(input_reg, input_reg);
|
||||
}
|
||||
|
||||
|
||||
@ -2137,7 +2191,35 @@ void LCodeGen::DoMathSin(LUnaryMathOperation* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
|
||||
Abort("Unimplemented: %s", "DoUnaryMathOperation");
|
||||
switch (instr->op()) {
|
||||
case kMathAbs:
|
||||
DoMathAbs(instr);
|
||||
break;
|
||||
case kMathFloor:
|
||||
DoMathFloor(instr);
|
||||
break;
|
||||
case kMathRound:
|
||||
DoMathRound(instr);
|
||||
break;
|
||||
case kMathSqrt:
|
||||
DoMathSqrt(instr);
|
||||
break;
|
||||
case kMathPowHalf:
|
||||
DoMathPowHalf(instr);
|
||||
break;
|
||||
case kMathCos:
|
||||
DoMathCos(instr);
|
||||
break;
|
||||
case kMathSin:
|
||||
DoMathSin(instr);
|
||||
break;
|
||||
case kMathLog:
|
||||
DoMathLog(instr);
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1181,8 +1181,30 @@ LInstruction* LChunkBuilder::DoCallConstantFunction(
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
|
||||
Abort("Unimplemented: %s", "DoUnaryMathOperation");
|
||||
return NULL;
|
||||
BuiltinFunctionId op = instr->op();
|
||||
if (op == kMathLog || op == kMathSin || op == kMathCos) {
|
||||
LOperand* input = UseFixedDouble(instr->value(), xmm1);
|
||||
LUnaryMathOperation* result = new LUnaryMathOperation(input);
|
||||
return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
|
||||
} else {
|
||||
LOperand* input = UseRegisterAtStart(instr->value());
|
||||
LUnaryMathOperation* result = new LUnaryMathOperation(input);
|
||||
switch (op) {
|
||||
case kMathAbs:
|
||||
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
|
||||
case kMathFloor:
|
||||
return AssignEnvironment(DefineAsRegister(result));
|
||||
case kMathRound:
|
||||
return AssignEnvironment(DefineAsRegister(result));
|
||||
case kMathSqrt:
|
||||
return DefineSameAsFirst(result);
|
||||
case kMathPowHalf:
|
||||
return DefineSameAsFirst(result);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user