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:
Victor Carlquist 2015-02-10 12:50:42 -02:00
parent 1e887fd19a
commit 4e40652ac1
7 changed files with 73 additions and 72 deletions

View File

@ -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);

View File

@ -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) \

View File

@ -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;

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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);