/*
 * Copyright (c) 1983, 1993, 2001
 *      The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#include "gprof.h"
#include "search_list.h"
#include "source.h"
#include "symtab.h"
#include "cg_arcs.h"
#include "corefile.h"
#include "hist.h"

    /*
     *        opcode of the `calls' instruction
     */
#define	CALLS	0xfb

    /*
     *        register for pc relative addressing
     */
#define	PC	0xf

enum opermodes
  {
    literal, indexed, reg, regdef, autodec, autoinc, autoincdef,
    bytedisp, bytedispdef, worddisp, worddispdef, longdisp, longdispdef,
    immediate, absolute, byterel, bytereldef, wordrel, wordreldef,
    longrel, longreldef
  };
typedef enum opermodes operandenum;

/* *INDENT-OFF* */
/* Here to document only.  We can't use this when cross compiling as
   the bitfield layout might not be the same as native.

   struct modebyte
     {
       unsigned int regfield:4;
       unsigned int modefield:4;
     };
*/
/* *INDENT-ON* */

/*
 * A symbol to be the child of indirect calls:
 */
static Sym indirectchild;

static operandenum vax_operandmode (unsigned char *);
static char *vax_operandname (operandenum);
static long vax_operandlength (unsigned char *);
static bfd_signed_vma vax_offset (unsigned char *);
void vax_find_call (Sym *, bfd_vma, bfd_vma);

static operandenum
vax_operandmode (unsigned char *modep)
{
  int usesreg = *modep & 0xf;

  switch ((*modep >> 4) & 0xf)
    {
    case 0:
    case 1:
    case 2:
    case 3:
      return literal;
    case 4:
      return indexed;
    case 5:
      return reg;
    case 6:
      return regdef;
    case 7:
      return autodec;
    case 8:
      return usesreg != PC ? autoinc : immediate;
    case 9:
      return usesreg != PC ? autoincdef : absolute;
    case 10:
      return usesreg != PC ? bytedisp : byterel;
    case 11:
      return usesreg != PC ? bytedispdef : bytereldef;
    case 12:
      return usesreg != PC ? worddisp : wordrel;
    case 13:
      return usesreg != PC ? worddispdef : wordreldef;
    case 14:
      return usesreg != PC ? longdisp : longrel;
    case 15:
      return usesreg != PC ? longdispdef : longreldef;
    }
  /* NOTREACHED */
  abort ();
}

static char *
vax_operandname (operandenum mode)
{

  switch (mode)
    {
    case literal:
      return "literal";
    case indexed:
      return "indexed";
    case reg:
      return "register";
    case regdef:
      return "register deferred";
    case autodec:
      return "autodecrement";
    case autoinc:
      return "autoincrement";
    case autoincdef:
      return "autoincrement deferred";
    case bytedisp:
      return "byte displacement";
    case bytedispdef:
      return "byte displacement deferred";
    case byterel:
      return "byte relative";
    case bytereldef:
      return "byte relative deferred";
    case worddisp:
      return "word displacement";
    case worddispdef:
      return "word displacement deferred";
    case wordrel:
      return "word relative";
    case wordreldef:
      return "word relative deferred";
    case immediate:
      return "immediate";
    case absolute:
      return "absolute";
    case longdisp:
      return "long displacement";
    case longdispdef:
      return "long displacement deferred";
    case longrel:
      return "long relative";
    case longreldef:
      return "long relative deferred";
    }
  /* NOTREACHED */
  abort ();
}

static long
vax_operandlength (unsigned char *modep)
{

  switch (vax_operandmode (modep))
    {
    case literal:
    case reg:
    case regdef:
    case autodec:
    case autoinc:
    case autoincdef:
      return 1;
    case bytedisp:
    case bytedispdef:
    case byterel:
    case bytereldef:
      return 2;
    case worddisp:
    case worddispdef:
    case wordrel:
    case wordreldef:
      return 3;
    case immediate:
    case absolute:
    case longdisp:
    case longdispdef:
    case longrel:
    case longreldef:
      return 5;
    case indexed:
      return 1 + vax_operandlength (modep + 1);
    }
  /* NOTREACHED */
  abort ();
}

