/* Perform arithmetic and other operations on values, for GDB.

   Copyright (C) 1986-2021 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/>.  */

#include "defs.h"
#include "value.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "target.h"
#include "language.h"
#include "target-float.h"
#include "infcall.h"
#include "gdbsupport/byte-vector.h"
#include "gdbarch.h"

/* Define whether or not the C operator '/' truncates towards zero for
   differently signed operands (truncation direction is undefined in C).  */

#ifndef TRUNCATION_TOWARDS_ZERO
#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2)
#endif

/* Given a pointer, return the size of its target.
   If the pointer type is void *, then return 1.
   If the target type is incomplete, then error out.
   This isn't a general purpose function, but just a 
   helper for value_ptradd.  */

static LONGEST
find_size_for_pointer_math (struct type *ptr_type)
{
  LONGEST sz = -1;
  struct type *ptr_target;

  gdb_assert (ptr_type->code () == TYPE_CODE_PTR);
  ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type));

  sz = type_length_units (ptr_target);
  if (sz == 0)
    {
      if (ptr_type->code () == TYPE_CODE_VOID)
	sz = 1;
      else
	{
	  const char *name;
	  
	  name = ptr_target->name ();
	  if (name == NULL)
	    error (_("Cannot perform pointer math on incomplete types, "
		   "try casting to a known type, or void *."));
	  else
	    error (_("Cannot perform pointer math on incomplete type \"%s\", "
		   "try casting to a known type, or void *."), name);
	}
    }
  return sz;
}

/* Given a pointer ARG1 and an integral value ARG2, return the
   result of C-style pointer arithmetic ARG1 + ARG2.  */

struct value *
value_ptradd (struct value *arg1, LONGEST arg2)
{
  struct type *valptrtype;
  LONGEST sz;
  struct value *result;

  arg1 = coerce_array (arg1);
  valptrtype = check_typedef (value_type (arg1));
  sz = find_size_for_pointer_math (valptrtype);

  result = value_from_pointer (valptrtype,
			       value_as_address (arg1) + sz * arg2);
  if (VALUE_LVAL (result) != lval_internalvar)
    set_value_component_location (result, arg1);
  return result;
}

/* Given two compatible pointer values ARG1 and ARG2, return the
   result of C-style pointer arithmetic ARG1 - ARG2.  */

LONGEST
value_ptrdiff (struct value *arg1, struct value *arg2)
{
  struct type *type1, *type2;
  LONGEST sz;

  arg1 = coerce_array (arg1);
  arg2 = coerce_array (arg2);
  type1 = check_typedef (value_type (arg1));
  type2 = check_typedef (value_type (arg2));

  gdb_assert (type1->code () == TYPE_CODE_PTR);
  gdb_assert (type2->code () == TYPE_CODE_PTR);

  if (TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)))
      != TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2))))
    error (_("First argument of `-' is a pointer and "
	     "second argument is neither\n"
	     "an integer nor a pointer of the same type."));

  sz = type_length_units (check_typedef (TYPE_TARGET_TYPE (type1)));
  if (sz == 0) 
    {
      warning (_("Type size unknown, assuming 1. "
	       "Try casting to a known type, or void *."));
      sz = 1;
    }

  return (value_as_long (arg1) - value_as_long (arg2)) / sz;
}

/* Return the value of ARRAY[IDX].

   ARRAY may be of type TYPE_CODE_ARRAY or TYPE_CODE_STRING.  If the
   current language supports C-style arrays, it may also be TYPE_CODE_PTR.

   See comments in value_coerce_array() for rationale for reason for
   doing lower bounds adjustment here rather than there.
   FIXME:  Perhaps we should validate that the index is valid and if
   verbosity is set, warn about invalid indices (but still use them).  */

struct value *
value_subscript (struct value *array, LONGEST index)
{
  bool c_style = current_language->c_style_arrays_p ();
  struct type *tarray;

  array = coerce_ref (array);
  tarray = check_typedef (value_type (array));

  if (tarray->code () == TYPE_CODE_ARRAY
      || tarray->code () == TYPE_CODE_STRING)
    {
      struct type *range_type = tarray->index_type ();
      gdb::optional<LONGEST> lowerbound = get_discrete_low_bound (range_type);
      if (!lowerbound.has_value ())
	lowerbound = 0;

      if (VALUE_LVAL (array) != lval_memory)
	return value_subscripted_rvalue (array, index, *lowerbound);

      if (!c_style)
	{
	  gdb::optional<LONGEST> upperbound
	    = get_discrete_high_bound (range_type);

	  if (!upperbound.has_value ())
	    upperbound = 0;

	  if (index >= *lowerbound && index <= *upperbound)
	    return value_subscripted_rvalue (array, index, *lowerbound);

	  /* Emit warning unless we have an array of unknown size.
	     An array of unknown size has lowerbound 0 and upperbound -1.  */
	  if (*upperbound > -1)
	    warning (_("array or string index out of range"));
	  /* fall doing C stuff */
	  c_style = true;
	}

      index -= *lowerbound;
      array = value_coerce_array (array);
    }

  if (c_style)
    return value_ind (value_ptradd (array, index));
  else
    error (_("not an array or string"));
}

/* Return the value of EXPR[IDX], expr an aggregate rvalue
   (eg, a vector register).  This routine used to promote floats
   to doubles, but no longer does.  */

struct value *
value_subscripted_rvalue (struct value *array, LONGEST index, LONGEST lowerbound)
{
  struct type *array_type = check_typedef (value_type (array));
  struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
  LONGEST elt_size = type_length_units (elt_type);

  /* Fetch the bit stride and convert it to a byte stride, assuming 8 bits
     in a byte.  */
  LONGEST stride = array_type->bit_stride ();
  if (stride != 0)
    {
      struct gdbarch *arch = elt_type->arch ();
      int unit_size = gdbarch_addressable_memory_unit_size (arch);
      elt_size = stride / (unit_size * 8);
    }

  LONGEST elt_offs = elt_size * (index - lowerbound);
  bool array_upper_bound_undefined
    = array_type->bounds ()->high.kind () == PROP_UNDEFINED;

  if (index < lowerbound
      || (!array_upper_bound_undefined
	  && elt_offs >= type_length_units (array_type))
      || (VALUE_LVAL (array) != lval_memory && array_upper_bound_undefined))
    {
      if (type_not_associated (array_type))
	error (_("no such vector element (vector not associated)"));
      else if (type_not_allocated (array_type))
	error (_("no such vector element (vector not allocated)"));
      else
	error (_("no such vector element"));
    }

  if (is_dynamic_type (elt_type))
    {
      CORE_ADDR address;

      address = value_address (array) + elt_offs;
      elt_type = resolve_dynamic_type (elt_type, {}, address);
    }

  return value_from_component (array, elt_type, elt_offs);
}


/* Check to see if either argument is a structure, or a reference to
   one.  This is called so we know whether to go ahead with the normal
   binop or look for a user defined function instead.

   For now, we do not overload the `=' operator.  */

int
binop_types_user_defined_p (enum exp_opcode op,
			    struct type *type1, struct type *type2)
{
  if (op == BINOP_ASSIGN || op == BINOP_CONCAT)
    return 0;

  type1 = check_typedef (type1);
  if (TYPE_IS_REFERENCE (type1))
    type1 = check_typedef (TYPE_TARGET_TYPE (type1));

