/* Ada Ravenscar thread support.

   Copyright (C) 2004-2022 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 RAVENSCAR_THREAD_H
#define 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 /* !defined (RAVENSCAR_THREAD_H) */
