/* Prologue value handling for GDB.
   Copyright 2003, 2004, 2005 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:

        Free Software Foundation, Inc.
        51 Franklin St - Fifth Floor
        Boston, MA 02110-1301
        USA */

#include "defs.h"
#include "gdb_string.h"
#include "gdb_assert.h"
#include "prologue-value.h"
#include "regcache.h"


/* Constructors.  */

pv_t
pv_unknown (void)
{
  pv_t v = { pvk_unknown, 0, 0 };

  return v;
}


pv_t
pv_constant (CORE_ADDR k)
{
  pv_t v;

  v.kind = pvk_constant;
  v.reg = -1;                   /* for debugging */
  v.k = k;

  return v;
}


pv_t
pv_register (int reg, CORE_ADDR k)
{
  pv_t v;

  v.kind = pvk_register;
  v.reg = reg;
  v.k = k;

  return v;
}



/* Arithmetic operations.  */

/* If one of *A and *B is a constant, and the other isn't, swap the
   values as necessary to ensure that *B is the constant.  This can
   reduce the number of cases we need to analyze in the functions
   below.  */
static void
constant_last (pv_t *a, pv_t *b)
{
  if (a->kind == pvk_constant
      && b->kind != pvk_constant)
    {
      pv_t temp = *a;
      *a = *b;
      *b = temp;
    }
}


pv_t
pv_add (pv_t a, pv_t b)
{
  constant_last (&a, &b);

  /* We can add a constant to a register.  */
  if (a.kind == pvk_register
      && b.kind == pvk_constant)
    return pv_register (a.reg, a.k + b.k);

  /* We can add a constant to another constant.  */
  else if (a.kind == pvk_constant
           && b.kind == pvk_constant)
    return pv_constant (a.k + b.k);

  /* Anything else we don't know how to add.  We don't have a
     representation for, say, the sum of two registers, or a multiple
     of a register's value (adding a register to itself).  */
  else
    return pv_unknown ();
}


pv_t
pv_add_constant (pv_t v, CORE_ADDR k)
{
  /* Rather than thinking of all the cases we can and can't handle,
     we'll just let pv_add take care of that for us.  */
  return pv_add (v, pv_constant (k));
}


pv_t
pv_subtract (pv_t a, pv_t b)
{
  /* This isn't quite the same as negating B and adding it to A, since
     we don't have a representation for the negation of anything but a
     constant.  For example, we can't negate { pvk_register, R1, 10 },
     but we do know that { pvk_register, R1, 10 } minus { pvk_register,
     R1, 5 } is { pvk_constant, <ignored>, 5 }.

     This means, for example, that we could subtract two stack
     addresses; they're both relative to the original SP.  Since the
     frame pointer is set based on the SP, its value will be the
     original SP plus some constant (probably zero), so we can use its
     value just fine, too.  */

  constant_last (&a, &b);

  /* We can subtract two constants.  */
  if (a.kind == pvk_constant
      && b.kind == pvk_constant)
    return pv_constant (a.k - b.k);

  /* We can subtract a constant from a register.  */
  else if (a.kind == pvk_register
           && b.kind == pvk_constant)
    return pv_register (a.reg, a.k - b.k);

  /* We can subtract a register from itself, yielding a constant.  */
  else if (a.kind == pvk_register
           && b.kind == pvk_register
           && a.reg == b.reg)
    return pv_constant (a.k - b.k);

  /* We don't know how to subtract anything else.  */
  else
    return pv_unknown ();
}


pv_t
pv_logical_and (pv_t a, pv_t b)
{
  constant_last (&a, &b);

  /* We can 'and' two constants.  */
  if (a.kind == pvk_constant
      && b.kind == pvk_constant)
    return pv_constant (a.k & b.k);

  /* We can 'and' anything with the constant zero.  */
  else if (b.kind == pvk_constant
           && b.k == 0)
    return pv_constant (0);
  
  /* We can 'and' anything with ~0.  */
  else if (b.kind == pvk_constant
           && b.k == ~ (CORE_ADDR) 0)
    return a;

  /* We can 'and' a register with itself.  */
  else if (a.kind == pvk_register
           && b.kind == pvk_register
           && a.reg == b.reg
           && a.k == b.k)
    return a;

  /* Otherwise, we don't know.  */
  else
    return pv_unknown ();
}



/* Examining prologue values.  */

int
pv_is_identical (pv_t a, pv_t b)
{
  if (a.kind != b.kind)
    return 0;

  switch (a.kind)
    {
    case pvk_unknown:
      return 1;
    case pvk_constant:
      return (a.k == b.k);
    case pvk_register:
      return (a.reg == b.reg && a.k == b.k);
    default:
      gdb_assert (0);
    }
}


