/* Copyright (C) 2012-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/>.  */

#include "extract-store-integer.h"
#include "osabi.h"
#include "regcache.h"
#include "gdbcore.h"
#include "gdbtypes.h"
#include "infcall.h"
#include "ppc-tdep.h"
#include "target-float.h"
#include "value.h"
#include "xcoffread.h"

/* Implement the "push_dummy_call" gdbarch method.  */

static CORE_ADDR
rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch,
				struct value *function,
				struct regcache *regcache, CORE_ADDR bp_addr,
				int nargs, struct value **args, CORE_ADDR sp,
				function_call_return_method return_method,
				CORE_ADDR struct_addr)
{
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int ii;
  int len = 0;
  int argno;			/* current argument number */
  int argbytes;			/* current argument byte */
  gdb_byte tmp_buffer[50];
  int f_argno = 0;		/* current floating point argno */
  int wordsize = tdep->wordsize;

  struct value *arg = 0;
  struct type *type;

  ULONGEST saved_sp;

  /* The calling convention this function implements assumes the
     processor has floating-point registers.  We shouldn't be using it
     on PPC variants that lack them.  */
  gdb_assert (ppc_floating_point_unit_p (gdbarch));

  /* The first eight words of ther arguments are passed in registers.
     Copy them appropriately.  */
  ii = 0;

  /* If the function is returning a `struct', then the first word
     (which will be passed in r3) is used for struct return address.
     In that case we should advance one word and start from r4
     register to copy parameters.  */
  if (return_method == return_method_struct)
    {
      regcache_raw_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
				   struct_addr);
      ii++;
    }

  /* Effectively indirect call... gcc does...

     return_val example( float, int);

     eabi:
     float in fp0, int in r3
     offset of stack on overflow 8/16
     for varargs, must go by type.
     power open:
     float in r3&r4, int in r5
     offset of stack on overflow different
     both:
     return in r3 or f0.  If no float, must study how gcc emulates floats;
     pay attention to arg promotion.
     User may have to cast\args to handle promotion correctly
     since gdb won't know if prototype supplied or not.  */

  for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
    {
      int reg_size = register_size (gdbarch, ii + 3);

      arg = args[argno];
      type = check_typedef (arg->type ());
      len = type->length ();

      if (type->code () == TYPE_CODE_FLT)
	{

	  /* Floating point arguments are passed in fpr's, as well as gpr's.
	     There are 13 fpr's reserved for passing parameters.  At this point
	     there is no way we would run out of them.

	     Always store the floating point value using the register's
	     floating-point format.  */
	  const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno;
	  gdb_byte reg_val[PPC_MAX_REGISTER_SIZE];
	  struct type *reg_type = register_type (gdbarch, fp_regnum);

	  gdb_assert (len <= 8);

	  target_float_convert (arg->contents ().data (), type, reg_val,
				reg_type);
	  regcache->cooked_write (fp_regnum, reg_val);
	  ++f_argno;
	}

      if (len > reg_size)
	{

	  /* Argument takes more than one register.  */
	  while (argbytes < len)
	    {
	      gdb_byte word[PPC_MAX_REGISTER_SIZE];
	      memset (word, 0, reg_size);
	      memcpy (word,
		      ((char *) arg->contents ().data ()) + argbytes,
		      (len - argbytes) > reg_size
			? reg_size : len - argbytes);
	      regcache->cooked_write (tdep->ppc_gp0_regnum + 3 + ii, word);
	      ++ii, argbytes += reg_size;

	      if (ii >= 8)
		goto ran_out_of_registers_for_arguments;
	    }
	  argbytes = 0;
	  --ii;
	}
      else
	{
	  /* Argument can fit in one register.  No problem.  */
	  gdb_byte word[PPC_MAX_REGISTER_SIZE];

	  memset (word, 0, reg_size);
	  memcpy (word, arg->contents ().data (), len);
	  regcache->cooked_write (tdep->ppc_gp0_regnum + 3 +ii, word);
	}
      ++argno;
    }