static bfd_signed_vma
vax_offset (unsigned char *modep)
{
  operandenum mode = vax_operandmode (modep);

  ++modep;				/* skip over the mode */
  switch (mode)
    {
    default:
      fprintf (stderr, "[reladdr] not relative address\n");
      return 0;
    case byterel:
      return 1 + bfd_get_signed_8 (core_bfd, modep);
    case wordrel:
      return 2 + bfd_get_signed_16 (core_bfd, modep);
    case longrel:
      return 4 + bfd_get_signed_32 (core_bfd, modep);
    }
}


void
vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
{
  unsigned char *instructp;
  long length;
  Sym *child;
  operandenum mode;
  operandenum firstmode;
  bfd_vma pc, destpc;
  static bool inited = false;

  if (!inited)
    {
      inited = true;
      sym_init (&indirectchild);
      indirectchild.cg.prop.fract = 1.0;
      indirectchild.cg.cyc.head = &indirectchild;
    }

  DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
			  parent->name, (unsigned long) p_lowpc,
			  (unsigned long) p_highpc));
  for (pc = p_lowpc; pc < p_highpc; pc += length)
    {
      length = 1;
      instructp = ((unsigned char *) core_text_space
		   + pc - core_text_sect->vma);
      if ((*instructp & 0xff) == CALLS)
	{
	  /*
	   *    maybe a calls, better check it out.
	   *      skip the count of the number of arguments.
	   */
	  DBG (CALLDEBUG,
	       printf ("[findcall]\t0x%lx:calls", (unsigned long) pc));
	  firstmode = vax_operandmode (instructp + length);
	  switch (firstmode)
	    {
	    case literal:
	    case immediate:
	      break;
	    default:
	      goto botched;
	    }
	  length += vax_operandlength (instructp + length);
	  mode = vax_operandmode (instructp + length);
	  DBG (CALLDEBUG,
	       printf ("\tfirst operand is %s", vax_operandname (firstmode));
	       printf ("\tsecond operand is %s\n", vax_operandname (mode)));
	  switch (mode)
	    {
	    case regdef:
	    case bytedispdef:
	    case worddispdef:
	    case longdispdef:
	    case bytereldef:
	    case wordreldef:
	    case longreldef:
	      /*
	       *    indirect call: call through pointer
	       *      either  *d(r)   as a parameter or local
	       *              (r)     as a return value
	       *              *f      as a global pointer
	       *      [are there others that we miss?,
	       *       e.g. arrays of pointers to functions???]
	       */
	      arc_add (parent, &indirectchild, (unsigned long) 0);
	      length += vax_operandlength (instructp + length);
	      continue;
	    case byterel:
	    case wordrel:
	    case longrel:
	      /*
	       *    regular pc relative addressing
	       *      check that this is the address of
	       *      a function.
	       */
	      destpc = pc + vax_offset (instructp + length);
	      if (hist_check_address (destpc))
		{
		  child = sym_lookup (&symtab, destpc);
		  if (child)
		    {
		      DBG (CALLDEBUG,
		           printf ("[findcall]\tdestpc 0x%lx",
			           (unsigned long) destpc);
		           printf (" child->name %s", child->name);
		           printf (" child->addr 0x%lx\n",
			           (unsigned long) child->addr);
		        );
		      if (child->addr == destpc)
		        {
		          /*
		           *    a hit
		           */
		          arc_add (parent, child, (unsigned long) 0);
		          length += vax_operandlength (instructp + length);
		          continue;
		        }
		    }
		  goto botched;
		}
	      /*
	       *    else:
	       *      it looked like a calls,
	       *      but it wasn't to anywhere.
	       */
	      goto botched;
	    default:
	    botched:
	      /*
	       *    something funny going on.
	       */
	      DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n"));
	      length = 1;
	      continue;
	    }
	}
    }
}
