Bug 806643 - Negate doubles by flipping signed bit. r=sstangl

This commit is contained in:
Tony Young 2012-10-30 14:59:06 -07:00
Родитель 68936b490f
Коммит 870d76ed15
7 изменённых файлов: 46 добавлений и 0 удалений

Просмотреть файл

@ -1327,6 +1327,16 @@ class LMinMaxD : public LInstructionHelper<1, 2, 0>
} }
}; };
// Negative of a double.
class LNegD : public LInstructionHelper<1, 1, 0>
{
public:
LIR_HEADER(NegD);
LNegD(const LAllocation &num) {
setOperand(0, num);
}
};
// Absolute value of an integer. // Absolute value of an integer.
class LAbsI : public LInstructionHelper<1, 1, 0> class LAbsI : public LInstructionHelper<1, 1, 0>
{ {

Просмотреть файл

@ -66,6 +66,7 @@
_(IsNullOrUndefinedAndBranch) \ _(IsNullOrUndefinedAndBranch) \
_(MinMaxI) \ _(MinMaxI) \
_(MinMaxD) \ _(MinMaxD) \
_(NegD) \
_(AbsI) \ _(AbsI) \
_(AbsD) \ _(AbsD) \
_(SqrtD) \ _(SqrtD) \

Просмотреть файл

@ -855,6 +855,15 @@ LIRGenerator::visitMul(MMul *ins)
} }
if (ins->specialization() == MIRType_Double) { if (ins->specialization() == MIRType_Double) {
JS_ASSERT(lhs->type() == MIRType_Double); JS_ASSERT(lhs->type() == MIRType_Double);
// If our LHS is a constant -1.0, we can optimize to an LNegD.
if (lhs->isConstant() && lhs->toConstant()->value() == DoubleValue(-1.0))
return defineReuseInput(new LNegD(useRegisterAtStart(rhs)), ins, 0);
// We can do the same for the RHS, if we just swap the operands.
if (rhs->isConstant() && rhs->toConstant()->value() == DoubleValue(-1.0))
return defineReuseInput(new LNegD(useRegisterAtStart(lhs)), ins, 0);
return lowerForFPU(new LMathD(JSOP_MUL), ins, lhs, rhs); return lowerForFPU(new LMathD(JSOP_MUL), ins, lhs, rhs);
} }

Просмотреть файл

@ -320,6 +320,15 @@ CodeGeneratorARM::visitMinMaxD(LMinMaxD *ins)
return true; return true;
} }
bool
CodeGeneratorARM::visitNegD(LNegD *ins)
{
FloatRegister input = ToFloatRegister(ins->input());
JS_ASSERT(input == ToFloatRegister(ins->output()));
masm.as_vneg(input, input);
return true;
}
bool bool
CodeGeneratorARM::visitAbsD(LAbsD *ins) CodeGeneratorARM::visitAbsD(LAbsD *ins)
{ {

Просмотреть файл

@ -69,6 +69,7 @@ class CodeGeneratorARM : public CodeGeneratorShared
public: public:
// Instruction visitors. // Instruction visitors.
virtual bool visitMinMaxD(LMinMaxD *ins); virtual bool visitMinMaxD(LMinMaxD *ins);
virtual bool visitNegD(LNegD *ins);
virtual bool visitAbsD(LAbsD *ins); virtual bool visitAbsD(LAbsD *ins);
virtual bool visitSqrtD(LSqrtD *ins); virtual bool visitSqrtD(LSqrtD *ins);
virtual bool visitAddI(LAddI *ins); virtual bool visitAddI(LAddI *ins);

Просмотреть файл

@ -446,6 +446,21 @@ CodeGeneratorX86Shared::visitMinMaxD(LMinMaxD *ins)
return true; return true;
} }
bool
CodeGeneratorX86Shared::visitNegD(LNegD *ins)
{
// XOR the float in a float register with -0.0.
FloatRegister input = ToFloatRegister(ins->input());
JS_ASSERT(input == ToFloatRegister(ins->output()));
// From MacroAssemblerX86Shared::maybeInlineDouble
masm.pcmpeqw(ScratchFloatReg, ScratchFloatReg);
masm.psllq(Imm32(63), ScratchFloatReg);
masm.xorpd(ScratchFloatReg, input); // s ^ 0x80000000000000
return true;
}
bool bool
CodeGeneratorX86Shared::visitAbsD(LAbsD *ins) CodeGeneratorX86Shared::visitAbsD(LAbsD *ins)
{ {

Просмотреть файл

@ -88,6 +88,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
public: public:
// Instruction visitors. // Instruction visitors.
virtual bool visitMinMaxD(LMinMaxD *ins); virtual bool visitMinMaxD(LMinMaxD *ins);
virtual bool visitNegD(LNegD *ins);
virtual bool visitAbsD(LAbsD *ins); virtual bool visitAbsD(LAbsD *ins);
virtual bool visitSqrtD(LSqrtD *ins); virtual bool visitSqrtD(LSqrtD *ins);
virtual bool visitPowHalfD(LPowHalfD *ins); virtual bool visitPowHalfD(LPowHalfD *ins);