  type2 = check_typedef (type2);
  if (TYPE_IS_REFERENCE (type2))
    type2 = check_typedef (TYPE_TARGET_TYPE (type2));

  return (type1->code () == TYPE_CODE_STRUCT
	  || type2->code () == TYPE_CODE_STRUCT);
}

/* Check to see if either argument is a structure, or a reference to
   one.  This is called so we know whether to go ahead with the normal
   binop or look for a user defined function instead.

   For now, we do not overload the `=' operator.  */

int
binop_user_defined_p (enum exp_opcode op,
		      struct value *arg1, struct value *arg2)
{
  return binop_types_user_defined_p (op, value_type (arg1), value_type (arg2));
}

/* Check to see if argument is a structure.  This is called so
   we know whether to go ahead with the normal unop or look for a 
   user defined function instead.

   For now, we do not overload the `&' operator.  */

int
unop_user_defined_p (enum exp_opcode op, struct value *arg1)
{
  struct type *type1;

  if (op == UNOP_ADDR)
    return 0;
  type1 = check_typedef (value_type (arg1));
  if (TYPE_IS_REFERENCE (type1))
    type1 = check_typedef (TYPE_TARGET_TYPE (type1));
  return type1->code () == TYPE_CODE_STRUCT;
}

/* Try to find an operator named OPERATOR which takes NARGS arguments
   specified in ARGS.  If the operator found is a static member operator
   *STATIC_MEMFUNP will be set to 1, and otherwise 0.
   The search if performed through find_overload_match which will handle
   member operators, non member operators, operators imported implicitly or
   explicitly, and perform correct overload resolution in all of the above
   situations or combinations thereof.  */

static struct value *
value_user_defined_cpp_op (gdb::array_view<value *> args, char *oper,
			   int *static_memfuncp, enum noside noside)
{

  struct symbol *symp = NULL;
  struct value *valp = NULL;

  find_overload_match (args, oper, BOTH /* could be method */,
		       &args[0] /* objp */,
		       NULL /* pass NULL symbol since symbol is unknown */,
		       &valp, &symp, static_memfuncp, 0, noside);

  if (valp)
    return valp;

  if (symp)
    {
      /* This is a non member function and does not
	 expect a reference as its first argument
	 rather the explicit structure.  */
      args[0] = value_ind (args[0]);
      return value_of_variable (symp, 0);
    }

  error (_("Could not find %s."), oper);
}

/* Lookup user defined operator NAME.  Return a value representing the
   function, otherwise return NULL.  */

static struct value *
value_user_defined_op (struct value **argp, gdb::array_view<value *> args,
		       char *name, int *static_memfuncp, enum noside noside)
{
  struct value *result = NULL;

  if (current_language->la_language == language_cplus)
    {
      result = value_user_defined_cpp_op (args, name, static_memfuncp,
					  noside);
    }
  else
    result = value_struct_elt (argp, args, name, static_memfuncp,
			       "structure");

  return result;
}

/* We know either arg1 or arg2 is a structure, so try to find the right
   user defined function.  Create an argument vector that calls 
   arg1.operator @ (arg1,arg2) and return that value (where '@' is any
   binary operator which is legal for GNU C++).

   OP is the operator, and if it is BINOP_ASSIGN_MODIFY, then OTHEROP
   is the opcode saying how to modify it.  Otherwise, OTHEROP is
   unused.  */

struct value *
value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
	       enum exp_opcode otherop, enum noside noside)
{
  char *ptr;
  char tstr[13];
  int static_memfuncp;

  arg1 = coerce_ref (arg1);
  arg2 = coerce_ref (arg2);

  /* now we know that what we have to do is construct our
     arg vector and find the right function to call it with.  */

  if (check_typedef (value_type (arg1))->code () != TYPE_CODE_STRUCT)
    error (_("Can't do that binary op on that type"));	/* FIXME be explicit */

  value *argvec_storage[3];
  gdb::array_view<value *> argvec = argvec_storage;

  argvec[1] = value_addr (arg1);
  argvec[2] = arg2;

  /* Make the right function name up.  */
  strcpy (tstr, "operator__");
  ptr = tstr + 8;
  switch (op)
    {
    case BINOP_ADD:
      strcpy (ptr, "+");
      break;
    case BINOP_SUB:
      strcpy (ptr, "-");
      break;
    case BINOP_MUL:
      strcpy (ptr, "*");
      break;
    case BINOP_DIV:
      strcpy (ptr, "/");
      break;
    case BINOP_REM:
      strcpy (ptr, "%");
      break;
    case BINOP_LSH:
      strcpy (ptr, "<<");
      break;
    case BINOP_RSH:
      strcpy (ptr, ">>");
      break;
    case BINOP_BITWISE_AND:
      strcpy (ptr, "&");
      break;
    case BINOP_BITWISE_IOR:
      strcpy (ptr, "|");
      break;
    case BINOP_BITWISE_XOR:
      strcpy (ptr, "^");
      break;
    case BINOP_LOGICAL_AND:
      strcpy (ptr, "&&");
      break;
    case BINOP_LOGICAL_OR:
      strcpy (ptr, "||");
      break;
    case BINOP_MIN:
      strcpy (ptr, "<?");
      break;
    case BINOP_MAX:
      strcpy (ptr, ">?");
      break;
    case BINOP_ASSIGN:
      strcpy (ptr, "=");
      break;
    case BINOP_ASSIGN_MODIFY:
      switch (otherop)
	{
	case BINOP_ADD:
	  strcpy (ptr, "+=");
	  break;
	case BINOP_SUB:
	  strcpy (ptr, "-=");
	  break;
	case BINOP_MUL:
	  strcpy (ptr, "*=");
	  break;
	case BINOP_DIV:
	  strcpy (ptr, "/=");
	  break;
	case BINOP_REM:
	  strcpy (ptr, "%=");
	  break;
	case BINOP_BITWISE_AND:
	  strcpy (ptr, "&=");
	  break;
	case BINOP_BITWISE_IOR:
	  strcpy (ptr, "|=");
	  break;
	case BINOP_BITWISE_XOR:
	  strcpy (ptr, "^=");
	  break;
	case BINOP_MOD:	/* invalid */
	default:
	  error (_("Invalid binary operation specified."));
	}
      break;
    case BINOP_SUBSCRIPT:
      strcpy (ptr, "[]");
      break;
    case BINOP_EQUAL:
      strcpy (ptr, "==");
      break;
    case BINOP_NOTEQUAL:
      strcpy (ptr, "!=");
      break;
    case BINOP_LESS:
      strcpy (ptr, "<");
      break;
    case BINOP_GTR:
      strcpy (ptr, ">");
      break;
    case BINOP_GEQ:
      strcpy (ptr, ">=");
      break;
    case BINOP_LEQ:
      strcpy (ptr, "<=");
      break;
    case BINOP_MOD:		/* invalid */
    default:
      error (_("Invalid binary operation specified."));
    }

  argvec[0] = value_user_defined_op (&arg1, argvec.slice (1), tstr,
				     &static_memfuncp, noside);

