Bug 1090957 - IonMonkey: MIPS: Implement atomics in Lowering. r=lth
☠☠ backed out by 4aa558b944b5 ☠ ☠
authorHeiher <r@hev.cc>
Sun, 08 Nov 2015 04:37:21 +0800
changeset 271673 f45ccb4ab2cfbef4b11a675cab085ca6df696e99
parent 271672 a3b1e29fa2dbc35752abc50af80005e54eb6d44a
child 271674 0b64cc3528d9bc7e7e18e7325621fe7f0e520620
push id29650
push usercbook@mozilla.com
push dateMon, 09 Nov 2015 13:56:12 +0000
treeherdermozilla-central@e1ef2be156de [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1090957
milestone45.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 1090957 - IonMonkey: MIPS: Implement atomics in Lowering. r=lth --- js/src/jit/mips-shared/Lowering-mips-shared.cpp | 148 +++++++++++++++++++++++- 1 file changed, 142 insertions(+), 6 deletions(-)
js/src/jit/mips-shared/Lowering-mips-shared.cpp
--- a/js/src/jit/mips-shared/Lowering-mips-shared.cpp
+++ b/js/src/jit/mips-shared/Lowering-mips-shared.cpp
@@ -374,40 +374,176 @@ void
 LIRGeneratorMIPSShared::visitSimdValueX4(MSimdValueX4* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
 LIRGeneratorMIPSShared::visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement* ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSERT(ins->arrayType() != Scalar::Float32);
+    MOZ_ASSERT(ins->arrayType() != Scalar::Float64);
+
+    MOZ_ASSERT(ins->elements()->type() == MIRType_Elements);
+    MOZ_ASSERT(ins->index()->type() == MIRType_Int32);
+
+    const LUse elements = useRegister(ins->elements());
+    const LAllocation index = useRegisterOrConstant(ins->index());
+
+    // If the target is a floating register then we need a temp at the
+    // CodeGenerator level for creating the result.
+
+    const LAllocation newval = useRegister(ins->newval());
+    const LAllocation oldval = useRegister(ins->oldval());
+    LDefinition uint32Temp = LDefinition::BogusTemp();
+    if (ins->arrayType() == Scalar::Uint32 && IsFloatingPointType(ins->type()))
+        uint32Temp = temp();
+
+    LCompareExchangeTypedArrayElement* lir =
+        new(alloc()) LCompareExchangeTypedArrayElement(elements, index, oldval, newval, uint32Temp,
+                                                       /* valueTemp= */ temp(), /* offsetTemp= */ temp(),
+                                                       /* maskTemp= */ temp());
+
+    define(lir, ins);
 }
 
 void
 LIRGeneratorMIPSShared::visitAtomicExchangeTypedArrayElement(MAtomicExchangeTypedArrayElement* ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSERT(ins->arrayType() <= Scalar::Uint32);
+
+    MOZ_ASSERT(ins->elements()->type() == MIRType_Elements);
+    MOZ_ASSERT(ins->index()->type() == MIRType_Int32);
+
+    const LUse elements = useRegister(ins->elements());
+    const LAllocation index = useRegisterOrConstant(ins->index());
+
+    // If the target is a floating register then we need a temp at the
+    // CodeGenerator level for creating the result.
+
+    const LAllocation value = useRegister(ins->value());
+    LDefinition uint32Temp = LDefinition::BogusTemp();
+    if (ins->arrayType() == Scalar::Uint32) {
+        MOZ_ASSERT(ins->type() == MIRType_Double);
+        uint32Temp = temp();
+    }
+
+    LAtomicExchangeTypedArrayElement* lir =
+        new(alloc()) LAtomicExchangeTypedArrayElement(elements, index, value, uint32Temp,
+                                                      /* valueTemp= */ temp(), /* offsetTemp= */ temp(),
+                                                      /* maskTemp= */ temp());
+
+    define(lir, ins);
 }
 
 void
 LIRGeneratorMIPSShared::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSERT(ins->accessType() < Scalar::Float32);
+
+    MDefinition* ptr = ins->ptr();
+    MOZ_ASSERT(ptr->type() == MIRType_Int32);
+
+    LAsmJSCompareExchangeHeap* lir =
+        new(alloc()) LAsmJSCompareExchangeHeap(useRegister(ptr),
+                                               useRegister(ins->oldValue()),
+                                               useRegister(ins->newValue()),
+                                               /* valueTemp= */ temp(),
+                                               /* offsetTemp= */ temp(),
+                                               /* maskTemp= */ temp());
+
+    define(lir, ins);
 }
 
 void
 LIRGeneratorMIPSShared::visitAsmJSAtomicExchangeHeap(MAsmJSAtomicExchangeHeap* ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSERT(ins->ptr()->type() == MIRType_Int32);
+
+    const LAllocation ptr = useRegister(ins->ptr());
+    const LAllocation value = useRegister(ins->value());
+
+    // The output may not be used but will be clobbered regardless,
+    // so ignore the case where we're not using the value and just
+    // use the output register as a temp.
+
+    LAsmJSAtomicExchangeHeap* lir =
+        new(alloc()) LAsmJSAtomicExchangeHeap(ptr, value,
+                                              /* valueTemp= */ temp(),
+                                              /* offsetTemp= */ temp(),
+                                              /* maskTemp= */ temp());
+    define(lir, ins);
 }
 
 void
 LIRGeneratorMIPSShared::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSERT(ins->accessType() < Scalar::Float32);