int
pv_is_constant (pv_t a)
{
  return (a.kind == pvk_constant);
}


int
pv_is_register (pv_t a, int r)
{
  return (a.kind == pvk_register
          && a.reg == r);
}


int
pv_is_register_k (pv_t a, int r, CORE_ADDR k)
{
  return (a.kind == pvk_register
          && a.reg == r
          && a.k == k);
}


enum pv_boolean
pv_is_array_ref (pv_t addr, CORE_ADDR size,
                 pv_t array_addr, CORE_ADDR array_len, 
                 CORE_ADDR elt_size,
                 int *i)
{
  /* Note that, since .k is a CORE_ADDR, and CORE_ADDR is unsigned, if
     addr is *before* the start of the array, then this isn't going to
     be negative...  */
  pv_t offset = pv_subtract (addr, array_addr);

  if (offset.kind == pvk_constant)
    {
      /* This is a rather odd test.  We want to know if the SIZE bytes
         at ADDR don't overlap the array at all, so you'd expect it to
         be an || expression: "if we're completely before || we're
         completely after".  But with unsigned arithmetic, things are
         different: since it's a number circle, not a number line, the
         right values for offset.k are actually one contiguous range.  */
      if (offset.k <= -size
          && offset.k >= array_len * elt_size)
        return pv_definite_no;
      else if (offset.k % elt_size != 0
               || size != elt_size)
        return pv_maybe;
      else
        {
          *i = offset.k / elt_size;
          return pv_definite_yes;
        }
    }
  else
    return pv_maybe;
}



/* Areas.  */


/* A particular value known to be stored in an area.

   Entries form a ring, sorted by unsigned offset from the area's base
   register's value.  Since entries can straddle the wrap-around point,
   unsigned offsets form a circle, not a number line, so the list
   itself is structured the same way --- there is no inherent head.
   The entry with the lowest offset simply follows the entry with the
   highest offset.  Entries may abut, but never overlap.  The area's
   'entry' pointer points to an arbitrary node in the ring.  */
struct area_entry
{
  /* Links in the doubly-linked ring.  */
  struct area_entry *prev, *next;

  /* Offset of this entry's address from the value of the base
     register.  */
  CORE_ADDR offset;

  /* The size of this entry.  Note that an entry may wrap around from
     the end of the address space to the beginning.  */
  CORE_ADDR size;

  /* The value stored here.  */
  pv_t value;
};


struct pv_area
{
  /* This area's base register.  */
  int base_reg;

  /* The mask to apply to addresses, to make the wrap-around happen at
     the right place.  */
  CORE_ADDR addr_mask;

  /* An element of the doubly-linked ring of entries, or zero if we
     have none.  */
  struct area_entry *entry;
};


struct pv_area *
make_pv_area (int base_reg)
{
  struct pv_area *a = (struct pv_area *) xmalloc (sizeof (*a));

  memset (a, 0, sizeof (*a));

  a->base_reg = base_reg;
  a->entry = 0;

  /* Remember that shift amounts equal to the type's width are
     undefined.  */
  a->addr_mask = ((((CORE_ADDR) 1 << (TARGET_ADDR_BIT - 1)) - 1) << 1) | 1;

  return a;
}


/* Delete all entries from AREA.  */
static void
clear_entries (struct pv_area *area)
{
  struct area_entry *e = area->entry;

  if (e)
    {
      /* This needs to be a do-while loop, in order to actually
         process the node being checked for in the terminating
         condition.  */
      do
        {
          struct area_entry *next = e->next;
          xfree (e);
        }
      while (e != area->entry);

      area->entry = 0;
    }
}


void
free_pv_area (struct pv_area *area)
{
  clear_entries (area);
  xfree (area);
}


static void
do_free_pv_area_cleanup (void *arg)
{
  free_pv_area ((struct pv_area *) arg);
}


struct cleanup *
make_cleanup_free_pv_area (struct pv_area *area)
{
  return make_cleanup (do_free_pv_area_cleanup, (void *) area);
}


int
pv_area_store_would_trash (struct pv_area *area, pv_t addr)
{
  /* It may seem odd that pvk_constant appears here --- after all,
     that's the case where we know the most about the address!  But
     pv_areas are always relative to a register, and we don't know the
     value of the register, so we can't compare entry addresses to
     constants.  */
  return (addr.kind == pvk_unknown
          || addr.kind == pvk_constant
          || (addr.kind == pvk_register && addr.reg != area->base_reg));
}


/* Return a pointer to the first entry we hit in AREA starting at
   OFFSET and going forward.

   This may return zero, if AREA has no entries.

   And since the entries are a ring, this may return an entry that
   entirely preceeds OFFSET.  This is the correct behavior: depending
   on the sizes involved, we could still overlap such an area, with
   wrap-around.  */
