/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_H_
#define ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_H_

#include <vector>

#include <android-base/logging.h>

#include "arch/instruction_set.h"
#include "base/arena_allocator.h"
#include "base/arena_object.h"
#include "base/array_ref.h"
#include "base/enums.h"
#include "base/macros.h"
#include "managed_register.h"
#include "offsets.h"

namespace art HIDDEN {

class ArenaAllocator;
class DebugFrameOpCodeWriterForAssembler;
class InstructionSetFeatures;
class MemoryRegion;
class JNIMacroLabel;

enum class JNIMacroUnaryCondition {
  kZero,
  kNotZero
};

class ArgumentLocation {
 public:
  ArgumentLocation(ManagedRegister reg, size_t size)
      : reg_(reg), frame_offset_(0u), size_(size) {
    DCHECK(reg.IsRegister());
  }

  ArgumentLocation(FrameOffset frame_offset, size_t size)
      : reg_(ManagedRegister::NoRegister()), frame_offset_(frame_offset), size_(size) {}

  bool IsRegister() const {
    return reg_.IsRegister();
  }

  ManagedRegister GetRegister() const {
    DCHECK(IsRegister());
    return reg_;
  }

  FrameOffset GetFrameOffset() const {
    DCHECK(!IsRegister());
    return frame_offset_;
  }

  size_t GetSize() const {
    return size_;
  }

 private:
  ManagedRegister reg_;
  FrameOffset frame_offset_;
  size_t size_;
};

template <PointerSize kPointerSize>
class JNIMacroAssembler : public DeletableArenaObject<kArenaAllocAssembler> {
 public:
  static std::unique_ptr<JNIMacroAssembler<kPointerSize>> Create(
      ArenaAllocator* allocator,
      InstructionSet instruction_set,
      const InstructionSetFeatures* instruction_set_features = nullptr);

  // Finalize the code; emit slow paths, fixup branches, add literal pool, etc.
  virtual void FinalizeCode() = 0;

  // Size of generated code
  virtual size_t CodeSize() const = 0;

  // Copy instructions out of assembly buffer into the given region of memory
  virtual void FinalizeInstructions(const MemoryRegion& region) = 0;

  // Emit code that will create an activation on the stack
  virtual void BuildFrame(size_t frame_size,
                          ManagedRegister method_reg,
                          ArrayRef<const ManagedRegister> callee_save_regs) = 0;

  // Emit code that will remove an activation from the stack
  //
  // Argument `may_suspend` must be `true` if the compiled method may be
  // suspended during its execution (otherwise `false`, if it is impossible
  // to suspend during its execution).
  virtual void RemoveFrame(size_t frame_size,
                           ArrayRef<const ManagedRegister> callee_save_regs,
                           bool may_suspend) = 0;

  virtual void IncreaseFrameSize(size_t adjust) = 0;
  virtual void DecreaseFrameSize(size_t adjust) = 0;

  // Return the same core register but with correct size if the architecture-specific
  // ManagedRegister has different representation for different sizes.
  virtual ManagedRegister CoreRegisterWithSize(ManagedRegister src, size_t size) = 0;

  // Store routines
  virtual void Store(FrameOffset offs, ManagedRegister src, size_t size) = 0;
  virtual void Store(ManagedRegister base, MemberOffset offs, ManagedRegister src, size_t size) = 0;
  virtual void StoreRawPtr(FrameOffset dest, ManagedRegister src) = 0;

  // Stores stack pointer by tagging it if required so we can walk the stack. In debuggable runtimes
  // we use tag to tell if we are using JITed code or AOT code. In non-debuggable runtimes we never
  // use JITed code when AOT code is present. So checking for AOT code is sufficient to detect which
  // code is being executed. We avoid tagging in non-debuggable runtimes to reduce instructions.
  virtual void StoreStackPointerToThread(ThreadOffset<kPointerSize> thr_offs, bool tag_sp) = 0;

  // Load routines
  virtual void Load(ManagedRegister dest, FrameOffset src, size_t size) = 0;
  virtual void Load(ManagedRegister dest, ManagedRegister base, MemberOffset offs, size_t size) = 0;

  virtual void LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset<kPointerSize> offs) = 0;

  // Copying routines

  // Move arguments from `srcs` locations to `dests` locations.
  //
  // References shall be spilled to `refs` frame offsets (kInvalidReferenceOffset indicates
  // a non-reference type) if they are in registers and corresponding `dests` shall be
  // filled with `jobject` replacements. If the first argument is a reference, it is
  // assumed to be `this` and cannot be null, all other reference arguments can be null.
  virtual void MoveArguments(ArrayRef<ArgumentLocation> dests,
                             ArrayRef<ArgumentLocation> srcs,
                             ArrayRef<FrameOffset> refs) = 0;

  virtual void Move(ManagedRegister dest, ManagedRegister src, size_t size) = 0;

  virtual void Move(ManagedRegister dst, size_t value) = 0;

  // Sign extension
  virtual void SignExtend(ManagedRegister mreg, size_t size) = 0;

  // Zero extension
  virtual void ZeroExtend(ManagedRegister mreg, size_t size) = 0;

  // Exploit fast access in managed code to Thread::Current()
  virtual void GetCurrentThread(ManagedRegister dest) = 0;
  virtual void GetCurrentThread(FrameOffset dest_offset) = 0;

  // Decode JNI transition or local `jobject`. For (weak) global `jobject`, jump to slow path.
  virtual void DecodeJNITransitionOrLocalJObject(ManagedRegister reg,
                                                 JNIMacroLabel* slow_path,
                                                 JNIMacroLabel* resume) = 0;

