/* Functions for manipulating expressions designed to be executed on the agent
   Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009, 2010
   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/>.  */

/* Despite what the above comment says about this file being part of
   GDB, we would like to keep these functions free of GDB
   dependencies, since we want to be able to use them in contexts
   outside of GDB (test suites, the stub, etc.)  */

#include "defs.h"
#include "ax.h"

#include "value.h"
#include "gdb_string.h"

static void grow_expr (struct agent_expr *x, int n);

static void append_const (struct agent_expr *x, LONGEST val, int n);

static LONGEST read_const (struct agent_expr *x, int o, int n);

static void generic_ext (struct agent_expr *x, enum agent_op op, int n);

/* Functions for building expressions.  */

/* Allocate a new, empty agent expression.  */
struct agent_expr *
new_agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope)
{
  struct agent_expr *x = xmalloc (sizeof (*x));

  x->len = 0;
  x->size = 1;			/* Change this to a larger value once
				   reallocation code is tested.  */
  x->buf = xmalloc (x->size);

  x->gdbarch = gdbarch;
  x->scope = scope;

  /* Bit vector for registers used.  */
  x->reg_mask_len = 1;
  x->reg_mask = xmalloc (x->reg_mask_len * sizeof (x->reg_mask[0]));
  memset (x->reg_mask, 0, x->reg_mask_len * sizeof (x->reg_mask[0]));

  return x;
}

/* Free a agent expression.  */
void
free_agent_expr (struct agent_expr *x)
{
  xfree (x->buf);
  xfree (x->reg_mask);
  xfree (x);
}

static void
do_free_agent_expr_cleanup (void *x)
{
  free_agent_expr (x);
}

struct cleanup *
make_cleanup_free_agent_expr (struct agent_expr *x)
{
  return make_cleanup (do_free_agent_expr_cleanup, x);
}


/* Make sure that X has room for at least N more bytes.  This doesn't
   affect the length, just the allocated size.  */
static void
grow_expr (struct agent_expr *x, int n)
{
  if (x->len + n > x->size)
    {
      x->size *= 2;
      if (x->size < x->len + n)
	x->size = x->len + n + 10;
      x->buf = xrealloc (x->buf, x->size);
    }
}


/* Append the low N bytes of VAL as an N-byte integer to the
   expression X, in big-endian order.  */
static void
append_const (struct agent_expr *x, LONGEST val, int n)
{
  int i;

  grow_expr (x, n);
  for (i = n - 1; i >= 0; i--)
    {
      x->buf[x->len + i] = val & 0xff;
      val >>= 8;
    }
  x->len += n;
}


/* Extract an N-byte big-endian unsigned integer from expression X at
   offset O.  */
static LONGEST
read_const (struct agent_expr *x, int o, int n)
{
  int i;
  LONGEST accum = 0;

  /* Make sure we're not reading off the end of the expression.  */
  if (o + n > x->len)
    error (_("GDB bug: ax-general.c (read_const): incomplete constant"));

  for (i = 0; i < n; i++)
    accum = (accum << 8) | x->buf[o + i];

  return accum;
}


/* Append a simple operator OP to EXPR.  */
void
ax_simple (struct agent_expr *x, enum agent_op op)
{
  grow_expr (x, 1);
  x->buf[x->len++] = op;
}


/* Append a sign-extension or zero-extension instruction to EXPR, to
   extend an N-bit value.  */
static void
generic_ext (struct agent_expr *x, enum agent_op op, int n)
{
  /* N must fit in a byte.  */
  if (n < 0 || n > 255)
    error (_("GDB bug: ax-general.c (generic_ext): bit count out of range"));
  /* That had better be enough range.  */
  if (sizeof (LONGEST) * 8 > 255)
    error (_("GDB bug: ax-general.c (generic_ext): opcode has inadequate range"));

  grow_expr (x, 2);
  x->buf[x->len++] = op;
  x->buf[x->len++] = n;
}


/* Append a sign-extension instruction to EXPR, to extend an N-bit value.  */
void
ax_ext (struct agent_expr *x, int n)
{
  generic_ext (x, aop_ext, n);
}


/* Append a zero-extension instruction to EXPR, to extend an N-bit value.  */
void
ax_zero_ext (struct agent_expr *x, int n)
{
  generic_ext (x, aop_zero_ext, n);
}


/* Append a trace_quick instruction to EXPR, to record N bytes.  */
void
ax_trace_quick (struct agent_expr *x, int n)
{
  /* N must fit in a byte.  */
  if (n < 0 || n > 255)
    error (_("GDB bug: ax-general.c (ax_trace_quick): size out of range for trace_quick"));

  grow_expr (x, 2);
  x->buf[x->len++] = aop_trace_quick;
  x->buf[x->len++] = n;
}