  if (argvec[0])
    {
      if (static_memfuncp)
	{
	  argvec[1] = argvec[0];
	  argvec = argvec.slice (1);
	}
      if (value_type (argvec[0])->code () == TYPE_CODE_XMETHOD)
	{
	  /* Static xmethods are not supported yet.  */
	  gdb_assert (static_memfuncp == 0);
	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
	    {
	      struct type *return_type
		= result_type_of_xmethod (argvec[0], argvec.slice (1));

	      if (return_type == NULL)
		error (_("Xmethod is missing return type."));
	      return value_zero (return_type, VALUE_LVAL (arg1));
	    }
	  return call_xmethod (argvec[0], argvec.slice (1));
	}
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	{
	  struct type *return_type;

	  return_type
	    = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0])));
	  return value_zero (return_type, VALUE_LVAL (arg1));
	}
      return call_function_by_hand (argvec[0], NULL,
				    argvec.slice (1, 2 - static_memfuncp));
    }
  throw_error (NOT_FOUND_ERROR,
	       _("member function %s not found"), tstr);
}

/* We know that arg1 is a structure, so try to find a unary user
   defined operator that matches the operator in question.
   Create an argument vector that calls arg1.operator @ (arg1)
   and return that value (where '@' is (almost) any unary operator which
   is legal for GNU C++).  */

struct value *
value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
{
  struct gdbarch *gdbarch = value_type (arg1)->arch ();
  char *ptr;
  char tstr[13], mangle_tstr[13];
  int static_memfuncp, nargs;

  arg1 = coerce_ref (arg1);

  /* now we know that what we have to do is construct our
     arg vector and find the right function to call it with.  */

  if (check_typedef (value_type (arg1))->code () != TYPE_CODE_STRUCT)
    error (_("Can't do that unary op on that type"));	/* FIXME be explicit */

  value *argvec_storage[3];
  gdb::array_view<value *> argvec = argvec_storage;

  argvec[1] = value_addr (arg1);
  argvec[2] = 0;

  nargs = 1;

  /* Make the right function name up.  */
  strcpy (tstr, "operator__");
  ptr = tstr + 8;
  strcpy (mangle_tstr, "__");
  switch (op)
    {
    case UNOP_PREINCREMENT:
      strcpy (ptr, "++");
      break;
    case UNOP_PREDECREMENT:
      strcpy (ptr, "--");
      break;
    case UNOP_POSTINCREMENT:
      strcpy (ptr, "++");
      argvec[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
      nargs ++;
      break;
    case UNOP_POSTDECREMENT:
      strcpy (ptr, "--");
      argvec[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
      nargs ++;
      break;
    case UNOP_LOGICAL_NOT:
      strcpy (ptr, "!");
      break;
    case UNOP_COMPLEMENT:
      strcpy (ptr, "~");
      break;
    case UNOP_NEG:
      strcpy (ptr, "-");
      break;
    case UNOP_PLUS:
      strcpy (ptr, "+");
      break;
    case UNOP_IND:
      strcpy (ptr, "*");
      break;
    case STRUCTOP_PTR:
      strcpy (ptr, "->");
      break;
    default:
      error (_("Invalid unary operation specified."));
    }

  argvec[0] = value_user_defined_op (&arg1, argvec.slice (1, nargs), tstr,
				     &static_memfuncp, noside);

  if (argvec[0])
    {
      if (static_memfuncp)
	{
	  argvec[1] = argvec[0];
	  argvec = argvec.slice (1);
	}
      if (value_type (argvec[0])->code () == TYPE_CODE_XMETHOD)
	{
	  /* Static xmethods are not supported yet.  */
	  gdb_assert (static_memfuncp == 0);
	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
	    {
	      struct type *return_type
		= result_type_of_xmethod (argvec[0], argvec[1]);

	      if (return_type == NULL)
		error (_("Xmethod is missing return type."));
	      return value_zero (return_type, VALUE_LVAL (arg1));
	    }
	  return call_xmethod (argvec[0], argvec[1]);
	}
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	{
	  struct type *return_type;

	  return_type
	    = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0])));
	  return value_zero (return_type, VALUE_LVAL (arg1));
	}
      return call_function_by_hand (argvec[0], NULL,
				    argvec.slice (1, nargs));
    }
  throw_error (NOT_FOUND_ERROR,
	       _("member function %s not found"), tstr);
}


/* Concatenate two values with the following conditions:

   (1)  Both values must be either bitstring values or character string
   values and the resulting value consists of the concatenation of
   ARG1 followed by ARG2.

   or

   One value must be an integer value and the other value must be
   either a bitstring value or character string value, which is
   to be repeated by the number of times specified by the integer
   value.


   (2)  Boolean values are also allowed and are treated as bit string
   values of length 1.

   (3)  Character values are also allowed and are treated as character
   string values of length 1.  */

struct value *
value_concat (struct value *arg1, struct value *arg2)
{
  struct value *inval1;
  struct value *inval2;
  struct value *outval = NULL;
  int inval1len, inval2len;
  int count, idx;
  char inchar;
  struct type *type1 = check_typedef (value_type (arg1));
  struct type *type2 = check_typedef (value_type (arg2));
  struct type *char_type;

  /* First figure out if we are dealing with two values to be concatenated
     or a repeat count and a value to be repeated.  INVAL1 is set to the
     first of two concatenated values, or the repeat count.  INVAL2 is set
     to the second of the two concatenated values or the value to be 
     repeated.  */

  if (type2->code () == TYPE_CODE_INT)
    {
      struct type *tmp = type1;

      type1 = tmp;
      tmp = type2;
      inval1 = arg2;
      inval2 = arg1;
    }
  else
    {
      inval1 = arg1;
      inval2 = arg2;
    }

  /* Now process the input values.  */

  if (type1->code () == TYPE_CODE_INT)
    {
      /* We have a repeat count.  Validate the second value and then
	 construct a value repeated that many times.  */
      if (type2->code () == TYPE_CODE_STRING
	  || type2->code () == TYPE_CODE_CHAR)
	{
	  count = longest_to_int (value_as_long (inval1));
	  inval2len = TYPE_LENGTH (type2);
	  std::vector<char> ptr (count * inval2len);
	  if (type2->code () == TYPE_CODE_CHAR)
	    {
	      char_type = type2;

	      inchar = (char) unpack_long (type2,
					   value_contents (inval2));
	      for (idx = 0; idx < count; idx++)
		{
		  ptr[idx] = inchar;
		}
	    }
	  else
	    {
	      char_type = TYPE_TARGET_TYPE (type2);

	      for (idx = 0; idx < count; idx++)
		{
		  memcpy (&ptr[idx * inval2len], value_contents (inval2),
			  inval2len);
		}
	    }
	  outval = value_string (ptr.data (), count * inval2len, char_type);
	}
      else if (type2->code () == TYPE_CODE_BOOL)
	{
	  error (_("unimplemented support for boolean repeats"));
	}
      else
	{
	  error (_("can't repeat values of that type"));
	}
    }
  else if (type1->code () == TYPE_CODE_STRING
	   || type1->code () == TYPE_CODE_CHAR)
    {
      /* We have two character strings to concatenate.  */
      if (type2->code () != TYPE_CODE_STRING
	  && type2->code () != TYPE_CODE_CHAR)
	{
	  error (_("Strings can only be concatenated with other strings."));
	}
      inval1len = TYPE_LENGTH (type1);
      inval2len = TYPE_LENGTH (type2);
      std::vector<char> ptr (inval1len + inval2len);
      if (type1->code () == TYPE_CODE_CHAR)
	{
	  char_type = type1;

	  ptr[0] = (char) unpack_long (type1, value_contents (inval1));
	}
      else
	{
	  char_type = TYPE_TARGET_TYPE (type1);

	  memcpy (ptr.data (), value_contents (inval1), inval1len);
	}
      if (type2->code () == TYPE_CODE_CHAR)
	{
	  ptr[inval1len] =
	    (char) unpack_long (type2, value_contents (inval2));
	}
      else
	{
	  memcpy (&ptr[inval1len], value_contents (inval2), inval2len);
	}
      outval = value_string (ptr.data (), inval1len + inval2len, char_type);
    }
  else if (type1->code () == TYPE_CODE_BOOL)
    {
      /* We have two bitstrings to concatenate.  */
      if (type2->code () != TYPE_CODE_BOOL)
	{
	  error (_("Booleans can only be concatenated "
		   "with other bitstrings or booleans."));
	}
      error (_("unimplemented support for boolean concatenation."));
    }
  else
    {
      /* We don't know how to concatenate these operands.  */
      error (_("illegal operands for concatenation."));
    }
  return (outval);
}

