Bug 1025475: SIMD x86-x64: Implement SIMD constructors; r=sunfish

This commit is contained in:
Benjamin Bouvier 2014-08-13 15:08:16 +02:00
Родитель cc9b09f336
Коммит 561a6af341
10 изменённых файлов: 108 добавлений и 0 удалений

Просмотреть файл

@ -128,6 +128,25 @@ class LMoveGroup : public LInstructionHelper<0, 0, 0>
}
};
// Constructs a SIMD value with 4 components (e.g. int32x4, float32x4).
class LSimdValueX4 : public LInstructionHelper<1, 4, 0>
{
public:
LIR_HEADER(SimdValueX4)
LSimdValueX4(const LAllocation &x, const LAllocation &y,
const LAllocation &z, const LAllocation &w)
{
setOperand(0, x);
setOperand(1, y);
setOperand(2, z);
setOperand(3, w);
}
MSimdValueX4 *mir() const {
return mir_->toSimdValueX4();
}
};
// Extracts an element from a given SIMD int32x4 lane.
class LSimdExtractElementI : public LInstructionHelper<1, 1, 0>
{

Просмотреть файл

@ -16,6 +16,7 @@
_(Pointer) \
_(Double) \
_(Float32) \
_(SimdValueX4) \
_(SimdExtractElementI) \
_(SimdExtractElementF) \
_(Value) \

Просмотреть файл

@ -3650,6 +3650,17 @@ LIRGenerator::visitRecompileCheck(MRecompileCheck *ins)
return assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitSimdValueX4(MSimdValueX4 *ins)
{
LAllocation x = useRegisterAtStart(ins->getOperand(0));
LAllocation y = useRegisterAtStart(ins->getOperand(1));
LAllocation z = useRegisterAtStart(ins->getOperand(2));
LAllocation w = useRegisterAtStart(ins->getOperand(3));
return define(new(alloc()) LSimdValueX4(x, y, z, w), ins);
}
bool
LIRGenerator::visitSimdExtractElement(MSimdExtractElement *ins)
{

Просмотреть файл

@ -265,6 +265,7 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitGetDOMMember(MGetDOMMember *ins);
bool visitRecompileCheck(MRecompileCheck *ins);
bool visitSimdExtractElement(MSimdExtractElement *ins);
bool visitSimdValueX4(MSimdValueX4 *ins);
};
} // namespace jit

Просмотреть файл

@ -13,6 +13,7 @@
#define jit_MIR_h
#include "mozilla/Array.h"
#include "mozilla/DebugOnly.h"
#include "jit/CompilerRoot.h"
#include "jit/FixedList.h"
@ -1233,6 +1234,42 @@ class MConstant : public MNullaryInstruction
ALLOW_CLONE(MConstant)
};
// Generic constructor of SIMD valuesX4.
class MSimdValueX4 : public MQuaternaryInstruction
{
protected:
MSimdValueX4(MIRType type, MDefinition *x, MDefinition *y, MDefinition *z, MDefinition *w)
: MQuaternaryInstruction(x, y, z, w)
{
JS_ASSERT(IsSimdType(type));
mozilla::DebugOnly<MIRType> scalarType = SimdTypeToScalarType(type);
JS_ASSERT(scalarType == x->type());
JS_ASSERT(scalarType == y->type());
JS_ASSERT(scalarType == z->type());
JS_ASSERT(scalarType == w->type());
setMovable();
setResultType(type);
}
public:
INSTRUCTION_HEADER(SimdValueX4)
static MSimdValueX4 *New(TempAllocator &alloc, MIRType type, MDefinition *x,
MDefinition *y, MDefinition *z, MDefinition *w)
{
return new(alloc) MSimdValueX4(type, x, y, z, w);
}
AliasSet getAliasSet() const {
return AliasSet::None();
}
bool congruentTo(const MDefinition *ins) const {
return congruentIfOperandsEqual(ins);
}
};
// Extracts a lane element from a given vector type, given by its lane symbol.
class MSimdExtractElement : public MUnaryInstruction
{

Просмотреть файл

@ -12,6 +12,7 @@ namespace jit {
#define MIR_OPCODE_LIST(_) \
_(Constant) \
_(SimdValueX4) \
_(SimdExtractElement) \
_(CloneLiteral) \
_(Parameter) \

Просмотреть файл

@ -112,6 +112,7 @@ class ParallelSafetyVisitor : public MDefinitionVisitor
// obviously safe for now. We can loosen as we need.
SAFE_OP(Constant)
SAFE_OP(SimdValueX4)
SAFE_OP(SimdExtractElement)
UNSAFE_OP(CloneLiteral)
SAFE_OP(Parameter)

Просмотреть файл

@ -227,6 +227,7 @@ class CodeGeneratorARM : public CodeGeneratorShared
public:
// Unimplemented SIMD instructions
bool visitSimdValueX4(LSimdValueX4 *lir) { MOZ_ASSUME_UNREACHABLE("NYI"); }
bool visitSimdExtractElementI(LSimdExtractElementI *ins) { MOZ_ASSUME_UNREACHABLE("NYI"); }
bool visitSimdExtractElementF(LSimdExtractElementF *ins) { MOZ_ASSUME_UNREACHABLE("NYI"); }
};

Просмотреть файл

@ -2053,6 +2053,41 @@ CodeGeneratorX86Shared::visitNegF(LNegF *ins)
return true;
}
bool
CodeGeneratorX86Shared::visitSimdValueX4(LSimdValueX4 *ins)
{
FloatRegister output = ToFloatRegister(ins->output());
MSimdValueX4 *mir = ins->mir();
JS_ASSERT(IsSimdType(mir->type()));
JS_STATIC_ASSERT(sizeof(float) == sizeof(int32_t));
masm.reserveStack(Simd128DataSize);
// TODO see bug 1051860 for possible optimizations.
switch (mir->type()) {
case MIRType_Int32x4: {
for (size_t i = 0; i < 4; ++i) {
Register r = ToRegister(ins->getOperand(i));
masm.store32(r, Address(StackPointer, i * sizeof(int32_t)));
}
masm.loadAlignedInt32x4(Address(StackPointer, 0), output);
break;
}
case MIRType_Float32x4: {
for (size_t i = 0; i < 4; ++i) {
FloatRegister r = ToFloatRegister(ins->getOperand(i));
masm.storeFloat32(r, Address(StackPointer, i * sizeof(float)));
}
masm.loadAlignedFloat32x4(Address(StackPointer, 0), output);
break;
}
default: MOZ_ASSUME_UNREACHABLE("Unknown SIMD kind");
}
masm.freeStack(Simd128DataSize);
return true;
}
bool
CodeGeneratorX86Shared::visitSimdExtractElementI(LSimdExtractElementI *ins)
{

Просмотреть файл

@ -205,6 +205,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
bool visitNegF(LNegF *lir);
// SIMD operators
bool visitSimdValueX4(LSimdValueX4 *lir);
bool visitSimdExtractElementI(LSimdExtractElementI *lir);
bool visitSimdExtractElementF(LSimdExtractElementF *lir);