ran_out_of_registers_for_arguments:

  regcache_cooked_read_unsigned (regcache,
				 gdbarch_sp_regnum (gdbarch),
				 &saved_sp);

  /* Location for 8 parameters are always reserved.  */
  sp -= wordsize * 8;

  /* Another six words for back chain, TOC register, link register, etc.  */
  sp -= wordsize * 6;

  /* Stack pointer must be quadword aligned.  */
  sp = align_down (sp, 16);

  /* If there are more arguments, allocate space for them in
     the stack, then push them starting from the ninth one.  */

  if ((argno < nargs) || argbytes)
    {
      int space = 0, jj;

      if (argbytes)
	{
	  space += align_up (len - argbytes, 4);
	  jj = argno + 1;
	}
      else
	jj = argno;

      for (; jj < nargs; ++jj)
	{
	  struct value *val = args[jj];

	  space += align_up (val->type ()->length (), 4);
	}

      /* Add location required for the rest of the parameters.  */
      space = align_up (space, 16);
      sp -= space;

      /* This is another instance we need to be concerned about
	 securing our stack space.  If we write anything underneath %sp
	 (r1), we might conflict with the kernel who thinks he is free
	 to use this area.  So, update %sp first before doing anything
	 else.  */

      regcache_raw_write_signed (regcache,
				 gdbarch_sp_regnum (gdbarch), sp);

      /* If the last argument copied into the registers didn't fit there
	 completely, push the rest of it into stack.  */

      if (argbytes)
	{
	  write_memory (sp + 24 + (ii * 4),
			arg->contents ().data () + argbytes,
			len - argbytes);
	  ++argno;
	  ii += align_up (len - argbytes, 4) / 4;
	}

      /* Push the rest of the arguments into stack.  */
      for (; argno < nargs; ++argno)
	{

	  arg = args[argno];
	  type = check_typedef (arg->type ());
	  len = type->length ();


	  /* Float types should be passed in fpr's, as well as in the
	     stack.  */
	  if (type->code () == TYPE_CODE_FLT && f_argno < 13)
	    {

	      gdb_assert (len <= 8);

	      regcache->cooked_write (tdep->ppc_fp0_regnum + 1 + f_argno,
				      arg->contents ().data ());
	      ++f_argno;
	    }

	  write_memory (sp + 24 + (ii * 4), arg->contents ().data (), len);
	  ii += align_up (len, 4) / 4;
	}
    }

  /* Set the stack pointer.  According to the ABI, the SP is meant to
     be set _before_ the corresponding stack space is used.  On AIX,
     this even applies when the target has been completely stopped!
     Not doing this can lead to conflicts with the kernel which thinks
     that it still has control over this not-yet-allocated stack
     region.  */
  regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp);

  /* Set back chain properly.  */
  store_unsigned_integer (tmp_buffer, wordsize, byte_order, saved_sp);
  write_memory (sp, tmp_buffer, wordsize);

  /* Point the inferior function call's return address at the dummy's
     breakpoint.  */
  regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);

  target_store_registers (regcache, -1);
  return sp;
}

/* Implement the "return_value" gdbarch method.  */