/* Integer exponentiation: V1**V2, where both arguments are
   integers.  Requires V1 != 0 if V2 < 0.  Returns 1 for 0 ** 0.  */

static LONGEST
integer_pow (LONGEST v1, LONGEST v2)
{
  if (v2 < 0)
    {
      if (v1 == 0)
	error (_("Attempt to raise 0 to negative power."));
      else
	return 0;
    }
  else 
    {
      /* The Russian Peasant's Algorithm.  */
      LONGEST v;
      
      v = 1;
      for (;;)
	{
	  if (v2 & 1L) 
	    v *= v1;
	  v2 >>= 1;
	  if (v2 == 0)
	    return v;
	  v1 *= v1;
	}
    }
}

/* Obtain argument values for binary operation, converting from
   other types if one of them is not floating point.  */
static void
value_args_as_target_float (struct value *arg1, struct value *arg2,
			    gdb_byte *x, struct type **eff_type_x,
			    gdb_byte *y, struct type **eff_type_y)
{
  struct type *type1, *type2;

  type1 = check_typedef (value_type (arg1));
  type2 = check_typedef (value_type (arg2));

  /* At least one of the arguments must be of floating-point type.  */
  gdb_assert (is_floating_type (type1) || is_floating_type (type2));

  if (is_floating_type (type1) && is_floating_type (type2)
      && type1->code () != type2->code ())
    /* The DFP extension to the C language does not allow mixing of
     * decimal float types with other float types in expressions
     * (see WDTR 24732, page 12).  */
    error (_("Mixing decimal floating types with "
	     "other floating types is not allowed."));

  /* Obtain value of arg1, converting from other types if necessary.  */

  if (is_floating_type (type1))
    {
      *eff_type_x = type1;
      memcpy (x, value_contents (arg1), TYPE_LENGTH (type1));
    }
  else if (is_integral_type (type1))
    {
      *eff_type_x = type2;
      if (type1->is_unsigned ())
	target_float_from_ulongest (x, *eff_type_x, value_as_long (arg1));
      else
	target_float_from_longest (x, *eff_type_x, value_as_long (arg1));
    }
  else
    error (_("Don't know how to convert from %s to %s."), type1->name (),
	     type2->name ());

  /* Obtain value of arg2, converting from other types if necessary.  */

  if (is_floating_type (type2))
    {
      *eff_type_y = type2;
      memcpy (y, value_contents (arg2), TYPE_LENGTH (type2));
    }
  else if (is_integral_type (type2))
    {
      *eff_type_y = type1;
      if (type2->is_unsigned ())
	target_float_from_ulongest (y, *eff_type_y, value_as_long (arg2));
      else
	target_float_from_longest (y, *eff_type_y, value_as_long (arg2));
    }
  else
    error (_("Don't know how to convert from %s to %s."), type1->name (),
	     type2->name ());
}

/* Assuming at last one of ARG1 or ARG2 is a fixed point value,
   perform the binary operation OP on these two operands, and return
   the resulting value (also as a fixed point).  */

static struct value *
fixed_point_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
{
  struct type *type1 = check_typedef (value_type (arg1));
  struct type *type2 = check_typedef (value_type (arg2));
  const struct language_defn *language = current_language;

  struct gdbarch *gdbarch = type1->arch ();
  struct value *val;

  gdb_mpq v1, v2, res;

  gdb_assert (is_fixed_point_type (type1) || is_fixed_point_type (type2));
  if (op == BINOP_MUL || op == BINOP_DIV)
    {
      v1 = value_to_gdb_mpq (arg1);
      v2 = value_to_gdb_mpq (arg2);

      /* The code below uses TYPE1 for the result type, so make sure
	 it is set properly.  */
      if (!is_fixed_point_type (type1))
	type1 = type2;
    }
  else
    {
      if (!is_fixed_point_type (type1))
	{
	  arg1 = value_cast (type2, arg1);
	  type1 = type2;
	}
      if (!is_fixed_point_type (type2))
	{
	  arg2 = value_cast (type1, arg2);
	  type2 = type1;
	}

      v1.read_fixed_point (gdb::make_array_view (value_contents (arg1),
						 TYPE_LENGTH (type1)),
			   type_byte_order (type1), type1->is_unsigned (),
			   type1->fixed_point_scaling_factor ());
      v2.read_fixed_point (gdb::make_array_view (value_contents (arg2),
						 TYPE_LENGTH (type2)),
			   type_byte_order (type2), type2->is_unsigned (),
			   type2->fixed_point_scaling_factor ());
    }

  auto fixed_point_to_value = [type1] (const gdb_mpq &fp)
    {
      value *fp_val = allocate_value (type1);

      fp.write_fixed_point
	(gdb::make_array_view (value_contents_raw (fp_val),
			       TYPE_LENGTH (type1)),
	 type_byte_order (type1),
	 type1->is_unsigned (),
	 type1->fixed_point_scaling_factor ());

      return fp_val;
    };

  switch (op)
    {
    case BINOP_ADD:
      mpq_add (res.val, v1.val, v2.val);
      val = fixed_point_to_value (res);
      break;

    case BINOP_SUB:
      mpq_sub (res.val, v1.val, v2.val);
      val = fixed_point_to_value (res);
      break;

    case BINOP_MIN:
      val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) < 0 ? v1 : v2);
      break;

    case BINOP_MAX:
      val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) > 0 ? v1 : v2);
      break;

    case BINOP_MUL:
      mpq_mul (res.val, v1.val, v2.val);
      val = fixed_point_to_value (res);
      break;

    case BINOP_DIV:
      if (mpq_sgn (v2.val) == 0)
	error (_("Division by zero"));
      mpq_div (res.val, v1.val, v2.val);
      val = fixed_point_to_value (res);
      break;

    case BINOP_EQUAL:
      val = value_from_ulongest (language_bool_type (language, gdbarch),
				 mpq_cmp (v1.val, v2.val) == 0 ? 1 : 0);
      break;

    case BINOP_LESS:
      val = value_from_ulongest (language_bool_type (language, gdbarch),
				 mpq_cmp (v1.val, v2.val) < 0 ? 1 : 0);
      break;

    default:
      error (_("Integer-only operation on fixed point number."));
    }

  return val;
}

/* A helper function that finds the type to use for a binary operation
   involving TYPE1 and TYPE2.  */

