Bug 913282: More Float32 Operators: Not; p=dougc,bbouvier, r=jonco,nbp

dougc for the ARM parts, bbouvier for the rest
This commit is contained in:
Benjamin Bouvier 2013-10-22 14:53:52 +02:00
parent 5dc4bbbc7b
commit 45596c00a4
9 changed files with 81 additions and 0 deletions

View File

@ -2020,6 +2020,17 @@ class LNotD : public LInstructionHelper<1, 1, 0>
}
};
// Not operation on a float32.
class LNotF : public LInstructionHelper<1, 1, 0>
{
public:
LIR_HEADER(NotF)
LNotF(const LAllocation &input) {
setOperand(0, input);
}
};
// Boolean complement operation on an object.
class LNotO : public LInstructionHelper<1, 1, 0>
{

View File

@ -112,6 +112,7 @@
_(MathFunctionF) \
_(NotI) \
_(NotD) \
_(NotF) \
_(NotO) \
_(NotV) \
_(AddI) \

View File

@ -2259,6 +2259,8 @@ LIRGenerator::visitNot(MNot *ins)
}
case MIRType_Double:
return define(new LNotD(useRegister(op)), ins);
case MIRType_Float32:
return define(new LNotF(useRegister(op)), ins);
case MIRType_Undefined:
case MIRType_Null:
return define(new LInteger(1), ins);

View File

@ -2462,6 +2462,14 @@ MNot::foldsTo(bool useValueNumbers)
return this;
}
void
MNot::trySpecializeFloat32()
{
MDefinition *in = input();
if (!in->canProduceFloat32() && in->type() == MIRType_Float32)
ConvertDefinitionToDouble<0>(in, this);
}
void
MBeta::printOpcode(FILE *fp) const
{

View File

@ -5131,6 +5131,14 @@ class MNot
TypePolicy *typePolicy() {
return this;
}
void trySpecializeFloat32();
bool isFloat32Commutative() const { return true; }
#ifdef DEBUG
bool isConsistentFloat32Use() const {
return true;
}
#endif
};
// Bailout if index + minimum < 0 or index + maximum >= length. The length used

View File

@ -1609,6 +1609,44 @@ CodeGeneratorARM::visitNotD(LNotD *ins)
// Do the compare
masm.ma_vcmpz(opd);
// TODO There are three variations here to compare performance-wise.
bool nocond = true;
if (nocond) {
// Load the value into the dest register
masm.as_vmrs(dest);
masm.ma_lsr(Imm32(28), dest, dest);
masm.ma_alu(dest, lsr(dest, 2), dest, op_orr); // 28 + 2 = 30
masm.ma_and(Imm32(1), dest);
} else {
masm.as_vmrs(pc);
masm.ma_mov(Imm32(0), dest);
masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal);
masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow);
#if 0
masm.as_vmrs(ToRegister(dest));
// Mask out just the two bits we care about. If neither bit is set,
// the dest is already zero
masm.ma_and(Imm32(0x50000000), dest, dest, Assembler::SetCond);
// If it is non-zero, then force it to be 1.
masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::NotEqual);
#endif
}
return true;
}
bool
CodeGeneratorARM::visitNotF(LNotF *ins)
{
// Since this operation is not, we want to set a bit if
// the double is falsey, which means 0.0, -0.0 or NaN.
// when comparing with 0, an input of 0 will set the Z bit (30)
// and NaN will set the V bit (28) of the APSR.
FloatRegister opd = ToFloatRegister(ins->input());
Register dest = ToRegister(ins->output());
// Do the compare
masm.ma_vcmpz_f32(opd);
// TODO There are three variations here to compare performance-wise.
bool nocond = true;
if (nocond) {
// Load the value into the dest register

View File

@ -104,6 +104,7 @@ class CodeGeneratorARM : public CodeGeneratorShared
virtual bool visitUInt32ToDouble(LUInt32ToDouble *lir);
virtual bool visitNotI(LNotI *ins);
virtual bool visitNotD(LNotD *ins);
virtual bool visitNotF(LNotF *ins);
virtual bool visitMathD(LMathD *math);
virtual bool visitMathF(LMathF *math);

View File

@ -232,6 +232,17 @@ CodeGeneratorX86Shared::visitNotD(LNotD *ins)
return true;
}
bool
CodeGeneratorX86Shared::visitNotF(LNotF *ins)
{
FloatRegister opd = ToFloatRegister(ins->input());
masm.xorps(ScratchFloatReg, ScratchFloatReg);
masm.compareFloat(Assembler::DoubleEqualOrUnordered, opd, ScratchFloatReg);
masm.emitSet(Assembler::Equal, ToRegister(ins->output()), Assembler::NaN_IsTrue);
return true;
}
bool
CodeGeneratorX86Shared::visitCompareDAndBranch(LCompareDAndBranch *comp)
{

View File

@ -110,6 +110,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab);
virtual bool visitNotI(LNotI *comp);
virtual bool visitNotD(LNotD *comp);
virtual bool visitNotF(LNotF *comp);
virtual bool visitMathD(LMathD *math);
virtual bool visitMathF(LMathF *math);
virtual bool visitFloor(LFloor *lir);