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