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();
|
||||
|
||||
switch (global->simdOperation()) {
|
||||
case AsmJSSimdOperation_add:
|
||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Add, def, type);
|
||||
case AsmJSSimdOperation_sub:
|
||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Sub, def, type);
|
||||
case AsmJSSimdOperation_mul:
|
||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Mul, def, type);
|
||||
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);
|
||||
#define OP_CHECK_CASE_LIST_(OP) \
|
||||
case AsmJSSimdOperation_##OP: \
|
||||
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Op_##OP, def, type);
|
||||
ARITH_COMMONX4_SIMD_OP(OP_CHECK_CASE_LIST_)
|
||||
ARITH_FLOAT32X4_SIMD_OP(OP_CHECK_CASE_LIST_)
|
||||
#undef OP_CHECK_CASE_LIST_
|
||||
|
||||
case AsmJSSimdOperation_lessThan:
|
||||
return CheckSimdBinary(f, call, opType, MSimdBinaryComp::lessThan, def, type);
|
||||
|
@ -190,31 +190,37 @@
|
||||
_(shiftLeftByScalar) \
|
||||
_(shiftRightArithmeticByScalar) \
|
||||
_(shiftRightLogicalByScalar)
|
||||
#define FOREACH_FLOAT32X4_SIMD_OP(_) \
|
||||
_(abs) \
|
||||
_(sqrt) \
|
||||
_(reciprocal) \
|
||||
_(reciprocalSqrt) \
|
||||
_(fromInt32x4) \
|
||||
_(fromInt32x4Bits) \
|
||||
#define ARITH_FLOAT32X4_SIMD_OP(_) \
|
||||
_(div) \
|
||||
_(max) \
|
||||
_(min) \
|
||||
_(maxNum) \
|
||||
_(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) \
|
||||
_(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) \
|
||||
_(lessThanOrEqual) \
|
||||
_(equal) \
|
||||
_(notEqual) \
|
||||
_(greaterThan) \
|
||||
_(greaterThanOrEqual) \
|
||||
_(and) \
|
||||
_(or) \
|
||||
_(xor) \
|
||||
_(bitselect) \
|
||||
_(select) \
|
||||
_(swizzle) \
|
||||
|
@ -9167,13 +9167,18 @@ GetTemplateObjectForNative(JSContext *cx, HandleScript script, jsbytecode *pc,
|
||||
}
|
||||
|
||||
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()));
|
||||
res.set(TypedObject::createZeroed(cx, descr, 0, gc::TenuredHeap));
|
||||
if (!res)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#undef ADD_INT32X4_SIMD_OP_NAME_
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -257,10 +257,17 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target)
|
||||
return inlineBoundFunction(callInfo, target);
|
||||
|
||||
// Simd functions
|
||||
if (native == js::simd_int32x4_add)
|
||||
return inlineSimdInt32x4BinaryArith(callInfo, native, MSimdBinaryArith::Add);
|
||||
if (native == js::simd_int32x4_and)
|
||||
return inlineSimdInt32x4BinaryBitwise(callInfo, native, MSimdBinaryBitwise::and_);
|
||||
#define INLINE_INT32X4_SIMD_ARITH_(OP) \
|
||||
if (native == js::simd_int32x4_##OP) \
|
||||
return inlineSimdInt32x4BinaryArith(callInfo, native, MSimdBinaryArith::Op_##OP);
|
||||
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;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "mozilla/Array.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "builtin/SIMD.h"
|
||||
#include "jit/AtomicOp.h"
|
||||
#include "jit/FixedList.h"
|
||||
#include "jit/InlineList.h"
|
||||
@ -1958,26 +1959,18 @@ class MSimdBinaryArith
|
||||
{
|
||||
public:
|
||||
enum Operation {
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Min,
|
||||
Max,
|
||||
MinNum,
|
||||
MaxNum
|
||||
#define OP_LIST_(OP) Op_##OP,
|
||||
ARITH_COMMONX4_SIMD_OP(OP_LIST_)
|
||||
ARITH_FLOAT32X4_SIMD_OP(OP_LIST_)
|
||||
#undef OP_LIST_
|
||||
};
|
||||
|
||||
static const char* OperationName(Operation op) {
|
||||
switch (op) {
|
||||
case Add: return "Add";
|
||||
case Sub: return "Sub";
|
||||
case Mul: return "Mul";
|
||||
case Div: return "Div";
|
||||
case Min: return "Min";
|
||||
case Max: return "Max";
|
||||
case MinNum: return "MinNum";
|
||||
case MaxNum: return "MaxNum";
|
||||
#define OP_CASE_LIST_(OP) case Op_##OP: return #OP;
|
||||
ARITH_COMMONX4_SIMD_OP(OP_CASE_LIST_)
|
||||
ARITH_FLOAT32X4_SIMD_OP(OP_CASE_LIST_)
|
||||
#undef OP_CASE_LIST_
|
||||
}
|
||||
MOZ_CRASH("unexpected operation");
|
||||
}
|
||||
@ -1988,11 +1981,11 @@ class MSimdBinaryArith
|
||||
MSimdBinaryArith(MDefinition *left, MDefinition *right, Operation op, MIRType type)
|
||||
: 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));
|
||||
setResultType(type);
|
||||
setMovable();
|
||||
if (op == Add || op == Mul || op == Min || op == Max)
|
||||
if (op == Op_add || op == Op_mul || op == Op_min || op == Op_max)
|
||||
setCommutative();
|
||||
}
|
||||
|
||||
|
@ -2657,13 +2657,13 @@ CodeGeneratorX86Shared::visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *ins)
|
||||
|
||||
MSimdBinaryArith::Operation op = ins->operation();
|
||||
switch (op) {
|
||||
case MSimdBinaryArith::Add:
|
||||
case MSimdBinaryArith::Op_add:
|
||||
masm.vpaddd(rhs, lhs, output);
|
||||
return;
|
||||
case MSimdBinaryArith::Sub:
|
||||
case MSimdBinaryArith::Op_sub:
|
||||
masm.vpsubd(rhs, lhs, output);
|
||||
return;
|
||||
case MSimdBinaryArith::Mul: {
|
||||
case MSimdBinaryArith::Op_mul: {
|
||||
if (AssemblerX86Shared::HasSSE41()) {
|
||||
masm.vpmulld(rhs, lhs, output);
|
||||
return;
|
||||
@ -2684,19 +2684,19 @@ CodeGeneratorX86Shared::visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *ins)
|
||||
masm.vshufps(MacroAssembler::ComputeShuffleMask(LaneZ, LaneX, LaneW, LaneY), lhs, lhs, lhs);
|
||||
return;
|
||||
}
|
||||
case MSimdBinaryArith::Div:
|
||||
case MSimdBinaryArith::Op_div:
|
||||
// x86 doesn't have SIMD i32 div.
|
||||
break;
|
||||
case MSimdBinaryArith::Max:
|
||||
case MSimdBinaryArith::Op_max:
|
||||
// we can do max with a single instruction only if we have SSE4.1
|
||||
// using the PMAXSD instruction.
|
||||
break;
|
||||
case MSimdBinaryArith::Min:
|
||||
case MSimdBinaryArith::Op_min:
|
||||
// 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:
|
||||
case MSimdBinaryArith::Op_minNum:
|
||||
case MSimdBinaryArith::Op_maxNum:
|
||||
break;
|
||||
}
|
||||
MOZ_CRASH("unexpected SIMD op");
|
||||
@ -2711,19 +2711,19 @@ CodeGeneratorX86Shared::visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *ins)
|
||||
|
||||
MSimdBinaryArith::Operation op = ins->operation();
|
||||
switch (op) {
|
||||
case MSimdBinaryArith::Add:
|
||||
case MSimdBinaryArith::Op_add:
|
||||
masm.vaddps(rhs, lhs, output);
|
||||
return;
|
||||
case MSimdBinaryArith::Sub:
|
||||
case MSimdBinaryArith::Op_sub:
|
||||
masm.vsubps(rhs, lhs, output);
|
||||
return;
|
||||
case MSimdBinaryArith::Mul:
|
||||
case MSimdBinaryArith::Op_mul:
|
||||
masm.vmulps(rhs, lhs, output);
|
||||
return;
|
||||
case MSimdBinaryArith::Div:
|
||||
case MSimdBinaryArith::Op_div:
|
||||
masm.vdivps(rhs, lhs, output);
|
||||
return;
|
||||
case MSimdBinaryArith::Max: {
|
||||
case MSimdBinaryArith::Op_max: {
|
||||
FloatRegister lhsCopy = masm.reusedInputFloat32x4(lhs, 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
|
||||
return;
|
||||
}
|
||||
case MSimdBinaryArith::Min: {
|
||||
case MSimdBinaryArith::Op_min: {
|
||||
FloatRegister rhsCopy = masm.reusedInputAlignedFloat32x4(rhs, ScratchSimdReg);
|
||||
masm.vminps(Operand(lhs), rhsCopy, ScratchSimdReg);
|
||||
masm.vminps(rhs, lhs, output);
|
||||
masm.vorps(ScratchSimdReg, output, output); // NaN or'd with arbitrary bits is NaN
|
||||
return;
|
||||
}
|
||||
case MSimdBinaryArith::MinNum: {
|
||||
case MSimdBinaryArith::Op_minNum: {
|
||||
FloatRegister tmp = ToFloatRegister(ins->temp());
|
||||
masm.loadConstantInt32x4(SimdConstant::SplatX4(int32_t(0x80000000)), tmp);
|
||||
|
||||
@ -2773,7 +2773,7 @@ CodeGeneratorX86Shared::visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *ins)
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MSimdBinaryArith::MaxNum: {
|
||||
case MSimdBinaryArith::Op_maxNum: {
|
||||
FloatRegister mask = ScratchSimdReg;
|
||||
masm.loadConstantInt32x4(SimdConstant::SplatX4(0), mask);
|
||||
masm.vpcmpeqd(Operand(lhs), mask, mask);
|
||||
|
@ -639,7 +639,7 @@ LIRGeneratorX86Shared::visitSimdBinaryArith(MSimdBinaryArith *ins)
|
||||
|
||||
if (ins->type() == MIRType_Int32x4) {
|
||||
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());
|
||||
lowerForFPU(lir, ins, lhs, rhs);
|
||||
return;
|
||||
@ -649,9 +649,9 @@ LIRGeneratorX86Shared::visitSimdBinaryArith(MSimdBinaryArith *ins)
|
||||
|
||||
LSimdBinaryArithFx4 *lir = new(alloc()) LSimdBinaryArithFx4();
|
||||
|
||||
bool needsTemp = ins->operation() == MSimdBinaryArith::Max ||
|
||||
ins->operation() == MSimdBinaryArith::MinNum ||
|
||||
ins->operation() == MSimdBinaryArith::MaxNum;
|
||||
bool needsTemp = ins->operation() == MSimdBinaryArith::Op_max ||
|
||||
ins->operation() == MSimdBinaryArith::Op_minNum ||
|
||||
ins->operation() == MSimdBinaryArith::Op_maxNum;
|
||||
lir->setTemp(0, needsTemp ? temp(LDefinition::FLOAT32X4) : LDefinition::BogusTemp());
|
||||
|
||||
lowerForFPU(lir, ins, lhs, rhs);
|
||||
|
Loading…
Reference in New Issue
Block a user