/* Definitions to make GDB run on a mips box under Mach 3.0
   Copyright 1992, 1993, 1998, 2000, 2001 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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* Mach specific routines for little endian mips (e.g. pmax)
 * running Mach 3.0
 *
 * Author: Jukka Virtanen <jtv@hut.fi>
 */

#include "defs.h"
#include "inferior.h"
#include "regcache.h"

#include <stdio.h>

#include <mach.h>
#include <mach/message.h>
#include <mach/exception.h>
#include <mach_error.h>

/* Find offsets to thread states at compile time.
 * If your compiler does not grok this, check the hand coded
 * offsets and use them.
 */

#if 1

#define  REG_OFFSET(reg) (int)(&((struct mips_thread_state *)0)->reg)
#define CREG_OFFSET(reg) (int)(&((struct mips_float_state *)0)->reg)
#define EREG_OFFSET(reg) (int)(&((struct mips_exc_state *)0)->reg)

/* at reg_offset[i] is the offset to the mips_thread_state
 * location where the gdb registers[i] is stored.
 *
 * -1 means mach does not save it anywhere.
 */
static int reg_offset[] =
{
  /*  zero              at                v0                v1       */
  -1, REG_OFFSET (r1), REG_OFFSET (r2), REG_OFFSET (r3),

  /*  a0                a1                a2                a3       */
  REG_OFFSET (r4), REG_OFFSET (r5), REG_OFFSET (r6), REG_OFFSET (r7),

  /*  t0                t1                t2                t3       */
  REG_OFFSET (r8), REG_OFFSET (r9), REG_OFFSET (r10), REG_OFFSET (r11),

  /*  t4                t5                t6                t7       */
  REG_OFFSET (r12), REG_OFFSET (r13), REG_OFFSET (r14), REG_OFFSET (r15),

  /*  s0                s1                s2                s3       */
  REG_OFFSET (r16), REG_OFFSET (r17), REG_OFFSET (r18), REG_OFFSET (r19),

  /*  s4                s5                s6                s7       */
  REG_OFFSET (r20), REG_OFFSET (r21), REG_OFFSET (r22), REG_OFFSET (r23),

  /*  t8                t9                k0                k1       */
  REG_OFFSET (r24), REG_OFFSET (r25), REG_OFFSET (r26), REG_OFFSET (r27),

  /*  gp                sp            s8(30) == fp(72)      ra       */
  REG_OFFSET (r28), REG_OFFSET (r29), REG_OFFSET (r30), REG_OFFSET (r31),

  /*  sr(32) PS_REGNUM   */
  EREG_OFFSET (coproc_state),

  /*  lo(33)            hi(34)    */
  REG_OFFSET (mdlo), REG_OFFSET (mdhi),

  /*  bad(35)                 cause(36)          pc(37)  */
  EREG_OFFSET (address), EREG_OFFSET (cause), REG_OFFSET (pc),

  /*  f0(38)             f1(39)             f2(40)             f3(41)   */
  CREG_OFFSET (r0), CREG_OFFSET (r1), CREG_OFFSET (r2), CREG_OFFSET (r3),
  CREG_OFFSET (r4), CREG_OFFSET (r5), CREG_OFFSET (r6), CREG_OFFSET (r7),
  CREG_OFFSET (r8), CREG_OFFSET (r9), CREG_OFFSET (r10), CREG_OFFSET (r11),
  CREG_OFFSET (r12), CREG_OFFSET (r13), CREG_OFFSET (r14), CREG_OFFSET (r15),
  CREG_OFFSET (r16), CREG_OFFSET (r17), CREG_OFFSET (r18), CREG_OFFSET (r19),
  CREG_OFFSET (r20), CREG_OFFSET (r21), CREG_OFFSET (r22), CREG_OFFSET (r23),
  CREG_OFFSET (r24), CREG_OFFSET (r25), CREG_OFFSET (r26), CREG_OFFSET (r27),
  CREG_OFFSET (r28), CREG_OFFSET (r29), CREG_OFFSET (r30), CREG_OFFSET (r31),

  /*  fsr(70)           fir(71)         fp(72) == s8(30) */
  CREG_OFFSET (csr), CREG_OFFSET (esr), REG_OFFSET (r30)
};
#else
/* If the compiler does not grok the above defines */
static int reg_offset[] =
{
/* mach_thread_state offsets: */
  -1, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56,
  60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120,
/*sr, lo, hi,addr,cause,pc   */
  8, 124, 128, 4, 0, 132,
/* mach_float_state offsets: */
  0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
  64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
/*fsr,fir */
  128, 132,
/* FP_REGNUM pseudo maps to s8==r30 in mach_thread_state */
  116
};
#endif

