// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/globals.h"  // Needed here to get TARGET_ARCH_DBC.
#if defined(TARGET_ARCH_DBC)

#include "vm/compiler/backend/il.h"

#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/backend/locations.h"
#include "vm/compiler/backend/range_analysis.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/cpu.h"
#include "vm/dart_entry.h"
#include "vm/object_store.h"
#include "vm/parser.h"
#include "vm/simulator.h"
#include "vm/stack_frame.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"

#define __ compiler->assembler()->

namespace dart {

DECLARE_FLAG(bool, emit_edge_counters);
DECLARE_FLAG(int, optimization_counter_threshold);

// List of instructions that are still unimplemented by DBC backend.
#define FOR_EACH_UNIMPLEMENTED_INSTRUCTION(M)                                  \
  M(BinaryInt32Op)                                                             \
  M(BinaryUint32Op)                                                            \
  M(BoxInt64)                                                                  \
  M(CheckCondition)                                                            \
  M(DoubleToInteger)                                                           \
  M(ExtractNthOutput)                                                          \
  M(GuardFieldClass)                                                           \
  M(GuardFieldLength)                                                          \
  M(GuardFieldType)                                                            \
  M(IfThenElse)                                                                \
  M(Int32ToDouble)                                                             \
  M(LoadCodeUnits)                                                             \
  M(ShiftUint32Op)                                                             \
  M(SpeculativeShiftUint32Op)                                                  \
  M(TruncDivMod)                                                               \
  M(UnaryUint32Op)                                                             \
  M(UnboxedIntConverter)

// List of instructions that are not used by DBC.
// Things we aren't planning to implement for DBC:
// - Unboxed SIMD,
// - Unboxed Mint,
// - Optimized RegExps,
// - Precompilation.
#define FOR_EACH_UNREACHABLE_INSTRUCTION(M)                                    \
  M(CaseInsensitiveCompareUC16)                                                \
  M(GenericCheckBound)                                                         \
  M(CheckNull)                                                                 \
  M(IndirectGoto)                                                              \
  M(Int64ToDouble)                                                             \
  M(BinaryInt64Op)                                                             \
  M(ShiftInt64Op)                                                              \
  M(SpeculativeShiftInt64Op)                                                   \
  M(UnaryInt64Op)                                                              \
  M(CheckedSmiOp)                                                              \
  M(CheckedSmiComparison)                                                      \
  M(SimdOp)

// Location summaries actually are not used by the unoptimizing DBC compiler
// because we don't allocate any registers.
static LocationSummary* CreateLocationSummary(
    Zone* zone,
    intptr_t num_inputs,
    Location output = Location::NoLocation(),
    LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall,
    intptr_t num_temps = 0) {
  LocationSummary* locs =
      new (zone) LocationSummary(zone, num_inputs, num_temps, contains_call);
  for (intptr_t i = 0; i < num_inputs; i++) {
    locs->set_in(i, (contains_call == LocationSummary::kNoCall)
                        ? Location::RequiresRegister()
                        : Location::RegisterLocation(i));
  }
  for (intptr_t i = 0; i < num_temps; i++) {
    locs->set_temp(i, Location::RequiresRegister());
  }
  if (!output.IsInvalid()) {
    // For instructions that call we default to returning result in R0.
    locs->set_out(0, output);
  }
  return locs;
}

#define DEFINE_MAKE_LOCATION_SUMMARY(Name, ...)                                \
  LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt)      \
      const {                                                                  \
    return CreateLocationSummary(zone, __VA_ARGS__);                           \
  }

#define EMIT_NATIVE_CODE(Name, ...)                                            \
  DEFINE_MAKE_LOCATION_SUMMARY(Name, __VA_ARGS__);                             \
  void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler)

#define DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name)                       \
  LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt)      \
      const {                                                                  \
    if (!opt) UNIMPLEMENTED();                                                 \
    return NULL;                                                               \
  }

#define DEFINE_UNREACHABLE_MAKE_LOCATION_SUMMARY(Name)                         \
  LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt)      \
      const {                                                                  \
    UNREACHABLE();                                                             \
    return NULL;                                                               \
  }

#define DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name)                            \
  void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler) {              \
    UNIMPLEMENTED();                                                           \
  }

#define DEFINE_UNREACHABLE_EMIT_NATIVE_CODE(Name)                              \
  void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler) {              \
    UNREACHABLE();                                                             \
  }

#define DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(Name)                            \
  void Name##Instr::EmitBranchCode(FlowGraphCompiler*, BranchInstr*) {         \
    UNIMPLEMENTED();                                                           \
  }                                                                            \
  Condition Name##Instr::EmitComparisonCode(FlowGraphCompiler*,                \
                                            BranchLabels) {                    \
    UNIMPLEMENTED();                                                           \
    return NEXT_IS_TRUE;                                                       \
  }

#define DEFINE_UNIMPLEMENTED(Name)                                             \
  DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name)                             \
  DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name)

FOR_EACH_UNIMPLEMENTED_INSTRUCTION(DEFINE_UNIMPLEMENTED)

#undef DEFINE_UNIMPLEMENTED

#define DEFINE_UNREACHABLE(Name)                                               \
  DEFINE_UNREACHABLE_MAKE_LOCATION_SUMMARY(Name)                               \
  DEFINE_UNREACHABLE_EMIT_NATIVE_CODE(Name)

FOR_EACH_UNREACHABLE_INSTRUCTION(DEFINE_UNREACHABLE)

#undef DEFINE_UNREACHABLE

// Only used in AOT compilation.
DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(CheckedSmiComparison)

EMIT_NATIVE_CODE(InstanceOf,
                 3,
                 Location::SameAsFirstInput(),
                 LocationSummary::kCall) {
  SubtypeTestCache& test_cache = SubtypeTestCache::Handle();
  if (!type().IsVoidType() && type().IsInstantiated()) {
    test_cache = SubtypeTestCache::New();
  }

  if (compiler->is_optimizing()) {
    __ Push(locs()->in(0).reg());  // Value.
    __ Push(locs()->in(1).reg());  // Instantiator type arguments.
    __ Push(locs()->in(2).reg());  // Function type arguments.
  }

  __ PushConstant(type());
  __ PushConstant(test_cache);
  __ InstanceOf();
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                 token_pos());
  compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
  if (compiler->is_optimizing()) {
    __ PopLocal(locs()->out(0).reg());
  }
}

DEFINE_MAKE_LOCATION_SUMMARY(AssertAssignable,
                             3,
                             Location::SameAsFirstInput(),
                             LocationSummary::kCall);

DEFINE_MAKE_LOCATION_SUMMARY(AssertSubtype,
                             2,
                             Location::NoLocation(),
                             LocationSummary::kCall);

EMIT_NATIVE_CODE(AssertBoolean,
                 1,
                 Location::SameAsFirstInput(),
                 LocationSummary::kCall) {
  if (compiler->is_optimizing()) {
    __ Push(locs()->in(0).reg());
  }
  __ AssertBoolean(0);
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                 token_pos());
  compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
  if (compiler->is_optimizing()) {
    __ Drop1();
  }
}

EMIT_NATIVE_CODE(PolymorphicInstanceCall,
                 0,
                 Location::RegisterLocation(0),
                 LocationSummary::kCall) {
  const Array& arguments_descriptor =
      Array::Handle(instance_call()->GetArgumentsDescriptor());
  const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);

  // Push the target onto the stack.
  const intptr_t length = targets_.length();
  if (!Utils::IsUint(8, length)) {
    Unsupported(compiler);
    UNREACHABLE();
  }
  bool using_ranges = false;
  for (intptr_t i = 0; i < length; i++) {
    if (!targets_[i].IsSingleCid()) {
      using_ranges = true;
      break;
    }
  }

  if (using_ranges) {
    __ PushPolymorphicInstanceCallByRange(
        instance_call()->ArgumentCountWithoutTypeArgs(), length);
  } else {
    __ PushPolymorphicInstanceCall(
        instance_call()->ArgumentCountWithoutTypeArgs(), length);
  }
  for (intptr_t i = 0; i < length; i++) {
    const Function& target = *targets_.TargetAt(i)->target;

    __ Nop(compiler->ToEmbeddableCid(targets_[i].cid_start, this));
    if (using_ranges) {
      __ Nop(compiler->ToEmbeddableCid(1 + targets_[i].Extent(), this));
    }
    __ Nop(__ AddConstant(target));
  }
  compiler->EmitDeopt(deopt_id(), ICData::kDeoptPolymorphicInstanceCallTestFail,
                      0);

  // Call the function.
  __ StaticCall(instance_call()->ArgumentCount(), argdesc_kidx);
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                 instance_call()->token_pos());
  compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
  __ PopLocal(locs()->out(0).reg());
}

