// 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 "test/unittests/compiler/interpreter-assembler-unittest.h"

#include "src/code-factory.h"
#include "src/compiler/graph.h"
#include "src/compiler/node.h"
#include "src/interface-descriptors.h"
#include "src/isolate.h"
#include "test/unittests/compiler/compiler-test-utils.h"
#include "test/unittests/compiler/node-test-utils.h"

using ::testing::_;

namespace v8 {
namespace internal {
namespace compiler {

const interpreter::Bytecode kBytecodes[] = {
#define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name,
    BYTECODE_LIST(DEFINE_BYTECODE)
#undef DEFINE_BYTECODE
};


Matcher<Node*> IsIntPtrConstant(const intptr_t value) {
  return kPointerSize == 8 ? IsInt64Constant(static_cast<int64_t>(value))
                           : IsInt32Constant(static_cast<int32_t>(value));
}


Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher,
                           const Matcher<Node*>& rhs_matcher) {
  return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher)
                           : IsInt32Add(lhs_matcher, rhs_matcher);
}


Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher,
                           const Matcher<Node*>& rhs_matcher) {
  return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher)
                           : IsInt32Sub(lhs_matcher, rhs_matcher);
}


Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher,
                         const Matcher<Node*>& rhs_matcher) {
  return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher)
                           : IsWord32Shl(lhs_matcher, rhs_matcher);
}


Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher,
                         const Matcher<Node*>& rhs_matcher) {
  return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher)
                           : IsWord32Sar(lhs_matcher, rhs_matcher);
}


Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher,
                        const Matcher<Node*>& rhs_matcher) {
  return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher)
                           : IsWord32Or(lhs_matcher, rhs_matcher);
}


Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad(
    const Matcher<LoadRepresentation>& rep_matcher,
    const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) {
  return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher,
                               graph()->start(), graph()->start());
}


Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore(
    const Matcher<StoreRepresentation>& rep_matcher,
    const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher,
    const Matcher<Node*>& value_matcher) {
  return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher,
                                value_matcher, graph()->start(),
                                graph()->start());
}


template <class... A>
Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsCall(
    const Matcher<const CallDescriptor*>& descriptor_matcher, A... args) {
  return ::i::compiler::IsCall(descriptor_matcher, args..., graph()->start(),
                               graph()->start());
}


Matcher<Node*>
InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand(
    int offset) {
  return IsLoad(
      kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
      IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
                  IsInt32Constant(offset)));
}


Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::
    IsBytecodeOperandSignExtended(int offset) {
  Matcher<Node*> load_matcher = IsLoad(
      kMachInt8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
      IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
                  IsInt32Constant(offset)));
  if (kPointerSize == 8) {
    load_matcher = IsChangeInt32ToInt64(load_matcher);
  }
  return load_matcher;
}


Matcher<Node*>
InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort(
    int offset) {
  if (TargetSupportsUnalignedAccess()) {
    return IsLoad(
        kMachUint16, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
        IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
                    IsInt32Constant(offset)));
  } else {
    Matcher<Node*> first_byte = IsLoad(
        kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
        IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
                    IsInt32Constant(offset)));
    Matcher<Node*> second_byte = IsLoad(
        kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
        IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
                    IsInt32Constant(offset + 1)));
#if V8_TARGET_LITTLE_ENDIAN
    return IsWordOr(IsWordShl(second_byte, IsInt32Constant(kBitsPerByte)),
                    first_byte);
#elif V8_TARGET_BIG_ENDIAN
    return IsWordOr(IsWordShl(first_byte, IsInt32Constant(kBitsPerByte)),
                    second_byte);
#else
#error "Unknown Architecture"
#endif
  }
}


Graph*
InterpreterAssemblerTest::InterpreterAssemblerForTest::GetCompletedGraph() {
  End();
  return graph();
}


TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    m.Dispatch();
    Graph* graph = m.GetCompletedGraph();

    Node* end = graph->end();
    EXPECT_EQ(1, end->InputCount());
    Node* tail_call_node = end->InputAt(0);

    Matcher<Node*> next_bytecode_offset_matcher =
        IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
                    IsInt32Constant(interpreter::Bytecodes::Size(bytecode)));
    Matcher<Node*> target_bytecode_matcher = m.IsLoad(
        kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
        next_bytecode_offset_matcher);
    Matcher<Node*> code_target_matcher = m.IsLoad(
        kMachPtr, IsParameter(Linkage::kInterpreterDispatchTableParameter),
        IsWord32Shl(target_bytecode_matcher,
                    IsInt32Constant(kPointerSizeLog2)));

    EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind());
    EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots);
    EXPECT_THAT(
        tail_call_node,
        IsTailCall(m.call_descriptor(), code_target_matcher,
                   IsParameter(Linkage::kInterpreterAccumulatorParameter),
                   IsParameter(Linkage::kInterpreterRegisterFileParameter),
                   next_bytecode_offset_matcher,
                   IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
                   IsParameter(Linkage::kInterpreterDispatchTableParameter),
                   IsParameter(Linkage::kInterpreterContextParameter),
                   graph->start(), graph->start()));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, Jump) {
  int jump_offsets[] = {-9710, -77, 0, +3, +97109};
  TRACED_FOREACH(int, jump_offset, jump_offsets) {
    TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
      InterpreterAssemblerForTest m(this, bytecode);
      m.Jump(m.Int32Constant(jump_offset));
      Graph* graph = m.GetCompletedGraph();
      Node* end = graph->end();
      EXPECT_EQ(1, end->InputCount());
      Node* tail_call_node = end->InputAt(0);

      Matcher<Node*> next_bytecode_offset_matcher =
          IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
                      IsInt32Constant(jump_offset));
      Matcher<Node*> target_bytecode_matcher = m.IsLoad(
          kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
          next_bytecode_offset_matcher);
      Matcher<Node*> code_target_matcher = m.IsLoad(
          kMachPtr, IsParameter(Linkage::kInterpreterDispatchTableParameter),
          IsWord32Shl(target_bytecode_matcher,
                      IsInt32Constant(kPointerSizeLog2)));

      EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind());
      EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots);
      EXPECT_THAT(
          tail_call_node,
          IsTailCall(m.call_descriptor(), code_target_matcher,
                     IsParameter(Linkage::kInterpreterAccumulatorParameter),
                     IsParameter(Linkage::kInterpreterRegisterFileParameter),
                     next_bytecode_offset_matcher,
                     IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
                     IsParameter(Linkage::kInterpreterDispatchTableParameter),
                     IsParameter(Linkage::kInterpreterContextParameter),
                     graph->start(), graph->start()));
    }
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) {
  static const int kJumpIfTrueOffset = 73;

  MachineOperatorBuilder machine(zone());

  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* lhs = m.IntPtrConstant(0);
    Node* rhs = m.IntPtrConstant(1);
    m.JumpIfWordEqual(lhs, rhs, m.Int32Constant(kJumpIfTrueOffset));
    Graph* graph = m.GetCompletedGraph();
    Node* end = graph->end();
    EXPECT_EQ(2, end->InputCount());

    int jump_offsets[] = {kJumpIfTrueOffset,
                          interpreter::Bytecodes::Size(bytecode)};
    for (int i = 0; i < static_cast<int>(arraysize(jump_offsets)); i++) {
      Matcher<Node*> next_bytecode_offset_matcher =
          IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
                      IsInt32Constant(jump_offsets[i]));
      Matcher<Node*> target_bytecode_matcher = m.IsLoad(
          kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
          next_bytecode_offset_matcher);
      Matcher<Node*> code_target_matcher = m.IsLoad(
          kMachPtr, IsParameter(Linkage::kInterpreterDispatchTableParameter),
          IsWord32Shl(target_bytecode_matcher,
                      IsInt32Constant(kPointerSizeLog2)));
      EXPECT_THAT(
          end->InputAt(i),
          IsTailCall(m.call_descriptor(), code_target_matcher,
                     IsParameter(Linkage::kInterpreterAccumulatorParameter),
                     IsParameter(Linkage::kInterpreterRegisterFileParameter),
                     next_bytecode_offset_matcher,
                     IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
                     IsParameter(Linkage::kInterpreterDispatchTableParameter),
                     IsParameter(Linkage::kInterpreterContextParameter),
                     graph->start(), graph->start()));
    }

    // TODO(oth): test control flow paths.
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, Return) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    m.Return();
    Graph* graph = m.GetCompletedGraph();

    Node* end = graph->end();
    EXPECT_EQ(1, end->InputCount());
    Node* tail_call_node = end->InputAt(0);

    EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind());
    EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots);
    Handle<HeapObject> exit_trampoline =
        isolate()->builtins()->InterpreterExitTrampoline();
    EXPECT_THAT(
        tail_call_node,
        IsTailCall(m.call_descriptor(), IsHeapConstant(exit_trampoline),
                   IsParameter(Linkage::kInterpreterAccumulatorParameter),
                   IsParameter(Linkage::kInterpreterRegisterFileParameter),
                   IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
                   IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
                   IsParameter(Linkage::kInterpreterDispatchTableParameter),
                   IsParameter(Linkage::kInterpreterContextParameter),
                   graph->start(), graph->start()));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode);
    for (int i = 0; i < number_of_operands; i++) {
      int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i);
      switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) {
        case interpreter::OperandType::kCount8:
          EXPECT_THAT(m.BytecodeOperandCount8(i), m.IsBytecodeOperand(offset));
          break;
        case interpreter::OperandType::kIdx8:
          EXPECT_THAT(m.BytecodeOperandIdx8(i), m.IsBytecodeOperand(offset));
          break;
        case interpreter::OperandType::kImm8:
          EXPECT_THAT(m.BytecodeOperandImm8(i),
                      m.IsBytecodeOperandSignExtended(offset));
          break;
        case interpreter::OperandType::kReg8:
          EXPECT_THAT(m.BytecodeOperandReg8(i),
                      m.IsBytecodeOperandSignExtended(offset));
          break;
        case interpreter::OperandType::kIdx16:
          EXPECT_THAT(m.BytecodeOperandIdx16(i),
                      m.IsBytecodeOperandShort(offset));
          break;
        case interpreter::OperandType::kNone:
          UNREACHABLE();
          break;
      }
    }
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    // Should be incoming accumulator if not set.
    EXPECT_THAT(m.GetAccumulator(),
                IsParameter(Linkage::kInterpreterAccumulatorParameter));

    // Should be set by SedtAccumulator.
    Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef);
    m.SetAccumulator(accumulator_value_1);
    EXPECT_THAT(m.GetAccumulator(), accumulator_value_1);
    Node* accumulator_value_2 = m.Int32Constant(42);
    m.SetAccumulator(accumulator_value_2);
    EXPECT_THAT(m.GetAccumulator(), accumulator_value_2);

    // Should be passed to next bytecode handler on dispatch.
    m.Dispatch();
    Graph* graph = m.GetCompletedGraph();

    Node* end = graph->end();
    EXPECT_EQ(1, end->InputCount());
    Node* tail_call_node = end->InputAt(0);

    EXPECT_THAT(tail_call_node,
                IsTailCall(m.call_descriptor(), _, accumulator_value_2, _, _, _,
                           _, graph->start(), graph->start()));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* reg_index_node = m.Int32Constant(44);
    Node* reg_location_node = m.RegisterLocation(reg_index_node);
    EXPECT_THAT(
        reg_location_node,
        IsIntPtrAdd(
            IsParameter(Linkage::kInterpreterRegisterFileParameter),
            IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2))));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* reg_index_node = m.Int32Constant(44);
    Node* load_reg_node = m.LoadRegister(reg_index_node);
    EXPECT_THAT(
        load_reg_node,
        m.IsLoad(kMachAnyTagged,
                 IsParameter(Linkage::kInterpreterRegisterFileParameter),
                 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2))));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* store_value = m.Int32Constant(0xdeadbeef);
    Node* reg_index_node = m.Int32Constant(44);
    Node* store_reg_node = m.StoreRegister(store_value, reg_index_node);
    EXPECT_THAT(
        store_reg_node,
        m.IsStore(StoreRepresentation(kMachAnyTagged, kNoWriteBarrier),
                  IsParameter(Linkage::kInterpreterRegisterFileParameter),
                  IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)),
                  store_value));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* value = m.Int32Constant(44);
    EXPECT_THAT(m.SmiTag(value),
                IsWordShl(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize)));
    EXPECT_THAT(m.SmiUntag(value),
                IsWordSar(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize)));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* a = m.Int32Constant(0);
    Node* b = m.Int32Constant(1);
    Node* add = m.IntPtrAdd(a, b);
    EXPECT_THAT(add, IsIntPtrAdd(a, b));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* a = m.Int32Constant(0);
    Node* b = m.Int32Constant(1);
    Node* add = m.IntPtrSub(a, b);
    EXPECT_THAT(add, IsIntPtrSub(a, b));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, WordShl) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* a = m.Int32Constant(0);
    Node* add = m.WordShl(a, 10);
    EXPECT_THAT(add, IsWordShl(a, IsInt32Constant(10)));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* index = m.Int32Constant(2);
    Node* load_constant = m.LoadConstantPoolEntry(index);
    Matcher<Node*> constant_pool_matcher = m.IsLoad(
        kMachAnyTagged,
        IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
        IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - kHeapObjectTag));
    EXPECT_THAT(
        load_constant,
        m.IsLoad(kMachAnyTagged, constant_pool_matcher,
                 IsIntPtrAdd(
                     IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
                     IsWordShl(index, IsInt32Constant(kPointerSizeLog2)))));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* context = m.Int32Constant(1);
    Node* slot_index = m.Int32Constant(22);
    Node* load_context_slot = m.LoadContextSlot(context, slot_index);

    Matcher<Node*> offset =
        IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)),
                    IsInt32Constant(Context::kHeaderSize - kHeapObjectTag));
    EXPECT_THAT(load_context_slot, m.IsLoad(kMachAnyTagged, context, offset));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* context = m.Int32Constant(1);
    Node* slot_index = m.Int32Constant(22);
    Node* value = m.Int32Constant(100);
    Node* store_context_slot = m.StoreContextSlot(context, slot_index, value);

    Matcher<Node*> offset =
        IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)),
                    IsInt32Constant(Context::kHeaderSize - kHeapObjectTag));
    EXPECT_THAT(store_context_slot,
                m.IsStore(StoreRepresentation(kMachAnyTagged, kNoWriteBarrier),
                          context, offset, value));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* object = m.IntPtrConstant(0xdeadbeef);
    int offset = 16;
    Node* load_field = m.LoadObjectField(object, offset);
    EXPECT_THAT(load_field,
                m.IsLoad(kMachAnyTagged, object,
                         IsIntPtrConstant(offset - kHeapObjectTag)));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* arg1 = m.Int32Constant(2);
    Node* arg2 = m.Int32Constant(3);
    Node* call_runtime = m.CallRuntime(Runtime::kAdd, arg1, arg2);
    EXPECT_THAT(call_runtime,
                m.IsCall(_, _, arg1, arg2, _, IsInt32Constant(2),
                         IsParameter(Linkage::kInterpreterContextParameter)));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Callable builtin = CodeFactory::InterpreterCEntry(isolate());

    Node* function_id = m.Int32Constant(0);
    Node* first_arg = m.Int32Constant(1);
    Node* arg_count = m.Int32Constant(2);

    Matcher<Node*> function_table = IsExternalConstant(
        ExternalReference::runtime_function_table_address(isolate()));
    Matcher<Node*> function = IsIntPtrAdd(
        function_table,
        IsInt32Mul(function_id, IsInt32Constant(sizeof(Runtime::Function))));
    Matcher<Node*> function_entry =
        m.IsLoad(kMachPtr, function,
                 IsInt32Constant(offsetof(Runtime::Function, entry)));

    Node* call_runtime = m.CallRuntime(function_id, first_arg, arg_count);
    EXPECT_THAT(call_runtime,
                m.IsCall(_, IsHeapConstant(builtin.code()), arg_count,
                         first_arg, function_entry,
                         IsParameter(Linkage::kInterpreterContextParameter)));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, CallIC) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    LoadWithVectorDescriptor descriptor(isolate());
    Node* target = m.Int32Constant(1);
    Node* arg1 = m.Int32Constant(2);
    Node* arg2 = m.Int32Constant(3);
    Node* arg3 = m.Int32Constant(4);
    Node* arg4 = m.Int32Constant(5);
    Node* call_ic = m.CallIC(descriptor, target, arg1, arg2, arg3, arg4);
    EXPECT_THAT(call_ic,
                m.IsCall(_, target, arg1, arg2, arg3, arg4,
                         IsParameter(Linkage::kInterpreterContextParameter)));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, CallJS) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Callable builtin = CodeFactory::InterpreterPushArgsAndCall(isolate());
    Node* function = m.Int32Constant(0);
    Node* first_arg = m.Int32Constant(1);
    Node* arg_count = m.Int32Constant(2);
    Node* call_js = m.CallJS(function, first_arg, arg_count);
    EXPECT_THAT(
        call_js,
        m.IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg,
                 function, IsParameter(Linkage::kInterpreterContextParameter)));
  }
}


TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) {
  TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
    InterpreterAssemblerForTest m(this, bytecode);
    Node* feedback_vector = m.LoadTypeFeedbackVector();

    Matcher<Node*> load_function_matcher = m.IsLoad(
        kMachAnyTagged, IsParameter(Linkage::kInterpreterRegisterFileParameter),
        IsIntPtrConstant(
            InterpreterFrameConstants::kFunctionFromRegisterPointer));
    Matcher<Node*> load_shared_function_info_matcher =
        m.IsLoad(kMachAnyTagged, load_function_matcher,
                 IsIntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
                                  kHeapObjectTag));

    EXPECT_THAT(
        feedback_vector,
        m.IsLoad(kMachAnyTagged, load_shared_function_info_matcher,
                 IsIntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset -
                                  kHeapObjectTag)));
  }
}

}  // namespace compiler
}  // namespace internal
}  // namespace v8
