mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1059529: SIMD x86-x64 backend: Implement bitwise operations; a=ijibaja,dougc,bbouvier; r=sunfish
This commit is contained in:
parent
80e5c8c723
commit
1e51b824ea
@ -266,6 +266,22 @@ class LSimdBinaryArithFx4 : public LSimdBinaryArith
|
||||
LSimdBinaryArithFx4() : LSimdBinaryArith() {}
|
||||
};
|
||||
|
||||
// Binary SIMD bitwise operation between two int32x4 or float32x4 operands
|
||||
class LSimdBinaryBitwiseX4 : public LInstructionHelper<1, 2, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(SimdBinaryBitwiseX4);
|
||||
const LAllocation *lhs() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LAllocation *rhs() {
|
||||
return getOperand(1);
|
||||
}
|
||||
MSimdBinaryBitwise::Operation operation() const {
|
||||
return mir_->toSimdBinaryBitwise()->operation();
|
||||
}
|
||||
};
|
||||
|
||||
// Constant 32-bit integer.
|
||||
class LInteger : public LInstructionHelper<1, 0, 0>
|
||||
{
|
||||
|
@ -25,6 +25,7 @@
|
||||
_(SimdBinaryCompFx4) \
|
||||
_(SimdBinaryArithIx4) \
|
||||
_(SimdBinaryArithFx4) \
|
||||
_(SimdBinaryBitwiseX4) \
|
||||
_(Value) \
|
||||
_(CloneLiteral) \
|
||||
_(Parameter) \
|
||||
|
@ -3765,6 +3765,20 @@ LIRGenerator::visitSimdBinaryArith(MSimdBinaryArith *ins)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitSimdBinaryBitwise(MSimdBinaryBitwise *ins)
|
||||
{
|
||||
MOZ_ASSERT(IsSimdType(ins->type()));
|
||||
|
||||
if (ins->type() == MIRType_Int32x4 || ins->type() == MIRType_Float32x4) {
|
||||
LSimdBinaryBitwiseX4 *add = new(alloc()) LSimdBinaryBitwiseX4;
|
||||
return lowerForFPU(add, ins, ins->lhs(), ins->rhs());
|
||||
}
|
||||
|
||||
MOZ_CRASH("Unknown SIMD kind when doing bitwise operations");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
SpewResumePoint(MBasicBlock *block, MInstruction *ins, MResumePoint *resumePoint)
|
||||
{
|
||||
|
@ -270,6 +270,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||
bool visitSimdExtractElement(MSimdExtractElement *ins);
|
||||
bool visitSimdBinaryComp(MSimdBinaryComp *ins);
|
||||
bool visitSimdBinaryArith(MSimdBinaryArith *ins);
|
||||
bool visitSimdBinaryBitwise(MSimdBinaryBitwise *ins);
|
||||
bool visitSimdValueX4(MSimdValueX4 *ins);
|
||||
bool visitSimdConstant(MSimdConstant *ins);
|
||||
bool visitPhi(MPhi *ins);
|
||||
|
@ -1480,6 +1480,50 @@ class MSimdBinaryArith : public MBinaryInstruction
|
||||
}
|
||||
};
|
||||
|
||||
class MSimdBinaryBitwise : public MBinaryInstruction
|
||||
{
|
||||
public:
|
||||
enum Operation {
|
||||
and_,
|
||||
or_,
|
||||
xor_
|
||||
};
|
||||
|
||||
private:
|
||||
Operation operation_;
|
||||
|
||||
MSimdBinaryBitwise(MDefinition *left, MDefinition *right, Operation op, MIRType type)
|
||||
: MBinaryInstruction(left, right), operation_(op)
|
||||
{
|
||||
MOZ_ASSERT(IsSimdType(type));
|
||||
MOZ_ASSERT(left->type() == right->type());
|
||||
MOZ_ASSERT(left->type() == type);
|
||||
setResultType(type);
|
||||
setMovable();
|
||||
setCommutative();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(SimdBinaryBitwise);
|
||||
static MSimdBinaryBitwise *NewAsmJS(TempAllocator &alloc, MDefinition *left,
|
||||
MDefinition *right, Operation op, MIRType t)
|
||||
{
|
||||
return new(alloc) MSimdBinaryBitwise(left, right, op, t);
|
||||
}
|
||||
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::None();
|
||||
}
|
||||
|
||||
Operation operation() const { return operation_; }
|
||||
|
||||
bool congruentTo(const MDefinition *ins) const {
|
||||
if (!binaryCongruentTo(ins))
|
||||
return false;
|
||||
return operation_ == ins->toSimdBinaryBitwise()->operation();
|
||||
}
|
||||
};
|
||||
|
||||
// Deep clone a constant JSObject.
|
||||
class MCloneLiteral
|
||||
: public MUnaryInstruction,
|
||||
|
@ -17,6 +17,7 @@ namespace jit {
|
||||
_(SimdExtractElement) \
|
||||
_(SimdBinaryComp) \
|
||||
_(SimdBinaryArith) \
|
||||
_(SimdBinaryBitwise) \
|
||||
_(CloneLiteral) \
|
||||
_(Parameter) \
|
||||
_(Callee) \
|
||||
|
@ -117,6 +117,7 @@ class ParallelSafetyVisitor : public MDefinitionVisitor
|
||||
SAFE_OP(SimdExtractElement)
|
||||
SAFE_OP(SimdBinaryComp)
|
||||
SAFE_OP(SimdBinaryArith)
|
||||
SAFE_OP(SimdBinaryBitwise)
|
||||
UNSAFE_OP(CloneLiteral)
|
||||
SAFE_OP(Parameter)
|
||||
SAFE_OP(Callee)
|
||||
|
@ -238,6 +238,7 @@ class CodeGeneratorARM : public CodeGeneratorShared
|
||||
bool visitSimdBinaryCompFx4(LSimdBinaryCompFx4 *lir) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *lir) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *lir) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdBinaryBitwiseX4(LSimdBinaryBitwiseX4 *lir) { MOZ_CRASH("NYI"); }
|
||||
};
|
||||
|
||||
typedef CodeGeneratorARM CodeGeneratorSpecific;
|
||||
|
@ -1665,6 +1665,54 @@ class AssemblerX86Shared : public AssemblerShared
|
||||
MOZ_CRASH("unexpected operand kind");
|
||||
}
|
||||
}
|
||||
void andps(const Operand &src, FloatRegister dest) {
|
||||
MOZ_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::FPREG:
|
||||
masm.andps_rr(src.fpu(), dest.code());
|
||||
break;
|
||||
case Operand::MEM_REG_DISP:
|
||||
masm.andps_mr(src.disp(), src.base(), dest.code());
|
||||
break;
|
||||
case Operand::MEM_ADDRESS32:
|
||||
masm.andps_mr(src.address(), dest.code());
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("unexpected operand kind");
|
||||
}
|
||||
}
|
||||
void orps(const Operand &src, FloatRegister dest) {
|
||||
MOZ_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::FPREG:
|
||||
masm.orps_rr(src.fpu(), dest.code());
|
||||
break;
|
||||
case Operand::MEM_REG_DISP:
|
||||
masm.orps_mr(src.disp(), src.base(), dest.code());
|
||||
break;
|
||||
case Operand::MEM_ADDRESS32:
|
||||
masm.orps_mr(src.address(), dest.code());
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("unexpected operand kind");
|
||||
}
|
||||
}
|
||||
void xorps(const Operand &src, FloatRegister dest) {
|
||||
MOZ_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::FPREG:
|
||||
masm.xorps_rr(src.fpu(), dest.code());
|
||||
break;
|
||||
case Operand::MEM_REG_DISP:
|
||||
masm.xorps_mr(src.disp(), src.base(), dest.code());
|
||||
break;
|
||||
case Operand::MEM_ADDRESS32:
|
||||
masm.xorps_mr(src.address(), dest.code());
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("unexpected operand kind");
|
||||
}
|
||||
}
|
||||
void pxor(FloatRegister src, FloatRegister dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.pxor_rr(src.code(), dest.code());
|
||||
|
@ -295,6 +295,9 @@ private:
|
||||
OP2_CVTTSD2SI_GdWsd = 0x2C,
|
||||
OP2_UCOMISD_VsdWsd = 0x2E,
|
||||
OP2_MOVMSKPD_EdVd = 0x50,
|
||||
OP2_ANDPS_VpsWps = 0x54,
|
||||
OP2_ORPS_VpsWps = 0x56,
|
||||
OP2_XORPS_VpsWps = 0x57,
|
||||
OP2_ADDSD_VsdWsd = 0x58,
|
||||
OP2_ADDPS_VpsWps = 0x58,
|
||||
OP2_MULSD_VsdWsd = 0x59,
|
||||
@ -3424,13 +3427,6 @@ public:
|
||||
m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
|
||||
}
|
||||
|
||||
void xorps_rr(XMMRegisterID src, XMMRegisterID dst)
|
||||
{
|
||||
spew("xorps %s, %s",
|
||||
nameFPReg(src), nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
|
||||
}
|
||||
|
||||
void orpd_rr(XMMRegisterID src, XMMRegisterID dst)
|
||||
{
|
||||
spew("orpd %s, %s",
|
||||
@ -3451,7 +3447,63 @@ public:
|
||||
{
|
||||
spew("andps %s, %s",
|
||||
nameFPReg(src), nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_ANDPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
|
||||
m_formatter.twoByteOp(OP2_ANDPS_VpsWps, (RegisterID)dst, (RegisterID)src);
|
||||
}
|
||||
|
||||
void andps_mr(int offset, RegisterID base, XMMRegisterID dst)
|
||||
{
|
||||
spew("andps %s0x%x(%s), %s",
|
||||
PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_ANDPS_VpsWps, (RegisterID)dst, base, offset);
|
||||
}
|
||||
|
||||
void andps_mr(const void* address, XMMRegisterID dst)
|
||||
{
|
||||
spew("andps %p, %s",
|
||||
address, nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_ANDPS_VpsWps, (RegisterID)dst, address);
|
||||
}
|
||||
|
||||
void orps_rr(XMMRegisterID src, XMMRegisterID dst)
|
||||
{
|
||||
spew("orps %s, %s",
|
||||
nameFPReg(src), nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_ORPS_VpsWps, (RegisterID)dst, (RegisterID)src);
|
||||
}
|
||||
|
||||
void orps_mr(int offset, RegisterID base, XMMRegisterID dst)
|
||||
{
|
||||
spew("orps %s0x%x(%s), %s",
|
||||
PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_ORPS_VpsWps, (RegisterID)dst, base, offset);
|
||||
}
|
||||
|
||||
void orps_mr(const void* address, XMMRegisterID dst)
|
||||
{
|
||||
spew("orps %p, %s",
|
||||
address, nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_ORPS_VpsWps, (RegisterID)dst, address);
|
||||
}
|
||||
|
||||
void xorps_rr(XMMRegisterID src, XMMRegisterID dst)
|
||||
{
|
||||
spew("xorps %s, %s",
|
||||
nameFPReg(src), nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_XORPS_VpsWps, (RegisterID)dst, (RegisterID)src);
|
||||
}
|
||||
|
||||
void xorps_mr(int offset, RegisterID base, XMMRegisterID dst)
|
||||
{
|
||||
spew("xorps %s0x%x(%s), %s",
|
||||
PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_XORPS_VpsWps, (RegisterID)dst, base, offset);
|
||||
}
|
||||
|
||||
void xorps_mr(const void* address, XMMRegisterID dst)
|
||||
{
|
||||
spew("xorps %p, %s",
|
||||
address, nameFPReg(dst));
|
||||
m_formatter.twoByteOp(OP2_XORPS_VpsWps, (RegisterID)dst, address);
|
||||
}
|
||||
|
||||
void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
|
||||
|
@ -2309,6 +2309,28 @@ CodeGeneratorX86Shared::visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *ins)
|
||||
MOZ_CRASH("unexpected SIMD op");
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitSimdBinaryBitwiseX4(LSimdBinaryBitwiseX4 *ins)
|
||||
{
|
||||
FloatRegister lhs = ToFloatRegister(ins->lhs());
|
||||
Operand rhs = ToOperand(ins->rhs());
|
||||
MOZ_ASSERT(ToFloatRegister(ins->output()) == lhs);
|
||||
|
||||
MSimdBinaryBitwise::Operation op = ins->operation();
|
||||
switch (op) {
|
||||
case MSimdBinaryBitwise::and_:
|
||||
masm.bitwiseAndX4(rhs, lhs);
|
||||
return true;
|
||||
case MSimdBinaryBitwise::or_:
|
||||
masm.bitwiseOrX4(rhs, lhs);
|
||||
return true;
|
||||
case MSimdBinaryBitwise::xor_:
|
||||
masm.bitwiseXorX4(rhs, lhs);
|
||||
return true;
|
||||
}
|
||||
MOZ_CRASH("unexpected SIMD bitwise op");
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitForkJoinGetSlice(LForkJoinGetSlice *ins)
|
||||
{
|
||||
|
@ -215,6 +215,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
|
||||
bool visitSimdBinaryCompFx4(LSimdBinaryCompFx4 *lir);
|
||||
bool visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *lir);
|
||||
bool visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *lir);
|
||||
bool visitSimdBinaryBitwiseX4(LSimdBinaryBitwiseX4 *lir);
|
||||
|
||||
// Out of line visitors.
|
||||
bool visitOutOfLineBailout(OutOfLineBailout *ool);
|
||||
|
@ -467,6 +467,18 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
cvtsd2ss(src, dest);
|
||||
}
|
||||
|
||||
void bitwiseAndX4(const Operand &src, FloatRegister dest) {
|
||||
// TODO Using the "ps" variant for all types incurs a domain crossing
|
||||
// penalty for integer types and double.
|
||||
andps(src, dest);
|
||||
}
|
||||
void bitwiseOrX4(const Operand &src, FloatRegister dest) {
|
||||
orps(src, dest);
|
||||
}
|
||||
void bitwiseXorX4(const Operand &src, FloatRegister dest) {
|
||||
xorps(src, dest);
|
||||
}
|
||||
|
||||
void loadAlignedInt32x4(const Address &src, FloatRegister dest) {
|
||||
movdqa(Operand(src), dest);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user