EMIT_NATIVE_CODE(LoadIndexedUnsafe, 1, Location::RegisterLocation(0)) {
  ASSERT(base_reg() == FPREG);

  ASSERT(offset_ % kWordSize == 0);
  const intptr_t slot_offset = offset_ / kWordSize;
  ASSERT(Utils::IsInt(8, slot_offset));

  if (compiler->is_optimizing()) {
    const Register index = locs()->in(0).reg();
    const Register result = locs()->out(0).reg();
    __ LoadFpRelativeSlotOpt(result, index, slot_offset);
  } else {
    __ LoadFpRelativeSlot(slot_offset);
  }
}

EMIT_NATIVE_CODE(StoreIndexedUnsafe, 2, Location::RegisterLocation(0)) {
  ASSERT(base_reg() == FPREG);

  ASSERT(offset_ % kWordSize == 0);
  const intptr_t slot_offset = offset_ / kWordSize;
  ASSERT(Utils::IsInt(8, slot_offset));

  if (compiler->is_optimizing()) {
    const Register index = locs()->in(kIndexPos).reg();
    const Register value = locs()->in(kValuePos).reg();
    __ StoreFpRelativeSlotOpt(value, index, slot_offset);
  } else {
    __ StoreFpRelativeSlot(slot_offset);
  }
}

EMIT_NATIVE_CODE(TailCall,
                 1,
                 Location::NoLocation(),
                 LocationSummary::kNoCall,
                 1) {
  if (compiler->is_optimizing()) {
    const Register arg_desc = locs()->in(0).reg();
    const Register temp = locs()->temp(0).reg();
    __ LoadConstant(temp, code());
    __ TailCallOpt(arg_desc, temp);
  } else {
    __ PushConstant(code());
    __ TailCall();
  }
}

EMIT_NATIVE_CODE(Stop, 0) {
  __ Stop(message());
}

EMIT_NATIVE_CODE(CheckStackOverflow,
                 0,
                 Location::NoLocation(),
                 LocationSummary::kCall) {
  if (compiler->ForceSlowPathForStackOverflow()) {
    __ CheckStackAlwaysExit();
  } else {
    __ CheckStack();
  }
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                 token_pos());
  compiler->RecordAfterCall(this, FlowGraphCompiler::kNoResult);
}

EMIT_NATIVE_CODE(PushArgument, 1) {
  if (compiler->is_optimizing()) {
    __ Push(locs()->in(0).reg());
  }
}

EMIT_NATIVE_CODE(LoadLocal, 0) {
  ASSERT(!compiler->is_optimizing());
  const intptr_t slot_index =
      compiler::target::frame_layout.FrameSlotForVariable(&local());
  __ Push(LocalVarIndex(0, slot_index));
}

EMIT_NATIVE_CODE(StoreLocal, 0) {
  ASSERT(!compiler->is_optimizing());
  const intptr_t slot_index =
      compiler::target::frame_layout.FrameSlotForVariable(&local());
  if (HasTemp()) {
    __ StoreLocal(LocalVarIndex(0, slot_index));
  } else {
    __ PopLocal(LocalVarIndex(0, slot_index));
  }
}

EMIT_NATIVE_CODE(LoadClassId, 1, Location::RequiresRegister()) {
  if (compiler->is_optimizing()) {
    __ LoadClassId(locs()->out(0).reg(), locs()->in(0).reg());
  } else {
    __ LoadClassIdTOS();
  }
}

EMIT_NATIVE_CODE(Constant, 0, Location::RequiresRegister()) {
  if (compiler->is_optimizing()) {
    if (locs()->out(0).IsRegister()) {
      __ LoadConstant(locs()->out(0).reg(), value());
    }
  } else {
    __ PushConstant(value());
  }
}

EMIT_NATIVE_CODE(UnboxedConstant, 0, Location::RequiresRegister()) {
  // The register allocator drops constant definitions that have no uses.
  if (locs()->out(0).IsInvalid()) {
    return;
  }
  if (representation_ != kUnboxedDouble) {
    Unsupported(compiler);
    UNREACHABLE();
  }
  const Register result = locs()->out(0).reg();
  if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) {
    __ BitXor(result, result, result);
  } else {
    __ LoadConstant(result, value());
    __ UnboxDouble(result, result);
  }
}

EMIT_NATIVE_CODE(Return, 1) {
  if (compiler->is_optimizing()) {
    __ Return(locs()->in(0).reg());
  } else {
    __ ReturnTOS();
  }
}

LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(

    Zone* zone,
    bool opt) const {
  const intptr_t kNumInputs = 1;
  const intptr_t kNumTemps = 1;
  LocationSummary* locs = new (zone)
      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
  for (intptr_t i = 0; i < kNumInputs; i++) {
    locs->set_in(i, Location::RequiresRegister());
  }
  for (intptr_t i = 0; i < kNumTemps; i++) {
    locs->set_temp(i, Location::RequiresRegister());
  }
  return locs;
}

void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
  if (compiler->is_optimizing()) {
    __ LoadConstant(locs()->temp(0).reg(),
                    Field::ZoneHandle(field().Original()));
    __ StoreField(locs()->temp(0).reg(),
                  Field::static_value_offset() / kWordSize,
                  locs()->in(0).reg());
  } else {
    const intptr_t kidx = __ AddConstant(field());
    __ StoreStaticTOS(kidx);
  }
}

EMIT_NATIVE_CODE(LoadStaticField, 1, Location::RequiresRegister()) {
  if (compiler->is_optimizing()) {
    __ LoadField(locs()->out(0).reg(), locs()->in(0).reg(),
                 Field::static_value_offset() / kWordSize);
  } else {
    const intptr_t kidx = __ AddConstant(StaticField());
    __ PushStatic(kidx);
  }
}

EMIT_NATIVE_CODE(InitStaticField,
                 1,
                 Location::NoLocation(),
                 LocationSummary::kCall) {
  if (compiler->is_optimizing()) {
    __ Push(locs()->in(0).reg());
    __ InitStaticTOS();
  } else {
    __ InitStaticTOS();
  }
  compiler->RecordAfterCall(this, FlowGraphCompiler::kNoResult);
}

EMIT_NATIVE_CODE(ClosureCall,
                 1,
                 Location::RegisterLocation(0),
                 LocationSummary::kCall) {
  if (compiler->is_optimizing()) {
    __ Push(locs()->in(0).reg());
  }

  const Array& arguments_descriptor =
      Array::ZoneHandle(GetArgumentsDescriptor());
  const intptr_t argdesc_kidx =
      compiler->assembler()->AddConstant(arguments_descriptor);
  __ StaticCall(ArgumentCount(), argdesc_kidx);
  compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
  if (compiler->is_optimizing()) {
    __ PopLocal(locs()->out(0).reg());
  }
}

static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
                                  Condition true_condition,
                                  BranchLabels labels) {
  if (true_condition == NEXT_IS_TRUE) {
    // NEXT_IS_TRUE indicates that the preceeding test expects the true case
    // to be in the subsequent instruction, which it skips if the test fails.
    __ Jump(labels.true_label);
    if (labels.fall_through != labels.false_label) {
      // The preceeding Jump instruction will be skipped if the test fails.
      // If we aren't falling through to the false case, then we have to do
      // a Jump to it here.
      __ Jump(labels.false_label);
    }
  } else {
    ASSERT(true_condition == NEXT_IS_FALSE);
    // NEXT_IS_FALSE indicates that the preceeding test has been flipped and
    // expects the false case to be in the subsequent instruction, which it
    // skips if the test succeeds.
    __ Jump(labels.false_label);
    if (labels.fall_through != labels.true_label) {
      // The preceeding Jump instruction will be skipped if the test succeeds.
      // If we aren't falling through to the true case, then we have to do
      // a Jump to it here.
      __ Jump(labels.true_label);
    }
  }
}

Condition StrictCompareInstr::GetNextInstructionCondition(
    FlowGraphCompiler* compiler,
    BranchLabels labels) {
  return (labels.fall_through == labels.false_label) ? NEXT_IS_TRUE
                                                     : NEXT_IS_FALSE;
}

Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                 BranchLabels labels) {
  ASSERT((kind() == Token::kNE_STRICT) || (kind() == Token::kEQ_STRICT));

  Token::Kind comparison;
  Condition condition;
  if (labels.fall_through == labels.false_label) {
    condition = NEXT_IS_TRUE;
    comparison = kind();
  } else {
    // Flip comparison to save a jump.
    condition = NEXT_IS_FALSE;
    comparison =
        (kind() == Token::kEQ_STRICT) ? Token::kNE_STRICT : Token::kEQ_STRICT;
  }

  if (!compiler->is_optimizing()) {
    const SimulatorBytecode::Opcode eq_op =
        needs_number_check() ? SimulatorBytecode::kIfEqStrictNumTOS
                             : SimulatorBytecode::kIfEqStrictTOS;
    const SimulatorBytecode::Opcode ne_op =
        needs_number_check() ? SimulatorBytecode::kIfNeStrictNumTOS
                             : SimulatorBytecode::kIfNeStrictTOS;
    __ Emit(comparison == Token::kEQ_STRICT ? eq_op : ne_op);
  } else {
    const SimulatorBytecode::Opcode eq_op =
        needs_number_check() ? SimulatorBytecode::kIfEqStrictNum
                             : SimulatorBytecode::kIfEqStrict;
    const SimulatorBytecode::Opcode ne_op =
        needs_number_check() ? SimulatorBytecode::kIfNeStrictNum
                             : SimulatorBytecode::kIfNeStrict;
    __ Emit(SimulatorBytecode::Encode(
        (comparison == Token::kEQ_STRICT) ? eq_op : ne_op, locs()->in(0).reg(),
        locs()->in(1).reg()));
  }

  if (needs_number_check() && token_pos().IsReal()) {
    compiler->RecordSafepoint(locs());
    compiler->AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id_,
                                   token_pos());
  }

  return condition;
}