static struct type *
promotion_type (struct type *type1, struct type *type2)
{
  struct type *result_type;

  if (is_floating_type (type1) || is_floating_type (type2))
    {
      /* If only one type is floating-point, use its type.
	 Otherwise use the bigger type.  */
      if (!is_floating_type (type1))
	result_type = type2;
      else if (!is_floating_type (type2))
	result_type = type1;
      else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1))
	result_type = type2;
      else
	result_type = type1;
    }
  else
    {
      /* Integer types.  */
      if (TYPE_LENGTH (type1) > TYPE_LENGTH (type2))
	result_type = type1;
      else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1))
	result_type = type2;
      else if (type1->is_unsigned ())
	result_type = type1;
      else if (type2->is_unsigned ())
	result_type = type2;
      else
	result_type = type1;
    }

  return result_type;
}

static struct value *scalar_binop (struct value *arg1, struct value *arg2,
				   enum exp_opcode op);

/* Perform a binary operation on complex operands.  */

static struct value *
complex_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
{
  struct type *arg1_type = check_typedef (value_type (arg1));
  struct type *arg2_type = check_typedef (value_type (arg2));

  struct value *arg1_real, *arg1_imag, *arg2_real, *arg2_imag;
  if (arg1_type->code () == TYPE_CODE_COMPLEX)
    {
      arg1_real = value_real_part (arg1);
      arg1_imag = value_imaginary_part (arg1);
    }
  else
    {
      arg1_real = arg1;
      arg1_imag = value_zero (arg1_type, not_lval);
    }
  if (arg2_type->code () == TYPE_CODE_COMPLEX)
    {
      arg2_real = value_real_part (arg2);
      arg2_imag = value_imaginary_part (arg2);
    }
  else
    {
      arg2_real = arg2;
      arg2_imag = value_zero (arg2_type, not_lval);
    }

  struct type *comp_type = promotion_type (value_type (arg1_real),
					   value_type (arg2_real));
  if (!can_create_complex_type (comp_type))
    error (_("Argument to complex arithmetic operation not supported."));

  arg1_real = value_cast (comp_type, arg1_real);
  arg1_imag = value_cast (comp_type, arg1_imag);
  arg2_real = value_cast (comp_type, arg2_real);
  arg2_imag = value_cast (comp_type, arg2_imag);

  struct type *result_type = init_complex_type (nullptr, comp_type);

  struct value *result_real, *result_imag;
  switch (op)
    {
    case BINOP_ADD:
    case BINOP_SUB:
      result_real = scalar_binop (arg1_real, arg2_real, op);
      result_imag = scalar_binop (arg1_imag, arg2_imag, op);
      break;

    case BINOP_MUL:
      {
	struct value *x1 = scalar_binop (arg1_real, arg2_real, op);
	struct value *x2 = scalar_binop (arg1_imag, arg2_imag, op);
	result_real = scalar_binop (x1, x2, BINOP_SUB);

	x1 = scalar_binop (arg1_real, arg2_imag, op);
	x2 = scalar_binop (arg1_imag, arg2_real, op);
	result_imag = scalar_binop (x1, x2, BINOP_ADD);
      }
      break;

    case BINOP_DIV:
      {
	if (arg2_type->code () == TYPE_CODE_COMPLEX)
	  {
	    struct value *conjugate = value_complement (arg2);
	    /* We have to reconstruct ARG1, in case the type was
	       promoted.  */
	    arg1 = value_literal_complex (arg1_real, arg1_imag, result_type);

	    struct value *numerator = scalar_binop (arg1, conjugate,
						    BINOP_MUL);
	    arg1_real = value_real_part (numerator);
	    arg1_imag = value_imaginary_part (numerator);

	    struct value *x1 = scalar_binop (arg2_real, arg2_real, BINOP_MUL);
	    struct value *x2 = scalar_binop (arg2_imag, arg2_imag, BINOP_MUL);
	    arg2_real = scalar_binop (x1, x2, BINOP_ADD);
	  }

	result_real = scalar_binop (arg1_real, arg2_real, op);
	result_imag = scalar_binop (arg1_imag, arg2_real, op);
      }
      break;

    case BINOP_EQUAL:
    case BINOP_NOTEQUAL:
      {
	struct value *x1 = scalar_binop (arg1_real, arg2_real, op);
	struct value *x2 = scalar_binop (arg1_imag, arg2_imag, op);

	LONGEST v1 = value_as_long (x1);
	LONGEST v2 = value_as_long (x2);

	if (op == BINOP_EQUAL)
	  v1 = v1 && v2;
	else
	  v1 = v1 || v2;

	return value_from_longest (value_type (x1), v1);
      }
      break;

    default:
      error (_("Invalid binary operation on numbers."));
    }

  return value_literal_complex (result_real, result_imag, result_type);
}

/* Perform a binary operation on two operands which have reasonable
   representations as integers or floats.  This includes booleans,
   characters, integers, or floats.
   Does not support addition and subtraction on pointers;
   use value_ptradd, value_ptrsub or value_ptrdiff for those operations.  */

