mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 13:25:37 +00:00
Bug 1129148 - Wrote a MACRO to generate conditions to inline SIMD instructions (sub, mul, and, or, xor). r=nbp
--HG-- extra : rebase_source : 8bea5ac7a63434082b5636766883c985a7f5118d
This commit is contained in:
parent
1e887fd19a
commit
4e40652ac1
@ -5852,22 +5852,12 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
|
|||||||
AsmJSSimdType opType = global->simdOperationType();
|
AsmJSSimdType opType = global->simdOperationType();
|
||||||
|
|
||||||
switch (global->simdOperation()) {
|
switch (global->simdOperation()) {
|
||||||
case AsmJSSimdOperation_add:
|
#define OP_CHECK_CASE_LIST_(OP) \
|
||||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Add, def, type);
|
case AsmJSSimdOperation_##OP: \
|
||||||
case AsmJSSimdOperation_sub:
|
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Op_##OP, def, type);
|
||||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Sub, def, type);
|
ARITH_COMMONX4_SIMD_OP(OP_CHECK_CASE_LIST_)
|
||||||
case AsmJSSimdOperation_mul:
|
ARITH_FLOAT32X4_SIMD_OP(OP_CHECK_CASE_LIST_)
|
||||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Mul, def, type);
|
#undef OP_CHECK_CASE_LIST_
|
||||||
case AsmJSSimdOperation_div:
|
|
||||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Div, def, type);
|
|
||||||
case AsmJSSimdOperation_max:
|
|
||||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Max, def, type);
|
|
||||||
case AsmJSSimdOperation_min:
|
|
||||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Min, def, type);
|
|
||||||
case AsmJSSimdOperation_maxNum:
|
|
||||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::MaxNum, def, type);
|
|
||||||
case AsmJSSimdOperation_minNum:
|
|
||||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::MinNum, def, type);
|
|
||||||
|
|
||||||
case AsmJSSimdOperation_lessThan:
|
case AsmJSSimdOperation_lessThan:
|
||||||
return CheckSimdBinary(f, call, opType, MSimdBinaryComp::lessThan, def, type);
|
return CheckSimdBinary(f, call, opType, MSimdBinaryComp::lessThan, def, type);
|
||||||
|
@ -190,31 +190,37 @@
|
|||||||
_(shiftLeftByScalar) \
|
_(shiftLeftByScalar) \
|
||||||
_(shiftRightArithmeticByScalar) \
|
_(shiftRightArithmeticByScalar) \
|
||||||
_(shiftRightLogicalByScalar)
|
_(shiftRightLogicalByScalar)
|
||||||
#define FOREACH_FLOAT32X4_SIMD_OP(_) \
|
#define ARITH_FLOAT32X4_SIMD_OP(_) \
|
||||||
_(abs) \
|
|
||||||
_(sqrt) \
|
|
||||||
_(reciprocal) \
|
|
||||||
_(reciprocalSqrt) \
|
|
||||||
_(fromInt32x4) \
|
|
||||||
_(fromInt32x4Bits) \
|
|
||||||
_(div) \
|
_(div) \
|
||||||
_(max) \
|
_(max) \
|
||||||
_(min) \
|
_(min) \
|
||||||
_(maxNum) \
|
_(maxNum) \
|
||||||
_(minNum)
|
_(minNum)
|
||||||
#define FOREACH_COMMONX4_SIMD_OP(_) \
|
#define FOREACH_FLOAT32X4_SIMD_OP(_) \
|
||||||
|
ARITH_FLOAT32X4_SIMD_OP(_) \
|
||||||
|
_(abs) \
|
||||||
|
_(sqrt) \
|
||||||
|
_(reciprocal) \
|
||||||
|
_(reciprocalSqrt) \
|
||||||
|
_(fromInt32x4) \
|
||||||
|
_(fromInt32x4Bits)
|
||||||
|
#define ARITH_COMMONX4_SIMD_OP(_) \
|
||||||
_(add) \
|
_(add) \
|
||||||
_(sub) \
|
_(sub) \
|
||||||
_(mul) \
|
_(mul)
|
||||||
|
#define BITWISE_COMMONX4_SIMD_OP(_) \
|
||||||
|
_(and) \
|
||||||
|
_(or) \
|
||||||
|
_(xor)
|
||||||
|
#define FOREACH_COMMONX4_SIMD_OP(_) \
|
||||||
|
ARITH_COMMONX4_SIMD_OP(_) \
|
||||||
|
BITWISE_COMMONX4_SIMD_OP(_) \
|
||||||
_(lessThan) \
|
_(lessThan) \
|
||||||
_(lessThanOrEqual) \
|
_(lessThanOrEqual) \
|
||||||
_(equal) \
|
_(equal) \
|
||||||
_(notEqual) \
|
_(notEqual) \
|
||||||
_(greaterThan) \
|
_(greaterThan) \
|
||||||
_(greaterThanOrEqual) \
|
_(greaterThanOrEqual) \
|
||||||
_(and) \
|
|
||||||
_(or) \
|
|
||||||
_(xor) \
|
|
||||||
_(bitselect) \
|
_(bitselect) \
|
||||||
_(select) \
|
_(select) \
|
||||||
_(swizzle) \
|
_(swizzle) \
|
||||||
|
@ -9167,13 +9167,18 @@ GetTemplateObjectForNative(JSContext *cx, HandleScript script, jsbytecode *pc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (JitSupportsSimd()) {
|
if (JitSupportsSimd()) {
|
||||||
if (native == js::simd_int32x4_add || native == js::simd_int32x4_and) {
|
#define ADD_INT32X4_SIMD_OP_NAME_(OP) || native == js::simd_int32x4_##OP
|
||||||
|
if (false
|
||||||
|
ARITH_COMMONX4_SIMD_OP(ADD_INT32X4_SIMD_OP_NAME_)
|
||||||
|
BITWISE_COMMONX4_SIMD_OP(ADD_INT32X4_SIMD_OP_NAME_))
|
||||||
|
{
|
||||||
Rooted<TypeDescr *> descr(cx, &Int32x4::GetTypeDescr(*cx->global()));
|
Rooted<TypeDescr *> descr(cx, &Int32x4::GetTypeDescr(*cx->global()));
|
||||||
res.set(TypedObject::createZeroed(cx, descr, 0, gc::TenuredHeap));
|
res.set(TypedObject::createZeroed(cx, descr, 0, gc::TenuredHeap));
|
||||||
if (!res)
|
if (!res)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#undef ADD_INT32X4_SIMD_OP_NAME_
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -257,10 +257,17 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target)
|
|||||||
return inlineBoundFunction(callInfo, target);
|
return inlineBoundFunction(callInfo, target);
|
||||||
|
|
||||||
// Simd functions
|
// Simd functions
|
||||||
if (native == js::simd_int32x4_add)
|
#define INLINE_INT32X4_SIMD_ARITH_(OP) \
|
||||||
return inlineSimdInt32x4BinaryArith(callInfo, native, MSimdBinaryArith::Add);
|
if (native == js::simd_int32x4_##OP) \
|
||||||
if (native == js::simd_int32x4_and)
|
return inlineSimdInt32x4BinaryArith(callInfo, native, MSimdBinaryArith::Op_##OP);
|
||||||
return inlineSimdInt32x4BinaryBitwise(callInfo, native, MSimdBinaryBitwise::and_);
|
ARITH_COMMONX4_SIMD_OP(INLINE_INT32X4_SIMD_ARITH_)
|
||||||
|
#undef INLINE_INT32X4_SIMD_ARITH_
|
||||||
|
|
||||||
|
#define INLINE_INT32X4_SIMD_BITWISE_(OP) \
|
||||||
|
if (native == js::simd_int32x4_##OP) \
|
||||||
|
return inlineSimdInt32x4BinaryBitwise(callInfo, native, MSimdBinaryBitwise::OP##_);
|
||||||
|
BITWISE_COMMONX4_SIMD_OP(INLINE_INT32X4_SIMD_BITWISE_)
|
||||||
|
#undef INLINE_INT32X4_SIMD_BITWISE_
|
||||||
|
|
||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "mozilla/Array.h"
|
#include "mozilla/Array.h"
|
||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
|
|
||||||
|
#include "builtin/SIMD.h"
|
||||||
#include "jit/AtomicOp.h"
|
#include "jit/AtomicOp.h"
|
||||||
#include "jit/FixedList.h"
|
#include "jit/FixedList.h"
|
||||||
#include "jit/InlineList.h"
|
#include "jit/InlineList.h"
|
||||||
@ -1958,26 +1959,18 @@ class MSimdBinaryArith
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Operation {
|
enum Operation {
|
||||||
Add,
|
#define OP_LIST_(OP) Op_##OP,
|
||||||
Sub,
|
ARITH_COMMONX4_SIMD_OP(OP_LIST_)
|
||||||
Mul,
|
ARITH_FLOAT32X4_SIMD_OP(OP_LIST_)
|
||||||
Div,
|
#undef OP_LIST_
|
||||||
Min,
|
|
||||||
Max,
|
|
||||||
MinNum,
|
|
||||||
MaxNum
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* OperationName(Operation op) {
|
static const char* OperationName(Operation op) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Add: return "Add";
|
#define OP_CASE_LIST_(OP) case Op_##OP: return #OP;
|
||||||
case Sub: return "Sub";
|
ARITH_COMMONX4_SIMD_OP(OP_CASE_LIST_)
|
||||||
case Mul: return "Mul";
|
ARITH_FLOAT32X4_SIMD_OP(OP_CASE_LIST_)
|
||||||
case Div: return "Div";
|
#undef OP_CASE_LIST_
|
||||||
case Min: return "Min";
|
|
||||||
case Max: return "Max";
|
|
||||||
case MinNum: return "MinNum";
|
|
||||||
case MaxNum: return "MaxNum";
|
|
||||||
}
|
}
|
||||||
MOZ_CRASH("unexpected operation");
|
MOZ_CRASH("unexpected operation");
|
||||||
}
|
}
|
||||||
@ -1988,11 +1981,11 @@ class MSimdBinaryArith
|
|||||||
MSimdBinaryArith(MDefinition *left, MDefinition *right, Operation op, MIRType type)
|
MSimdBinaryArith(MDefinition *left, MDefinition *right, Operation op, MIRType type)
|
||||||
: MBinaryInstruction(left, right), operation_(op)
|
: MBinaryInstruction(left, right), operation_(op)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT_IF(type == MIRType_Int32x4, op == Add || op == Sub || op == Mul);
|
MOZ_ASSERT_IF(type == MIRType_Int32x4, op == Op_add || op == Op_sub || op == Op_mul);
|
||||||
MOZ_ASSERT(IsSimdType(type));
|
MOZ_ASSERT(IsSimdType(type));
|
||||||
setResultType(type);
|
setResultType(type);
|
||||||
setMovable();
|
setMovable();
|
||||||
if (op == Add || op == Mul || op == Min || op == Max)
|
if (op == Op_add || op == Op_mul || op == Op_min || op == Op_max)
|
||||||
setCommutative();
|
setCommutative();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2657,13 +2657,13 @@ CodeGeneratorX86Shared::visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *ins)
|
|||||||
|
|
||||||
MSimdBinaryArith::Operation op = ins->operation();
|
MSimdBinaryArith::Operation op = ins->operation();
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case MSimdBinaryArith::Add:
|
case MSimdBinaryArith::Op_add:
|
||||||
masm.vpaddd(rhs, lhs, output);
|
masm.vpaddd(rhs, lhs, output);
|
||||||
return;
|
return;
|
||||||
case MSimdBinaryArith::Sub:
|
case MSimdBinaryArith::Op_sub:
|
||||||
masm.vpsubd(rhs, lhs, output);
|
masm.vpsubd(rhs, lhs, output);
|
||||||
return;
|
return;
|
||||||
case MSimdBinaryArith::Mul: {
|
case MSimdBinaryArith::Op_mul: {
|
||||||
if (AssemblerX86Shared::HasSSE41()) {
|
if (AssemblerX86Shared::HasSSE41()) {
|
||||||
masm.vpmulld(rhs, lhs, output);
|
masm.vpmulld(rhs, lhs, output);
|
||||||
return;
|
return;
|
||||||
@ -2684,19 +2684,19 @@ CodeGeneratorX86Shared::visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *ins)
|
|||||||
masm.vshufps(MacroAssembler::ComputeShuffleMask(LaneZ, LaneX, LaneW, LaneY), lhs, lhs, lhs);
|
masm.vshufps(MacroAssembler::ComputeShuffleMask(LaneZ, LaneX, LaneW, LaneY), lhs, lhs, lhs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case MSimdBinaryArith::Div:
|
case MSimdBinaryArith::Op_div:
|
||||||
// x86 doesn't have SIMD i32 div.
|
// x86 doesn't have SIMD i32 div.
|
||||||
break;
|
break;
|
||||||
case MSimdBinaryArith::Max:
|
case MSimdBinaryArith::Op_max:
|
||||||
// we can do max with a single instruction only if we have SSE4.1
|
// we can do max with a single instruction only if we have SSE4.1
|
||||||
// using the PMAXSD instruction.
|
// using the PMAXSD instruction.
|
||||||
break;
|
break;
|
||||||
case MSimdBinaryArith::Min:
|
case MSimdBinaryArith::Op_min:
|
||||||
// we can do max with a single instruction only if we have SSE4.1
|
// we can do max with a single instruction only if we have SSE4.1
|
||||||
// using the PMINSD instruction.
|
// using the PMINSD instruction.
|
||||||
break;
|
break;
|
||||||
case MSimdBinaryArith::MinNum:
|
case MSimdBinaryArith::Op_minNum:
|
||||||
case MSimdBinaryArith::MaxNum:
|
case MSimdBinaryArith::Op_maxNum:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
MOZ_CRASH("unexpected SIMD op");
|
MOZ_CRASH("unexpected SIMD op");
|
||||||
@ -2711,19 +2711,19 @@ CodeGeneratorX86Shared::visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *ins)
|
|||||||
|
|
||||||
MSimdBinaryArith::Operation op = ins->operation();
|
MSimdBinaryArith::Operation op = ins->operation();
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case MSimdBinaryArith::Add:
|
case MSimdBinaryArith::Op_add:
|
||||||
masm.vaddps(rhs, lhs, output);
|
masm.vaddps(rhs, lhs, output);
|
||||||
return;
|
return;
|
||||||
case MSimdBinaryArith::Sub:
|
case MSimdBinaryArith::Op_sub:
|
||||||
masm.vsubps(rhs, lhs, output);
|
masm.vsubps(rhs, lhs, output);
|
||||||
return;
|
return;
|
||||||
case MSimdBinaryArith::Mul:
|
case MSimdBinaryArith::Op_mul:
|
||||||
masm.vmulps(rhs, lhs, output);
|
masm.vmulps(rhs, lhs, output);
|
||||||
return;
|
return;
|
||||||
case MSimdBinaryArith::Div:
|
case MSimdBinaryArith::Op_div:
|
||||||
masm.vdivps(rhs, lhs, output);
|
masm.vdivps(rhs, lhs, output);
|
||||||
return;
|
return;
|
||||||
case MSimdBinaryArith::Max: {
|
case MSimdBinaryArith::Op_max: {
|
||||||
FloatRegister lhsCopy = masm.reusedInputFloat32x4(lhs, ScratchSimdReg);
|
FloatRegister lhsCopy = masm.reusedInputFloat32x4(lhs, ScratchSimdReg);
|
||||||
masm.vcmpunordps(rhs, lhsCopy, ScratchSimdReg);
|
masm.vcmpunordps(rhs, lhsCopy, ScratchSimdReg);
|
||||||
|
|
||||||
@ -2736,14 +2736,14 @@ CodeGeneratorX86Shared::visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *ins)
|
|||||||
masm.vorps(ScratchSimdReg, output, output); // or in the all-ones NaNs
|
masm.vorps(ScratchSimdReg, output, output); // or in the all-ones NaNs
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case MSimdBinaryArith::Min: {
|
case MSimdBinaryArith::Op_min: {
|
||||||
FloatRegister rhsCopy = masm.reusedInputAlignedFloat32x4(rhs, ScratchSimdReg);
|
FloatRegister rhsCopy = masm.reusedInputAlignedFloat32x4(rhs, ScratchSimdReg);
|
||||||
masm.vminps(Operand(lhs), rhsCopy, ScratchSimdReg);
|
masm.vminps(Operand(lhs), rhsCopy, ScratchSimdReg);
|
||||||
masm.vminps(rhs, lhs, output);
|
masm.vminps(rhs, lhs, output);
|
||||||
masm.vorps(ScratchSimdReg, output, output); // NaN or'd with arbitrary bits is NaN
|
masm.vorps(ScratchSimdReg, output, output); // NaN or'd with arbitrary bits is NaN
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case MSimdBinaryArith::MinNum: {
|
case MSimdBinaryArith::Op_minNum: {
|
||||||
FloatRegister tmp = ToFloatRegister(ins->temp());
|
FloatRegister tmp = ToFloatRegister(ins->temp());
|
||||||
masm.loadConstantInt32x4(SimdConstant::SplatX4(int32_t(0x80000000)), tmp);
|
masm.loadConstantInt32x4(SimdConstant::SplatX4(int32_t(0x80000000)), tmp);
|
||||||
|
|
||||||
@ -2773,7 +2773,7 @@ CodeGeneratorX86Shared::visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *ins)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case MSimdBinaryArith::MaxNum: {
|
case MSimdBinaryArith::Op_maxNum: {
|
||||||
FloatRegister mask = ScratchSimdReg;
|
FloatRegister mask = ScratchSimdReg;
|
||||||
masm.loadConstantInt32x4(SimdConstant::SplatX4(0), mask);
|
masm.loadConstantInt32x4(SimdConstant::SplatX4(0), mask);
|
||||||
masm.vpcmpeqd(Operand(lhs), mask, mask);
|
masm.vpcmpeqd(Operand(lhs), mask, mask);
|
||||||
|
@ -639,7 +639,7 @@ LIRGeneratorX86Shared::visitSimdBinaryArith(MSimdBinaryArith *ins)
|
|||||||
|
|
||||||
if (ins->type() == MIRType_Int32x4) {
|
if (ins->type() == MIRType_Int32x4) {
|
||||||
LSimdBinaryArithIx4 *lir = new(alloc()) LSimdBinaryArithIx4();
|
LSimdBinaryArithIx4 *lir = new(alloc()) LSimdBinaryArithIx4();
|
||||||
bool needsTemp = ins->operation() == MSimdBinaryArith::Mul && !MacroAssembler::HasSSE41();
|
bool needsTemp = ins->operation() == MSimdBinaryArith::Op_mul && !MacroAssembler::HasSSE41();
|
||||||
lir->setTemp(0, needsTemp ? temp(LDefinition::INT32X4) : LDefinition::BogusTemp());
|
lir->setTemp(0, needsTemp ? temp(LDefinition::INT32X4) : LDefinition::BogusTemp());
|
||||||
lowerForFPU(lir, ins, lhs, rhs);
|
lowerForFPU(lir, ins, lhs, rhs);
|
||||||
return;
|
return;
|
||||||
@ -649,9 +649,9 @@ LIRGeneratorX86Shared::visitSimdBinaryArith(MSimdBinaryArith *ins)
|
|||||||
|
|
||||||
LSimdBinaryArithFx4 *lir = new(alloc()) LSimdBinaryArithFx4();
|
LSimdBinaryArithFx4 *lir = new(alloc()) LSimdBinaryArithFx4();
|
||||||
|
|
||||||
bool needsTemp = ins->operation() == MSimdBinaryArith::Max ||
|
bool needsTemp = ins->operation() == MSimdBinaryArith::Op_max ||
|
||||||
ins->operation() == MSimdBinaryArith::MinNum ||
|
ins->operation() == MSimdBinaryArith::Op_minNum ||
|
||||||
ins->operation() == MSimdBinaryArith::MaxNum;
|
ins->operation() == MSimdBinaryArith::Op_maxNum;
|
||||||
lir->setTemp(0, needsTemp ? temp(LDefinition::FLOAT32X4) : LDefinition::BogusTemp());
|
lir->setTemp(0, needsTemp ? temp(LDefinition::FLOAT32X4) : LDefinition::BogusTemp());
|
||||||
|
|
||||||
lowerForFPU(lir, ins, lhs, rhs);
|
lowerForFPU(lir, ins, lhs, rhs);
|
||||||
|
Loading…
Reference in New Issue
Block a user