DEFINE_MAKE_LOCATION_SUMMARY(StrictCompare,
                             2,
                             Location::RequiresRegister(),
                             needs_number_check() ? LocationSummary::kCall
                                                  : LocationSummary::kNoCall)

void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                     BranchInstr* branch) {
  BranchLabels labels = compiler->CreateBranchLabels(branch);
  Condition true_condition = EmitComparisonCode(compiler, labels);
  if (true_condition != INVALID_CONDITION) {
    EmitBranchOnCondition(compiler, true_condition, labels);
  }
}

void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
  Label is_true, is_false;
  BranchLabels labels = {&is_true, &is_false, &is_false};
  Condition true_condition =
      this->GetNextInstructionCondition(compiler, labels);
  if (true_condition == INVALID_CONDITION || !compiler->is_optimizing() ||
      is_true.IsLinked() || is_false.IsLinked()) {
    Condition actual_condition = EmitComparisonCode(compiler, labels);
    ASSERT(actual_condition == true_condition);
    if (true_condition != INVALID_CONDITION) {
      EmitBranchOnCondition(compiler, true_condition, labels);
    }
    Label done;
    __ Bind(&is_false);
    __ PushConstant(Bool::False());
    __ Jump(&done);
    __ Bind(&is_true);
    __ PushConstant(Bool::True());
    __ Bind(&done);
  } else {
    const Register result = this->locs()->out(0).reg();
    bool next_is_true = true_condition == NEXT_IS_TRUE;
    __ LoadConstant(result, Bool::Get(!next_is_true));
    Condition actual_condition = EmitComparisonCode(compiler, labels);
    ASSERT(actual_condition == true_condition);
    // Although we have a condition to branch on, the comparison code may also
    // have contained a direct branch to one of the labels, so they may need to
    // be bound.
    if (next_is_true && is_true.IsLinked()) {
      __ Bind(&is_true);
    } else if (!next_is_true && is_false.IsLinked()) {
      __ Bind(&is_false);
    }
    // This instruction is conditionally skipped by EmitComparisonCode.
    __ LoadConstant(result, Bool::Get(next_is_true));
    // If the other label is linked we need to bind it and emit code that loads
    // the correct boolean.
    if ((next_is_true && is_false.IsLinked()) ||
        (!next_is_true && is_true.IsLinked())) {
      Label done;
      __ Jump(&done);
      __ Bind(next_is_true ? &is_false : &is_true);
      __ LoadConstant(result, Bool::Get(!next_is_true));
      __ Bind(&done);
    }
  }
}

LocationSummary* BranchInstr::MakeLocationSummary(

    Zone* zone,
    bool opt) const {
  comparison()->InitializeLocationSummary(zone, opt);
  if (!comparison()->HasLocs()) {
    return NULL;
  }
  // Branches don't produce a result.
  comparison()->locs()->set_out(0, Location::NoLocation());
  return comparison()->locs();
}

void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
  comparison()->EmitBranchCode(compiler, this);
}

EMIT_NATIVE_CODE(Goto, 0) {
  if (!compiler->is_optimizing()) {
    // Add a deoptimization descriptor for deoptimizing instructions that
    // may be inserted before this instruction.
    compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
                                   TokenPosition::kNoSource);
  }
  if (HasParallelMove()) {
    compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
  }
  // We can fall through if the successor is the next block in the list.
  // Otherwise, we need a jump.
  if (!compiler->CanFallThroughTo(successor())) {
    __ Jump(compiler->GetJumpLabel(successor()));
  }
}

Condition TestSmiInstr::GetNextInstructionCondition(FlowGraphCompiler* compiler,
                                                    BranchLabels labels) {
  ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
  return (kind() == Token::kEQ) ? NEXT_IS_TRUE : NEXT_IS_FALSE;
}

Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                           BranchLabels labels) {
  ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
  Register left = locs()->in(0).reg();
  Register right = locs()->in(1).reg();
  __ TestSmi(left, right);
  return (kind() == Token::kEQ) ? NEXT_IS_TRUE : NEXT_IS_FALSE;
}

DEFINE_MAKE_LOCATION_SUMMARY(TestSmi,
                             2,
                             Location::RequiresRegister(),
                             LocationSummary::kNoCall)

Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                            BranchLabels labels) {
  ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
  const Register value = locs()->in(0).reg();
  const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;

  const ZoneGrowableArray<intptr_t>& data = cid_results();
  const intptr_t num_cases = data.length() / 2;
  ASSERT(num_cases <= 255);
  __ TestCids(value, num_cases);

  bool result = false;
  for (intptr_t i = 0; i < data.length(); i += 2) {
    const intptr_t test_cid = data[i];
    result = data[i + 1] == true_result;
    __ Nop(result ? 1 : 0, compiler->ToEmbeddableCid(test_cid, this));
  }

  // No match found, deoptimize or default action.
  if (CanDeoptimize()) {
    compiler->EmitDeopt(deopt_id(), ICData::kDeoptTestCids,
                        licm_hoisted_ ? ICData::kHoisted : 0);
  } else {
    // If the cid is not in the list, jump to the opposite label from the cids
    // that are in the list.  These must be all the same (see asserts in the
    // constructor).
    Label* target = result ? labels.false_label : labels.true_label;
    __ Jump(target);
  }

  return NEXT_IS_TRUE;
}

Condition TestCidsInstr::GetNextInstructionCondition(
    FlowGraphCompiler* compiler,
    BranchLabels labels) {
  return NEXT_IS_TRUE;
}

DEFINE_MAKE_LOCATION_SUMMARY(TestCids,
                             1,
                             Location::RequiresRegister(),
                             LocationSummary::kNoCall)

EMIT_NATIVE_CODE(CreateArray,
                 2,
                 Location::RequiresRegister(),
                 LocationSummary::kCall) {
  if (compiler->is_optimizing()) {
    const Register length = locs()->in(kLengthPos).reg();
    const Register type_arguments = locs()->in(kElementTypePos).reg();
    const Register out = locs()->out(0).reg();
    __ CreateArrayOpt(out, length, type_arguments);
    __ Push(type_arguments);
    __ Push(length);
    __ CreateArrayTOS();
    compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
    __ PopLocal(out);
  } else {
    __ CreateArrayTOS();
    compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
  }
}

EMIT_NATIVE_CODE(StoreIndexed,
                 3,
                 Location::NoLocation(),
                 LocationSummary::kNoCall,
                 1) {
  if (!compiler->is_optimizing()) {
    ASSERT(class_id() == kArrayCid);
    __ StoreIndexedTOS();
    return;
  }
  const Register array = locs()->in(kArrayPos).reg();
  const Register index = locs()->in(kIndexPos).reg();
  const Register value = locs()->in(kValuePos).reg();
  const Register temp = locs()->temp(0).reg();
  switch (class_id()) {
    case kArrayCid:
      __ StoreIndexed(array, index, value);
      break;
    case kTypedDataUint8ArrayCid:
    case kTypedDataInt8ArrayCid:
    case kExternalOneByteStringCid:
    case kExternalTypedDataUint8ArrayCid:
      ASSERT(index_scale() == 1);
      if (IsExternal()) {
        __ StoreIndexedUntaggedUint8(array, index, value);
      } else {
        __ StoreIndexedUint8(array, index, value);
      }
      break;
    case kOneByteStringCid:
      ASSERT(index_scale() == 1);
      __ StoreIndexedOneByteString(array, index, value);
      break;
    case kTypedDataInt32ArrayCid:
    case kTypedDataUint32ArrayCid: {
      if (IsExternal()) {
        if (index_scale() == 1) {
          __ StoreIndexedUntaggedUint32(array, index, value);
        } else {
          __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
          __ StoreIndexedUntaggedUint32(array, temp, value);
        }
      } else {
        if (index_scale() == 1) {
          __ StoreIndexedUint32(array, index, value);
        } else {
          __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
          __ StoreIndexedUint32(array, temp, value);
        }
      }
      break;
    }
    case kTypedDataFloat32ArrayCid:
      if (IsExternal()) {
        if (index_scale() == 1) {
          __ StoreIndexedUntaggedFloat32(array, index, value);
        } else {
          __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
          __ StoreIndexedUntaggedFloat32(array, temp, value);
        }
      } else {
        if (index_scale() == 1) {
          __ StoreIndexedFloat32(array, index, value);
        } else if (index_scale() == 4) {
          __ StoreIndexed4Float32(array, index, value);
        } else {
          __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
          __ StoreIndexedFloat32(array, temp, value);
        }
      }
      break;
    case kTypedDataFloat64ArrayCid:
      if (IsExternal()) {
        if (index_scale() == 1) {
          __ StoreIndexedUntaggedFloat64(array, index, value);
        } else {
          __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
          __ StoreIndexedUntaggedFloat64(array, temp, value);
        }
      } else {
        if (index_scale() == 1) {
          __ StoreIndexedFloat64(array, index, value);
        } else if (index_scale() == 8) {
          __ StoreIndexed8Float64(array, index, value);
        } else {
          __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
          __ StoreIndexedFloat64(array, temp, value);
        }
      }
      break;
    default:
      Unsupported(compiler);
      UNREACHABLE();
      break;
  }
}