/* Append a goto op to EXPR.  OP is the actual op (must be aop_goto or
   aop_if_goto).  We assume we don't know the target offset yet,
   because it's probably a forward branch, so we leave space in EXPR
   for the target, and return the offset in EXPR of that space, so we
   can backpatch it once we do know the target offset.  Use ax_label
   to do the backpatching.  */
int
ax_goto (struct agent_expr *x, enum agent_op op)
{
  grow_expr (x, 3);
  x->buf[x->len + 0] = op;
  x->buf[x->len + 1] = 0xff;
  x->buf[x->len + 2] = 0xff;
  x->len += 3;
  return x->len - 2;
}

/* Suppose a given call to ax_goto returns some value PATCH.  When you
   know the offset TARGET that goto should jump to, call
   ax_label (EXPR, PATCH, TARGET)
   to patch TARGET into the ax_goto instruction.  */
void
ax_label (struct agent_expr *x, int patch, int target)
{
  /* Make sure the value is in range.  Don't accept 0xffff as an
     offset; that's our magic sentinel value for unpatched branches.  */
  if (target < 0 || target >= 0xffff)
    error (_("GDB bug: ax-general.c (ax_label): label target out of range"));

  x->buf[patch] = (target >> 8) & 0xff;
  x->buf[patch + 1] = target & 0xff;
}


/* Assemble code to push a constant on the stack.  */
void
ax_const_l (struct agent_expr *x, LONGEST l)
{
  static enum agent_op ops[]
  =
  {aop_const8, aop_const16, aop_const32, aop_const64};
  int size;
  int op;

  /* How big is the number?  'op' keeps track of which opcode to use.
     Notice that we don't really care whether the original number was
     signed or unsigned; we always reproduce the value exactly, and
     use the shortest representation.  */
  for (op = 0, size = 8; size < 64; size *= 2, op++)
    {
      LONGEST lim = ((LONGEST) 1) << (size - 1);

      if (-lim <= l && l <= lim - 1)
        break;
    }

  /* Emit the right opcode... */
  ax_simple (x, ops[op]);

  /* Emit the low SIZE bytes as an unsigned number.  We know that
     sign-extending this will yield l.  */
  append_const (x, l, size / 8);

  /* Now, if it was negative, and not full-sized, sign-extend it.  */
  if (l < 0 && size < 64)
    ax_ext (x, size);
}


void
ax_const_d (struct agent_expr *x, LONGEST d)
{
  /* FIXME: floating-point support not present yet.  */
  error (_("GDB bug: ax-general.c (ax_const_d): floating point not supported yet"));
}


/* Assemble code to push the value of register number REG on the
   stack.  */
void
ax_reg (struct agent_expr *x, int reg)
{
  /* Make sure the register number is in range.  */
  if (reg < 0 || reg > 0xffff)
    error (_("GDB bug: ax-general.c (ax_reg): register number out of range"));
  grow_expr (x, 3);
  x->buf[x->len] = aop_reg;
  x->buf[x->len + 1] = (reg >> 8) & 0xff;
  x->buf[x->len + 2] = (reg) & 0xff;
  x->len += 3;
}

/* Assemble code to operate on a trace state variable.  */

void
ax_tsv (struct agent_expr *x, enum agent_op op, int num)
{
  /* Make sure the tsv number is in range.  */
  if (num < 0 || num > 0xffff)
    internal_error (__FILE__, __LINE__, _("ax-general.c (ax_tsv): variable number is %d, out of range"), num);

  grow_expr (x, 3);
  x->buf[x->len] = op;
  x->buf[x->len + 1] = (num >> 8) & 0xff;
  x->buf[x->len + 2] = (num) & 0xff;
  x->len += 3;
}



/* Functions for disassembling agent expressions, and otherwise
   debugging the expression compiler.  */

