Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / v8 / src / arm64 / lithium-arm64.cc
index 60bf51e..3eb2778 100644 (file)
@@ -1,29 +1,6 @@
 // Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 #include "v8.h"
 
@@ -515,6 +492,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
       !hinstr->HasObservableSideEffects();
   if (needs_environment && !instr->HasEnvironment()) {
     instr = AssignEnvironment(instr);
+    // We can't really figure out if the environment is needed or not.
+    instr->environment()->set_has_been_used();
   }
 
   return instr;
@@ -702,7 +681,8 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
     // the it was just a plain use), so it is free to move the split child into
     // the same register that is used for the use-at-start.
     // See https://code.google.com/p/chromium/issues/detail?id=201590
-    if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+    if (!(instr->ClobbersRegisters() &&
+          instr->ClobbersDoubleRegisters(isolate()))) {
       int fixed = 0;
       int used_at_start = 0;
       for (UseIterator it(instr); !it.Done(); it.Advance()) {
@@ -947,9 +927,16 @@ LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
 
 
 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
-  LOperand* value = UseRegisterOrConstantAtStart(instr->index());
-  LOperand* length = UseRegister(instr->length());
-  return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
+  if (!FLAG_debug_code && instr->skip_check()) return NULL;
+  LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+  LOperand* length = !index->IsConstantOperand()
+      ? UseRegisterOrConstantAtStart(instr->length())
+      : UseRegisterAtStart(instr->length());
+  LInstruction* result = new(zone()) LBoundsCheck(index, length);
+  if (!FLAG_debug_code || !instr->skip_check()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1074,63 +1061,58 @@ LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
   Representation from = instr->from();
   Representation to = instr->to();
-
+  HValue* val = instr->value();
   if (from.IsSmi()) {
     if (to.IsTagged()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       return DefineSameAsFirst(new(zone()) LDummyUse(value));
     }
     from = Representation::Tagged();
   }
-
   if (from.IsTagged()) {
     if (to.IsDouble()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       LOperand* temp = TempRegister();
-      LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
-      return AssignEnvironment(DefineAsRegister(res));
+      LInstruction* result =
+          DefineAsRegister(new(zone()) LNumberUntagD(value, temp));
+      if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+      return result;
     } else if (to.IsSmi()) {
-      LOperand* value = UseRegister(instr->value());
-      if (instr->value()->type().IsSmi()) {
+      LOperand* value = UseRegister(val);
+      if (val->type().IsSmi()) {
         return DefineSameAsFirst(new(zone()) LDummyUse(value));
       }
       return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
-      LInstruction* res = NULL;
-
-      if (instr->value()->type().IsSmi() ||
-          instr->value()->representation().IsSmi()) {
-        LOperand* value = UseRegisterAtStart(instr->value());
-        res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
+      if (val->type().IsSmi() || val->representation().IsSmi()) {
+        LOperand* value = UseRegisterAtStart(val);
+        return DefineAsRegister(new(zone()) LSmiUntag(value, false));
       } else {
-        LOperand* value = UseRegister(instr->value());
+        LOperand* value = UseRegister(val);
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24);
-        res = DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2));
-        res = AssignEnvironment(res);
+        LInstruction* result =
+            DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2));
+        if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+        return result;
       }
-
-      return res;
     }
   } else if (from.IsDouble()) {
     if (to.IsTagged()) {
       info()->MarkAsDeferredCalling();
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       LOperand* temp1 = TempRegister();
       LOperand* temp2 = TempRegister();
-
       LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
       return AssignPointerMap(DefineAsRegister(result));
     } else {
       ASSERT(to.IsSmi() || to.IsInteger32());
-      LOperand* value = UseRegister(instr->value());
-
       if (instr->CanTruncateToInt32()) {
-        LTruncateDoubleToIntOrSmi* result =
-            new(zone()) LTruncateDoubleToIntOrSmi(value);
-        return DefineAsRegister(result);
+        LOperand* value = UseRegister(val);
+        return DefineAsRegister(new(zone()) LTruncateDoubleToIntOrSmi(value));
       } else {
+        LOperand* value = UseRegister(val);
         LDoubleToIntOrSmi* result = new(zone()) LDoubleToIntOrSmi(value);
         return AssignEnvironment(DefineAsRegister(result));
       }
@@ -1138,37 +1120,35 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
   } else if (from.IsInteger32()) {
     info()->MarkAsDeferredCalling();
     if (to.IsTagged()) {
-      if (instr->value()->CheckFlag(HInstruction::kUint32)) {
-        LOperand* value = UseRegister(instr->value());
-        LNumberTagU* result = new(zone()) LNumberTagU(value,
-                                                      TempRegister(),
-                                                      TempRegister());
-        return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+      if (val->CheckFlag(HInstruction::kUint32)) {
+        LOperand* value = UseRegister(val);
+        LNumberTagU* result =
+            new(zone()) LNumberTagU(value, TempRegister(), TempRegister());
+        return AssignPointerMap(DefineAsRegister(result));
       } else {
         STATIC_ASSERT((kMinInt == Smi::kMinValue) &&
                       (kMaxInt == Smi::kMaxValue));
-        LOperand* value = UseRegisterAtStart(instr->value());
+        LOperand* value = UseRegisterAtStart(val);
         return DefineAsRegister(new(zone()) LSmiTag(value));
       }
     } else if (to.IsSmi()) {
-      LOperand* value = UseRegisterAtStart(instr->value());
+      LOperand* value = UseRegisterAtStart(val);
       LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
-      if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+      if (val->CheckFlag(HInstruction::kUint32)) {
         result = AssignEnvironment(result);
       }
       return result;
     } else {
       ASSERT(to.IsDouble());
-      if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+      if (val->CheckFlag(HInstruction::kUint32)) {
         return DefineAsRegister(
-            new(zone()) LUint32ToDouble(UseRegisterAtStart(instr->value())));
+            new(zone()) LUint32ToDouble(UseRegisterAtStart(val)));
       } else {
         return DefineAsRegister(
-            new(zone()) LInteger32ToDouble(UseRegisterAtStart(instr->value())));
+            new(zone()) LInteger32ToDouble(UseRegisterAtStart(val)));
       }
     }
   }