EMIT_NATIVE_CODE(LoadIndexed,
                 2,
                 Location::RequiresRegister(),
                 LocationSummary::kNoCall,
                 1) {
  if (compiler->is_optimizing()) {
    ASSERT(compiler->is_optimizing());
    const Register array = locs()->in(0).reg();
    const Register index = locs()->in(1).reg();
    const Register temp = locs()->temp(0).reg();
    const Register result = locs()->out(0).reg();
    switch (class_id()) {
      case kArrayCid:
      case kImmutableArrayCid:
        __ LoadIndexed(result, array, index);
        break;
      case kTypedDataUint8ArrayCid:
      case kTypedDataUint8ClampedArrayCid:
      case kExternalOneByteStringCid:
      case kExternalTypedDataUint8ArrayCid:
      case kExternalTypedDataUint8ClampedArrayCid:
        ASSERT(index_scale() == 1);
        if (IsExternal()) {
          __ LoadIndexedUntaggedUint8(result, array, index);
        } else {
          __ LoadIndexedUint8(result, array, index);
        }
        break;
      case kTypedDataInt8ArrayCid:
        ASSERT(index_scale() == 1);
        if (IsExternal()) {
          __ LoadIndexedUntaggedInt8(result, array, index);
        } else {
          __ LoadIndexedInt8(result, array, index);
        }
        break;
      case kOneByteStringCid:
        ASSERT(index_scale() == 1);
        __ LoadIndexedOneByteString(result, array, index);
        break;
      case kTwoByteStringCid:
        if (index_scale() != 2) {
          // TODO(zra): Fix-up index.
          Unsupported(compiler);
          UNREACHABLE();
        }
        if (IsExternal()) {
          Unsupported(compiler);
          UNREACHABLE();
        }
        __ LoadIndexedTwoByteString(result, array, index);
        break;
      case kTypedDataInt32ArrayCid:
        ASSERT(representation() == kUnboxedInt32);
        if (IsExternal()) {
          if (index_scale() == 1) {
            __ LoadIndexedUntaggedInt32(result, array, index);
          } else {
            __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
            __ LoadIndexedUntaggedInt32(result, array, temp);
          }
        } else {
          if (index_scale() == 1) {
            __ LoadIndexedInt32(result, array, index);
          } else {
            __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
            __ LoadIndexedInt32(result, array, temp);
          }
        }
        break;
      case kTypedDataUint32ArrayCid:
        ASSERT(representation() == kUnboxedUint32);
        if (IsExternal()) {
          if (index_scale() == 1) {
            __ LoadIndexedUntaggedUint32(result, array, index);
          } else {
            __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
            __ LoadIndexedUntaggedUint32(result, array, temp);
          }
        } else {
          if (index_scale() == 1) {
            __ LoadIndexedUint32(result, array, index);
          } else {
            __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
            __ LoadIndexedUint32(result, array, temp);
          }
        }
        break;
      case kTypedDataFloat32ArrayCid:
        if (IsExternal()) {
          if (index_scale() == 1) {
            __ LoadIndexedUntaggedFloat32(result, array, index);
          } else {
            __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
            __ LoadIndexedUntaggedFloat32(result, array, temp);
          }
        } else {
          if (index_scale() == 1) {
            __ LoadIndexedFloat32(result, array, index);
          } else if (index_scale() == 4) {
            __ LoadIndexed4Float32(result, array, index);
          } else {
            __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
            __ LoadIndexedFloat32(result, array, temp);
          }
        }
        break;
      case kTypedDataFloat64ArrayCid:
        if (IsExternal()) {
          if (index_scale() == 1) {
            __ LoadIndexedUntaggedFloat64(result, array, index);
          } else {
            __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
            __ LoadIndexedUntaggedFloat64(result, array, temp);
          }
        } else {
          if (index_scale() == 1) {
            __ LoadIndexedFloat64(result, array, index);
          } else if (index_scale() == 8) {
            __ LoadIndexed8Float64(result, array, index);
          } else {
            __ ShlImm(temp, index, Utils::ShiftForPowerOfTwo(index_scale()));
            __ LoadIndexedFloat64(result, array, temp);
          }
        }
        break;
      default:
        Unsupported(compiler);
        UNREACHABLE();
        break;
    }
  } else {
    switch (class_id()) {
      case kArrayCid:
      case kImmutableArrayCid:
        __ LoadIndexedTOS();
        break;
      default:
        Unsupported(compiler);
        UNREACHABLE();
        break;
    }
  }
}

EMIT_NATIVE_CODE(StringInterpolate,
                 1,
                 Location::RegisterLocation(0),
                 LocationSummary::kCall) {
  if (compiler->is_optimizing()) {
    __ Push(locs()->in(0).reg());
  }
  const intptr_t kTypeArgsLen = 0;
  const intptr_t kArgumentCount = 1;
  const Array& arguments_descriptor = Array::Handle(ArgumentsDescriptor::New(
      kTypeArgsLen, kArgumentCount, Object::null_array()));
  __ PushConstant(CallFunction());
  const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);
  __ StaticCall(kArgumentCount, argdesc_kidx);
  // Note: can't use RecordAfterCall here because
  // StringInterpolateInstr::ArgumentCount() is 0. However
  // internally it does a call with 1 argument which needs to
  // be reflected in the lazy deoptimization environment.
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                 token_pos());
  compiler->RecordAfterCallHelper(token_pos(), deopt_id(), kArgumentCount,
                                  FlowGraphCompiler::kHasResult, locs());
  if (compiler->is_optimizing()) {
    __ PopLocal(locs()->out(0).reg());
  }
}

void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
  UNREACHABLE();
}

EMIT_NATIVE_CODE(NativeCall,
                 0,
                 Location::NoLocation(),
                 LocationSummary::kCall) {
  SetupNative();

  const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());

  NativeFunctionWrapper trampoline;
  NativeFunction function;
  if (link_lazily()) {
    trampoline = &NativeEntry::BootstrapNativeCallWrapper;
    function = reinterpret_cast<NativeFunction>(&NativeEntry::LinkNativeCall);
  } else {
    if (is_bootstrap_native()) {
      trampoline = &NativeEntry::BootstrapNativeCallWrapper;
    } else if (is_auto_scope()) {
      trampoline = &NativeEntry::AutoScopeNativeCallWrapper;
    } else {
      trampoline = &NativeEntry::NoScopeNativeCallWrapper;
    }
    function = native_c_function();
  }

  const ExternalLabel trampoline_label(reinterpret_cast<uword>(trampoline));
  const intptr_t trampoline_kidx =
      __ object_pool_builder().FindNativeFunctionWrapper(
          &trampoline_label, ObjectPool::Patchability::kPatchable);
  const ExternalLabel label(reinterpret_cast<uword>(function));
  const intptr_t target_kidx = __ object_pool_builder().FindNativeFunction(
      &label, ObjectPool::Patchability::kPatchable);
  const intptr_t argc_tag_kidx =
      __ object_pool_builder().FindImmediate(static_cast<uword>(argc_tag));
  __ NativeCall(trampoline_kidx, target_kidx, argc_tag_kidx);
  compiler->RecordSafepoint(locs());
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
                                 token_pos());
}

EMIT_NATIVE_CODE(OneByteStringFromCharCode,
                 1,
                 Location::RequiresRegister(),
                 LocationSummary::kNoCall) {
  ASSERT(compiler->is_optimizing());
  const Register char_code = locs()->in(0).reg();  // Char code is a smi.
  const Register result = locs()->out(0).reg();
  __ OneByteStringFromCharCode(result, char_code);
}

