// 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"  // NOLINT
#if defined(TARGET_ARCH_DBC)

#include "vm/assembler.h"
#include "vm/cpu.h"
#include "vm/longjump.h"
#include "vm/runtime_entry.h"
#include "vm/simulator.h"
#include "vm/stack_frame.h"
#include "vm/stub_code.h"

namespace dart {

DECLARE_FLAG(bool, check_code_pointer);
DECLARE_FLAG(bool, inline_alloc);

void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
  const uword end = data + length;
  while (data < end) {
    *reinterpret_cast<int32_t*>(data) = Bytecode::kTrap;
    data += sizeof(int32_t);
  }
}

#define DEFINE_EMIT(Name, Signature, Fmt0, Fmt1, Fmt2)                         \
  void Assembler::Name(PARAMS_##Signature) {                                   \
    Emit(Bytecode::FENCODE_##Signature(Bytecode::k##Name ENCODE_##Signature)); \
  }

#define PARAMS_0
#define PARAMS_A_D uintptr_t ra, uintptr_t rd
#define PARAMS_D uintptr_t rd
#define PARAMS_A_B_C uintptr_t ra, uintptr_t rb, uintptr_t rc
#define PARAMS_A uintptr_t ra
#define PARAMS_T intptr_t x
#define PARAMS_A_X uintptr_t ra, intptr_t x
#define PARAMS_X intptr_t x

#define ENCODE_0
#define ENCODE_A_D , ra, rd
#define ENCODE_D , 0, rd
#define ENCODE_A_B_C , ra, rb, rc
#define ENCODE_A , ra, 0
#define ENCODE_T , x
#define ENCODE_A_X , ra, x
#define ENCODE_X , 0, x

#define FENCODE_0 Encode
#define FENCODE_A_D Encode
#define FENCODE_D Encode
#define FENCODE_A_B_C Encode
#define FENCODE_A Encode
#define FENCODE_T EncodeSigned
#define FENCODE_A_X EncodeSigned
#define FENCODE_X EncodeSigned

BYTECODES_LIST(DEFINE_EMIT)

#undef DEFINE_EMIT

void Assembler::Emit(int32_t value) {
  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
  buffer_.Emit<int32_t>(value);
}

const char* Assembler::RegisterName(Register reg) {
  return Thread::Current()->zone()->PrintToString("R%d", reg);
}

static int32_t EncodeJump(int32_t relative_pc) {
  return Bytecode::kJump | (relative_pc << 8);
}

static int32_t OffsetToPC(int32_t offset) {
  return offset >> 2;
}

void Assembler::Jump(Label* label) {
  if (label->IsBound()) {
    Emit(EncodeJump(OffsetToPC(label->Position() - buffer_.Size())));
  } else {
    const intptr_t position = buffer_.Size();
    Emit(label->position_);
    label->LinkTo(position);
  }
}

void Assembler::Bind(Label* label) {
  ASSERT(!label->IsBound());
  ASSERT(!label->IsBound());
  intptr_t bound_pc = buffer_.Size();
  while (label->IsLinked()) {
    const int32_t position = label->Position();
    const int32_t next_position = buffer_.Load<int32_t>(position);
    buffer_.Store<int32_t>(position,
                           EncodeJump(OffsetToPC(bound_pc - position)));
    label->position_ = next_position;
  }
  label->BindTo(bound_pc);
}

void Assembler::Stop(const char* message) {
  // TODO(vegorov) support passing a message to the bytecode.
  Emit(Bytecode::kTrap);
}

void Assembler::PushConstant(const Object& obj) {
  PushConstant(AddConstant(obj));
}

void Assembler::LoadConstant(uintptr_t ra, const Object& obj) {
  LoadConstant(ra, AddConstant(obj));
}

intptr_t Assembler::AddConstant(const Object& obj) {
  return object_pool_wrapper().FindObject(Object::ZoneHandle(obj.raw()));
}

}  // namespace dart

#endif  // defined TARGET_ARCH_DBC
