mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
5dc4bbbc7b
commit
45596c00a4
@ -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>
|
||||
{
|
||||
|
@ -112,6 +112,7 @@
|
||||
_(MathFunctionF) \
|
||||
_(NotI) \
|
||||
_(NotD) \
|
||||
_(NotF) \
|
||||
_(NotO) \
|
||||
_(NotV) \
|
||||
_(AddI) \
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user