EMIT_NATIVE_CODE(StringToCharCode,
                 1,
                 Location::RequiresRegister(),
                 LocationSummary::kNoCall) {
  ASSERT(cid_ == kOneByteStringCid);
  const Register str = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();  // Result char code is a smi.
  __ StringToCharCode(result, str);
}

EMIT_NATIVE_CODE(AllocateObject,
                 0,
                 Location::RequiresRegister(),
                 LocationSummary::kCall) {
  if (ArgumentCount() == 1) {
    // Allocate with type arguments.
    if (compiler->is_optimizing()) {
      // If we're optimizing, try a streamlined fastpath.
      const intptr_t instance_size = cls().instance_size();
      Isolate* isolate = Isolate::Current();
      if (Heap::IsAllocatableInNewSpace(instance_size) &&
          !cls().TraceAllocation(isolate)) {
        uint32_t tags = 0;
        tags = RawObject::SizeTag::update(instance_size, tags);
        ASSERT(cls().id() != kIllegalCid);
        tags = RawObject::ClassIdTag::update(cls().id(), tags);
        if (Smi::IsValid(tags)) {
          const intptr_t tags_kidx =
              __ AddConstant(Smi::Handle(Smi::New(tags)));
          __ AllocateTOpt(locs()->out(0).reg(), tags_kidx);
          __ Nop(cls().type_arguments_field_offset());
        }
      }
      __ PushConstant(cls());
      __ AllocateT();
      compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
                                     token_pos());
      compiler->RecordSafepoint(locs());
      __ PopLocal(locs()->out(0).reg());
    } else {
      __ PushConstant(cls());
      __ AllocateT();
      compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
                                     token_pos());
      compiler->RecordSafepoint(locs());
    }
  } else if (compiler->is_optimizing()) {
    // If we're optimizing, try a streamlined fastpath.
    const intptr_t instance_size = cls().instance_size();
    Isolate* isolate = Isolate::Current();
    if (Heap::IsAllocatableInNewSpace(instance_size) &&
        !cls().TraceAllocation(isolate)) {
      uword tags = 0;
      tags = RawObject::SizeTag::update(instance_size, tags);
      ASSERT(cls().id() != kIllegalCid);
      tags = RawObject::ClassIdTag::update(cls().id(), tags);
      // tags also has the initial zero hash code on 64 bit.
      if (Smi::IsValid(tags)) {
        const intptr_t tags_kidx = __ AddConstant(Smi::Handle(Smi::New(tags)));
        __ AllocateOpt(locs()->out(0).reg(), tags_kidx);
      }
    }
    const intptr_t kidx = __ AddConstant(cls());
    __ Allocate(kidx);
    compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
                                   token_pos());
    compiler->RecordSafepoint(locs());
    __ PopLocal(locs()->out(0).reg());
  } else {
    const intptr_t kidx = __ AddConstant(cls());
    __ Allocate(kidx);
    compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
                                   token_pos());
    compiler->RecordSafepoint(locs());
  }
}

EMIT_NATIVE_CODE(StoreInstanceField, 2) {
  ASSERT(OffsetInBytes() % kWordSize == 0);
  if (compiler->is_optimizing()) {
    const Register value = locs()->in(1).reg();
    const Register instance = locs()->in(0).reg();
    if (Utils::IsInt(8, OffsetInBytes() / kWordSize)) {
      __ StoreField(instance, OffsetInBytes() / kWordSize, value);
    } else {
      __ StoreFieldExt(instance, value);
      __ Nop(OffsetInBytes() / kWordSize);
    }
  } else {
    __ StoreFieldTOS(OffsetInBytes() / kWordSize);
  }
}

EMIT_NATIVE_CODE(LoadField, 1, Location::RequiresRegister()) {
  ASSERT(OffsetInBytes() % kWordSize == 0);
  if (compiler->is_optimizing()) {
    const Register result = locs()->out(0).reg();
    const Register instance = locs()->in(0).reg();
    if (Utils::IsInt(8, OffsetInBytes() / kWordSize)) {
      __ LoadField(result, instance, OffsetInBytes() / kWordSize);
    } else {
      __ LoadFieldExt(result, instance);
      __ Nop(OffsetInBytes() / kWordSize);
    }
  } else {
    __ LoadFieldTOS(OffsetInBytes() / kWordSize);
  }
}

EMIT_NATIVE_CODE(LoadUntagged, 1, Location::RequiresRegister()) {
  const Register obj = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  if (object()->definition()->representation() == kUntagged) {
    __ LoadUntagged(result, obj, offset() / kWordSize);
  } else {
    ASSERT(object()->definition()->representation() == kTagged);
    __ LoadField(result, obj, offset() / kWordSize);
  }
}

EMIT_NATIVE_CODE(BooleanNegate, 1, Location::RequiresRegister()) {
  if (compiler->is_optimizing()) {
    __ BooleanNegate(locs()->out(0).reg(), locs()->in(0).reg());
  } else {
    __ BooleanNegateTOS();
  }
}

EMIT_NATIVE_CODE(AllocateContext,
                 0,
                 Location::RequiresRegister(),
                 LocationSummary::kCall) {
  ASSERT(!compiler->is_optimizing());
  __ AllocateContext(num_context_variables());
  compiler->RecordSafepoint(locs());
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
                                 token_pos());
}

EMIT_NATIVE_CODE(AllocateUninitializedContext,
                 0,
                 Location::RequiresRegister(),
                 LocationSummary::kCall) {
  ASSERT(compiler->is_optimizing());
  __ AllocateUninitializedContext(locs()->out(0).reg(),
                                  num_context_variables());
  __ AllocateContext(num_context_variables());
  compiler->RecordSafepoint(locs());
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
                                 token_pos());
  __ PopLocal(locs()->out(0).reg());
}

EMIT_NATIVE_CODE(CloneContext,
                 1,
                 Location::RequiresRegister(),
                 LocationSummary::kCall) {
  if (compiler->is_optimizing()) {
    __ Push(locs()->in(0).reg());
  }
  __ CloneContext();
  compiler->RecordSafepoint(locs());
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
                                 token_pos());
  if (compiler->is_optimizing()) {
    __ PopLocal(locs()->out(0).reg());
  }
}

EMIT_NATIVE_CODE(CatchBlockEntry, 0) {
  __ Bind(compiler->GetJumpLabel(this));
  compiler->AddExceptionHandler(catch_try_index(), try_index(),
                                compiler->assembler()->CodeSize(),
                                handler_token_pos(), is_generated(),
                                catch_handler_types_, needs_stacktrace());
  // On lazy deoptimization we patch the optimized code here to enter the
  // deoptimization stub.
  const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId());
  if (compiler->is_optimizing()) {
    compiler->AddDeoptIndexAtCall(deopt_id);
  } else {
    compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
                                   TokenPosition::kNoSource);
  }
  if (HasParallelMove()) {
    compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
  }
  __ SetFrame(compiler->StackSize());

  if (!compiler->is_optimizing()) {
    if (raw_exception_var_ != nullptr) {
      __ MoveSpecial(
          LocalVarIndex(0, compiler::target::frame_layout.FrameSlotForVariable(
                               raw_exception_var_)),
          Simulator::kExceptionSpecialIndex);
    }
    if (raw_stacktrace_var_ != nullptr) {
      __ MoveSpecial(
          LocalVarIndex(0, compiler::target::frame_layout.FrameSlotForVariable(
                               raw_stacktrace_var_)),
          Simulator::kStackTraceSpecialIndex);
    }
  }
}

EMIT_NATIVE_CODE(Throw, 0, Location::NoLocation(), LocationSummary::kCall) {
  __ Throw(0);
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                 token_pos());
  compiler->RecordAfterCall(this, FlowGraphCompiler::kNoResult);
  __ Trap();
}

EMIT_NATIVE_CODE(ReThrow, 0, Location::NoLocation(), LocationSummary::kCall) {
  compiler->SetNeedsStackTrace(catch_try_index());
  __ Throw(1);
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                 token_pos());
  compiler->RecordAfterCall(this, FlowGraphCompiler::kNoResult);
  __ Trap();
}

EMIT_NATIVE_CODE(InstantiateType,
                 2,
                 Location::RequiresRegister(),
                 LocationSummary::kCall) {
  if (compiler->is_optimizing()) {
    __ Push(locs()->in(0).reg());  // Instantiator type arguments.
    __ Push(locs()->in(1).reg());  // Function type arguments.
  }
  __ InstantiateType(__ AddConstant(type()));
  compiler->RecordSafepoint(locs());
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                 token_pos());
  if (compiler->is_optimizing()) {
    __ PopLocal(locs()->out(0).reg());
  }
}