/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM
 * Caller knows that the regs handled in one transaction are of same size.
 */
#define FETCH_REGS(state, regnum, count) \
  memcpy (&deprecated_registers[REGISTER_BYTE (regnum)], \
	  (char *)state+reg_offset[ regnum ], \
	  count*REGISTER_SIZE)

/* Store COUNT contiguous registers to thread STATE starting from REGNUM */
#define STORE_REGS(state, regnum, count) \
  memcpy ((char *)state+reg_offset[ regnum ], \
	  &deprecated_registers[REGISTER_BYTE (regnum)], \
	  count*REGISTER_SIZE)

#define REGS_ALL    -1
#define REGS_NORMAL  1
#define REGS_EXC     2
#define REGS_COP1    4

/* Hardware regs that matches FP_REGNUM */
#define MACH_FP_REGNUM 30

/* Fech thread's registers. if regno == -1, fetch all regs */
void
fetch_inferior_registers (int regno)
{
  kern_return_t ret;

  thread_state_data_t state;
  struct mips_exc_state exc_state;

  int stateCnt = MIPS_THREAD_STATE_COUNT;

  int which_regs = 0;		/* A bit mask */

  if (!MACH_PORT_VALID (current_thread))
    error ("fetch inferior registers: Invalid thread");

  if (regno < -1 || regno >= NUM_REGS)
    error ("invalid register %d supplied to fetch_inferior_registers", regno);

  if (regno == -1)
    which_regs = REGS_ALL;
  else if (regno == ZERO_REGNUM)
    {
      int zero = 0;
      supply_register (ZERO_REGNUM, &zero);
      return;
    }
  else if ((ZERO_REGNUM < regno && regno < PS_REGNUM)
	   || regno == FP_REGNUM
	   || regno == LO_REGNUM
	   || regno == HI_REGNUM
	   || regno == PC_REGNUM)
    which_regs = REGS_NORMAL;
  else if (FP0_REGNUM <= regno && regno <= FCRIR_REGNUM)
    which_regs = REGS_COP1 | REGS_EXC;
  else
    which_regs = REGS_EXC;

  /* fetch regs saved to mips_thread_state */
  if (which_regs & REGS_NORMAL)
    {
      ret = thread_get_state (current_thread,
			      MIPS_THREAD_STATE,
			      state,
			      &stateCnt);
      CHK ("fetch inferior registers: thread_get_state", ret);

      if (which_regs == REGS_NORMAL)
	{
	  /* Fetch also FP_REGNUM if fetching MACH_FP_REGNUM and vice versa */
	  if (regno == MACH_FP_REGNUM || regno == FP_REGNUM)
	    {
	      supply_register (FP_REGNUM,
			       (char *) state + reg_offset[MACH_FP_REGNUM]);
	      supply_register (MACH_FP_REGNUM,
			       (char *) state + reg_offset[MACH_FP_REGNUM]);
	    }
	  else
	    supply_register (regno,
			     (char *) state + reg_offset[regno]);
	  return;
	}

      /* ZERO_REGNUM is always zero */
      *(int *) deprecated_registers = 0;

      /* Copy thread saved regs 1..31 to gdb's reg value array
       * Luckily, they are contiquous
       */
      FETCH_REGS (state, 1, 31);

      /* Copy mdlo and mdhi */
      FETCH_REGS (state, LO_REGNUM, 2);

      /* Copy PC */
      FETCH_REGS (state, PC_REGNUM, 1);

      /* Mach 3.0 saves FP to MACH_FP_REGNUM.
       * For some reason gdb wants to assign a pseudo register for it.
       */
      FETCH_REGS (state, FP_REGNUM, 1);
    }

  /* Read exc state. Also read if need to fetch floats */
  if (which_regs & REGS_EXC)
    {
      stateCnt = MIPS_EXC_STATE_COUNT;
      ret = thread_get_state (current_thread,
			      MIPS_EXC_STATE,
			      (thread_state_t) & exc_state,
			      &stateCnt);
      CHK ("fetch inferior regs (exc): thread_get_state", ret);

      /* We need to fetch exc_state to see if the floating
       * state is valid for the thread.
       */

      /* cproc_state: Which coprocessors the thread uses */
      supply_register (PS_REGNUM,
		       (char *) &exc_state + reg_offset[PS_REGNUM]);

      if (which_regs == REGS_EXC || which_regs == REGS_ALL)
	{
	  supply_register (BADVADDR_REGNUM,
			 (char *) &exc_state + reg_offset[BADVADDR_REGNUM]);

	  supply_register (CAUSE_REGNUM,
			   (char *) &exc_state + reg_offset[CAUSE_REGNUM]);
	  if (which_regs == REGS_EXC)
	    return;
	}
    }


  if (which_regs & REGS_COP1)
    {
      /* If the thread does not have saved COPROC1, set regs to zero */

      if (!(exc_state.coproc_state & MIPS_STATUS_USE_COP1))
	bzero (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM)],
	       sizeof (struct mips_float_state));
      else
	{
	  stateCnt = MIPS_FLOAT_STATE_COUNT;
	  ret = thread_get_state (current_thread,
				  MIPS_FLOAT_STATE,
				  state,
				  &stateCnt);
	  CHK ("fetch inferior regs (floats): thread_get_state", ret);

	  if (regno != -1)
	    {
	      supply_register (regno,
			       (char *) state + reg_offset[regno]);
	      return;
	    }

	  FETCH_REGS (state, FP0_REGNUM, 34);
	}
    }

  /* All registers are valid, if not returned yet */
  deprecated_registers_fetched ();
}

