Bug 1069956: SIMD x86-x64 backend: implement SimdReinterpretCast; r=sunfish
authorBenjamin Bouvier <benj@benj.me>
Thu, 25 Sep 2014 13:18:14 +0200
changeset 230471 c965698b314e116da8d54f5b5e7665ee75e29477
parent 230470 fd0ef779e8a17325af669c6bfb86029c8c57e470
child 230472 e2c803c2aeec002102c76757fc1b6efdff769f68
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1069956
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1069956: SIMD x86-x64 backend: implement SimdReinterpretCast; r=sunfish
js/src/jit/Lowering.cpp
js/src/jit/Lowering.h
js/src/jit/MIR.h
js/src/jit/MOpcodes.h
js/src/jit/ParallelSafetyAnalysis.cpp
js/src/jit/shared/Lowering-shared-inl.h
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -3722,16 +3722,23 @@ LIRGenerator::visitSimdConvert(MSimdConv
         MOZ_ASSERT(input->type() == MIRType_Int32x4);
         return define(new(alloc()) LInt32x4ToFloat32x4(use), ins);
     }
 
     MOZ_CRASH("Unknown SIMD kind when generating constant");
 }
 
 bool
+LIRGenerator::visitSimdReinterpretCast(MSimdReinterpretCast *ins)
+{
+    MOZ_ASSERT(IsSimdType(ins->type()) && IsSimdType(ins->input()->type()));
+    return redefine(ins, ins->input());
+}
+
+bool
 LIRGenerator::visitSimdExtractElement(MSimdExtractElement *ins)
 {
     JS_ASSERT(IsSimdType(ins->input()->type()));
     JS_ASSERT(!IsSimdType(ins->type()));
 
     if (ins->input()->type() == MIRType_Int32x4) {
         // Note: there could be int16x8 in the future, which doesn't use the
         // same instruction. We either need to pass the arity or create new LIns.
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -271,16 +271,17 @@ class LIRGenerator : public LIRGenerator
     bool visitSimdExtractElement(MSimdExtractElement *ins);
     bool visitSimdInsertElement(MSimdInsertElement *ins);
     bool visitSimdSignMask(MSimdSignMask *ins);
     bool visitSimdBinaryComp(MSimdBinaryComp *ins);
     bool visitSimdBinaryArith(MSimdBinaryArith *ins);
     bool visitSimdBinaryBitwise(MSimdBinaryBitwise *ins);
     bool visitSimdConstant(MSimdConstant *ins);
     bool visitSimdConvert(MSimdConvert *ins);
+    bool visitSimdReinterpretCast(MSimdReinterpretCast *ins);
     bool visitPhi(MPhi *ins);
     bool visitBeta(MBeta *ins);
     bool visitObjectState(MObjectState *ins);
     bool visitArrayState(MArrayState *ins);
     bool visitUnknownValue(MUnknownValue *ins);
     bool visitLexicalCheck(MLexicalCheck *ins);
     bool visitThrowUninitializedLexical(MThrowUninitializedLexical *ins);
 };
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -1384,16 +1384,44 @@ class MSimdConvert : public MUnaryInstru
         return AliasSet::None();
     }
     bool congruentTo(const MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     ALLOW_CLONE(MSimdConvert)
 };
 
+// Casts bits of a vector input to another SIMD type (doesn't generate code).
+class MSimdReinterpretCast : public MUnaryInstruction
+{
+    MSimdReinterpretCast(MDefinition *obj, MIRType fromType, MIRType toType)
+      : MUnaryInstruction(obj)
+    {
+        MOZ_ASSERT(IsSimdType(obj->type()) && fromType == obj->type());
+        MOZ_ASSERT(IsSimdType(toType));
+        setResultType(toType);
+    }
+
+  public:
+    INSTRUCTION_HEADER(SimdReinterpretCast);
+    static MSimdReinterpretCast* NewAsmJS(TempAllocator &alloc, MDefinition *obj, MIRType fromType,
+                                          MIRType toType)
+    {
+        return new(alloc) MSimdReinterpretCast(obj, fromType, toType);
+    }
+
+    AliasSet getAliasSet() const {
+        return AliasSet::None();
+    }
+    bool congruentTo(const MDefinition *ins) const {
+        return congruentIfOperandsEqual(ins);
+    }
+    ALLOW_CLONE(MSimdReinterpretCast)
+};
+
 // Extracts a lane element from a given vector type, given by its lane symbol.
 class MSimdExtractElement : public MUnaryInstruction
 {
   protected:
     SimdLane lane_;
 
     MSimdExtractElement(MDefinition *obj, MIRType type, SimdLane lane)
       : MUnaryInstruction(obj), lane_(lane)
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -11,16 +11,17 @@ namespace js {
 namespace jit {
 
 #define MIR_OPCODE_LIST(_)                                                  \
     _(Constant)                                                             \
     _(SimdValueX4)                                                          \
     _(SimdSplatX4)                                                          \
     _(SimdConstant)                                                         \
     _(SimdConvert)                                                          \
+    _(SimdReinterpretCast)                                                  \
     _(SimdExtractElement)                                                   \
     _(SimdInsertElement)                                                    \
     _(SimdSignMask)                                                         \
     _(SimdBinaryComp)                                                       \
     _(SimdBinaryArith)                                                      \
     _(SimdBinaryBitwise)                                                    \
     _(SimdTernaryBitwise)                                                   \
     _(CloneLiteral)                                                         \
--- a/js/src/jit/ParallelSafetyAnalysis.cpp
+++ b/js/src/jit/ParallelSafetyAnalysis.cpp
@@ -110,16 +110,17 @@ class ParallelSafetyVisitor : public MDe
     // I am taking the policy of blacklisting everything that's not
     // obviously safe for now.  We can loosen as we need.
 
     SAFE_OP(Constant)
     SAFE_OP(SimdValueX4)
     SAFE_OP(SimdSplatX4)
     SAFE_OP(SimdConstant)
     SAFE_OP(SimdConvert)
+    SAFE_OP(SimdReinterpretCast)
     SAFE_OP(SimdExtractElement)
     SAFE_OP(SimdInsertElement)
     SAFE_OP(SimdSignMask)
     SAFE_OP(SimdBinaryComp)
     SAFE_OP(SimdBinaryArith)
     SAFE_OP(SimdBinaryBitwise)
     SAFE_OP(SimdTernaryBitwise)
     UNSAFE_OP(CloneLiteral)
--- a/js/src/jit/shared/Lowering-shared-inl.h
+++ b/js/src/jit/shared/Lowering-shared-inl.h
@@ -187,16 +187,19 @@ static inline bool
 IsCompatibleLIRCoercion(MIRType to, MIRType from)
 {
     if (to == from)
         return true;
     if ((to == MIRType_Int32 || to == MIRType_Boolean) &&
         (from == MIRType_Int32 || from == MIRType_Boolean)) {
         return true;
     }
+    // SIMD types can be coerced with from*Bits operators.
+    if (IsSimdType(to) && IsSimdType(from))
+        return true;
     return false;
 }
 
 bool
 LIRGeneratorShared::redefine(MDefinition *def, MDefinition *as)
 {
     JS_ASSERT(IsCompatibleLIRCoercion(def->type(), as->type()));