+
+    MDefinition* ptr = ins->ptr();
+    MOZ_ASSERT(ptr->type() == MIRType_Int32);
+
+    if (!ins->hasUses()) {
+        LAsmJSAtomicBinopHeapForEffect* lir =
+            new(alloc()) LAsmJSAtomicBinopHeapForEffect(useRegister(ptr),
+                                                        useRegister(ins->value()),
+                                                        /* flagTemp= */ temp(),
+                                                        /* valueTemp= */ temp(),
+                                                        /* offsetTemp= */ temp(),
+                                                        /* maskTemp= */ temp());
+        add(lir, ins);
+        return;
+    }
+
+    LAsmJSAtomicBinopHeap* lir =
+        new(alloc()) LAsmJSAtomicBinopHeap(useRegister(ptr),
+                                           useRegister(ins->value()),
+                                           /* temp= */ LDefinition::BogusTemp(),
+                                           /* flagTemp= */ temp(),
+                                           /* valueTemp= */ temp(),
+                                           /* offsetTemp= */ temp(),
+                                           /* maskTemp= */ temp());
+
+    define(lir, ins);
 }
 
 void
 LIRGeneratorMIPSShared::visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop* ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSERT(ins->arrayType() != Scalar::Uint8Clamped);
+    MOZ_ASSERT(ins->arrayType() != Scalar::Float32);
+    MOZ_ASSERT(ins->arrayType() != Scalar::Float64);
+
+    MOZ_ASSERT(ins->elements()->type() == MIRType_Elements);
+    MOZ_ASSERT(ins->index()->type() == MIRType_Int32);
+
+    const LUse elements = useRegister(ins->elements());
+    const LAllocation index = useRegisterOrConstant(ins->index());
+    const LAllocation value = useRegister(ins->value());
+
+    if (!ins->hasUses()) {
+        LAtomicTypedArrayElementBinopForEffect* lir =
+            new(alloc()) LAtomicTypedArrayElementBinopForEffect(elements, index, value,
+                                                                /* flagTemp= */ temp(),
+                                                                /* valueTemp= */ temp(),
+                                                                /* offsetTemp= */ temp(),
+                                                                /* maskTemp= */ temp());
+        add(lir, ins);
+        return;
+    }
+
+    // For a Uint32Array with a known double result we need a temp for
+    // the intermediate output.
+
+    LDefinition flagTemp = temp();
+    LDefinition outTemp = LDefinition::BogusTemp();
+
+    if (ins->arrayType() == Scalar::Uint32 && IsFloatingPointType(ins->type()))
+        outTemp = temp();
+
+    // On mips, map flagTemp to temp1 and outTemp to temp2, at least for now.
+
+    LAtomicTypedArrayElementBinop* lir =
+        new(alloc()) LAtomicTypedArrayElementBinop(elements, index, value, flagTemp, outTemp,
+                                                   /* valueTemp= */ temp(), /* offsetTemp= */ temp(),
+                                                   /* maskTemp= */ temp());
+    define(lir, ins);
 }