static struct area_entry *
find_entry (struct pv_area *area, CORE_ADDR offset)
{
  struct area_entry *e = area->entry;

  if (! e)
    return 0;

  /* If the next entry would be better than the current one, then scan
     forward.  Since we use '<' in this loop, it always terminates.
     
     Note that, even setting aside the addr_mask stuff, we must not
     simplify this, in high school algebra fashion, to
     (e->next->offset < e->offset), because of the way < interacts
     with wrap-around.  We have to subtract offset from both sides to
     make sure both things we're comparing are on the same side of the
     discontinuity.  */
  while (((e->next->offset - offset) & area->addr_mask)
         < ((e->offset - offset) & area->addr_mask))
    e = e->next;

  /* If the previous entry would be better than the current one, then
     scan backwards.  */
  while (((e->prev->offset - offset) & area->addr_mask)
         < ((e->offset - offset) & area->addr_mask))
    e = e->prev;

  /* In case there's some locality to the searches, set the area's
     pointer to the entry we've found.  */
  area->entry = e;

  return e;
}


/* Return non-zero if the SIZE bytes at OFFSET would overlap ENTRY;
   return zero otherwise.  AREA is the area to which ENTRY belongs.  */
static int
overlaps (struct pv_area *area,
          struct area_entry *entry,
          CORE_ADDR offset,
          CORE_ADDR size)
{
  /* Think carefully about wrap-around before simplifying this.  */
  return (((entry->offset - offset) & area->addr_mask) < size
          || ((offset - entry->offset) & area->addr_mask) < entry->size);
}


void
pv_area_store (struct pv_area *area,
               pv_t addr,
               CORE_ADDR size,
               pv_t value)
{
  /* Remove any (potentially) overlapping entries.  */
  if (pv_area_store_would_trash (area, addr))
    clear_entries (area);
  else
    {
      CORE_ADDR offset = addr.k;
      struct area_entry *e = find_entry (area, offset);

      /* Delete all entries that we would overlap.  */
      while (e && overlaps (area, e, offset, size))
        {
          struct area_entry *next = (e->next == e) ? 0 : e->next;
          e->prev->next = e->next;
          e->next->prev = e->prev;

          xfree (e);
          e = next;
        }

      /* Move the area's pointer to the next remaining entry.  This
         will also zero the pointer if we've deleted all the entries.  */
      area->entry = e;
    }

  /* Now, there are no entries overlapping us, and area->entry is
     either zero or pointing at the closest entry after us.  We can
     just insert ourselves before that.

     But if we're storing an unknown value, don't bother --- that's
     the default.  */
  if (value.kind == pvk_unknown)
    return;
  else
    {
      CORE_ADDR offset = addr.k;
      struct area_entry *e = (struct area_entry *) xmalloc (sizeof (*e));
      e->offset = offset;
      e->size = size;
      e->value = value;

      if (area->entry)
        {
          e->prev = area->entry->prev;
          e->next = area->entry;
          e->prev->next = e->next->prev = e;
        }
      else
        {
          e->prev = e->next = e;
          area->entry = e;
        }
    }
}


pv_t
pv_area_fetch (struct pv_area *area, pv_t addr, CORE_ADDR size)
{
  /* If we have no entries, or we can't decide how ADDR relates to the
     entries we do have, then the value is unknown.  */
  if (! area->entry
      || pv_area_store_would_trash (area, addr))
    return pv_unknown ();
  else
    {
      CORE_ADDR offset = addr.k;
      struct area_entry *e = find_entry (area, offset);

      /* If this entry exactly matches what we're looking for, then
         we're set.  Otherwise, say it's unknown.  */
      if (e->offset == offset && e->size == size)
        return e->value;
      else
        return pv_unknown ();
    }
}


int
pv_area_find_reg (struct pv_area *area,
                  struct gdbarch *gdbarch,
                  int reg,
                  CORE_ADDR *offset_p)
{
  struct area_entry *e = area->entry;

  if (e)
    do
      {
        if (e->value.kind == pvk_register
            && e->value.reg == reg
            && e->value.k == 0
            && e->size == register_size (gdbarch, reg))
          {
            if (offset_p)
              *offset_p = e->offset;
            return 1;
          }

        e = e->next;
      }
    while (e != area->entry);

  return 0;
}


void
pv_area_scan (struct pv_area *area,
              void (*func) (void *closure,
                            pv_t addr,
                            CORE_ADDR size,
                            pv_t value),
              void *closure)
{
  struct area_entry *e = area->entry;
  pv_t addr;

  addr.kind = pvk_register;
  addr.reg = area->base_reg;

  if (e)
    do
      {
        addr.k = e->offset;
        func (closure, addr, e->size, e->value);
        e = e->next;
      }
    while (e != area->entry);
}