struct aop_map aop_map[] =
{
  {0, 0, 0, 0, 0},
  {"float", 0, 0, 0, 0},	/* 0x01 */
  {"add", 0, 0, 2, 1},		/* 0x02 */
  {"sub", 0, 0, 2, 1},		/* 0x03 */
  {"mul", 0, 0, 2, 1},		/* 0x04 */
  {"div_signed", 0, 0, 2, 1},	/* 0x05 */
  {"div_unsigned", 0, 0, 2, 1},	/* 0x06 */
  {"rem_signed", 0, 0, 2, 1},	/* 0x07 */
  {"rem_unsigned", 0, 0, 2, 1},	/* 0x08 */
  {"lsh", 0, 0, 2, 1},		/* 0x09 */
  {"rsh_signed", 0, 0, 2, 1},	/* 0x0a */
  {"rsh_unsigned", 0, 0, 2, 1},	/* 0x0b */
  {"trace", 0, 0, 2, 0},	/* 0x0c */
  {"trace_quick", 1, 0, 1, 1},	/* 0x0d */
  {"log_not", 0, 0, 1, 1},	/* 0x0e */
  {"bit_and", 0, 0, 2, 1},	/* 0x0f */
  {"bit_or", 0, 0, 2, 1},	/* 0x10 */
  {"bit_xor", 0, 0, 2, 1},	/* 0x11 */
  {"bit_not", 0, 0, 1, 1},	/* 0x12 */
  {"equal", 0, 0, 2, 1},	/* 0x13 */
  {"less_signed", 0, 0, 2, 1},	/* 0x14 */
  {"less_unsigned", 0, 0, 2, 1},	/* 0x15 */
  {"ext", 1, 0, 1, 1},		/* 0x16 */
  {"ref8", 0, 8, 1, 1},		/* 0x17 */
  {"ref16", 0, 16, 1, 1},	/* 0x18 */
  {"ref32", 0, 32, 1, 1},	/* 0x19 */
  {"ref64", 0, 64, 1, 1},	/* 0x1a */
  {"ref_float", 0, 0, 1, 1},	/* 0x1b */
  {"ref_double", 0, 0, 1, 1},	/* 0x1c */
  {"ref_long_double", 0, 0, 1, 1},	/* 0x1d */
  {"l_to_d", 0, 0, 1, 1},	/* 0x1e */
  {"d_to_l", 0, 0, 1, 1},	/* 0x1f */
  {"if_goto", 2, 0, 1, 0},	/* 0x20 */
  {"goto", 2, 0, 0, 0},		/* 0x21 */
  {"const8", 1, 8, 0, 1},	/* 0x22 */
  {"const16", 2, 16, 0, 1},	/* 0x23 */
  {"const32", 4, 32, 0, 1},	/* 0x24 */
  {"const64", 8, 64, 0, 1},	/* 0x25 */
  {"reg", 2, 0, 0, 1},		/* 0x26 */
  {"end", 0, 0, 0, 0},		/* 0x27 */
  {"dup", 0, 0, 1, 2},		/* 0x28 */
  {"pop", 0, 0, 1, 0},		/* 0x29 */
  {"zero_ext", 1, 0, 1, 1},	/* 0x2a */
  {"swap", 0, 0, 2, 2},		/* 0x2b */
  {"getv", 2, 0, 0, 1},		/* 0x2c */
  {"setv", 2, 0, 0, 1},		/* 0x2d */
  {"tracev", 2, 0, 0, 1},	/* 0x2e */
  {0, 0, 0, 0, 0},		/* 0x2f */
  {"trace16", 2, 0, 1, 1},	/* 0x30 */
};


/* Disassemble the expression EXPR, writing to F.  */
void
ax_print (struct ui_file *f, struct agent_expr *x)
{
  int i;
  int is_float = 0;

  fprintf_filtered (f, _("Scope: %s\n"), paddress (x->gdbarch, x->scope));
  fprintf_filtered (f, _("Reg mask:"));
  for (i = 0; i < x->reg_mask_len; ++i)
    fprintf_filtered (f, _(" %02x"), x->reg_mask[i]);
  fprintf_filtered (f, _("\n"));

  /* Check the size of the name array against the number of entries in
     the enum, to catch additions that people didn't sync.  */
  if ((sizeof (aop_map) / sizeof (aop_map[0]))
      != aop_last)
    error (_("GDB bug: ax-general.c (ax_print): opcode map out of sync"));

  for (i = 0; i < x->len;)
    {
      enum agent_op op = x->buf[i];

      if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
	  || !aop_map[op].name)
	{
	  fprintf_filtered (f, _("%3d  <bad opcode %02x>\n"), i, op);
	  i++;
	  continue;
	}
      if (i + 1 + aop_map[op].op_size > x->len)
	{
	  fprintf_filtered (f, _("%3d  <incomplete opcode %s>\n"),
			    i, aop_map[op].name);
	  break;
	}

      fprintf_filtered (f, "%3d  %s", i, aop_map[op].name);
      if (aop_map[op].op_size > 0)
	{
	  fputs_filtered (" ", f);

	  print_longest (f, 'd', 0,
			 read_const (x, i + 1, aop_map[op].op_size));
	}
      fprintf_filtered (f, "\n");
      i += 1 + aop_map[op].op_size;

      is_float = (op == aop_float);
    }
}

