mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1094855: Implement SIMD.float32x4.minNum/maxNum in the JITs; r=sunfish
This commit is contained in:
parent
9d4ff51379
commit
286105327c
@ -4083,7 +4083,9 @@ LIRGenerator::visitSimdBinaryArith(MSimdBinaryArith *ins)
|
||||
|
||||
LSimdBinaryArithFx4 *lir = new(alloc()) LSimdBinaryArithFx4();
|
||||
|
||||
bool needsTemp = ins->operation() == MSimdBinaryArith::Max;
|
||||
bool needsTemp = ins->operation() == MSimdBinaryArith::Max ||
|
||||
ins->operation() == MSimdBinaryArith::MinNum ||
|
||||
ins->operation() == MSimdBinaryArith::MaxNum;
|
||||
lir->setTemp(0, needsTemp ? temp(LDefinition::FLOAT32X4) : LDefinition::BogusTemp());
|
||||
|
||||
return lowerForFPU(lir, ins, lhs, rhs);
|
||||
|
@ -1857,7 +1857,9 @@ class MSimdBinaryArith : public MBinaryInstruction
|
||||
Mul,
|
||||
Div,
|
||||
Min,
|
||||
Max
|
||||
Max,
|
||||
MinNum,
|
||||
MaxNum
|
||||
};
|
||||
|
||||
static const char* OperationName(Operation op) {
|
||||
@ -1868,6 +1870,8 @@ class MSimdBinaryArith : public MBinaryInstruction
|
||||
case Div: return "Div";
|
||||
case Min: return "Min";
|
||||
case Max: return "Max";
|
||||
case MinNum: return "MinNum";
|
||||
case MaxNum: return "MaxNum";
|
||||
}
|
||||
MOZ_CRASH("unexpected operation");
|
||||
}
|
||||
|
@ -1907,6 +1907,7 @@ class AssemblerX86Shared : public AssemblerShared
|
||||
}
|
||||
}
|
||||
void andnps(const Operand &src, FloatRegister dest) {
|
||||
// Negates bits of dest and then applies AND
|
||||
MOZ_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::FPREG:
|
||||
|
@ -2769,6 +2769,9 @@ CodeGeneratorX86Shared::visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *ins)
|
||||
// we can do max with a single instruction only if we have SSE4.1
|
||||
// using the PMINSD instruction.
|
||||
break;
|
||||
case MSimdBinaryArith::MinNum:
|
||||
case MSimdBinaryArith::MaxNum:
|
||||
break;
|
||||
}
|
||||
MOZ_CRASH("unexpected SIMD op");
|
||||
}
|
||||
@ -2815,6 +2818,54 @@ CodeGeneratorX86Shared::visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *ins)
|
||||
masm.orps(rhsCopy, lhs); // NaN or'd with arbitrary bits is NaN
|
||||
return true;
|
||||
}
|
||||
case MSimdBinaryArith::MinNum: {
|
||||
FloatRegister tmp = ToFloatRegister(ins->temp());
|
||||
masm.loadConstantInt32x4(SimdConstant::SplatX4(int32_t(0x80000000)), ScratchSimdReg);
|
||||
masm.movdqa(ScratchSimdReg, tmp);
|
||||
|
||||
FloatRegister mask = ScratchSimdReg;
|
||||
masm.pcmpeqd(Operand(lhs), mask);
|
||||
masm.andps(tmp, mask);
|
||||
|
||||
masm.movaps(lhs, tmp);
|
||||
masm.minps(rhs, tmp);
|
||||
masm.orps(mask, tmp);
|
||||
|
||||
masm.movaps(rhs, mask);
|
||||
masm.cmpneqps(Operand(mask), mask);
|
||||
|
||||
// Emulates blendv
|
||||
masm.andps(Operand(mask), lhs);
|
||||
masm.andnps(Operand(tmp), mask);
|
||||
masm.orps(Operand(mask), lhs);
|
||||
return true;
|
||||
}
|
||||
case MSimdBinaryArith::MaxNum: {
|
||||
FloatRegister mask = ScratchSimdReg;
|
||||
masm.loadConstantInt32x4(SimdConstant::SplatX4(0), mask);
|
||||
masm.pcmpeqd(Operand(lhs), mask);
|
||||
|
||||
FloatRegister tmp = ToFloatRegister(ins->temp());
|
||||
masm.loadConstantInt32x4(SimdConstant::SplatX4(int32_t(0x80000000)), tmp);
|
||||
masm.andps(tmp, mask);
|
||||
|
||||
masm.movaps(lhs, tmp);
|
||||
masm.maxps(rhs, tmp);
|
||||
masm.andnps(Operand(tmp), mask);
|
||||
|
||||
// Ensure tmp always contains the temporary result
|
||||
mask = tmp;
|
||||
tmp = ScratchSimdReg;
|
||||
|
||||
masm.movaps(rhs, mask);
|
||||
masm.cmpneqps(Operand(mask), mask);
|
||||
|
||||
// Emulates blendv
|
||||
masm.andps(Operand(mask), lhs);
|
||||
masm.andnps(Operand(tmp), mask);
|
||||
masm.orps(Operand(mask), lhs);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
MOZ_CRASH("unexpected SIMD op");
|
||||
}
|
||||
@ -2965,8 +3016,6 @@ CodeGeneratorX86Shared::visitSimdSelect(LSimdSelect *ins)
|
||||
FloatRegister onFalse = ToFloatRegister(ins->rhs());
|
||||
|
||||
MOZ_ASSERT(onTrue == ToFloatRegister(ins->output()));
|
||||
// The onFalse argument is not destroyed but due to limitations of the
|
||||
// register allocator its life ends at the start of the operation.
|
||||
masm.bitwiseAndX4(Operand(mask), onTrue);
|
||||
masm.bitwiseAndNotX4(Operand(onFalse), mask);
|
||||
masm.bitwiseOrX4(Operand(mask), onTrue);
|
||||
|
Loading…
Reference in New Issue
Block a user