static enum return_value_convention
rs6000_lynx178_return_value (struct gdbarch *gdbarch, struct value *function,
			     struct type *valtype, struct regcache *regcache,
			     gdb_byte *readbuf, const gdb_byte *writebuf)
{
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* The calling convention this function implements assumes the
     processor has floating-point registers.  We shouldn't be using it
     on PowerPC variants that lack them.  */
  gdb_assert (ppc_floating_point_unit_p (gdbarch));

  /* AltiVec extension: Functions that declare a vector data type as a
     return value place that return value in VR2.  */
  if (valtype->code () == TYPE_CODE_ARRAY && valtype->is_vector ()
      && valtype->length () == 16)
    {
      if (readbuf)
	regcache->cooked_read (tdep->ppc_vr0_regnum + 2, readbuf);
      if (writebuf)
	regcache->cooked_write (tdep->ppc_vr0_regnum + 2, writebuf);

      return RETURN_VALUE_REGISTER_CONVENTION;
    }

  /* If the called subprogram returns an aggregate, there exists an
     implicit first argument, whose value is the address of a caller-
     allocated buffer into which the callee is assumed to store its
     return value.  All explicit parameters are appropriately
     relabeled.  */
  if (valtype->code () == TYPE_CODE_STRUCT
      || valtype->code () == TYPE_CODE_UNION
      || valtype->code () == TYPE_CODE_ARRAY)
    return RETURN_VALUE_STRUCT_CONVENTION;

  /* Scalar floating-point values are returned in FPR1 for float or
     double, and in FPR1:FPR2 for quadword precision.  Fortran
     complex*8 and complex*16 are returned in FPR1:FPR2, and
     complex*32 is returned in FPR1:FPR4.  */
  if (valtype->code () == TYPE_CODE_FLT
      && (valtype->length () == 4 || valtype->length () == 8))
    {
      struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum);
      gdb_byte regval[8];

      /* FIXME: kettenis/2007-01-01: Add support for quadword
	 precision and complex.  */

      if (readbuf)
	{
	  regcache->cooked_read (tdep->ppc_fp0_regnum + 1, regval);
	  target_float_convert (regval, regtype, readbuf, valtype);
	}
      if (writebuf)
	{
	  target_float_convert (writebuf, valtype, regval, regtype);
	  regcache->cooked_write (tdep->ppc_fp0_regnum + 1, regval);
	}

      return RETURN_VALUE_REGISTER_CONVENTION;
  }

  /* Values of the types int, long, short, pointer, and char (length
     is less than or equal to four bytes), as well as bit values of
     lengths less than or equal to 32 bits, must be returned right
     justified in GPR3 with signed values sign extended and unsigned
     values zero extended, as necessary.  */
  if (valtype->length () <= tdep->wordsize)
    {
      if (readbuf)
	{
	  ULONGEST regval;

	  /* For reading we don't have to worry about sign extension.  */
	  regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
					 &regval);
	  store_unsigned_integer (readbuf, valtype->length (), byte_order,
				  regval);
	}
      if (writebuf)
	{
	  /* For writing, use unpack_long since that should handle any
	     required sign extension.  */
	  regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
					  unpack_long (valtype, writebuf));
	}

      return RETURN_VALUE_REGISTER_CONVENTION;
    }

  /* Eight-byte non-floating-point scalar values must be returned in
     GPR3:GPR4.  */

  if (valtype->length () == 8)
    {
      gdb_assert (valtype->code () != TYPE_CODE_FLT);
      gdb_assert (tdep->wordsize == 4);

      if (readbuf)
	{
	  gdb_byte regval[8];

	  regcache->cooked_read (tdep->ppc_gp0_regnum + 3, regval);
	  regcache->cooked_read (tdep->ppc_gp0_regnum + 4, regval + 4);
	  memcpy (readbuf, regval, 8);
	}
      if (writebuf)
	{
	  regcache->cooked_write (tdep->ppc_gp0_regnum + 3, writebuf);
	  regcache->cooked_write (tdep->ppc_gp0_regnum + 4, writebuf + 4);
	}

      return RETURN_VALUE_REGISTER_CONVENTION;
    }

  return RETURN_VALUE_STRUCT_CONVENTION;
}

/* PowerPC Lynx178 OSABI sniffer.  */

static enum gdb_osabi
rs6000_lynx178_osabi_sniffer (bfd *abfd)
{
  if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
    return GDB_OSABI_UNKNOWN;

  /* The only noticeable difference between Lynx178 XCOFF files and
     AIX XCOFF files comes from the fact that there are no shared
     libraries on Lynx178.  So if the number of import files is
     different from zero, it cannot be a Lynx178 binary.  */
  if (xcoff_get_n_import_files (abfd) != 0)
    return GDB_OSABI_UNKNOWN;

  return GDB_OSABI_LYNXOS178;
}

/* Callback for powerpc-lynx178 initialization.  */

static void
rs6000_lynx178_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  set_gdbarch_push_dummy_call (gdbarch, rs6000_lynx178_push_dummy_call);
  set_gdbarch_return_value (gdbarch, rs6000_lynx178_return_value);
  set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
}

void _initialize_rs6000_lynx178_tdep ();
void
_initialize_rs6000_lynx178_tdep ()
{
  gdbarch_register_osabi_sniffer (bfd_arch_rs6000,
				  bfd_target_xcoff_flavour,
				  rs6000_lynx178_osabi_sniffer);
  gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_LYNXOS178,
			  rs6000_lynx178_init_osabi);
}

