/* Address ranges.
   Copyright (C) 1998 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions.

This file is part of the GNU Simulators.

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, 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.  */

/* Tell sim-arange.h it's us.  */
#define SIM_ARANGE_C

#include "libiberty.h"
#include "sim-basics.h"
#include "sim-assert.h"

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#define DEFINE_INLINE_P (! defined (SIM_ARANGE_C_INCLUDED))
#define DEFINE_NON_INLINE_P defined (SIM_ARANGE_C_INCLUDED)

#if DEFINE_NON_INLINE_P

/* Insert a range.  */

static void
insert_range (ADDR_SUBRANGE **pos, ADDR_SUBRANGE *asr)
{
  asr->next = *pos;
  *pos = asr;
}

/* Delete a range.  */

static void
delete_range (ADDR_SUBRANGE **thisasrp)
{
  ADDR_SUBRANGE *thisasr;

  thisasr = *thisasrp;
  *thisasrp = thisasr->next;

  free (thisasr);
}

/* Add or delete an address range.
   This code was borrowed from linux's locks.c:posix_lock_file().
   ??? Todo: Given our simpler needs this could be simplified
   (split into two fns).  */

static void
frob_range (ADDR_RANGE *ar, address_word start, address_word end, int delete_p)
{
  ADDR_SUBRANGE *asr;
  ADDR_SUBRANGE *new_asr, *new_asr2;
  ADDR_SUBRANGE *left = NULL;
  ADDR_SUBRANGE *right = NULL;
  ADDR_SUBRANGE **before;
  ADDR_SUBRANGE init_caller;
  ADDR_SUBRANGE *caller = &init_caller;
  int added_p = 0;

  memset (caller, 0, sizeof (ADDR_SUBRANGE));
  new_asr = ZALLOC (ADDR_SUBRANGE);
  new_asr2 = ZALLOC (ADDR_SUBRANGE);

  caller->start = start;
  caller->end = end;
  before = &ar->ranges;

  while ((asr = *before) != NULL)
    {
      if (! delete_p)
	{
	  /* Try next range if current range preceeds new one and not
	     adjacent or overlapping.  */
	  if (asr->end < caller->start - 1)
	    goto next_range;

	  /* Break out if new range preceeds current one and not
	     adjacent or overlapping.  */
	  if (asr->start > caller->end + 1)
	    break;

	  /* If we come here, the new and current ranges are adjacent or
	     overlapping. Make one range yielding from the lower start address
	     of both ranges to the higher end address.  */
	  if (asr->start > caller->start)
	    asr->start = caller->start;
	  else
	    caller->start = asr->start;
	  if (asr->end < caller->end)
	    asr->end = caller->end;
	  else
	    caller->end = asr->end;

	  if (added_p)
	    {
	      delete_range (before);
	      continue;
	    }
	  caller = asr;
	  added_p = 1;
	}
      else /* deleting a range */
	{
	  /* Try next range if current range preceeds new one.  */
	  if (asr->end < caller->start)
	    goto next_range;

	  /* Break out if new range preceeds current one.  */
	  if (asr->start > caller->end)
	    break;

	  added_p = 1;

	  if (asr->start < caller->start)
	    left = asr;

	  /* If the next range in the list has a higher end
	     address than the new one, insert the new one here.  */
	  if (asr->end > caller->end)
	    {
	      right = asr;
	      break;
	    }
	  if (asr->start >= caller->start)
	    {
	      /* The new range completely replaces an old
	         one (This may happen several times).  */
	      if (added_p)
		{
		  delete_range (before);
		  continue;
		}

	      /* Replace the old range with the new one.  */
	      asr->start = caller->start;
	      asr->end = caller->end;
	      caller = asr;
	      added_p = 1;
	    }
	}

      /* Go on to next range.  */
    next_range:
      before = &asr->next;
    }

  if (!added_p)
    {
      if (delete_p)
	goto out;
      new_asr->start = caller->start;
      new_asr->end = caller->end;
      insert_range (before, new_asr);
      new_asr = NULL;
    }
  if (right)
    {
      if (left == right)
	{
	  /* The new range breaks the old one in two pieces,
	     so we have to use the second new range.  */
	  new_asr2->start = right->start;
	  new_asr2->end = right->end;
	  left = new_asr2;
	  insert_range (before, left);
	  new_asr2 = NULL;
	}
      right->start = caller->end + 1;
    }
  if (left)
    {
      left->end = caller->start - 1;
    }

 out:
  if (new_asr)
    free(new_asr);
  if (new_asr2)
    free(new_asr2);
}

/* Free T and all subtrees.  */

static void
free_search_tree (ADDR_RANGE_TREE *t)
{
  if (t != NULL)
    {
      free_search_tree (t->lower);
      free_search_tree (t->higher);
      free (t);
    }
}

/* Subroutine of build_search_tree to recursively build a balanced tree.
   ??? It's not an optimum tree though.  */

static ADDR_RANGE_TREE *
build_tree_1 (ADDR_SUBRANGE **asrtab, unsigned int n)
{
  unsigned int mid = n / 2;
  ADDR_RANGE_TREE *t;

  if (n == 0)
    return NULL;
  t = (ADDR_RANGE_TREE *) xmalloc (sizeof (ADDR_RANGE_TREE));
  t->start = asrtab[mid]->start;
  t->end = asrtab[mid]->end;
  if (mid != 0)
    t->lower = build_tree_1 (asrtab, mid);
  else
    t->lower = NULL;
  if (n > mid + 1)
    t->higher = build_tree_1 (asrtab + mid + 1, n - mid - 1);
  else
    t->higher = NULL;
  return t;
}

/* Build a search tree for address range AR.  */

static void
build_search_tree (ADDR_RANGE *ar)
{
  /* ??? Simple version for now.  */
  ADDR_SUBRANGE *asr,**asrtab;
  unsigned int i, n;

  for (n = 0, asr = ar->ranges; asr != NULL; ++n, asr = asr->next)
    continue;
  asrtab = (ADDR_SUBRANGE **) xmalloc (n * sizeof (ADDR_SUBRANGE *));
  for (i = 0, asr = ar->ranges; i < n; ++i, asr = asr->next)
    asrtab[i] = asr;
  ar->range_tree = build_tree_1 (asrtab, n);
  free (asrtab);
}

void
sim_addr_range_add (ADDR_RANGE *ar, address_word start, address_word end)
{
  frob_range (ar, start, end, 0);

  /* Rebuild the search tree.  */
  /* ??? Instead of rebuilding it here it could be done in a module resume
     handler, say by first checking for a `changed' flag, assuming of course
     this would never be done while the simulation is running.  */
  free_search_tree (ar->range_tree);
  build_search_tree (ar);
}

void
sim_addr_range_delete (ADDR_RANGE *ar, address_word start, address_word end)
{
  frob_range (ar, start, end, 1);

  /* Rebuild the search tree.  */
  /* ??? Instead of rebuilding it here it could be done in a module resume
     handler, say by first checking for a `changed' flag, assuming of course
     this would never be done while the simulation is running.  */
  free_search_tree (ar->range_tree);
  build_search_tree (ar);
}

#endif /* DEFINE_NON_INLINE_P */

#if DEFINE_INLINE_P

SIM_ARANGE_INLINE int
sim_addr_range_hit_p (ADDR_RANGE *ar, address_word addr)
{
  ADDR_RANGE_TREE *t = ar->range_tree;

  while (t != NULL)
    {
      if (addr < t->start)
	t = t->lower;
      else if (addr > t->end)
	t = t->higher;
      else
	return 1;
    }
  return 0;
}

#endif /* DEFINE_INLINE_P */