EMIT_NATIVE_CODE(InstantiateTypeArguments,
                 2,
                 Location::RequiresRegister(),
                 LocationSummary::kCall) {
  if (compiler->is_optimizing()) {
    __ Push(locs()->in(0).reg());  // Instantiator type arguments.
    __ Push(locs()->in(1).reg());  // Function type arguments.
  }
  __ InstantiateTypeArgumentsTOS(
      type_arguments().IsRawWhenInstantiatedFromRaw(type_arguments().Length()),
      __ AddConstant(type_arguments()));
  compiler->RecordSafepoint(locs());
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                 token_pos());
  if (compiler->is_optimizing()) {
    __ PopLocal(locs()->out(0).reg());
  }
}

void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
  __ DebugStep();
  compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos());
}

void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
  BlockEntryInstr* entry = normal_entry();
  if (entry == nullptr) entry = osr_entry();

  if (!compiler->CanFallThroughTo(entry)) {
    __ Jump(compiler->GetJumpLabel(entry));
  }
}

LocationSummary* Instruction::MakeCallSummary(Zone* zone) {
  LocationSummary* result =
      new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
  // TODO(vegorov) support allocating out registers for calls.
  // Currently we require them to be fixed.
  result->set_out(0, Location::RegisterLocation(0));
  return result;
}

CompileType BinaryUint32OpInstr::ComputeType() const {
  return CompileType::Int();
}

CompileType ShiftUint32OpInstr::ComputeType() const {
  return CompileType::Int();
}

CompileType SpeculativeShiftUint32OpInstr::ComputeType() const {
  return CompileType::Int();
}

CompileType UnaryUint32OpInstr::ComputeType() const {
  return CompileType::Int();
}

CompileType LoadIndexedInstr::ComputeType() const {
  switch (class_id_) {
    case kArrayCid:
    case kImmutableArrayCid:
      return CompileType::Dynamic();

    case kTypedDataFloat32ArrayCid:
    case kTypedDataFloat64ArrayCid:
      return CompileType::FromCid(kDoubleCid);
    case kTypedDataFloat32x4ArrayCid:
      return CompileType::FromCid(kFloat32x4Cid);
    case kTypedDataInt32x4ArrayCid:
      return CompileType::FromCid(kInt32x4Cid);
    case kTypedDataFloat64x2ArrayCid:
      return CompileType::FromCid(kFloat64x2Cid);

    case kTypedDataInt8ArrayCid:
    case kTypedDataUint8ArrayCid:
    case kTypedDataUint8ClampedArrayCid:
    case kExternalTypedDataUint8ArrayCid:
    case kExternalTypedDataUint8ClampedArrayCid:
    case kTypedDataInt16ArrayCid:
    case kTypedDataUint16ArrayCid:
    case kOneByteStringCid:
    case kTwoByteStringCid:
    case kExternalOneByteStringCid:
    case kExternalTwoByteStringCid:
      return CompileType::FromCid(kSmiCid);

    case kTypedDataInt32ArrayCid:
    case kTypedDataUint32ArrayCid:
      return CompileType::Int();

    default:
      UNREACHABLE();
      return CompileType::Dynamic();
  }
}

Representation LoadIndexedInstr::representation() const {
  switch (class_id_) {
    case kArrayCid:
    case kImmutableArrayCid:
    case kTypedDataInt8ArrayCid:
    case kTypedDataUint8ArrayCid:
    case kTypedDataUint8ClampedArrayCid:
    case kExternalTypedDataUint8ArrayCid:
    case kExternalTypedDataUint8ClampedArrayCid:
    case kTypedDataInt16ArrayCid:
    case kTypedDataUint16ArrayCid:
    case kOneByteStringCid:
    case kTwoByteStringCid:
    case kExternalOneByteStringCid:
    case kExternalTwoByteStringCid:
      return kTagged;
    case kTypedDataInt32ArrayCid:
      return kUnboxedInt32;
    case kTypedDataUint32ArrayCid:
      return kUnboxedUint32;
    case kTypedDataFloat32ArrayCid:
    case kTypedDataFloat64ArrayCid:
      return kUnboxedDouble;
    case kTypedDataInt32x4ArrayCid:
      return kUnboxedInt32x4;
    case kTypedDataFloat32x4ArrayCid:
      return kUnboxedFloat32x4;
    case kTypedDataFloat64x2ArrayCid:
      return kUnboxedFloat64x2;
    default:
      UNREACHABLE();
      return kTagged;
  }
}

Representation StoreIndexedInstr::RequiredInputRepresentation(
    intptr_t idx) const {
  // Array can be a Dart object or a pointer to external data.
  if (idx == 0) {
    return kNoRepresentation;  // Flexible input representation.
  }
  if (idx == 1) {
    return kTagged;  // Index is a smi.
  }
  ASSERT(idx == 2);
  switch (class_id_) {
    case kArrayCid:
    case kOneByteStringCid:
    case kTwoByteStringCid:
    case kExternalOneByteStringCid:
    case kExternalTwoByteStringCid:
    case kTypedDataInt8ArrayCid:
    case kTypedDataUint8ArrayCid:
    case kExternalTypedDataUint8ArrayCid:
    case kTypedDataUint8ClampedArrayCid:
    case kExternalTypedDataUint8ClampedArrayCid:
    case kTypedDataInt16ArrayCid:
    case kTypedDataUint16ArrayCid:
      return kTagged;
    case kTypedDataInt32ArrayCid:
      return kUnboxedInt32;
    case kTypedDataUint32ArrayCid:
      return kUnboxedUint32;
    case kTypedDataFloat32ArrayCid:
    case kTypedDataFloat64ArrayCid:
      return kUnboxedDouble;
    case kTypedDataFloat32x4ArrayCid:
      return kUnboxedFloat32x4;
    case kTypedDataInt32x4ArrayCid:
      return kUnboxedInt32x4;
    case kTypedDataFloat64x2ArrayCid:
      return kUnboxedFloat64x2;
    default:
      UNREACHABLE();
      return kTagged;
  }
}

void Environment::DropArguments(intptr_t argc) {
#if defined(DEBUG)
  // Check that we are in the backend - register allocation has been run.
  ASSERT(locations_ != NULL);

  // Check that we are only dropping a valid number of instructions from the
  // environment.
  ASSERT(argc <= values_.length());
#endif
  values_.TruncateTo(values_.length() - argc);
}

EMIT_NATIVE_CODE(CheckSmi, 1) {
  __ CheckSmi(locs()->in(0).reg());
  compiler->EmitDeopt(deopt_id(), ICData::kDeoptCheckSmi,
                      licm_hoisted_ ? ICData::kHoisted : 0);
}

EMIT_NATIVE_CODE(CheckEitherNonSmi, 2) {
  const Register left = locs()->in(0).reg();
  const Register right = locs()->in(1).reg();
  __ CheckEitherNonSmi(left, right);
  compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinaryDoubleOp,
                      licm_hoisted_ ? ICData::kHoisted : 0);
}

EMIT_NATIVE_CODE(CheckClassId, 1) {
  if (cids_.IsSingleCid()) {
    __ CheckClassId(locs()->in(0).reg(),
                    compiler->ToEmbeddableCid(cids_.cid_start, this));
  } else {
    __ CheckClassIdRange(locs()->in(0).reg(),
                         compiler->ToEmbeddableCid(cids_.cid_start, this));
    __ Nop(compiler->ToEmbeddableCid(cids_.Extent(), this));
  }
  compiler->EmitDeopt(deopt_id(), ICData::kDeoptCheckClass);
}

EMIT_NATIVE_CODE(CheckClass, 1) {
  const Register value = locs()->in(0).reg();
  if (IsNullCheck()) {
    ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull());
    if (IsDeoptIfNull()) {
      __ IfEqNull(value);
    } else {
      __ IfNeNull(value);
    }
  } else {
    ASSERT(!cids_.IsMonomorphic() || !cids_.HasClassId(kSmiCid));
    const intptr_t may_be_smi = cids_.HasClassId(kSmiCid) ? 1 : 0;
    bool is_bit_test = false;
    intptr_t cid_mask = 0;
    if (IsBitTest()) {
      cid_mask = ComputeCidMask();
      is_bit_test = Smi::IsValid(cid_mask);
    }
    if (is_bit_test) {
      intptr_t min = cids_.ComputeLowestCid();
      __ CheckBitTest(value, may_be_smi);
      __ Nop(compiler->ToEmbeddableCid(min, this));
      __ Nop(__ AddConstant(Smi::Handle(Smi::New(cid_mask))));
    } else {
      bool using_ranges = false;
      int smi_adjustment = 0;
      int length = cids_.length();
      for (intptr_t i = 0; i < length; i++) {
        if (!cids_[i].IsSingleCid()) {
          using_ranges = true;
        } else if (cids_[i].cid_start == kSmiCid) {
          ASSERT(cids_[i].cid_end == kSmiCid);  // We are in the else clause.
          ASSERT(smi_adjustment == 0);
          smi_adjustment = 1;
        }
      }

      if (!Utils::IsUint(8, length)) {
        Unsupported(compiler);
        UNREACHABLE();
      }
      if (using_ranges) {
        __ CheckCidsByRange(value, may_be_smi, (length - smi_adjustment) * 2);
      } else {
        __ CheckCids(value, may_be_smi, length - smi_adjustment);
      }
      for (intptr_t i = 0; i < length; i++) {
        intptr_t cid_start = cids_[i].cid_start;
        intptr_t cid_end = cids_[i].cid_end;
        if (cid_start == kSmiCid && cid_end == kSmiCid) {
          ASSERT(smi_adjustment == 1);
          continue;
        }
        __ Nop(compiler->ToEmbeddableCid(cid_start, this));
        if (using_ranges) {
          __ Nop(compiler->ToEmbeddableCid(1 + cids_[i].Extent(), this));
        }
      }
    }
  }
  compiler->EmitDeopt(deopt_id(), ICData::kDeoptCheckClass,
                      licm_hoisted_ ? ICData::kHoisted : 0);
}