-
   UNREACHABLE();
   return NULL;
 }
@@ -1189,27 +1169,23 @@ LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
 
 
 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
-  if (instr->CanOmitMapChecks()) {
-    // LCheckMaps does nothing in this case.
-    return new(zone()) LCheckMaps(NULL);
-  } else {
-    LOperand* value = UseRegisterAtStart(instr->value());
-    LOperand* temp = TempRegister();
-
-    if (instr->has_migration_target()) {
-      info()->MarkAsDeferredCalling();
-      LInstruction* result = new(zone()) LCheckMaps(value, temp);
-      return AssignPointerMap(AssignEnvironment(result));
-    } else {
-      return AssignEnvironment(new(zone()) LCheckMaps(value, temp));
-    }
+  if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
+  LOperand* value = UseRegisterAtStart(instr->value());
+  LOperand* temp = TempRegister();
+  LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value, temp));
+  if (instr->HasMigrationTarget()) {
+    info()->MarkAsDeferredCalling();
+    result = AssignPointerMap(result);
   }
+  return result;
 }
 
 
 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
-  return AssignEnvironment(new(zone()) LCheckNonSmi(value));
+  LInstruction* result = new(zone()) LCheckNonSmi(value);
+  if (!instr->value()->IsHeapObject()) result = AssignEnvironment(result);
+  return result;
 }
 
 
@@ -1249,8 +1225,9 @@ LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
 
 LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
     HCompareNumericAndBranch* instr) {
+  LInstruction* goto_instr = CheckElideControlInstruction(instr);
+  if (goto_instr != NULL) return goto_instr;
   Representation r = instr->representation();
-
   if (r.IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(r));
     ASSERT(instr->right()->representation().Equals(r));
@@ -1418,8 +1395,12 @@ LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
   LOperand* divisor = UseRegister(instr->right());
   LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)
       ? NULL : TempRegister();
-  LDivI* div = new(zone()) LDivI(dividend, divisor, temp);
-  return AssignEnvironment(DefineAsRegister(div));
+  LInstruction* result =
+      DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp));
+  if (!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1447,6 +1428,7 @@ LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
 
 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
   HEnvironment* outer = current_block_->last_environment();
+  outer->set_ast_id(instr->ReturnId());
   HConstant* undefined = graph()->GetConstantUndefined();
   HEnvironment* inner = outer->CopyForInlining(instr->closure(),
                                                instr->arguments_count(),
@@ -1622,7 +1604,10 @@ LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
   LOperand* context = UseRegisterAtStart(instr->value());
   LInstruction* result =
       DefineAsRegister(new(zone()) LLoadContextSlot(context));
-  return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1656,9 +1641,10 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
   ASSERT(instr->key()->representation().IsSmiOrInteger32());
   ElementsKind elements_kind = instr->elements_kind();
   LOperand* elements = UseRegister(instr->elements());
-  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
 
   if (!instr->is_typed_elements()) {
+    LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+
     if (instr->representation().IsDouble()) {
       LOperand* temp = (!instr->key()->IsConstant() ||
                         instr->RequiresHoleCheck())
@@ -1686,18 +1672,16 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
            (instr->representation().IsDouble() &&
             IsDoubleOrFloatElementsKind(instr->elements_kind())));
 
+    LOperand* key = UseRegisterOrConstant(instr->key());
     LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister();
-    LLoadKeyedExternal* result =
-        new(zone()) LLoadKeyedExternal(elements, key, temp);
-    // An unsigned int array load might overflow and cause a deopt. Make sure it
-    // has an environment.
-    if (instr->RequiresHoleCheck() ||
-        elements_kind == EXTERNAL_UINT32_ELEMENTS ||
-        elements_kind == UINT32_ELEMENTS) {
-      return AssignEnvironment(DefineAsRegister(result));
-    } else {
-      return DefineAsRegister(result);
+    LInstruction* result = DefineAsRegister(
+        new(zone()) LLoadKeyedExternal(elements, key, temp));
+    if ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
+         elements_kind == UINT32_ELEMENTS) &&
+        !instr->CheckFlag(HInstruction::kUint32)) {
+      result = AssignEnvironment(result);
     }
+    return result;
   }
 }
 