static struct value *
scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
{
  struct value *val;
  struct type *type1, *type2, *result_type;

  arg1 = coerce_ref (arg1);
  arg2 = coerce_ref (arg2);

  type1 = check_typedef (value_type (arg1));
  type2 = check_typedef (value_type (arg2));

  if (type1->code () == TYPE_CODE_COMPLEX
      || type2->code () == TYPE_CODE_COMPLEX)
    return complex_binop (arg1, arg2, op);

  if ((!is_floating_value (arg1)
       && !is_integral_type (type1)
       && !is_fixed_point_type (type1))
      || (!is_floating_value (arg2)
	  && !is_integral_type (type2)
	  && !is_fixed_point_type (type2)))
    error (_("Argument to arithmetic operation not a number or boolean."));

  if (is_fixed_point_type (type1) || is_fixed_point_type (type2))
    return fixed_point_binop (arg1, arg2, op);

  if (is_floating_type (type1) || is_floating_type (type2))
    {
      result_type = promotion_type (type1, type2);
      val = allocate_value (result_type);

      struct type *eff_type_v1, *eff_type_v2;
      gdb::byte_vector v1, v2;
      v1.resize (TYPE_LENGTH (result_type));
      v2.resize (TYPE_LENGTH (result_type));

      value_args_as_target_float (arg1, arg2,
				  v1.data (), &eff_type_v1,
				  v2.data (), &eff_type_v2);
      target_float_binop (op, v1.data (), eff_type_v1,
			      v2.data (), eff_type_v2,
			      value_contents_raw (val), result_type);
    }
  else if (type1->code () == TYPE_CODE_BOOL
	   || type2->code () == TYPE_CODE_BOOL)
    {
      LONGEST v1, v2, v = 0;

      v1 = value_as_long (arg1);
      v2 = value_as_long (arg2);

      switch (op)
	{
	case BINOP_BITWISE_AND:
	  v = v1 & v2;
	  break;

	case BINOP_BITWISE_IOR:
	  v = v1 | v2;
	  break;

	case BINOP_BITWISE_XOR:
	  v = v1 ^ v2;
	  break;
	      
	case BINOP_EQUAL:
	  v = v1 == v2;
	  break;
	  
	case BINOP_NOTEQUAL:
	  v = v1 != v2;
	  break;

	default:
	  error (_("Invalid operation on booleans."));
	}

      result_type = type1;

      val = allocate_value (result_type);
      store_signed_integer (value_contents_raw (val),
			    TYPE_LENGTH (result_type),
			    type_byte_order (result_type),
			    v);
    }
  else
    /* Integral operations here.  */
    {
      /* Determine type length of the result, and if the operation should
	 be done unsigned.  For exponentiation and shift operators,
	 use the length and type of the left operand.  Otherwise,
	 use the signedness of the operand with the greater length.
	 If both operands are of equal length, use unsigned operation
	 if one of the operands is unsigned.  */
      if (op == BINOP_RSH || op == BINOP_LSH || op == BINOP_EXP)
	result_type = type1;
      else
	result_type = promotion_type (type1, type2);

      if (result_type->is_unsigned ())
	{
	  LONGEST v2_signed = value_as_long (arg2);
	  ULONGEST v1, v2, v = 0;

	  v1 = (ULONGEST) value_as_long (arg1);
	  v2 = (ULONGEST) v2_signed;

	  switch (op)
	    {
	    case BINOP_ADD:
	      v = v1 + v2;
	      break;

	    case BINOP_SUB:
	      v = v1 - v2;
	      break;

	    case BINOP_MUL:
	      v = v1 * v2;
	      break;

	    case BINOP_DIV:
	    case BINOP_INTDIV:
	      if (v2 != 0)
		v = v1 / v2;
	      else
		error (_("Division by zero"));
	      break;

	    case BINOP_EXP:
	      v = uinteger_pow (v1, v2_signed);
	      break;

	    case BINOP_REM:
	      if (v2 != 0)
		v = v1 % v2;
	      else
		error (_("Division by zero"));
	      break;

	    case BINOP_MOD:
	      /* Knuth 1.2.4, integer only.  Note that unlike the C '%' op,
		 v1 mod 0 has a defined value, v1.  */
	      if (v2 == 0)
		{
		  v = v1;
		}
	      else
		{
		  v = v1 / v2;
		  /* Note floor(v1/v2) == v1/v2 for unsigned.  */
		  v = v1 - (v2 * v);
		}
	      break;

	    case BINOP_LSH:
	      v = v1 << v2;
	      break;

	    case BINOP_RSH:
	      v = v1 >> v2;
	      break;

	    case BINOP_BITWISE_AND:
	      v = v1 & v2;
	      break;

	    case BINOP_BITWISE_IOR:
	      v = v1 | v2;
	      break;

	    case BINOP_BITWISE_XOR:
	      v = v1 ^ v2;
	      break;

	    case BINOP_LOGICAL_AND:
	      v = v1 && v2;
	      break;

	    case BINOP_LOGICAL_OR:
	      v = v1 || v2;
	      break;

	    case BINOP_MIN:
	      v = v1 < v2 ? v1 : v2;
	      break;

	    case BINOP_MAX:
	      v = v1 > v2 ? v1 : v2;
	      break;

	    case BINOP_EQUAL:
	      v = v1 == v2;
	      break;

	    case BINOP_NOTEQUAL:
	      v = v1 != v2;
	      break;

	    case BINOP_LESS:
	      v = v1 < v2;
	      break;

	    case BINOP_GTR:
	      v = v1 > v2;
	      break;

	    case BINOP_LEQ:
	      v = v1 <= v2;
	      break;

	    case BINOP_GEQ:
	      v = v1 >= v2;
	      break;

	    default:
	      error (_("Invalid binary operation on numbers."));
	    }

	  val = allocate_value (result_type);
	  store_unsigned_integer (value_contents_raw (val),
				  TYPE_LENGTH (value_type (val)),
				  type_byte_order (result_type),
				  v);
	}
      else
	{
	  LONGEST v1, v2, v = 0;

	  v1 = value_as_long (arg1);
	  v2 = value_as_long (arg2);

	  switch (op)
	    {
	    case BINOP_ADD:
	      v = v1 + v2;
	      break;

	    case BINOP_SUB:
	      v = v1 - v2;
	      break;

	    case BINOP_MUL:
	      v = v1 * v2;
	      break;

	    case BINOP_DIV:
	    case BINOP_INTDIV:
	      if (v2 != 0)
		v = v1 / v2;
	      else
		error (_("Division by zero"));
	      break;

	    case BINOP_EXP:
	      v = integer_pow (v1, v2);
	      break;

	    case BINOP_REM:
	      if (v2 != 0)
		v = v1 % v2;
	      else
		error (_("Division by zero"));
	      break;

	    case BINOP_MOD:
	      /* Knuth 1.2.4, integer only.  Note that unlike the C '%' op,
		 X mod 0 has a defined value, X.  */
	      if (v2 == 0)
		{
		  v = v1;
		}
	      else
		{
		  v = v1 / v2;
		  /* Compute floor.  */
		  if (TRUNCATION_TOWARDS_ZERO && (v < 0) && ((v1 % v2) != 0))
		    {
		      v--;
		    }
		  v = v1 - (v2 * v);
		}
	      break;

	    case BINOP_LSH:
	      v = v1 << v2;
	      break;

	    case BINOP_RSH:
	      v = v1 >> v2;
	      break;

	    case BINOP_BITWISE_AND:
	      v = v1 & v2;
	      break;

	    case BINOP_BITWISE_IOR:
	      v = v1 | v2;
	      break;

	    case BINOP_BITWISE_XOR:
	      v = v1 ^ v2;
	      break;

	    case BINOP_LOGICAL_AND:
	      v = v1 && v2;
	      break;

	    case BINOP_LOGICAL_OR:
	      v = v1 || v2;
	      break;

	    case BINOP_MIN:
	      v = v1 < v2 ? v1 : v2;
	      break;

	    case BINOP_MAX:
	      v = v1 > v2 ? v1 : v2;
	      break;

	    case BINOP_EQUAL:
	      v = v1 == v2;
	      break;

	    case BINOP_NOTEQUAL:
	      v = v1 != v2;
	      break;

	    case BINOP_LESS:
	      v = v1 < v2;
	      break;

	    case BINOP_GTR:
	      v = v1 > v2;
	      break;

	    case BINOP_LEQ:
	      v = v1 <= v2;
	      break;

	    case BINOP_GEQ:
	      v = v1 >= v2;
	      break;

	    default:
	      error (_("Invalid binary operation on numbers."));
	    }

	  val = allocate_value (result_type);
	  store_signed_integer (value_contents_raw (val),
				TYPE_LENGTH (value_type (val)),
				type_byte_order (result_type),
				v);
	}
    }

  return val;
}

/* Widen a scalar value SCALAR_VALUE to vector type VECTOR_TYPE by
   replicating SCALAR_VALUE for each element of the vector.  Only scalar
   types that can be cast to the type of one element of the vector are
   acceptable.  The newly created vector value is returned upon success,
   otherwise an error is thrown.  */

struct value *
value_vector_widen (struct value *scalar_value, struct type *vector_type)
{
  /* Widen the scalar to a vector.  */
  struct type *eltype, *scalar_type;
  struct value *val, *elval;
  LONGEST low_bound, high_bound;
  int i;

  vector_type = check_typedef (vector_type);

  gdb_assert (vector_type->code () == TYPE_CODE_ARRAY
	      && vector_type->is_vector ());

  if (!get_array_bounds (vector_type, &low_bound, &high_bound))
    error (_("Could not determine the vector bounds"));

  eltype = check_typedef (TYPE_TARGET_TYPE (vector_type));
  elval = value_cast (eltype, scalar_value);

  scalar_type = check_typedef (value_type (scalar_value));

  /* If we reduced the length of the scalar then check we didn't loose any
     important bits.  */
  if (TYPE_LENGTH (eltype) < TYPE_LENGTH (scalar_type)
      && !value_equal (elval, scalar_value))
    error (_("conversion of scalar to vector involves truncation"));

  val = allocate_value (vector_type);
  for (i = 0; i < high_bound - low_bound + 1; i++)
    /* Duplicate the contents of elval into the destination vector.  */
    memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
	    value_contents_all (elval), TYPE_LENGTH (eltype));

  return val;
}

