diff --git a/src/compiler/representation-change.cc b/src/compiler/representation-change.cc
new file mode 100644
index 0000000..5dab60f
--- /dev/null
+++ b/src/compiler/representation-change.cc
@@ -0,0 +1,537 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/representation-change.h"
+
+#include <sstream>
+
+#include "src/base/bits.h"
+#include "src/code-factory.h"
+#include "src/compiler/machine-operator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+const char* Truncation::description() const {
+  switch (kind()) {
+    case TruncationKind::kNone:
+      return "no-value-use";
+    case TruncationKind::kBool:
+      return "truncate-to-bool";
+    case TruncationKind::kWord32:
+      return "truncate-to-word32";
+    case TruncationKind::kWord64:
+      return "truncate-to-word64";
+    case TruncationKind::kFloat32:
+      return "truncate-to-float32";
+    case TruncationKind::kFloat64:
+      return "truncate-to-float64";
+    case TruncationKind::kAny:
+      return "no-truncation";
+  }
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+// Partial order for truncations:
+//
+//  kWord64       kAny
+//     ^            ^
+//     \            |
+//      \         kFloat64  <--+
+//       \        ^    ^       |
+//        \       /    |       |
+//         kWord32  kFloat32  kBool
+//               ^     ^      ^
+//               \     |      /
+//                \    |     /
+//                 \   |    /
+//                  \  |   /
+//                   \ |  /
+//                   kNone
+
+// static
+Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
+                                                  TruncationKind rep2) {
+  if (LessGeneral(rep1, rep2)) return rep2;
+  if (LessGeneral(rep2, rep1)) return rep1;
+  // Handle the generalization of float64-representable values.
+  if (LessGeneral(rep1, TruncationKind::kFloat64) &&
+      LessGeneral(rep2, TruncationKind::kFloat64)) {
+    return TruncationKind::kFloat64;
+  }
+  // All other combinations are illegal.
+  FATAL("Tried to combine incompatible truncations");
+  return TruncationKind::kNone;
+}
+
+
+// static
+bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) {
+  switch (rep1) {
+    case TruncationKind::kNone:
+      return true;
+    case TruncationKind::kBool:
+      return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
+    case TruncationKind::kWord32:
+      return rep2 == TruncationKind::kWord32 ||
+             rep2 == TruncationKind::kWord64 ||
+             rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
+    case TruncationKind::kWord64:
+      return rep2 == TruncationKind::kWord64;
+    case TruncationKind::kFloat32:
+      return rep2 == TruncationKind::kFloat32 ||
+             rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
+    case TruncationKind::kFloat64:
+      return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
+    case TruncationKind::kAny:
+      return rep2 == TruncationKind::kAny;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+
+namespace {
+
+// TODO(titzer): should Word64 also be implicitly convertable to others?
+bool IsWord(MachineRepresentation rep) {
+  return rep == MachineRepresentation::kWord8 ||
+         rep == MachineRepresentation::kWord16 ||
+         rep == MachineRepresentation::kWord32;
+}
+
+}  // namespace
+
+
+// Changes representation from {output_rep} to {use_rep}. The {truncation}
+// parameter is only used for sanity checking - if the changer cannot figure
+// out signedness for the word32->float64 conversion, then we check that the
+// uses truncate to word32 (so they do not care about signedness).
+Node* RepresentationChanger::GetRepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type,
+    MachineRepresentation use_rep, Truncation truncation) {
+  if (output_rep == MachineRepresentation::kNone) {
+    // The output representation should be set.
+    return TypeError(node, output_rep, output_type, use_rep);
+  }
+  if (use_rep == output_rep) {
+    // Representations are the same. That's a no-op.
+    return node;
+  }
+  if (IsWord(use_rep) && IsWord(output_rep)) {
+    // Both are words less than or equal to 32-bits.
+    // Since loads of integers from memory implicitly sign or zero extend the
+    // value to the full machine word size and stores implicitly truncate,
+    // no representation change is necessary.
+    return node;
+  }
+  switch (use_rep) {
+    case MachineRepresentation::kTagged:
+      return GetTaggedRepresentationFor(node, output_rep, output_type);
+    case MachineRepresentation::kFloat32:
+      return GetFloat32RepresentationFor(node, output_rep, output_type,
+                                         truncation);
+    case MachineRepresentation::kFloat64:
+      return GetFloat64RepresentationFor(node, output_rep, output_type,
+                                         truncation);
+    case MachineRepresentation::kBit:
+      return GetBitRepresentationFor(node, output_rep, output_type);
+    case MachineRepresentation::kWord8:
+    case MachineRepresentation::kWord16:
+    case MachineRepresentation::kWord32:
+      return GetWord32RepresentationFor(node, output_rep, output_type);
+    case MachineRepresentation::kWord64:
+      return GetWord64RepresentationFor(node, output_rep, output_type);
+    case MachineRepresentation::kNone:
+      return node;
+  }
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+Node* RepresentationChanger::GetTaggedRepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kNumberConstant:
+    case IrOpcode::kHeapConstant:
+      return node;  // No change necessary.
+    case IrOpcode::kInt32Constant:
+      if (output_type->Is(Type::Signed32())) {
+        int32_t value = OpParameter<int32_t>(node);
+        return jsgraph()->Constant(value);
+      } else if (output_type->Is(Type::Unsigned32())) {
+        uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
+        return jsgraph()->Constant(static_cast<double>(value));
+      } else if (output_rep == MachineRepresentation::kBit) {
+        return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
+                                               : jsgraph()->TrueConstant();
+      } else {
+        return TypeError(node, output_rep, output_type,
+                         MachineRepresentation::kTagged);
+      }
+    case IrOpcode::kFloat64Constant:
+      return jsgraph()->Constant(OpParameter<double>(node));
+    case IrOpcode::kFloat32Constant:
+      return jsgraph()->Constant(OpParameter<float>(node));
+    default:
+      break;
+  }
+  // Select the correct X -> Tagged operator.
+  const Operator* op;
+  if (output_rep == MachineRepresentation::kBit) {
+    op = simplified()->ChangeBitToBool();
+  } else if (IsWord(output_rep)) {
+    if (output_type->Is(Type::Unsigned32())) {
+      op = simplified()->ChangeUint32ToTagged();
+    } else if (output_type->Is(Type::Signed32())) {
+      op = simplified()->ChangeInt32ToTagged();
+    } else {
+      return TypeError(node, output_rep, output_type,
+                       MachineRepresentation::kTagged);
+    }
+  } else if (output_rep ==
+             MachineRepresentation::kFloat32) {  // float32 -> float64 -> tagged
+    node = InsertChangeFloat32ToFloat64(node);
+    op = simplified()->ChangeFloat64ToTagged();
+  } else if (output_rep == MachineRepresentation::kFloat64) {
+    op = simplified()->ChangeFloat64ToTagged();
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kTagged);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::GetFloat32RepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type,
+    Truncation truncation) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kFloat64Constant:
+    case IrOpcode::kNumberConstant:
+      return jsgraph()->Float32Constant(
+          DoubleToFloat32(OpParameter<double>(node)));
+    case IrOpcode::kInt32Constant:
+      if (output_type->Is(Type::Unsigned32())) {
+        uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
+        return jsgraph()->Float32Constant(static_cast<float>(value));
+      } else {
+        int32_t value = OpParameter<int32_t>(node);
+        return jsgraph()->Float32Constant(static_cast<float>(value));
+      }
+    case IrOpcode::kFloat32Constant:
+      return node;  // No change necessary.
+    default:
+      break;
+  }
+  // Select the correct X -> Float32 operator.
+  const Operator* op;
+  if (output_rep == MachineRepresentation::kBit) {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kFloat32);
+  } else if (IsWord(output_rep)) {
+    if (output_type->Is(Type::Signed32())) {
+      op = machine()->ChangeInt32ToFloat64();
+    } else {
+      // Either the output is int32 or the uses only care about the
+      // low 32 bits (so we can pick int32 safely).
+      DCHECK(output_type->Is(Type::Unsigned32()) ||
+             truncation.TruncatesToWord32());
+      op = machine()->ChangeUint32ToFloat64();
+    }
+    // int32 -> float64 -> float32
+    node = jsgraph()->graph()->NewNode(op, node);
+    op = machine()->TruncateFloat64ToFloat32();
+  } else if (output_rep == MachineRepresentation::kTagged) {
+    op = simplified()->ChangeTaggedToFloat64();  // tagged -> float64 -> float32
+    node = jsgraph()->graph()->NewNode(op, node);
+    op = machine()->TruncateFloat64ToFloat32();
+  } else if (output_rep == MachineRepresentation::kFloat64) {
+    op = machine()->TruncateFloat64ToFloat32();
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kFloat32);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::GetFloat64RepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type,
+    Truncation truncation) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kNumberConstant:
+      return jsgraph()->Float64Constant(OpParameter<double>(node));
+    case IrOpcode::kInt32Constant:
+      if (output_type->Is(Type::Signed32())) {
+        int32_t value = OpParameter<int32_t>(node);
+        return jsgraph()->Float64Constant(value);
+      } else {
+        DCHECK(output_type->Is(Type::Unsigned32()));
+        uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
+        return jsgraph()->Float64Constant(static_cast<double>(value));
+      }
+    case IrOpcode::kFloat64Constant:
+      return node;  // No change necessary.
+    case IrOpcode::kFloat32Constant:
+      return jsgraph()->Float64Constant(OpParameter<float>(node));
+    default:
+      break;
+  }
+  // Select the correct X -> Float64 operator.
+  const Operator* op;
+  if (output_rep == MachineRepresentation::kBit) {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kFloat64);
+  } else if (IsWord(output_rep)) {
+    if (output_type->Is(Type::Signed32())) {
+      op = machine()->ChangeInt32ToFloat64();
+    } else {
+      // Either the output is int32 or the uses only care about the
+      // low 32 bits (so we can pick int32 safely).
+      DCHECK(output_type->Is(Type::Unsigned32()) ||
+             truncation.TruncatesToWord32());
+      op = machine()->ChangeUint32ToFloat64();
+    }
+  } else if (output_rep == MachineRepresentation::kTagged) {
+    op = simplified()->ChangeTaggedToFloat64();
+  } else if (output_rep == MachineRepresentation::kFloat32) {
+    op = machine()->ChangeFloat32ToFloat64();
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kFloat64);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
+  return jsgraph()->Int32Constant(DoubleToInt32(value));
+}
+
+
+Node* RepresentationChanger::GetWord32RepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kInt32Constant:
+      return node;  // No change necessary.
+    case IrOpcode::kFloat32Constant:
+      return MakeTruncatedInt32Constant(OpParameter<float>(node));
+    case IrOpcode::kNumberConstant:
+    case IrOpcode::kFloat64Constant:
+      return MakeTruncatedInt32Constant(OpParameter<double>(node));
+    default:
+      break;
+  }
+  // Select the correct X -> Word32 operator.
+  const Operator* op;
+  Type* type = NodeProperties::GetType(node);
+
+  if (output_rep == MachineRepresentation::kBit) {
+    return node;  // Sloppy comparison -> word32
+  } else if (output_rep == MachineRepresentation::kFloat64) {
+    // TODO(jarin) Use only output_type here, once we intersect it with the
+    // type inferred by the typer.
+    if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
+      op = machine()->ChangeFloat64ToUint32();
+    } else if (output_type->Is(Type::Signed32()) ||
+               type->Is(Type::Signed32())) {
+      op = machine()->ChangeFloat64ToInt32();
+    } else {
+      op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
+    }
+  } else if (output_rep == MachineRepresentation::kFloat32) {
+    node = InsertChangeFloat32ToFloat64(node);  // float32 -> float64 -> int32
+    if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
+      op = machine()->ChangeFloat64ToUint32();
+    } else if (output_type->Is(Type::Signed32()) ||
+               type->Is(Type::Signed32())) {
+      op = machine()->ChangeFloat64ToInt32();
+    } else {
+      op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
+    }
+  } else if (output_rep == MachineRepresentation::kTagged) {
+    if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
+      op = simplified()->ChangeTaggedToUint32();
+    } else if (output_type->Is(Type::Signed32()) ||
+               type->Is(Type::Signed32())) {
+      op = simplified()->ChangeTaggedToInt32();
+    } else {
+      node = InsertChangeTaggedToFloat64(node);
+      op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
+    }
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kWord32);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::GetBitRepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kHeapConstant: {
+      Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node);
+      DCHECK(value.is_identical_to(factory()->true_value()) ||
+             value.is_identical_to(factory()->false_value()));
+      return jsgraph()->Int32Constant(
+          value.is_identical_to(factory()->true_value()) ? 1 : 0);
+    }
+    default:
+      break;
+  }
+  // Select the correct X -> Bit operator.
+  const Operator* op;
+  if (output_rep == MachineRepresentation::kTagged) {
+    op = simplified()->ChangeBoolToBit();
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kBit);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::GetWord64RepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type) {
+  if (output_rep == MachineRepresentation::kBit) {
+    return node;  // Sloppy comparison -> word64
+  }
+  // Can't really convert Word64 to anything else. Purported to be internal.
+  return TypeError(node, output_rep, output_type,
+                   MachineRepresentation::kWord64);
+}
+
+
+const Operator* RepresentationChanger::Int32OperatorFor(
+    IrOpcode::Value opcode) {
+  switch (opcode) {
+    case IrOpcode::kNumberAdd:
+      return machine()->Int32Add();
+    case IrOpcode::kNumberSubtract:
+      return machine()->Int32Sub();
+    case IrOpcode::kNumberMultiply:
+      return machine()->Int32Mul();
+    case IrOpcode::kNumberDivide:
+      return machine()->Int32Div();
+    case IrOpcode::kNumberModulus:
+      return machine()->Int32Mod();
+    case IrOpcode::kNumberBitwiseOr:
+      return machine()->Word32Or();
+    case IrOpcode::kNumberBitwiseXor:
+      return machine()->Word32Xor();
+    case IrOpcode::kNumberBitwiseAnd:
+      return machine()->Word32And();
+    case IrOpcode::kNumberEqual:
+      return machine()->Word32Equal();
+    case IrOpcode::kNumberLessThan:
+      return machine()->Int32LessThan();
+    case IrOpcode::kNumberLessThanOrEqual:
+      return machine()->Int32LessThanOrEqual();
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+const Operator* RepresentationChanger::Uint32OperatorFor(
+    IrOpcode::Value opcode) {
+  switch (opcode) {
+    case IrOpcode::kNumberAdd:
+      return machine()->Int32Add();
+    case IrOpcode::kNumberSubtract:
+      return machine()->Int32Sub();
+    case IrOpcode::kNumberMultiply:
+      return machine()->Int32Mul();
+    case IrOpcode::kNumberDivide:
+      return machine()->Uint32Div();
+    case IrOpcode::kNumberModulus:
+      return machine()->Uint32Mod();
+    case IrOpcode::kNumberEqual:
+      return machine()->Word32Equal();
+    case IrOpcode::kNumberLessThan:
+      return machine()->Uint32LessThan();
+    case IrOpcode::kNumberLessThanOrEqual:
+      return machine()->Uint32LessThanOrEqual();
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+const Operator* RepresentationChanger::Float64OperatorFor(
+    IrOpcode::Value opcode) {
+  switch (opcode) {
+    case IrOpcode::kNumberAdd:
+      return machine()->Float64Add();
+    case IrOpcode::kNumberSubtract:
+      return machine()->Float64Sub();
+    case IrOpcode::kNumberMultiply:
+      return machine()->Float64Mul();
+    case IrOpcode::kNumberDivide:
+      return machine()->Float64Div();
+    case IrOpcode::kNumberModulus:
+      return machine()->Float64Mod();
+    case IrOpcode::kNumberEqual:
+      return machine()->Float64Equal();
+    case IrOpcode::kNumberLessThan:
+      return machine()->Float64LessThan();
+    case IrOpcode::kNumberLessThanOrEqual:
+      return machine()->Float64LessThanOrEqual();
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+Node* RepresentationChanger::TypeError(Node* node,
+                                       MachineRepresentation output_rep,
+                                       Type* output_type,
+                                       MachineRepresentation use) {
+  type_error_ = true;
+  if (!testing_type_errors_) {
+    std::ostringstream out_str;
+    out_str << output_rep << " (";
+    output_type->PrintTo(out_str, Type::SEMANTIC_DIM);
+    out_str << ")";
+
+    std::ostringstream use_str;
+    use_str << use;
+
+    V8_Fatal(__FILE__, __LINE__,
+             "RepresentationChangerError: node #%d:%s of "
+             "%s cannot be changed to %s",
+             node->id(), node->op()->mnemonic(), out_str.str().c_str(),
+             use_str.str().c_str());
+  }
+  return node;
+}
+
+
+Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
+  return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
+}
+
+
+Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
+  return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
+                                     node);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