  // Heap::VerifyObject on src. In some cases (such as a reference to this) we
  // know that src may not be null.
  virtual void VerifyObject(ManagedRegister src, bool could_be_null) = 0;
  virtual void VerifyObject(FrameOffset src, bool could_be_null) = 0;

  // Jump to address held at [base+offset] (used for tail calls).
  virtual void Jump(ManagedRegister base, Offset offset) = 0;

  // Call to address held at [base+offset]
  virtual void Call(ManagedRegister base, Offset offset) = 0;
  virtual void CallFromThread(ThreadOffset<kPointerSize> offset) = 0;

  // Generate fast-path for transition to Native. Go to `label` if any thread flag is set.
  // The implementation can use `scratch_regs` which should be callee save core registers
  // (already saved before this call) and must preserve all argument registers.
  virtual void TryToTransitionFromRunnableToNative(
      JNIMacroLabel* label, ArrayRef<const ManagedRegister> scratch_regs) = 0;

  // Generate fast-path for transition to Runnable. Go to `label` if any thread flag is set.
  // The implementation can use `scratch_regs` which should be core argument registers
  // not used as return registers and it must preserve the `return_reg` if any.
  virtual void TryToTransitionFromNativeToRunnable(JNIMacroLabel* label,
                                                   ArrayRef<const ManagedRegister> scratch_regs,
                                                   ManagedRegister return_reg) = 0;

  // Generate suspend check and branch to `label` if there is a pending suspend request.
  virtual void SuspendCheck(JNIMacroLabel* label) = 0;

  // Generate code to check if Thread::Current()->exception_ is non-null
  // and branch to the `label` if it is.
  virtual void ExceptionPoll(JNIMacroLabel* label) = 0;
  // Deliver pending exception.
  virtual void DeliverPendingException() = 0;

  // Create a new label that can be used with Jump/Bind calls.
  virtual std::unique_ptr<JNIMacroLabel> CreateLabel() = 0;
  // Emit an unconditional jump to the label.
  virtual void Jump(JNIMacroLabel* label) = 0;
  // Emit a conditional jump to the label by applying a unary condition test to the GC marking flag.
  virtual void TestGcMarking(JNIMacroLabel* label, JNIMacroUnaryCondition cond) = 0;
  // Emit a conditional jump to the label by applying a unary condition test to object's mark bit.
  virtual void TestMarkBit(ManagedRegister ref,
                           JNIMacroLabel* label,
                           JNIMacroUnaryCondition cond) = 0;
  // Emit a conditional jump to label if the loaded value from specified locations is not zero.
  virtual void TestByteAndJumpIfNotZero(uintptr_t address, JNIMacroLabel* label) = 0;
  // Code at this offset will serve as the target for the Jump call.
  virtual void Bind(JNIMacroLabel* label) = 0;

  virtual ~JNIMacroAssembler() {}

  /**
   * @brief Buffer of DWARF's Call Frame Information opcodes.
   * @details It is used by debuggers and other tools to unwind the call stack.
   */
  virtual DebugFrameOpCodeWriterForAssembler& cfi() = 0;

  void SetEmitRunTimeChecksInDebugMode(bool value) {
    emit_run_time_checks_in_debug_mode_ = value;
  }

  static constexpr FrameOffset kInvalidReferenceOffset = FrameOffset(0);

 protected:
  JNIMacroAssembler() {}

  // Should run-time checks be emitted in debug mode?
  bool emit_run_time_checks_in_debug_mode_ = false;
};

// A "Label" class used with the JNIMacroAssembler
// allowing one to use branches (jumping from one place to another).
//
// This is just an interface, so every platform must provide
// its own implementation of it.
//
// It is only safe to use a label created
// via JNIMacroAssembler::CreateLabel with that same macro assembler.
class JNIMacroLabel {
 public:
  virtual ~JNIMacroLabel() = 0;

  const InstructionSet isa_;
 protected:
  explicit JNIMacroLabel(InstructionSet isa) : isa_(isa) {}
};

inline JNIMacroLabel::~JNIMacroLabel() {
  // Compulsory definition for a pure virtual destructor
  // to avoid linking errors.
}

template <typename T, PointerSize kPointerSize>
class JNIMacroAssemblerFwd : public JNIMacroAssembler<kPointerSize> {
 public:
  void FinalizeCode() override {
    asm_.FinalizeCode();
  }

  size_t CodeSize() const override {
    return asm_.CodeSize();
  }

  void FinalizeInstructions(const MemoryRegion& region) override {
    asm_.FinalizeInstructions(region);
  }

  DebugFrameOpCodeWriterForAssembler& cfi() override {
    return asm_.cfi();
  }

 protected:
  explicit JNIMacroAssemblerFwd(ArenaAllocator* allocator) : asm_(allocator) {}

  T asm_;
};

template <typename Self, typename PlatformLabel, InstructionSet kIsa>
class JNIMacroLabelCommon : public JNIMacroLabel {
 public:
  static Self* Cast(JNIMacroLabel* label) {
    CHECK(label != nullptr);
    CHECK_EQ(kIsa, label->isa_);

    return reinterpret_cast<Self*>(label);
  }

 protected:
  PlatformLabel* AsPlatformLabel() {
    return &label_;
  }

  JNIMacroLabelCommon() : JNIMacroLabel(kIsa) {
  }

  ~JNIMacroLabelCommon() override {}

 private:
  PlatformLabel label_;
};

}  // namespace art

#endif  // ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_H_
