/*
 * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "asm/assembler.hpp"
#include "asm/codeBuffer.hpp"
#include "memory/allocation.hpp"
#include "opto/c2_MacroAssembler.hpp"
#include "opto/compile.hpp"
#include "opto/output.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/tuple.hpp"

#ifndef SHARE_OPTO_C2_CODESTUBS_HPP
#define SHARE_OPTO_C2_CODESTUBS_HPP

template <class... Ts>
class C2GeneralStub;

class C2CodeStub : public ArenaObj {
private:
  Label _entry;
  Label _continuation;

  void add_to_stub_list();
protected:
  C2CodeStub() :
    _entry(),
    _continuation() {}

public:
  Label& entry()        { return _entry; }
  Label& continuation() { return _continuation; }

  virtual void emit(C2_MacroAssembler& masm) = 0;
  virtual int max_size() const = 0;

  template <class... Ts>
  static C2GeneralStub<Ts...>* make(const Ts&... data, int max_size,
                                    void (*emit)(C2_MacroAssembler&, C2GeneralStub<Ts...>&));
};

class C2CodeStubList {
private:
  GrowableArray<C2CodeStub*> _stubs;

public:
  C2CodeStubList();

  void add_stub(C2CodeStub* stub) { _stubs.append(stub); }
  void emit(CodeBuffer& cb);
};

class C2SafepointPollStub : public C2CodeStub {
private:
  uintptr_t _safepoint_offset;

public:
  C2SafepointPollStub(uintptr_t safepoint_offset) :
    _safepoint_offset(safepoint_offset) {}
  int max_size() const;
  void emit(C2_MacroAssembler& masm);
};

// We move non-hot code of the nmethod entry barrier to an out-of-line stub
class C2EntryBarrierStub: public C2CodeStub {
private:
  Label _guard; // Used on AArch64 and RISCV

public:
  C2EntryBarrierStub() : C2CodeStub(),
    _guard() {}

  Label& guard() { return _guard; }

  int max_size() const;
  void emit(C2_MacroAssembler& masm);
};

#ifdef _LP64
class C2HandleAnonOMOwnerStub : public C2CodeStub {
private:
  Register _monitor;
  Register _tmp;
public:
  C2HandleAnonOMOwnerStub(Register monitor, Register tmp = noreg) : C2CodeStub(),
    _monitor(monitor), _tmp(tmp) {}
  Register monitor() { return _monitor; }
  Register tmp() { return _tmp; }
  int max_size() const;
  void emit(C2_MacroAssembler& masm);
};
#endif

//-----------------------------C2GeneralStub-----------------------------------
// A generalized stub that can be used to implement an arbitrary stub in a
// type-safe manner. An example:
//
// Register dst; XMMRegister src;
// // The lambda defining how the code is emitted in the stub
// auto slowpath = [](C2_MacroAssembler& masm, C2GeneralStub<Register, XMMRegister>& stub) {
//   // Access the saved data in a type safe manner
//   Register dst = stub.get<0>();
//   XMMRegister src = stub.get<1>();
//   masm.bind(stub.entry());
//   ...
//   masm.jump(stub.continuation());
// }
// // Create a stub with 2 data fields being dst and src, a max size of 4 bytes
// // and predefined emission function
// auto stub = C2CodeStub::make<Register, XMMRegister>(dst, src, 4, slowpath);
// __ jump_conditional(stub->entry());
// ...
// __ bind(stub->continuation());
//
template <class... Ts>
class C2GeneralStub : public C2CodeStub {
private:
  Tuple<Ts...> _data;
  int _max_size;
  void (*_emit)(C2_MacroAssembler&, C2GeneralStub&);

  constexpr C2GeneralStub(const Ts&... data, int max_size,
                          void (*emit)(C2_MacroAssembler&, C2GeneralStub<Ts...>&))
    : _data(data...), _max_size(max_size), _emit(emit) {}

  friend C2CodeStub;
public:
  template <std::size_t I>
  constexpr const auto& data() const { return _data.template get<I>(); }

  int max_size() const { return _max_size; }
  void emit(C2_MacroAssembler& masm) { _emit(masm, *this); }
};

template <class... Ts>
C2GeneralStub<Ts...>* C2CodeStub::make(const Ts&... data, int max_size,
                                       void (*emit)(C2_MacroAssembler&, C2GeneralStub<Ts...>&)) {
  auto stub = new (Compile::current()->comp_arena()) C2GeneralStub<Ts...>(data..., max_size, emit);
  stub->add_to_stub_list();
  return stub;
}

#endif // SHARE_OPTO_C2_CODESTUBS_HPP