EMIT_NATIVE_CODE(BinarySmiOp, 2, Location::RequiresRegister()) {
  if (compiler->is_optimizing()) {
    const Register left = locs()->in(0).reg();
    const Register right = locs()->in(1).reg();
    const Register out = locs()->out(0).reg();
    const bool can_deopt = CanDeoptimize();
    bool needs_nop = false;
    switch (op_kind()) {
      case Token::kADD:
        __ Add(out, left, right);
        needs_nop = true;
        break;
      case Token::kSUB:
        __ Sub(out, left, right);
        needs_nop = true;
        break;
      case Token::kMUL:
        __ Mul(out, left, right);
        needs_nop = true;
        break;
      case Token::kTRUNCDIV:
        ASSERT(can_deopt);
        __ Div(out, left, right);
        break;
      case Token::kBIT_AND:
        ASSERT(!can_deopt);
        __ BitAnd(out, left, right);
        break;
      case Token::kBIT_OR:
        ASSERT(!can_deopt);
        __ BitOr(out, left, right);
        break;
      case Token::kBIT_XOR:
        ASSERT(!can_deopt);
        __ BitXor(out, left, right);
        break;
      case Token::kMOD:
        __ Mod(out, left, right);
        needs_nop = true;
        break;
      case Token::kSHR:
        __ Shr(out, left, right);
        needs_nop = true;
        break;
      case Token::kSHL:
        __ Shl(out, left, right);
        needs_nop = true;
        break;
      default:
        UNREACHABLE();
    }
    if (can_deopt) {
      compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinarySmiOp);
    } else if (needs_nop) {
      __ Nop(0);
    }
  } else {
    switch (op_kind()) {
      case Token::kADD:
        __ SmiAddTOS();
        break;
      case Token::kSUB:
        __ SmiSubTOS();
        break;
      case Token::kMUL:
        __ SmiMulTOS();
        break;
      case Token::kBIT_AND:
        __ SmiBitAndTOS();
        break;
      default:
        UNIMPLEMENTED();
    }
  }
}

EMIT_NATIVE_CODE(UnarySmiOp, 1, Location::RequiresRegister()) {
  switch (op_kind()) {
    case Token::kNEGATE: {
      __ Neg(locs()->out(0).reg(), locs()->in(0).reg());
      compiler->EmitDeopt(deopt_id(), ICData::kDeoptUnaryOp);
      break;
    }
    case Token::kBIT_NOT:
      __ BitNot(locs()->out(0).reg(), locs()->in(0).reg());
      break;
    default:
      UNREACHABLE();
      break;
  }
}

EMIT_NATIVE_CODE(Box, 1, Location::RequiresRegister(), LocationSummary::kCall) {
  ASSERT(from_representation() == kUnboxedDouble);
  const Register value = locs()->in(0).reg();
  const Register out = locs()->out(0).reg();
  const intptr_t instance_size = compiler->double_class().instance_size();
  Isolate* isolate = Isolate::Current();
  ASSERT(Heap::IsAllocatableInNewSpace(instance_size));
  if (!compiler->double_class().TraceAllocation(isolate)) {
    uword tags = 0;
    tags = RawObject::SizeTag::update(instance_size, tags);
    tags = RawObject::ClassIdTag::update(compiler->double_class().id(), tags);
    // tags also has the initial zero hash code on 64 bit.
    if (Smi::IsValid(tags)) {
      const intptr_t tags_kidx = __ AddConstant(Smi::Handle(Smi::New(tags)));
      __ AllocateOpt(out, tags_kidx);
    }
  }
  const intptr_t kidx = __ AddConstant(compiler->double_class());
  __ Allocate(kidx);
  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
                                 token_pos());
  compiler->RecordSafepoint(locs());
  __ PopLocal(out);
  __ WriteIntoDouble(out, value);
}

EMIT_NATIVE_CODE(Unbox, 1, Location::RequiresRegister()) {
  ASSERT(representation() == kUnboxedDouble);
  const intptr_t value_cid = value()->Type()->ToCid();
  const intptr_t box_cid = BoxCid();
  const Register box = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  if (value_cid == box_cid) {
    __ UnboxDouble(result, box);
  } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
    __ SmiToDouble(result, box);
  } else if ((value()->Type()->ToNullableCid() == box_cid) &&
             value()->Type()->is_nullable()) {
    __ IfEqNull(box);
    compiler->EmitDeopt(GetDeoptId(), ICData::kDeoptCheckClass);
    __ UnboxDouble(result, box);
  } else {
    __ CheckedUnboxDouble(result, box);
    compiler->EmitDeopt(GetDeoptId(), ICData::kDeoptCheckClass);
  }
}

EMIT_NATIVE_CODE(UnboxInteger32, 1, Location::RequiresRegister()) {
#if defined(ARCH_IS_64_BIT)
  const Register out = locs()->out(0).reg();
  const Register value = locs()->in(0).reg();
  const bool may_truncate = is_truncating() || !CanDeoptimize();
  __ UnboxInt32(out, value, may_truncate);
  if (CanDeoptimize()) {
    compiler->EmitDeopt(GetDeoptId(), ICData::kDeoptUnboxInteger);
  } else {
    __ Nop(0);
  }
#else
  Unsupported(compiler);
  UNREACHABLE();
#endif  // defined(ARCH_IS_64_BIT)
}

EMIT_NATIVE_CODE(BoxInteger32, 1, Location::RequiresRegister()) {
#if defined(ARCH_IS_64_BIT)
  const Register out = locs()->out(0).reg();
  const Register value = locs()->in(0).reg();
  if (from_representation() == kUnboxedInt32) {
    __ BoxInt32(out, value);
  } else {
    ASSERT(from_representation() == kUnboxedUint32);
    __ BoxUint32(out, value);
  }
#else
  Unsupported(compiler);
  UNREACHABLE();
#endif  // defined(ARCH_IS_64_BIT)
}

EMIT_NATIVE_CODE(DoubleToSmi, 1, Location::RequiresRegister()) {
  const Register value = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  __ DoubleToSmi(result, value);
  compiler->EmitDeopt(deopt_id(), ICData::kDeoptDoubleToSmi);
}

EMIT_NATIVE_CODE(SmiToDouble, 1, Location::RequiresRegister()) {
  const Register value = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  __ SmiToDouble(result, value);
}

EMIT_NATIVE_CODE(BinaryDoubleOp, 2, Location::RequiresRegister()) {
  const Register left = locs()->in(0).reg();
  const Register right = locs()->in(1).reg();
  const Register result = locs()->out(0).reg();
  switch (op_kind()) {
    case Token::kADD:
      __ DAdd(result, left, right);
      break;
    case Token::kSUB:
      __ DSub(result, left, right);
      break;
    case Token::kMUL:
      __ DMul(result, left, right);
      break;
    case Token::kDIV:
      __ DDiv(result, left, right);
      break;
    default:
      UNREACHABLE();
  }
}

Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                BranchLabels labels) {
  ASSERT(compiler->is_optimizing());
  const Register value = locs()->in(0).reg();
  switch (op_kind()) {
    case MethodRecognizer::kDouble_getIsNaN:
      __ DoubleIsNaN(value);
      break;
    case MethodRecognizer::kDouble_getIsInfinite:
      __ DoubleIsInfinite(value);
      break;
    default:
      UNREACHABLE();
  }
  const bool is_negated = kind() != Token::kEQ;
  return is_negated ? NEXT_IS_FALSE : NEXT_IS_TRUE;
}

Condition DoubleTestOpInstr::GetNextInstructionCondition(
    FlowGraphCompiler* compiler,
    BranchLabels labels) {
  const bool is_negated = kind() != Token::kEQ;
  return is_negated ? NEXT_IS_FALSE : NEXT_IS_TRUE;
}

