// 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/compiler/assembler/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) = SimulatorBytecode::kTrap;
    data += sizeof(int32_t);
  }
}

#define DEFINE_EMIT(Name, Signature, Fmt0, Fmt1, Fmt2)                         \
  void Assembler::Name(PARAMS_##Signature) {                                   \
    Emit(SimulatorBytecode::FENCODE_##Signature(                               \
        SimulatorBytecode::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_B_Y uintptr_t ra, uintptr_t rb, intptr_t ry
#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_B_Y , ra, rb, ry
#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_B_Y 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);
}

const char* Assembler::FpuRegisterName(FpuRegister reg) {
  return Thread::Current()->zone()->PrintToString("F%d", reg);
}

static int32_t EncodeJump(int32_t relative_pc) {
  return SimulatorBytecode::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(SimulatorBytecode::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