@@ -1885,13 +1869,10 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
 
     bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
     bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
-    bool needs_environment = can_overflow || bailout_on_minus_zero;
 
     HValue* least_const = instr->BetterLeftOperand();
     HValue* most_const = instr->BetterRightOperand();
 
-    LOperand* left;
-
     // LMulConstI can handle a subset of constants:
     //  With support for overflow detection:
     //    -1, 0, 1, 2
@@ -1911,26 +1892,27 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
                               IsPowerOf2(constant_abs - 1))))) {
         LConstantOperand* right = UseConstant(most_const);
         bool need_register = IsPowerOf2(constant_abs) && !small_constant;
-        left = need_register ? UseRegister(least_const)
-                             : UseRegisterAtStart(least_const);
-        LMulConstIS* mul = new(zone()) LMulConstIS(left, right);
-        if (needs_environment) AssignEnvironment(mul);
-        return DefineAsRegister(mul);
+        LOperand* left = need_register ? UseRegister(least_const)
+                                       : UseRegisterAtStart(least_const);
+        LInstruction* result =
+            DefineAsRegister(new(zone()) LMulConstIS(left, right));
+        if ((bailout_on_minus_zero && constant <= 0) || can_overflow) {
+          result = AssignEnvironment(result);
+        }
+        return result;
       }
     }
 
-    left = UseRegisterAtStart(least_const);
     // LMulI/S can handle all cases, but it requires that a register is
     // allocated for the second operand.
-    LInstruction* result;
-    if (instr->representation().IsSmi()) {
-      LOperand* right = UseRegisterAtStart(most_const);
-      result = DefineAsRegister(new(zone()) LMulS(left, right));
-    } else {
-      LOperand* right = UseRegisterAtStart(most_const);
-      result = DefineAsRegister(new(zone()) LMulI(left, right));
+    LOperand* left = UseRegisterAtStart(least_const);
+    LOperand* right = UseRegisterAtStart(most_const);
+    LInstruction* result = instr->representation().IsSmi()
+        ? DefineAsRegister(new(zone()) LMulS(left, right))
+        : DefineAsRegister(new(zone()) LMulI(left, right));
+    if ((bailout_on_minus_zero && least_const != most_const) || can_overflow) {
+      result = AssignEnvironment(result);
     }
-    if (needs_environment) AssignEnvironment(result);
     return result;
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::MUL, instr);
@@ -1956,7 +1938,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
   } else {
     ASSERT(info()->IsStub());
     CodeStubInterfaceDescriptor* descriptor =
-        info()->code_stub()->GetInterfaceDescriptor(info()->isolate());
+        info()->code_stub()->GetInterfaceDescriptor();
     int index = static_cast<int>(instr->index());
     Register reg = descriptor->GetParameterRegister(index);
     return DefineFixed(result, reg);
@@ -2160,7 +2142,10 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
     value = UseRegister(instr->value());
   }
   LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp);
-  return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2180,7 +2165,6 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
   LOperand* temp = NULL;
   LOperand* elements = NULL;
   LOperand* val = NULL;
-  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
 
   if (!instr->is_typed_elements() &&
       instr->value()->representation().IsTagged() &&
@@ -2204,16 +2188,19 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
             instr->elements()->representation().IsTagged()) ||
            (instr->is_external() &&
             instr->elements()->representation().IsExternal()));
+    LOperand* key = UseRegisterOrConstant(instr->key());
     return new(zone()) LStoreKeyedExternal(elements, key, val, temp);
 
   } else if (instr->value()->representation().IsDouble()) {
     ASSERT(instr->elements()->representation().IsTagged());
+    LOperand* key = UseRegisterOrConstantAtStart(instr->key());
     return new(zone()) LStoreKeyedFixedDouble(elements, key, val, temp);
 
   } else {
     ASSERT(instr->elements()->representation().IsTagged());
     ASSERT(instr->value()->representation().IsSmiOrTagged() ||
            instr->value()->representation().IsInteger32());
+    LOperand* key = UseRegisterOrConstantAtStart(instr->key());
     return new(zone()) LStoreKeyedFixed(elements, key, val, temp);
   }
 }
