/*
 * 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 StoreRef(FrameOffset dest, ManagedRegister src) = 0;
  virtual void StoreRawPtr(FrameOffset dest, ManagedRegister src) = 0;

  virtual void StoreImmediateToFrame(FrameOffset dest, uint32_t imm) = 0;

  virtual void StoreStackOffsetToThread(ThreadOffset<kPointerSize> thr_offs,
                                        FrameOffset fr_offs) = 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;

  virtual void StoreSpanning(FrameOffset dest,
                             ManagedRegister src,
                             FrameOffset in_off) = 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 LoadFromThread(ManagedRegister dest,
                              ThreadOffset<kPointerSize> src,
                              size_t size) = 0;

  virtual void LoadRef(ManagedRegister dest, FrameOffset src) = 0;
  // If unpoison_reference is true and kPoisonReference is true, then we negate the read reference.
  virtual void LoadRef(ManagedRegister dest,
                       ManagedRegister base,
                       MemberOffset offs,
                       bool unpoison_reference) = 0;

  virtual void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs) = 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 CopyRawPtrFromThread(FrameOffset fr_offs, ThreadOffset<kPointerSize> thr_offs) = 0;

  virtual void CopyRawPtrToThread(ThreadOffset<kPointerSize> thr_offs,
                                  FrameOffset fr_offs,
                                  ManagedRegister scratch) = 0;

  virtual void CopyRef(FrameOffset dest, FrameOffset src) = 0;
  virtual void CopyRef(FrameOffset dest,
                       ManagedRegister base,
                       MemberOffset offs,
                       bool unpoison_reference) = 0;

  virtual void Copy(FrameOffset dest, FrameOffset src, size_t size) = 0;

  virtual void Copy(FrameOffset dest,
                    ManagedRegister src_base,
                    Offset src_offset,
                    ManagedRegister scratch,
                    size_t size) = 0;

  virtual void Copy(ManagedRegister dest_base,
                    Offset dest_offset,
                    FrameOffset src,
                    ManagedRegister scratch,
                    size_t size) = 0;

  virtual void Copy(FrameOffset dest,
                    FrameOffset src_base,
                    Offset src_offset,
                    ManagedRegister scratch,
                    size_t size) = 0;

  virtual void Copy(ManagedRegister dest,
                    Offset dest_offset,
                    ManagedRegister src,
                    Offset src_offset,
                    ManagedRegister scratch,
                    size_t size) = 0;

  virtual void Copy(FrameOffset dest,
                    Offset dest_offset,
                    FrameOffset src,
                    Offset src_offset,
                    ManagedRegister scratch,
                    size_t size) = 0;

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

  virtual void MemoryBarrier(ManagedRegister scratch) = 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;

  // Set up `out_reg` to hold a `jobject` (`StackReference<Object>*` to a spilled value),
  // or to be null if the value is null and `null_allowed`. `in_reg` holds a possibly
  // stale reference that can be used to avoid loading the spilled value to
  // see if the value is null.
  virtual void CreateJObject(ManagedRegister out_reg,
                             FrameOffset spilled_reference_offset,
                             ManagedRegister in_reg,
                             bool null_allowed) = 0;

  // Set up `out_off` to hold a `jobject` (`StackReference<Object>*` to a spilled value),
  // or to be null if the value is null and `null_allowed`.
  virtual void CreateJObject(FrameOffset out_off,
                             FrameOffset spilled_reference_offset,
                             bool null_allowed) = 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_
