/* Ada Ravenscar thread support.

   Copyright (C) 2004-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDB_RAVENSCAR_THREAD_H
#define GDB_RAVENSCAR_THREAD_H

/* Architecture-specific hooks.  */

struct ravenscar_arch_ops
{
  ravenscar_arch_ops (gdb::array_view<const int> offsets_,
		      int first_stack = -1,
		      int last_stack = -1,
		      int v_init = -1,
		      int fpu_offset = -1,
		      int first_fp = -1,
		      int last_fp = -1)
    : offsets (offsets_),
      first_stack_register (first_stack),
      last_stack_register (last_stack),
      v_init_offset (v_init),
      fpu_context_offset (fpu_offset),
      first_fp_register (first_fp),
      last_fp_register (last_fp)
  {
    /* These must either both be -1 or both be valid.  */
    gdb_assert ((first_stack_register == -1) == (last_stack_register == -1));
    /* They must also be ordered.  */
    gdb_assert (last_stack_register >= first_stack_register);
    /* These must either all be -1 or all be valid.  */
    gdb_assert ((v_init_offset == -1) == (fpu_context_offset == -1)
		&& (fpu_context_offset == -1) == (first_fp_register == -1)
		&& (first_fp_register == -1) == (last_fp_register == -1));
  }

  /* Return true if this architecture implements on-demand floating
     point.  */
  bool on_demand_fp () const
  { return v_init_offset != -1; }

  /* Return true if REGNUM is a floating-point register for this
     target.  If this target does not use the on-demand FP scheme,
     this will always return false.  */
  bool is_fp_register (int regnum) const
  {
    return regnum >= first_fp_register && regnum <= last_fp_register;
  }

  /* Return the offset, in the current task context, of the byte
     indicating whether the FPU has been initialized for the task.
     This can only be called when the architecture implements
     on-demand floating-point.  */
  int get_v_init_offset () const
  {
    gdb_assert (on_demand_fp ());
    return v_init_offset;
  }

  /* Return the offset, in the current task context, of the FPU
     context.  This can only be called when the architecture
     implements on-demand floating-point.  */
  int get_fpu_context_offset () const
  {
    gdb_assert (on_demand_fp ());
    return fpu_context_offset;
  }

  void fetch_register (struct regcache *recache, int regnum) const;
  void store_register (struct regcache *recache, int regnum) const;

private:

  /* An array where the indices are register numbers and the contents
     are offsets.  The offsets are either in the thread descriptor or
     the stack, depending on the other fields.  An offset of -1 means
     that the corresponding register is not stored.  */
  const gdb::array_view<const int> offsets;

  /* If these are -1, then all registers for this architecture are
     stored in the thread descriptor.  Otherwise, these mark a range
     of registers that are stored on the stack.  */
  const int first_stack_register;
  const int last_stack_register;

  /* If these are -1, there is no special treatment for floating-point
     registers -- they are handled, or not, just like all other
     registers.

     Otherwise, they must all not be -1, and the target is one that
     uses on-demand FP initialization.  V_INIT_OFFSET is the offset of
     a boolean field in the context that indicates whether the FP
     registers have been initialized for this task.
     FPU_CONTEXT_OFFSET is the offset of the FPU context from the task
     context.  (This is needed to check whether the FPU registers have
     been saved.)  FIRST_FP_REGISTER and LAST_FP_REGISTER are the
     register numbers of the first and last (inclusive) floating point
     registers.  */
  const int v_init_offset;
  const int fpu_context_offset;
  const int first_fp_register;
  const int last_fp_register;

  /* Helper function to supply one register.  */
  void supply_one_register (struct regcache *regcache, int regnum,
			    CORE_ADDR descriptor,
			    CORE_ADDR stack_base) const;
  /* Helper function to store one register.  */
  void store_one_register (struct regcache *regcache, int regnum,
			   CORE_ADDR descriptor,
			   CORE_ADDR stack_base) const;
  /* Helper function to find stack address where registers are stored.
     This must be called with the stack pointer already supplied in
     the register cache.  */
  CORE_ADDR get_stack_base (struct regcache *) const;
};

#endif /* GDB_RAVENSCAR_THREAD_H */