/* Store gdb's view of registers to the thread.
 * All registers are always valid when entering here.
 * @@ ahem, maybe that is too strict, we could validate the necessary ones
 *    here.
 *
 * Hmm. It seems that gdb set $reg=value command first reads everything,
 * then sets the reg and then stores everything. -> we must make sure
 * that the immutable registers are not changed by reading them first.
 */

void
store_inferior_registers (register int regno)
{
  thread_state_data_t state;
  kern_return_t ret;

  if (!MACH_PORT_VALID (current_thread))
    error ("store inferior registers: Invalid thread");

  /* Check for read only regs.
   * @@ If some of these is can be changed, fix this
   */
  if (regno == ZERO_REGNUM ||
      regno == PS_REGNUM ||
      regno == BADVADDR_REGNUM ||
      regno == CAUSE_REGNUM ||
      regno == FCRIR_REGNUM)
    {
      message ("You can not alter read-only register `%s'",
	       REGISTER_NAME (regno));
      fetch_inferior_registers (regno);
      return;
    }

  if (regno == -1)
    {
      /* Don't allow these to change */

      /* ZERO_REGNUM */
      *(int *) deprecated_registers = 0;

      fetch_inferior_registers (PS_REGNUM);
      fetch_inferior_registers (BADVADDR_REGNUM);
      fetch_inferior_registers (CAUSE_REGNUM);
      fetch_inferior_registers (FCRIR_REGNUM);
    }

  if (regno == -1 || (ZERO_REGNUM < regno && regno <= PC_REGNUM))
    {
#if 1
      /* Mach 3.0 saves thread's FP to MACH_FP_REGNUM.
       * GDB wants assigns a pseudo register FP_REGNUM for frame pointer.
       *
       * @@@ Here I assume (!) that gdb's FP has the value that
       *     should go to threads frame pointer. If not true, this
       *     fails badly!!!!!
       */
      memcpy (&deprecated_registers[REGISTER_BYTE (MACH_FP_REGNUM)],
	      &deprecated_registers[REGISTER_BYTE (FP_REGNUM)],
	      REGISTER_RAW_SIZE (FP_REGNUM));
#endif

      /* Save gdb's regs 1..31 to thread saved regs 1..31
       * Luckily, they are contiquous
       */
      STORE_REGS (state, 1, 31);

      /* Save mdlo, mdhi */
      STORE_REGS (state, LO_REGNUM, 2);

      /* Save PC */
      STORE_REGS (state, PC_REGNUM, 1);

      ret = thread_set_state (current_thread,
			      MIPS_THREAD_STATE,
			      state,
			      MIPS_FLOAT_STATE_COUNT);
      CHK ("store inferior regs : thread_set_state", ret);
    }

  if (regno == -1 || regno >= FP0_REGNUM)
    {
      /* If thread has floating state, save it */
      if (read_register (PS_REGNUM) & MIPS_STATUS_USE_COP1)
	{
	  /* Do NOT save FCRIR_REGNUM */
	  STORE_REGS (state, FP0_REGNUM, 33);

	  ret = thread_set_state (current_thread,
				  MIPS_FLOAT_STATE,
				  state,
				  MIPS_FLOAT_STATE_COUNT);
	  CHK ("store inferior registers (floats): thread_set_state", ret);
	}
      else if (regno != -1)
	message
	  ("Thread does not use floating point unit, floating regs not saved");
    }
}