DEFINE_MAKE_LOCATION_SUMMARY(DoubleTestOp, 1, Location::RequiresRegister())

EMIT_NATIVE_CODE(UnaryDoubleOp, 1, Location::RequiresRegister()) {
  const Register value = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  __ DNeg(result, value);
}

EMIT_NATIVE_CODE(MathUnary, 1, Location::RequiresRegister()) {
  const Register value = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  if (kind() == MathUnaryInstr::kSqrt) {
    __ DSqrt(result, value);
  } else if (kind() == MathUnaryInstr::kDoubleSquare) {
    __ DMul(result, value, value);
  } else {
    Unsupported(compiler);
    UNREACHABLE();
  }
}

EMIT_NATIVE_CODE(DoubleToDouble, 1, Location::RequiresRegister()) {
  const Register in = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  switch (recognized_kind()) {
    case MethodRecognizer::kDoubleTruncate:
      __ DTruncate(result, in);
      break;
    case MethodRecognizer::kDoubleFloor:
      __ DFloor(result, in);
      break;
    case MethodRecognizer::kDoubleCeil:
      __ DCeil(result, in);
      break;
    default:
      UNREACHABLE();
  }
}

EMIT_NATIVE_CODE(DoubleToFloat, 1, Location::RequiresRegister()) {
  const Register in = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  __ DoubleToFloat(result, in);
}

EMIT_NATIVE_CODE(FloatToDouble, 1, Location::RequiresRegister()) {
  const Register in = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  __ FloatToDouble(result, in);
}

EMIT_NATIVE_CODE(InvokeMathCFunction,
                 InputCount(),
                 Location::RequiresRegister()) {
  const Register left = locs()->in(0).reg();
  const Register result = locs()->out(0).reg();
  if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
    const Register right = locs()->in(1).reg();
    __ DPow(result, left, right);
  } else if (recognized_kind() == MethodRecognizer::kDoubleMod) {
    const Register right = locs()->in(1).reg();
    __ DMod(result, left, right);
  } else if (recognized_kind() == MethodRecognizer::kMathSin) {
    __ DSin(result, left);
  } else if (recognized_kind() == MethodRecognizer::kMathCos) {
    __ DCos(result, left);
  } else {
    Unsupported(compiler);
    UNREACHABLE();
  }
}

EMIT_NATIVE_CODE(MathMinMax, 2, Location::RequiresRegister()) {
  ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
         (op_kind() == MethodRecognizer::kMathMax));
  const Register left = locs()->in(0).reg();
  const Register right = locs()->in(1).reg();
  const Register result = locs()->out(0).reg();
  if (result_cid() == kDoubleCid) {
    if (op_kind() == MethodRecognizer::kMathMin) {
      __ DMin(result, left, right);
    } else {
      __ DMax(result, left, right);
    }
  } else {
    ASSERT(result_cid() == kSmiCid);
    if (op_kind() == MethodRecognizer::kMathMin) {
      __ Min(result, left, right);
    } else {
      __ Max(result, left, right);
    }
  }
}

static SimulatorBytecode::Opcode OpcodeForSmiCondition(Token::Kind kind) {
  switch (kind) {
    case Token::kEQ:
      return SimulatorBytecode::kIfEqStrict;
    case Token::kNE:
      return SimulatorBytecode::kIfNeStrict;
    case Token::kLT:
      return SimulatorBytecode::kIfLt;
    case Token::kGT:
      return SimulatorBytecode::kIfGt;
    case Token::kLTE:
      return SimulatorBytecode::kIfLe;
    case Token::kGTE:
      return SimulatorBytecode::kIfGe;
    default:
      UNREACHABLE();
      return SimulatorBytecode::kTrap;
  }
}

static SimulatorBytecode::Opcode OpcodeForDoubleCondition(Token::Kind kind) {
  switch (kind) {
    case Token::kEQ:
      return SimulatorBytecode::kIfDEq;
    case Token::kNE:
      return SimulatorBytecode::kIfDNe;
    case Token::kLT:
      return SimulatorBytecode::kIfDLt;
    case Token::kGT:
      return SimulatorBytecode::kIfDGt;
    case Token::kLTE:
      return SimulatorBytecode::kIfDLe;
    case Token::kGTE:
      return SimulatorBytecode::kIfDGe;
    default:
      UNREACHABLE();
      return SimulatorBytecode::kTrap;
  }
}

static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
                                     LocationSummary* locs,
                                     Token::Kind kind,
                                     BranchLabels labels) {
  Token::Kind comparison = kind;
  Condition condition = NEXT_IS_TRUE;
  if (labels.fall_through != labels.false_label) {
    // If we aren't falling through to the false label, we can save a Jump
    // instruction in the case that the true case is the fall through by
    // negating the sense of the test such that the instruction following the
    // test is the Jump to the false label.  In the case where both labels are
    // null we don't negate the sense of the test.
    condition = NEXT_IS_FALSE;
    comparison = Token::NegateComparison(kind);
  }
  if (compiler->is_optimizing()) {
    const Register left = locs->in(0).reg();
    const Register right = locs->in(1).reg();
    __ Emit(SimulatorBytecode::Encode(OpcodeForSmiCondition(comparison), left,
                                      right));
    return condition;
  } else {
    switch (kind) {
      case Token::kEQ:
        __ IfEqStrictTOS();
        break;
      case Token::kNE:
        __ IfNeStrictTOS();
        break;
      case Token::kLT:
        __ IfSmiLtTOS();
        break;
      case Token::kLTE:
        __ IfSmiLeTOS();
        break;
      case Token::kGT:
        __ IfSmiGtTOS();
        break;
      case Token::kGTE:
        __ IfSmiGeTOS();
        break;
      default:
        UNIMPLEMENTED();
    }
    return condition;
  }
}

static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
                                        LocationSummary* locs,
                                        Token::Kind kind) {
  const Register left = locs->in(0).reg();
  const Register right = locs->in(1).reg();
  Token::Kind comparison = kind;
  // For double comparisons we can't flip the condition like with smi
  // comparisons because of NaN which will compare false for all except !=
  // operations.
  // TODO(fschneider): Change the block order instead in DBC so that the
  // false block in always the fall-through block.
  Condition condition = NEXT_IS_TRUE;
  __ Emit(SimulatorBytecode::Encode(OpcodeForDoubleCondition(comparison), left,
                                    right));
  return condition;
}

Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                   BranchLabels labels) {
  if (operation_cid() == kSmiCid) {
    return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
  } else {
    ASSERT(operation_cid() == kDoubleCid);
    return EmitDoubleComparisonOp(compiler, locs(), kind());
  }
}

Condition EqualityCompareInstr::GetNextInstructionCondition(
    FlowGraphCompiler* compiler,
    BranchLabels labels) {
  if (operation_cid() == kSmiCid) {
    return (labels.fall_through != labels.false_label) ? NEXT_IS_FALSE
                                                       : NEXT_IS_TRUE;
  } else {
    ASSERT(operation_cid() == kDoubleCid);
    return NEXT_IS_TRUE;
  }
}

DEFINE_MAKE_LOCATION_SUMMARY(EqualityCompare, 2, Location::RequiresRegister());

Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                BranchLabels labels) {
  if (operation_cid() == kSmiCid) {
    return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
  } else {
    ASSERT(operation_cid() == kDoubleCid);
    return EmitDoubleComparisonOp(compiler, locs(), kind());
  }
}

Condition RelationalOpInstr::GetNextInstructionCondition(
    FlowGraphCompiler* compiler,
    BranchLabels labels) {
  if (operation_cid() == kSmiCid) {
    return (labels.fall_through != labels.false_label) ? NEXT_IS_FALSE
                                                       : NEXT_IS_TRUE;
  } else {
    ASSERT(operation_cid() == kDoubleCid);
    return NEXT_IS_TRUE;
  }
}

DEFINE_MAKE_LOCATION_SUMMARY(RelationalOp, 2, Location::RequiresRegister())

EMIT_NATIVE_CODE(CheckArrayBound, 2) {
  const Register length = locs()->in(kLengthPos).reg();
  const Register index = locs()->in(kIndexPos).reg();
  const intptr_t index_cid = this->index()->Type()->ToCid();
  if (index_cid != kSmiCid) {
    __ CheckSmi(index);
    compiler->EmitDeopt(deopt_id(), ICData::kDeoptCheckArrayBound,
                        (generalized_ ? ICData::kGeneralized : 0) |
                            (licm_hoisted_ ? ICData::kHoisted : 0));
  }
  __ IfULe(length, index);
  compiler->EmitDeopt(deopt_id(), ICData::kDeoptCheckArrayBound,
                      (generalized_ ? ICData::kGeneralized : 0) |
                          (licm_hoisted_ ? ICData::kHoisted : 0));
}

}  // namespace dart

#endif  // defined TARGET_ARCH_DBC