/* Performs a binary operation on two vector operands by calling scalar_binop
   for each pair of vector components.  */

static struct value *
vector_binop (struct value *val1, struct value *val2, enum exp_opcode op)
{
  struct value *val, *tmp, *mark;
  struct type *type1, *type2, *eltype1, *eltype2;
  int t1_is_vec, t2_is_vec, elsize, i;
  LONGEST low_bound1, high_bound1, low_bound2, high_bound2;

  type1 = check_typedef (value_type (val1));
  type2 = check_typedef (value_type (val2));

  t1_is_vec = (type1->code () == TYPE_CODE_ARRAY
	       && type1->is_vector ()) ? 1 : 0;
  t2_is_vec = (type2->code () == TYPE_CODE_ARRAY
	       && type2->is_vector ()) ? 1 : 0;

  if (!t1_is_vec || !t2_is_vec)
    error (_("Vector operations are only supported among vectors"));

  if (!get_array_bounds (type1, &low_bound1, &high_bound1)
      || !get_array_bounds (type2, &low_bound2, &high_bound2))
    error (_("Could not determine the vector bounds"));

  eltype1 = check_typedef (TYPE_TARGET_TYPE (type1));
  eltype2 = check_typedef (TYPE_TARGET_TYPE (type2));
  elsize = TYPE_LENGTH (eltype1);

  if (eltype1->code () != eltype2->code ()
      || elsize != TYPE_LENGTH (eltype2)
      || eltype1->is_unsigned () != eltype2->is_unsigned ()
      || low_bound1 != low_bound2 || high_bound1 != high_bound2)
    error (_("Cannot perform operation on vectors with different types"));

  val = allocate_value (type1);
  mark = value_mark ();
  for (i = 0; i < high_bound1 - low_bound1 + 1; i++)
    {
      tmp = value_binop (value_subscript (val1, i),
			 value_subscript (val2, i), op);
      memcpy (value_contents_writeable (val) + i * elsize,
	      value_contents_all (tmp),
	      elsize);
     }
  value_free_to_mark (mark);

  return val;
}

/* Perform a binary operation on two operands.  */

struct value *
value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
{
  struct value *val;
  struct type *type1 = check_typedef (value_type (arg1));
  struct type *type2 = check_typedef (value_type (arg2));
  int t1_is_vec = (type1->code () == TYPE_CODE_ARRAY
		   && type1->is_vector ());
  int t2_is_vec = (type2->code () == TYPE_CODE_ARRAY
		   && type2->is_vector ());

  if (!t1_is_vec && !t2_is_vec)
    val = scalar_binop (arg1, arg2, op);
  else if (t1_is_vec && t2_is_vec)
    val = vector_binop (arg1, arg2, op);
  else
    {
      /* Widen the scalar operand to a vector.  */
      struct value **v = t1_is_vec ? &arg2 : &arg1;
      struct type *t = t1_is_vec ? type2 : type1;
      
      if (t->code () != TYPE_CODE_FLT
	  && t->code () != TYPE_CODE_DECFLOAT
	  && !is_integral_type (t))
	error (_("Argument to operation not a number or boolean."));

      /* Replicate the scalar value to make a vector value.  */
      *v = value_vector_widen (*v, t1_is_vec ? type1 : type2);

      val = vector_binop (arg1, arg2, op);
    }

  return val;
}

/* Simulate the C operator ! -- return 1 if ARG1 contains zero.  */

int
value_logical_not (struct value *arg1)
{
  int len;
  const gdb_byte *p;
  struct type *type1;

  arg1 = coerce_array (arg1);
  type1 = check_typedef (value_type (arg1));

  if (is_floating_value (arg1))
    return target_float_is_zero (value_contents (arg1), type1);

  len = TYPE_LENGTH (type1);
  p = value_contents (arg1);

  while (--len >= 0)
    {
      if (*p++)
	break;
    }

  return len < 0;
}

/* Perform a comparison on two string values (whose content are not
   necessarily null terminated) based on their length.  */

static int
value_strcmp (struct value *arg1, struct value *arg2)
{
  int len1 = TYPE_LENGTH (value_type (arg1));
  int len2 = TYPE_LENGTH (value_type (arg2));
  const gdb_byte *s1 = value_contents (arg1);
  const gdb_byte *s2 = value_contents (arg2);
  int i, len = len1 < len2 ? len1 : len2;

  for (i = 0; i < len; i++)
    {
      if (s1[i] < s2[i])
	return -1;
      else if (s1[i] > s2[i])
	return 1;
      else
	continue;
    }

  if (len1 < len2)
    return -1;
  else if (len1 > len2)
    return 1;
  else
    return 0;
}

/* Simulate the C operator == by returning a 1
   iff ARG1 and ARG2 have equal contents.  */

int
value_equal (struct value *arg1, struct value *arg2)
{
  int len;
  const gdb_byte *p1;
  const gdb_byte *p2;
  struct type *type1, *type2;
  enum type_code code1;
  enum type_code code2;
  int is_int1, is_int2;

  arg1 = coerce_array (arg1);
  arg2 = coerce_array (arg2);

  type1 = check_typedef (value_type (arg1));
  type2 = check_typedef (value_type (arg2));
  code1 = type1->code ();
  code2 = type2->code ();
  is_int1 = is_integral_type (type1);
  is_int2 = is_integral_type (type2);

  if (is_int1 && is_int2)
    return longest_to_int (value_as_long (value_binop (arg1, arg2,
						       BINOP_EQUAL)));
  else if ((is_floating_value (arg1) || is_int1)
	   && (is_floating_value (arg2) || is_int2))
    {
      struct type *eff_type_v1, *eff_type_v2;
      gdb::byte_vector v1, v2;
      v1.resize (std::max (TYPE_LENGTH (type1), TYPE_LENGTH (type2)));
      v2.resize (std::max (TYPE_LENGTH (type1), TYPE_LENGTH (type2)));

      value_args_as_target_float (arg1, arg2,
				  v1.data (), &eff_type_v1,
				  v2.data (), &eff_type_v2);

      return target_float_compare (v1.data (), eff_type_v1,
				   v2.data (), eff_type_v2) == 0;
    }

  /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
     is bigger.  */
  else if (code1 == TYPE_CODE_PTR && is_int2)
    return value_as_address (arg1) == (CORE_ADDR) value_as_long (arg2);
  else if (code2 == TYPE_CODE_PTR && is_int1)
    return (CORE_ADDR) value_as_long (arg1) == value_as_address (arg2);

  else if (code1 == code2
	   && ((len = (int) TYPE_LENGTH (type1))
	       == (int) TYPE_LENGTH (type2)))
    {
      p1 = value_contents (arg1);
      p2 = value_contents (arg2);
      while (--len >= 0)
	{
	  if (*p1++ != *p2++)
	    break;
	}
      return len < 0;
    }
  else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING)
    {
      return value_strcmp (arg1, arg2) == 0;
    }
  else
    error (_("Invalid type combination in equality test."));
}

/* Compare values based on their raw contents.  Useful for arrays since
   value_equal coerces them to pointers, thus comparing just the address
   of the array instead of its contents.  */