/* Add register REG to the register mask for expression AX.  */
void
ax_reg_mask (struct agent_expr *ax, int reg)
{
  int byte = reg / 8;

  /* Grow the bit mask if necessary.  */
  if (byte >= ax->reg_mask_len)
    {
      /* It's not appropriate to double here.  This isn't a
	 string buffer.  */
      int new_len = byte + 1;
      unsigned char *new_reg_mask = xrealloc (ax->reg_mask,
					      new_len * sizeof (ax->reg_mask[0]));
      memset (new_reg_mask + ax->reg_mask_len, 0,
	      (new_len - ax->reg_mask_len) * sizeof (ax->reg_mask[0]));
      ax->reg_mask_len = new_len;
      ax->reg_mask = new_reg_mask;
    }

  ax->reg_mask[byte] |= 1 << (reg % 8);
}

/* Given an agent expression AX, fill in requirements and other descriptive
   bits.  */
void
ax_reqs (struct agent_expr *ax)
{
  int i;
  int height;

  /* Jump target table.  targets[i] is non-zero iff we have found a
     jump to offset i.  */
  char *targets = (char *) alloca (ax->len * sizeof (targets[0]));

  /* Instruction boundary table.  boundary[i] is non-zero iff our scan
     has reached an instruction starting at offset i.  */
  char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));

  /* Stack height record.  If either targets[i] or boundary[i] is
     non-zero, heights[i] is the height the stack should have before
     executing the bytecode at that point.  */
  int *heights = (int *) alloca (ax->len * sizeof (heights[0]));

  /* Pointer to a description of the present op.  */
  struct aop_map *op;

  memset (targets, 0, ax->len * sizeof (targets[0]));
  memset (boundary, 0, ax->len * sizeof (boundary[0]));

  ax->max_height = ax->min_height = height = 0;
  ax->flaw = agent_flaw_none;
  ax->max_data_size = 0;

  for (i = 0; i < ax->len; i += 1 + op->op_size)
    {
      if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
	{
	  ax->flaw = agent_flaw_bad_instruction;
	  return;
	}

      op = &aop_map[ax->buf[i]];

      if (!op->name)
	{
	  ax->flaw = agent_flaw_bad_instruction;
	  return;
	}

      if (i + 1 + op->op_size > ax->len)
	{
	  ax->flaw = agent_flaw_incomplete_instruction;
	  return;
	}

      /* If this instruction is a forward jump target, does the
         current stack height match the stack height at the jump
         source?  */
      if (targets[i] && (heights[i] != height))
	{
	  ax->flaw = agent_flaw_height_mismatch;
	  return;
	}

      boundary[i] = 1;
      heights[i] = height;

      height -= op->consumed;
      if (height < ax->min_height)
	ax->min_height = height;
      height += op->produced;
      if (height > ax->max_height)
	ax->max_height = height;

      if (op->data_size > ax->max_data_size)
	ax->max_data_size = op->data_size;

      /* For jump instructions, check that the target is a valid
         offset.  If it is, record the fact that that location is a
         jump target, and record the height we expect there.  */
      if (aop_goto == op - aop_map
	  || aop_if_goto == op - aop_map)
	{
	  int target = read_const (ax, i + 1, 2);
	  if (target < 0 || target >= ax->len)
	    {
	      ax->flaw = agent_flaw_bad_jump;
	      return;
	    }

	  /* Do we have any information about what the stack height
             should be at the target?  */
	  if (targets[target] || boundary[target])
	    {
	      if (heights[target] != height)
		{
		  ax->flaw = agent_flaw_height_mismatch;
		  return;
		}
	    }

          /* Record the target, along with the stack height we expect.  */
          targets[target] = 1;
          heights[target] = height;
	}

      /* For unconditional jumps with a successor, check that the
         successor is a target, and pick up its stack height.  */
      if (aop_goto == op - aop_map
	  && i + 3 < ax->len)
	{
	  if (!targets[i + 3])
	    {
	      ax->flaw = agent_flaw_hole;
	      return;
	    }

	  height = heights[i + 3];
	}

      /* For reg instructions, record the register in the bit mask.  */
      if (aop_reg == op - aop_map)
	{
	  int reg = read_const (ax, i + 1, 2);

	  ax_reg_mask (ax, reg);
	}
    }

  /* Check that all the targets are on boundaries.  */
  for (i = 0; i < ax->len; i++)
    if (targets[i] && !boundary[i])
      {
	ax->flaw = agent_flaw_bad_jump;
	return;
      }

  ax->final_height = height;
}
