Commit 1bfa6220 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Refactor MathPowHalf on ia32.

BUG=v8:397, v8:1848
TEST=regress-397.js

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10157 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 08b42625
......@@ -2934,31 +2934,33 @@ void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
}
void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
XMMRegister xmm_scratch = xmm0;
XMMRegister input_reg = ToDoubleRegister(instr->value());
Register scratch = ToRegister(instr->temp());
ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
Label return_infinity, done;
// Check base for +/- infinity.
__ push(ecx); // TODO(1848): reserve this register.
__ mov(ecx, factory()->infinity_value());
__ ucomisd(input_reg, FieldOperand(ecx, HeapNumber::kValueOffset));
__ j(equal, &return_infinity, Label::kNear);
__ xorps(xmm_scratch, xmm_scratch);
__ subsd(xmm_scratch, input_reg);
__ ucomisd(xmm_scratch, FieldOperand(ecx, HeapNumber::kValueOffset));
__ j(equal, &return_infinity, Label::kNear);
// Note that according to ECMA-262 15.8.2.13:
// Math.pow(-Infinity, 0.5) == Infinity
// Math.sqrt(-Infinity) == NaN
Label done, sqrt;
// Check base for -Infinity. According to IEEE-754, single-precision
// -Infinity has the highest 9 bits set and the lowest 23 bits cleared.
__ mov(scratch, 0xFF800000);
__ movd(xmm_scratch, scratch);
__ cvtss2sd(xmm_scratch, xmm_scratch);
__ ucomisd(input_reg, xmm_scratch);
__ j(not_equal, &sqrt, Label::kNear);
// If input is -Infinity, return Infinity.
__ xorps(input_reg, input_reg);
__ subsd(input_reg, xmm_scratch);
__ jmp(&done, Label::kNear);
__ pop(ecx);
// Square root.
__ bind(&sqrt);
__ xorps(xmm_scratch, xmm_scratch);
__ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
__ sqrtsd(input_reg, input_reg);
__ jmp(&done, Label::kNear);
__ bind(&return_infinity);
__ movdbl(input_reg, FieldOperand(ecx, HeapNumber::kValueOffset));
__ pop(ecx);
__ bind(&done);
}
......@@ -3062,9 +3064,6 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
case kMathSqrt:
DoMathSqrt(instr);
break;
case kMathPowHalf:
DoMathPowHalf(instr);
break;
case kMathCos:
DoMathCos(instr);
break;
......
......@@ -239,7 +239,6 @@ class LCodeGen BASE_EMBEDDED {
void DoMathFloor(LUnaryMathOperation* instr);
void DoMathRound(LUnaryMathOperation* instr);
void DoMathSqrt(LUnaryMathOperation* instr);
void DoMathPowHalf(LUnaryMathOperation* instr);
void DoMathLog(LUnaryMathOperation* instr);
void DoMathTan(LUnaryMathOperation* instr);
void DoMathCos(LUnaryMathOperation* instr);
......
......@@ -298,6 +298,12 @@ void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
}
void LMathPowHalf::PrintDataTo(StringStream* stream) {
stream->Add("/pow_half ");
InputAt(0)->PrintTo(stream);
}
void LLoadContextSlot::PrintDataTo(StringStream* stream) {
InputAt(0)->PrintTo(stream);
stream->Add("[%d]", slot_index());
......@@ -1184,6 +1190,11 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
} else {
LOperand* input = UseRegisterAtStart(instr->value());
LOperand* context = UseAny(instr->context()); // Deferred use by MathAbs.
if (op == kMathPowHalf) {
LOperand* temp = TempRegister();
LMathPowHalf* result = new(zone()) LMathPowHalf(context, input, temp);
return DefineSameAsFirst(result);
}
LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(context,
input);
switch (op) {
......@@ -1195,8 +1206,6 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
return AssignEnvironment(DefineAsRegister(result));
case kMathSqrt:
return DefineSameAsFirst(result);
case kMathPowHalf:
return DefineSameAsFirst(result);
default:
UNREACHABLE();
return NULL;
......
......@@ -123,6 +123,7 @@ class LCodeGen;
V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
V(MathPowHalf) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
......@@ -582,6 +583,24 @@ class LUnaryMathOperation: public LTemplateInstruction<1, 2, 0> {
};
class LMathPowHalf: public LTemplateInstruction<1, 2, 1> {
public:
LMathPowHalf(LOperand* context, LOperand* value, LOperand* temp) {
inputs_[1] = context;
inputs_[0] = value;
temps_[0] = temp;
}
LOperand* context() { return inputs_[1]; }
LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
virtual void PrintDataTo(StringStream* stream);
};
class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> {
public:
LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
......
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