@@ -2294,7 +2281,7 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
   LOperand* context = UseAny(instr->context());
   LStringCharCodeAt* result =
       new(zone()) LStringCharCodeAt(context, string, index);
-  return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+  return AssignPointerMap(DefineAsRegister(result));
 }
 
 
@@ -2365,17 +2352,18 @@ LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
 
 LInstruction* LChunkBuilder::DoTransitionElementsKind(
     HTransitionElementsKind* instr) {
-  LOperand* object = UseRegister(instr->object());
   if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+    LOperand* object = UseRegister(instr->object());
     LTransitionElementsKind* result =
         new(zone()) LTransitionElementsKind(object, NULL,
                                             TempRegister(), TempRegister());
     return result;
   } else {
+    LOperand* object = UseFixed(instr->object(), x0);
     LOperand* context = UseFixed(instr->context(), cp);
     LTransitionElementsKind* result =
-        new(zone()) LTransitionElementsKind(object, context, TempRegister());
-    return AssignPointerMap(result);
+        new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
+    return MarkAsCall(result, instr);
   }
 }
 
@@ -2429,21 +2417,14 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = TempRegister();
         LOperand* temp3 = TempRegister();
-        LMathAbsTagged* result =
-            new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3);
-        return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+        LInstruction* result = DefineAsRegister(
+            new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3));
+        return AssignEnvironment(AssignPointerMap(result));
       } else {
         LOperand* input = UseRegisterAtStart(instr->value());
-        LMathAbs* result = new(zone()) LMathAbs(input);
-        if (r.IsDouble()) {
-          // The Double case can never fail so it doesn't need an environment.
-          return DefineAsRegister(result);
-        } else {
-          ASSERT(r.IsInteger32() || r.IsSmi());
-          // The Integer32 and Smi cases need an environment because they can
-          // deoptimize on minimum representable number.
-          return AssignEnvironment(DefineAsRegister(result));
-        }
+        LInstruction* result = DefineAsRegister(new(zone()) LMathAbs(input));
+        if (!r.IsDouble()) result = AssignEnvironment(result);
+        return result;
       }
     }
     case kMathExp: {
@@ -2460,14 +2441,16 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
       return DefineAsRegister(result);
     }
     case kMathFloor: {
-      ASSERT(instr->representation().IsInteger32());
       ASSERT(instr->value()->representation().IsDouble());
-      // TODO(jbramley): ARM64 can easily handle a double argument with frintm,
-      // but we're never asked for it here. At the moment, we fall back to the
-      // runtime if the result doesn't fit, like the other architectures.
       LOperand* input = UseRegisterAtStart(instr->value());
-      LMathFloor* result = new(zone()) LMathFloor(input);
-      return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+      if (instr->representation().IsInteger32()) {
+        LMathFloorI* result = new(zone()) LMathFloorI(input);
+        return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+      } else {
+        ASSERT(instr->representation().IsDouble());
+        LMathFloorD* result = new(zone()) LMathFloorD(input);
+        return DefineAsRegister(result);
+      }
     }
     case kMathLog: {
       ASSERT(instr->representation().IsDouble());
@@ -2483,14 +2466,16 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
       return DefineAsRegister(new(zone()) LMathPowHalf(input));
     }
     case kMathRound: {
-      ASSERT(instr->representation().IsInteger32());
       ASSERT(instr->value()->representation().IsDouble());
-      // TODO(jbramley): As with kMathFloor, we can probably handle double
-      // results fairly easily, but we are never asked for them.
       LOperand* input = UseRegister(instr->value());
-      LOperand* temp = FixedTemp(d24);  // Choosen arbitrarily.
-      LMathRound* result = new(zone()) LMathRound(input, temp);
-      return AssignEnvironment(DefineAsRegister(result));
+      if (instr->representation().IsInteger32()) {
+        LMathRoundI* result = new(zone()) LMathRoundI(input, FixedTemp(d24));
+        return AssignEnvironment(DefineAsRegister(result));
+      } else {
+        ASSERT(instr->representation().IsDouble());
+        LMathRoundD* result = new(zone()) LMathRoundD(input);
+        return DefineAsRegister(result);
+      }
     }
     case kMathSqrt: {
       ASSERT(instr->representation().IsDouble());
@@ -2560,8 +2545,10 @@ LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
 
 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
   LOperand* object = UseRegisterAtStart(instr->object());
-  LOperand* index = UseRegister(instr->index());
-  return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index));
+  LOperand* index = UseRegisterAndClobber(instr->index());
+  LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index);
+  LInstruction* result = DefineSameAsFirst(load);
+  return AssignPointerMap(result);
 }