int
value_equal_contents (struct value *arg1, struct value *arg2)
{
  struct type *type1, *type2;

  type1 = check_typedef (value_type (arg1));
  type2 = check_typedef (value_type (arg2));

  return (type1->code () == type2->code ()
	  && TYPE_LENGTH (type1) == TYPE_LENGTH (type2)
	  && memcmp (value_contents (arg1), value_contents (arg2),
		     TYPE_LENGTH (type1)) == 0);
}

/* Simulate the C operator < by returning 1
   iff ARG1's contents are less than ARG2's.  */

int
value_less (struct value *arg1, struct value *arg2)
{
  enum type_code code1;
  enum type_code code2;
  struct type *type1, *type2;
  int is_int1, is_int2;

  arg1 = coerce_array (arg1);
  arg2 = coerce_array (arg2);

  type1 = check_typedef (value_type (arg1));
  type2 = check_typedef (value_type (arg2));
  code1 = type1->code ();
  code2 = type2->code ();
  is_int1 = is_integral_type (type1);
  is_int2 = is_integral_type (type2);

  if ((is_int1 && is_int2)
      || (is_fixed_point_type (type1) && is_fixed_point_type (type2)))
    return longest_to_int (value_as_long (value_binop (arg1, arg2,
						       BINOP_LESS)));
  else if ((is_floating_value (arg1) || is_int1)
	   && (is_floating_value (arg2) || is_int2))
    {
      struct type *eff_type_v1, *eff_type_v2;
      gdb::byte_vector v1, v2;
      v1.resize (std::max (TYPE_LENGTH (type1), TYPE_LENGTH (type2)));
      v2.resize (std::max (TYPE_LENGTH (type1), TYPE_LENGTH (type2)));

      value_args_as_target_float (arg1, arg2,
				  v1.data (), &eff_type_v1,
				  v2.data (), &eff_type_v2);

      return target_float_compare (v1.data (), eff_type_v1,
				   v2.data (), eff_type_v2) == -1;
    }
  else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
    return value_as_address (arg1) < value_as_address (arg2);

  /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
     is bigger.  */
  else if (code1 == TYPE_CODE_PTR && is_int2)
    return value_as_address (arg1) < (CORE_ADDR) value_as_long (arg2);
  else if (code2 == TYPE_CODE_PTR && is_int1)
    return (CORE_ADDR) value_as_long (arg1) < value_as_address (arg2);
  else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING)
    return value_strcmp (arg1, arg2) < 0;
  else
    {
      error (_("Invalid type combination in ordering comparison."));
      return 0;
    }
}

/* The unary operators +, - and ~.  They free the argument ARG1.  */

struct value *
value_pos (struct value *arg1)
{
  struct type *type;

  arg1 = coerce_ref (arg1);
  type = check_typedef (value_type (arg1));

  if (is_integral_type (type) || is_floating_value (arg1)
      || (type->code () == TYPE_CODE_ARRAY && type->is_vector ())
      || type->code () == TYPE_CODE_COMPLEX)
    return value_from_contents (type, value_contents (arg1));
  else
    error (_("Argument to positive operation not a number."));
}

struct value *
value_neg (struct value *arg1)
{
  struct type *type;

  arg1 = coerce_ref (arg1);
  type = check_typedef (value_type (arg1));

  if (is_integral_type (type) || is_floating_type (type))
    return value_binop (value_from_longest (type, 0), arg1, BINOP_SUB);
  else if (is_fixed_point_type (type))
    return value_binop (value_zero (type, not_lval), arg1, BINOP_SUB);
  else if (type->code () == TYPE_CODE_ARRAY && type->is_vector ())
    {
      struct value *tmp, *val = allocate_value (type);
      struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
      int i;
      LONGEST low_bound, high_bound;

      if (!get_array_bounds (type, &low_bound, &high_bound))
	error (_("Could not determine the vector bounds"));

      for (i = 0; i < high_bound - low_bound + 1; i++)
	{
	  tmp = value_neg (value_subscript (arg1, i));
	  memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype),
		  value_contents_all (tmp), TYPE_LENGTH (eltype));
	}
      return val;
    }
  else if (type->code () == TYPE_CODE_COMPLEX)
    {
      struct value *real = value_real_part (arg1);
      struct value *imag = value_imaginary_part (arg1);

      real = value_neg (real);
      imag = value_neg (imag);
      return value_literal_complex (real, imag, type);
    }
  else
    error (_("Argument to negate operation not a number."));
}

struct value *
value_complement (struct value *arg1)
{
  struct type *type;
  struct value *val;

  arg1 = coerce_ref (arg1);
  type = check_typedef (value_type (arg1));

  if (is_integral_type (type))
    val = value_from_longest (type, ~value_as_long (arg1));
  else if (type->code () == TYPE_CODE_ARRAY && type->is_vector ())
    {
      struct value *tmp;
      struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
      int i;
      LONGEST low_bound, high_bound;

      if (!get_array_bounds (type, &low_bound, &high_bound))
	error (_("Could not determine the vector bounds"));

      val = allocate_value (type);
      for (i = 0; i < high_bound - low_bound + 1; i++)
	{
	  tmp = value_complement (value_subscript (arg1, i));
	  memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype),
		  value_contents_all (tmp), TYPE_LENGTH (eltype));
	}
    }
  else if (type->code () == TYPE_CODE_COMPLEX)
    {
      /* GCC has an extension that treats ~complex as the complex
	 conjugate.  */
      struct value *real = value_real_part (arg1);
      struct value *imag = value_imaginary_part (arg1);

      imag = value_neg (imag);
      return value_literal_complex (real, imag, type);
    }
  else
    error (_("Argument to complement operation not an integer, boolean."));

  return val;
}

/* The INDEX'th bit of SET value whose value_type is TYPE,
   and whose value_contents is valaddr.
   Return -1 if out of range, -2 other error.  */

int
value_bit_index (struct type *type, const gdb_byte *valaddr, int index)
{
  struct gdbarch *gdbarch = type->arch ();
  LONGEST low_bound, high_bound;
  LONGEST word;
  unsigned rel_index;
  struct type *range = type->index_type ();

  if (!get_discrete_bounds (range, &low_bound, &high_bound))
    return -2;
  if (index < low_bound || index > high_bound)
    return -1;
  rel_index = index - low_bound;
  word = extract_unsigned_integer (valaddr + (rel_index / TARGET_CHAR_BIT), 1,
				   type_byte_order (type));
  rel_index %= TARGET_CHAR_BIT;
  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
    rel_index = TARGET_CHAR_BIT - 1 - rel_index;
  return (word >> rel_index) & 1;
}

int
value_in (struct value *element, struct value *set)
{
  int member;
  struct type *settype = check_typedef (value_type (set));
  struct type *eltype = check_typedef (value_type (element));

  if (eltype->code () == TYPE_CODE_RANGE)
    eltype = TYPE_TARGET_TYPE (eltype);
  if (settype->code () != TYPE_CODE_SET)
    error (_("Second argument of 'IN' has wrong type"));
  if (eltype->code () != TYPE_CODE_INT
      && eltype->code () != TYPE_CODE_CHAR
      && eltype->code () != TYPE_CODE_ENUM
      && eltype->code () != TYPE_CODE_BOOL)
    error (_("First argument of 'IN' has wrong type"));
  member = value_bit_index (settype, value_contents (set),
			    value_as_long (element));
  if (member < 0)
    error (_("First argument of 'IN' not in range"));
  return member;
}
