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
This commit is contained in:
parent
08b4262512
commit
1bfa622043
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user