119370Spst/* Perform arithmetic and other operations on values, for GDB.
2130803Smarcel
398944Sobrien   Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
4130803Smarcel   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
5130803Smarcel   Foundation, Inc.
619370Spst
798944Sobrien   This file is part of GDB.
819370Spst
998944Sobrien   This program is free software; you can redistribute it and/or modify
1098944Sobrien   it under the terms of the GNU General Public License as published by
1198944Sobrien   the Free Software Foundation; either version 2 of the License, or
1298944Sobrien   (at your option) any later version.
1319370Spst
1498944Sobrien   This program is distributed in the hope that it will be useful,
1598944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1698944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1798944Sobrien   GNU General Public License for more details.
1819370Spst
1998944Sobrien   You should have received a copy of the GNU General Public License
2098944Sobrien   along with this program; if not, write to the Free Software
2198944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2298944Sobrien   Boston, MA 02111-1307, USA.  */
2319370Spst
2419370Spst#include "defs.h"
2519370Spst#include "value.h"
2619370Spst#include "symtab.h"
2719370Spst#include "gdbtypes.h"
2819370Spst#include "expression.h"
2919370Spst#include "target.h"
3019370Spst#include "language.h"
3119370Spst#include "gdb_string.h"
3298944Sobrien#include "doublest.h"
3398944Sobrien#include <math.h>
34130803Smarcel#include "infcall.h"
3519370Spst
3619370Spst/* Define whether or not the C operator '/' truncates towards zero for
3719370Spst   differently signed operands (truncation direction is undefined in C). */
3819370Spst
3919370Spst#ifndef TRUNCATION_TOWARDS_ZERO
4019370Spst#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2)
4119370Spst#endif
4219370Spst
4398944Sobrienstatic struct value *value_subscripted_rvalue (struct value *, struct value *, int);
4419370Spst
4598944Sobrienvoid _initialize_valarith (void);
4698944Sobrien
4746283Sdfr
48130803Smarcel/* Given a pointer, return the size of its target.
49130803Smarcel   If the pointer type is void *, then return 1.
50130803Smarcel   If the target type is incomplete, then error out.
51130803Smarcel   This isn't a general purpose function, but just a
52130803Smarcel   helper for value_sub & value_add.
53130803Smarcel*/
54130803Smarcel
55130803Smarcelstatic LONGEST
56130803Smarcelfind_size_for_pointer_math (struct type *ptr_type)
57130803Smarcel{
58130803Smarcel  LONGEST sz = -1;
59130803Smarcel  struct type *ptr_target;
60130803Smarcel
61130803Smarcel  ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type));
62130803Smarcel
63130803Smarcel  sz = TYPE_LENGTH (ptr_target);
64130803Smarcel  if (sz == 0)
65130803Smarcel    {
66130803Smarcel      if (TYPE_CODE (ptr_type) == TYPE_CODE_VOID)
67130803Smarcel	sz = 1;
68130803Smarcel      else
69130803Smarcel	{
70130803Smarcel	  char *name;
71130803Smarcel
72130803Smarcel	  name = TYPE_NAME (ptr_target);
73130803Smarcel	  if (name == NULL)
74130803Smarcel	    name = TYPE_TAG_NAME (ptr_target);
75130803Smarcel	  if (name == NULL)
76130803Smarcel	    error ("Cannot perform pointer math on incomplete types, "
77130803Smarcel		   "try casting to a known type, or void *.");
78130803Smarcel	  else
79130803Smarcel	    error ("Cannot perform pointer math on incomplete type \"%s\", "
80130803Smarcel		   "try casting to a known type, or void *.", name);
81130803Smarcel	}
82130803Smarcel    }
83130803Smarcel  return sz;
84130803Smarcel}
85130803Smarcel
8698944Sobrienstruct value *
8798944Sobrienvalue_add (struct value *arg1, struct value *arg2)
8819370Spst{
8998944Sobrien  struct value *valint;
9098944Sobrien  struct value *valptr;
91130803Smarcel  LONGEST sz;
9219370Spst  struct type *type1, *type2, *valptrtype;
9319370Spst
9419370Spst  COERCE_NUMBER (arg1);
9519370Spst  COERCE_NUMBER (arg2);
9619370Spst  type1 = check_typedef (VALUE_TYPE (arg1));
9719370Spst  type2 = check_typedef (VALUE_TYPE (arg2));
9819370Spst
9919370Spst  if ((TYPE_CODE (type1) == TYPE_CODE_PTR
10019370Spst       || TYPE_CODE (type2) == TYPE_CODE_PTR)
10119370Spst      &&
10219370Spst      (TYPE_CODE (type1) == TYPE_CODE_INT
10319370Spst       || TYPE_CODE (type2) == TYPE_CODE_INT))
10419370Spst    /* Exactly one argument is a pointer, and one is an integer.  */
10519370Spst    {
10698944Sobrien      struct value *retval;
10746283Sdfr
10819370Spst      if (TYPE_CODE (type1) == TYPE_CODE_PTR)
10919370Spst	{
11019370Spst	  valptr = arg1;
11119370Spst	  valint = arg2;
11219370Spst	  valptrtype = type1;
11319370Spst	}
11419370Spst      else
11519370Spst	{
11619370Spst	  valptr = arg2;
11719370Spst	  valint = arg1;
11819370Spst	  valptrtype = type2;
11919370Spst	}
120130803Smarcel
121130803Smarcel      sz = find_size_for_pointer_math (valptrtype);
122130803Smarcel
12398944Sobrien      retval = value_from_pointer (valptrtype,
12498944Sobrien				   value_as_address (valptr)
125130803Smarcel				   + (sz * value_as_long (valint)));
12646283Sdfr      VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr);
12746283Sdfr      return retval;
12819370Spst    }
12919370Spst
13019370Spst  return value_binop (arg1, arg2, BINOP_ADD);
13119370Spst}
13219370Spst
13398944Sobrienstruct value *
13498944Sobrienvalue_sub (struct value *arg1, struct value *arg2)
13519370Spst{
13619370Spst  struct type *type1, *type2;
13719370Spst  COERCE_NUMBER (arg1);
13819370Spst  COERCE_NUMBER (arg2);
13919370Spst  type1 = check_typedef (VALUE_TYPE (arg1));
14019370Spst  type2 = check_typedef (VALUE_TYPE (arg2));
14119370Spst
14219370Spst  if (TYPE_CODE (type1) == TYPE_CODE_PTR)
14319370Spst    {
14419370Spst      if (TYPE_CODE (type2) == TYPE_CODE_INT)
14519370Spst	{
14619370Spst	  /* pointer - integer.  */
147130803Smarcel	  LONGEST sz = find_size_for_pointer_math (type1);
148130803Smarcel
14998944Sobrien	  return value_from_pointer (type1,
15098944Sobrien				     (value_as_address (arg1)
15198944Sobrien				      - (sz * value_as_long (arg2))));
15219370Spst	}
15319370Spst      else if (TYPE_CODE (type2) == TYPE_CODE_PTR
15498944Sobrien	       && TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)))
15598944Sobrien	       == TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2))))
15619370Spst	{
15719370Spst	  /* pointer to <type x> - pointer to <type x>.  */
15819370Spst	  LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)));
15919370Spst	  return value_from_longest
16098944Sobrien	    (builtin_type_long,	/* FIXME -- should be ptrdiff_t */
16119370Spst	     (value_as_long (arg1) - value_as_long (arg2)) / sz);
16219370Spst	}
16319370Spst      else
16419370Spst	{
16519370Spst	  error ("\
16619370SpstFirst argument of `-' is a pointer and second argument is neither\n\
16719370Spstan integer nor a pointer of the same type.");
16819370Spst	}
16919370Spst    }
17019370Spst
17119370Spst  return value_binop (arg1, arg2, BINOP_SUB);
17219370Spst}
17319370Spst
17419370Spst/* Return the value of ARRAY[IDX].
17519370Spst   See comments in value_coerce_array() for rationale for reason for
17619370Spst   doing lower bounds adjustment here rather than there.
17719370Spst   FIXME:  Perhaps we should validate that the index is valid and if
17819370Spst   verbosity is set, warn about invalid indices (but still use them). */
17919370Spst
18098944Sobrienstruct value *
18198944Sobrienvalue_subscript (struct value *array, struct value *idx)
18219370Spst{
18398944Sobrien  struct value *bound;
18419370Spst  int c_style = current_language->c_style_arrays;
18519370Spst  struct type *tarray;
18619370Spst
18719370Spst  COERCE_REF (array);
18819370Spst  tarray = check_typedef (VALUE_TYPE (array));
18919370Spst  COERCE_VARYING_ARRAY (array, tarray);
19019370Spst
19119370Spst  if (TYPE_CODE (tarray) == TYPE_CODE_ARRAY
19219370Spst      || TYPE_CODE (tarray) == TYPE_CODE_STRING)
19319370Spst    {
19419370Spst      struct type *range_type = TYPE_INDEX_TYPE (tarray);
19519370Spst      LONGEST lowerbound, upperbound;
19619370Spst      get_discrete_bounds (range_type, &lowerbound, &upperbound);
19719370Spst
19819370Spst      if (VALUE_LVAL (array) != lval_memory)
19919370Spst	return value_subscripted_rvalue (array, idx, lowerbound);
20019370Spst
20119370Spst      if (c_style == 0)
20219370Spst	{
20319370Spst	  LONGEST index = value_as_long (idx);
20419370Spst	  if (index >= lowerbound && index <= upperbound)
20519370Spst	    return value_subscripted_rvalue (array, idx, lowerbound);
20619370Spst	  warning ("array or string index out of range");
20719370Spst	  /* fall doing C stuff */
20819370Spst	  c_style = 1;
20919370Spst	}
21019370Spst
21119370Spst      if (lowerbound != 0)
21219370Spst	{
21319370Spst	  bound = value_from_longest (builtin_type_int, (LONGEST) lowerbound);
21419370Spst	  idx = value_sub (idx, bound);
21519370Spst	}
21619370Spst
21719370Spst      array = value_coerce_array (array);
21819370Spst    }
21919370Spst
22019370Spst  if (TYPE_CODE (tarray) == TYPE_CODE_BITSTRING)
22119370Spst    {
22219370Spst      struct type *range_type = TYPE_INDEX_TYPE (tarray);
22319370Spst      LONGEST index = value_as_long (idx);
22498944Sobrien      struct value *v;
22519370Spst      int offset, byte, bit_index;
22619370Spst      LONGEST lowerbound, upperbound;
22719370Spst      get_discrete_bounds (range_type, &lowerbound, &upperbound);
22819370Spst      if (index < lowerbound || index > upperbound)
22919370Spst	error ("bitstring index out of range");
23019370Spst      index -= lowerbound;
23119370Spst      offset = index / TARGET_CHAR_BIT;
23298944Sobrien      byte = *((char *) VALUE_CONTENTS (array) + offset);
23319370Spst      bit_index = index % TARGET_CHAR_BIT;
23419370Spst      byte >>= (BITS_BIG_ENDIAN ? TARGET_CHAR_BIT - 1 - bit_index : bit_index);
23519370Spst      v = value_from_longest (LA_BOOL_TYPE, byte & 1);
23619370Spst      VALUE_BITPOS (v) = bit_index;
23719370Spst      VALUE_BITSIZE (v) = 1;
23819370Spst      VALUE_LVAL (v) = VALUE_LVAL (array);
23919370Spst      if (VALUE_LVAL (array) == lval_internalvar)
24019370Spst	VALUE_LVAL (v) = lval_internalvar_component;
24119370Spst      VALUE_ADDRESS (v) = VALUE_ADDRESS (array);
24219370Spst      VALUE_OFFSET (v) = offset + VALUE_OFFSET (array);
24319370Spst      return v;
24419370Spst    }
24519370Spst
24619370Spst  if (c_style)
24719370Spst    return value_ind (value_add (array, idx));
24819370Spst  else
24919370Spst    error ("not an array or string");
25019370Spst}
25119370Spst
25219370Spst/* Return the value of EXPR[IDX], expr an aggregate rvalue
25319370Spst   (eg, a vector register).  This routine used to promote floats
25419370Spst   to doubles, but no longer does.  */
25519370Spst
25698944Sobrienstatic struct value *
25798944Sobrienvalue_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound)
25819370Spst{
25919370Spst  struct type *array_type = check_typedef (VALUE_TYPE (array));
26019370Spst  struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
26119370Spst  unsigned int elt_size = TYPE_LENGTH (elt_type);
26219370Spst  LONGEST index = value_as_long (idx);
26319370Spst  unsigned int elt_offs = elt_size * longest_to_int (index - lowerbound);
26498944Sobrien  struct value *v;
26519370Spst
26619370Spst  if (index < lowerbound || elt_offs >= TYPE_LENGTH (array_type))
26719370Spst    error ("no such vector element");
26819370Spst
26919370Spst  v = allocate_value (elt_type);
27019370Spst  if (VALUE_LAZY (array))
27119370Spst    VALUE_LAZY (v) = 1;
27219370Spst  else
27319370Spst    memcpy (VALUE_CONTENTS (v), VALUE_CONTENTS (array) + elt_offs, elt_size);
27419370Spst
27519370Spst  if (VALUE_LVAL (array) == lval_internalvar)
27619370Spst    VALUE_LVAL (v) = lval_internalvar_component;
27719370Spst  else
27819370Spst    VALUE_LVAL (v) = VALUE_LVAL (array);
27919370Spst  VALUE_ADDRESS (v) = VALUE_ADDRESS (array);
280130803Smarcel  VALUE_REGNO (v) = VALUE_REGNO (array);
28119370Spst  VALUE_OFFSET (v) = VALUE_OFFSET (array) + elt_offs;
28219370Spst  return v;
28319370Spst}
28419370Spst
28519370Spst/* Check to see if either argument is a structure.  This is called so
28619370Spst   we know whether to go ahead with the normal binop or look for a
28719370Spst   user defined function instead.
28819370Spst
28919370Spst   For now, we do not overload the `=' operator.  */
29019370Spst
29119370Spstint
29298944Sobrienbinop_user_defined_p (enum exp_opcode op, struct value *arg1, struct value *arg2)
29319370Spst{
29419370Spst  struct type *type1, *type2;
29519370Spst  if (op == BINOP_ASSIGN || op == BINOP_CONCAT)
29619370Spst    return 0;
29719370Spst  type1 = check_typedef (VALUE_TYPE (arg1));
29819370Spst  type2 = check_typedef (VALUE_TYPE (arg2));
29919370Spst  return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
30019370Spst	  || TYPE_CODE (type2) == TYPE_CODE_STRUCT
30119370Spst	  || (TYPE_CODE (type1) == TYPE_CODE_REF
30219370Spst	      && TYPE_CODE (TYPE_TARGET_TYPE (type1)) == TYPE_CODE_STRUCT)
30319370Spst	  || (TYPE_CODE (type2) == TYPE_CODE_REF
30419370Spst	      && TYPE_CODE (TYPE_TARGET_TYPE (type2)) == TYPE_CODE_STRUCT));
30519370Spst}
30619370Spst
30719370Spst/* Check to see if argument is a structure.  This is called so
30819370Spst   we know whether to go ahead with the normal unop or look for a
30919370Spst   user defined function instead.
31019370Spst
31119370Spst   For now, we do not overload the `&' operator.  */
31219370Spst
31398944Sobrienint
31498944Sobrienunop_user_defined_p (enum exp_opcode op, struct value *arg1)
31519370Spst{
31619370Spst  struct type *type1;
31719370Spst  if (op == UNOP_ADDR)
31819370Spst    return 0;
31919370Spst  type1 = check_typedef (VALUE_TYPE (arg1));
32019370Spst  for (;;)
32119370Spst    {
32219370Spst      if (TYPE_CODE (type1) == TYPE_CODE_STRUCT)
32319370Spst	return 1;
32419370Spst      else if (TYPE_CODE (type1) == TYPE_CODE_REF)
32519370Spst	type1 = TYPE_TARGET_TYPE (type1);
32619370Spst      else
32719370Spst	return 0;
32819370Spst    }
32919370Spst}
33019370Spst
33119370Spst/* We know either arg1 or arg2 is a structure, so try to find the right
33219370Spst   user defined function.  Create an argument vector that calls
33319370Spst   arg1.operator @ (arg1,arg2) and return that value (where '@' is any
33419370Spst   binary operator which is legal for GNU C++).
33519370Spst
33619370Spst   OP is the operatore, and if it is BINOP_ASSIGN_MODIFY, then OTHEROP
33719370Spst   is the opcode saying how to modify it.  Otherwise, OTHEROP is
33819370Spst   unused.  */
33919370Spst
34098944Sobrienstruct value *
34198944Sobrienvalue_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
34298944Sobrien	       enum exp_opcode otherop, enum noside noside)
34319370Spst{
34498944Sobrien  struct value **argvec;
34519370Spst  char *ptr;
34619370Spst  char tstr[13];
34719370Spst  int static_memfuncp;
34819370Spst
34919370Spst  COERCE_REF (arg1);
35019370Spst  COERCE_REF (arg2);
35119370Spst  COERCE_ENUM (arg1);
35219370Spst  COERCE_ENUM (arg2);
35319370Spst
35419370Spst  /* now we know that what we have to do is construct our
35519370Spst     arg vector and find the right function to call it with.  */
35619370Spst
35719370Spst  if (TYPE_CODE (check_typedef (VALUE_TYPE (arg1))) != TYPE_CODE_STRUCT)
35898944Sobrien    error ("Can't do that binary op on that type");	/* FIXME be explicit */
35919370Spst
36098944Sobrien  argvec = (struct value **) alloca (sizeof (struct value *) * 4);
36119370Spst  argvec[1] = value_addr (arg1);
36219370Spst  argvec[2] = arg2;
36319370Spst  argvec[3] = 0;
36419370Spst
36598944Sobrien  /* make the right function name up */
36698944Sobrien  strcpy (tstr, "operator__");
36798944Sobrien  ptr = tstr + 8;
36819370Spst  switch (op)
36919370Spst    {
37098944Sobrien    case BINOP_ADD:
37198944Sobrien      strcpy (ptr, "+");
37298944Sobrien      break;
37398944Sobrien    case BINOP_SUB:
37498944Sobrien      strcpy (ptr, "-");
37598944Sobrien      break;
37698944Sobrien    case BINOP_MUL:
37798944Sobrien      strcpy (ptr, "*");
37898944Sobrien      break;
37998944Sobrien    case BINOP_DIV:
38098944Sobrien      strcpy (ptr, "/");
38198944Sobrien      break;
38298944Sobrien    case BINOP_REM:
38398944Sobrien      strcpy (ptr, "%");
38498944Sobrien      break;
38598944Sobrien    case BINOP_LSH:
38698944Sobrien      strcpy (ptr, "<<");
38798944Sobrien      break;
38898944Sobrien    case BINOP_RSH:
38998944Sobrien      strcpy (ptr, ">>");
39098944Sobrien      break;
39198944Sobrien    case BINOP_BITWISE_AND:
39298944Sobrien      strcpy (ptr, "&");
39398944Sobrien      break;
39498944Sobrien    case BINOP_BITWISE_IOR:
39598944Sobrien      strcpy (ptr, "|");
39698944Sobrien      break;
39798944Sobrien    case BINOP_BITWISE_XOR:
39898944Sobrien      strcpy (ptr, "^");
39998944Sobrien      break;
40098944Sobrien    case BINOP_LOGICAL_AND:
40198944Sobrien      strcpy (ptr, "&&");
40298944Sobrien      break;
40398944Sobrien    case BINOP_LOGICAL_OR:
40498944Sobrien      strcpy (ptr, "||");
40598944Sobrien      break;
40698944Sobrien    case BINOP_MIN:
40798944Sobrien      strcpy (ptr, "<?");
40898944Sobrien      break;
40998944Sobrien    case BINOP_MAX:
41098944Sobrien      strcpy (ptr, ">?");
41198944Sobrien      break;
41298944Sobrien    case BINOP_ASSIGN:
41398944Sobrien      strcpy (ptr, "=");
41498944Sobrien      break;
41598944Sobrien    case BINOP_ASSIGN_MODIFY:
41619370Spst      switch (otherop)
41719370Spst	{
41898944Sobrien	case BINOP_ADD:
41998944Sobrien	  strcpy (ptr, "+=");
42098944Sobrien	  break;
42198944Sobrien	case BINOP_SUB:
42298944Sobrien	  strcpy (ptr, "-=");
42398944Sobrien	  break;
42498944Sobrien	case BINOP_MUL:
42598944Sobrien	  strcpy (ptr, "*=");
42698944Sobrien	  break;
42798944Sobrien	case BINOP_DIV:
42898944Sobrien	  strcpy (ptr, "/=");
42998944Sobrien	  break;
43098944Sobrien	case BINOP_REM:
43198944Sobrien	  strcpy (ptr, "%=");
43298944Sobrien	  break;
43398944Sobrien	case BINOP_BITWISE_AND:
43498944Sobrien	  strcpy (ptr, "&=");
43598944Sobrien	  break;
43698944Sobrien	case BINOP_BITWISE_IOR:
43798944Sobrien	  strcpy (ptr, "|=");
43898944Sobrien	  break;
43998944Sobrien	case BINOP_BITWISE_XOR:
44098944Sobrien	  strcpy (ptr, "^=");
44198944Sobrien	  break;
44298944Sobrien	case BINOP_MOD:	/* invalid */
44319370Spst	default:
44419370Spst	  error ("Invalid binary operation specified.");
44519370Spst	}
44619370Spst      break;
44798944Sobrien    case BINOP_SUBSCRIPT:
44898944Sobrien      strcpy (ptr, "[]");
44998944Sobrien      break;
45098944Sobrien    case BINOP_EQUAL:
45198944Sobrien      strcpy (ptr, "==");
45298944Sobrien      break;
45398944Sobrien    case BINOP_NOTEQUAL:
45498944Sobrien      strcpy (ptr, "!=");
45598944Sobrien      break;
45698944Sobrien    case BINOP_LESS:
45798944Sobrien      strcpy (ptr, "<");
45898944Sobrien      break;
45998944Sobrien    case BINOP_GTR:
46098944Sobrien      strcpy (ptr, ">");
46198944Sobrien      break;
46298944Sobrien    case BINOP_GEQ:
46398944Sobrien      strcpy (ptr, ">=");
46498944Sobrien      break;
46598944Sobrien    case BINOP_LEQ:
46698944Sobrien      strcpy (ptr, "<=");
46798944Sobrien      break;
46898944Sobrien    case BINOP_MOD:		/* invalid */
46919370Spst    default:
47019370Spst      error ("Invalid binary operation specified.");
47119370Spst    }
47219370Spst
47398944Sobrien  argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
47498944Sobrien
47519370Spst  if (argvec[0])
47619370Spst    {
47719370Spst      if (static_memfuncp)
47819370Spst	{
47919370Spst	  argvec[1] = argvec[0];
48019370Spst	  argvec++;
48119370Spst	}
48246283Sdfr      if (noside == EVAL_AVOID_SIDE_EFFECTS)
48346283Sdfr	{
48446283Sdfr	  struct type *return_type;
48546283Sdfr	  return_type
48646283Sdfr	    = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0])));
48746283Sdfr	  return value_zero (return_type, VALUE_LVAL (arg1));
48846283Sdfr	}
48919370Spst      return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1);
49019370Spst    }
49119370Spst  error ("member function %s not found", tstr);
49219370Spst#ifdef lint
49319370Spst  return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1);
49419370Spst#endif
49519370Spst}
49619370Spst
49719370Spst/* We know that arg1 is a structure, so try to find a unary user
49819370Spst   defined operator that matches the operator in question.
49919370Spst   Create an argument vector that calls arg1.operator @ (arg1)
50019370Spst   and return that value (where '@' is (almost) any unary operator which
50119370Spst   is legal for GNU C++).  */
50219370Spst
50398944Sobrienstruct value *
50498944Sobrienvalue_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
50519370Spst{
50698944Sobrien  struct value **argvec;
50719370Spst  char *ptr, *mangle_ptr;
50819370Spst  char tstr[13], mangle_tstr[13];
50998944Sobrien  int static_memfuncp, nargs;
51019370Spst
51119370Spst  COERCE_REF (arg1);
51219370Spst  COERCE_ENUM (arg1);
51319370Spst
51419370Spst  /* now we know that what we have to do is construct our
51519370Spst     arg vector and find the right function to call it with.  */
51619370Spst
51719370Spst  if (TYPE_CODE (check_typedef (VALUE_TYPE (arg1))) != TYPE_CODE_STRUCT)
51898944Sobrien    error ("Can't do that unary op on that type");	/* FIXME be explicit */
51919370Spst
52098944Sobrien  argvec = (struct value **) alloca (sizeof (struct value *) * 4);
52119370Spst  argvec[1] = value_addr (arg1);
52219370Spst  argvec[2] = 0;
52319370Spst
52498944Sobrien  nargs = 1;
52598944Sobrien
52698944Sobrien  /* make the right function name up */
52798944Sobrien  strcpy (tstr, "operator__");
52898944Sobrien  ptr = tstr + 8;
52998944Sobrien  strcpy (mangle_tstr, "__");
53098944Sobrien  mangle_ptr = mangle_tstr + 2;
53119370Spst  switch (op)
53219370Spst    {
53398944Sobrien    case UNOP_PREINCREMENT:
53498944Sobrien      strcpy (ptr, "++");
53598944Sobrien      break;
53698944Sobrien    case UNOP_PREDECREMENT:
53798944Sobrien      strcpy (ptr, "--");
53898944Sobrien      break;
53998944Sobrien    case UNOP_POSTINCREMENT:
54098944Sobrien      strcpy (ptr, "++");
54198944Sobrien      argvec[2] = value_from_longest (builtin_type_int, 0);
54298944Sobrien      argvec[3] = 0;
54398944Sobrien      nargs ++;
54498944Sobrien      break;
54598944Sobrien    case UNOP_POSTDECREMENT:
54698944Sobrien      strcpy (ptr, "--");
54798944Sobrien      argvec[2] = value_from_longest (builtin_type_int, 0);
54898944Sobrien      argvec[3] = 0;
54998944Sobrien      nargs ++;
55098944Sobrien      break;
55198944Sobrien    case UNOP_LOGICAL_NOT:
55298944Sobrien      strcpy (ptr, "!");
55398944Sobrien      break;
55498944Sobrien    case UNOP_COMPLEMENT:
55598944Sobrien      strcpy (ptr, "~");
55698944Sobrien      break;
55798944Sobrien    case UNOP_NEG:
55898944Sobrien      strcpy (ptr, "-");
55998944Sobrien      break;
56098944Sobrien    case UNOP_IND:
56198944Sobrien      strcpy (ptr, "*");
56298944Sobrien      break;
56319370Spst    default:
56446283Sdfr      error ("Invalid unary operation specified.");
56519370Spst    }
56619370Spst
56798944Sobrien  argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
56819370Spst
56919370Spst  if (argvec[0])
57019370Spst    {
57119370Spst      if (static_memfuncp)
57219370Spst	{
57319370Spst	  argvec[1] = argvec[0];
57498944Sobrien	  nargs --;
57519370Spst	  argvec++;
57619370Spst	}
57746283Sdfr      if (noside == EVAL_AVOID_SIDE_EFFECTS)
57846283Sdfr	{
57946283Sdfr	  struct type *return_type;
58046283Sdfr	  return_type
58146283Sdfr	    = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0])));
58246283Sdfr	  return value_zero (return_type, VALUE_LVAL (arg1));
58346283Sdfr	}
58498944Sobrien      return call_function_by_hand (argvec[0], nargs, argvec + 1);
58519370Spst    }
58619370Spst  error ("member function %s not found", tstr);
58798944Sobrien  return 0;			/* For lint -- never reached */
58819370Spst}
58998944Sobrien
59019370Spst
59119370Spst/* Concatenate two values with the following conditions:
59219370Spst
59398944Sobrien   (1)  Both values must be either bitstring values or character string
59498944Sobrien   values and the resulting value consists of the concatenation of
59598944Sobrien   ARG1 followed by ARG2.
59619370Spst
59798944Sobrien   or
59819370Spst
59998944Sobrien   One value must be an integer value and the other value must be
60098944Sobrien   either a bitstring value or character string value, which is
60198944Sobrien   to be repeated by the number of times specified by the integer
60298944Sobrien   value.
60319370Spst
60419370Spst
60598944Sobrien   (2)  Boolean values are also allowed and are treated as bit string
60698944Sobrien   values of length 1.
60719370Spst
60898944Sobrien   (3)  Character values are also allowed and are treated as character
60998944Sobrien   string values of length 1.
61098944Sobrien */
61119370Spst
61298944Sobrienstruct value *
61398944Sobrienvalue_concat (struct value *arg1, struct value *arg2)
61419370Spst{
61598944Sobrien  struct value *inval1;
61698944Sobrien  struct value *inval2;
61798944Sobrien  struct value *outval = NULL;
61819370Spst  int inval1len, inval2len;
61919370Spst  int count, idx;
62019370Spst  char *ptr;
62119370Spst  char inchar;
62219370Spst  struct type *type1 = check_typedef (VALUE_TYPE (arg1));
62319370Spst  struct type *type2 = check_typedef (VALUE_TYPE (arg2));
62419370Spst
62519370Spst  COERCE_VARYING_ARRAY (arg1, type1);
62619370Spst  COERCE_VARYING_ARRAY (arg2, type2);
62719370Spst
62819370Spst  /* First figure out if we are dealing with two values to be concatenated
62919370Spst     or a repeat count and a value to be repeated.  INVAL1 is set to the
63019370Spst     first of two concatenated values, or the repeat count.  INVAL2 is set
63119370Spst     to the second of the two concatenated values or the value to be
63219370Spst     repeated. */
63319370Spst
63419370Spst  if (TYPE_CODE (type2) == TYPE_CODE_INT)
63519370Spst    {
63619370Spst      struct type *tmp = type1;
63719370Spst      type1 = tmp;
63819370Spst      tmp = type2;
63919370Spst      inval1 = arg2;
64019370Spst      inval2 = arg1;
64119370Spst    }
64219370Spst  else
64319370Spst    {
64419370Spst      inval1 = arg1;
64519370Spst      inval2 = arg2;
64619370Spst    }
64719370Spst
64819370Spst  /* Now process the input values. */
64919370Spst
65019370Spst  if (TYPE_CODE (type1) == TYPE_CODE_INT)
65119370Spst    {
65219370Spst      /* We have a repeat count.  Validate the second value and then
65398944Sobrien         construct a value repeated that many times. */
65419370Spst      if (TYPE_CODE (type2) == TYPE_CODE_STRING
65519370Spst	  || TYPE_CODE (type2) == TYPE_CODE_CHAR)
65619370Spst	{
65719370Spst	  count = longest_to_int (value_as_long (inval1));
65819370Spst	  inval2len = TYPE_LENGTH (type2);
65919370Spst	  ptr = (char *) alloca (count * inval2len);
66019370Spst	  if (TYPE_CODE (type2) == TYPE_CODE_CHAR)
66119370Spst	    {
66219370Spst	      inchar = (char) unpack_long (type2,
66319370Spst					   VALUE_CONTENTS (inval2));
66419370Spst	      for (idx = 0; idx < count; idx++)
66519370Spst		{
66619370Spst		  *(ptr + idx) = inchar;
66719370Spst		}
66819370Spst	    }
66919370Spst	  else
67019370Spst	    {
67119370Spst	      for (idx = 0; idx < count; idx++)
67219370Spst		{
67319370Spst		  memcpy (ptr + (idx * inval2len), VALUE_CONTENTS (inval2),
67419370Spst			  inval2len);
67519370Spst		}
67619370Spst	    }
67719370Spst	  outval = value_string (ptr, count * inval2len);
67819370Spst	}
67919370Spst      else if (TYPE_CODE (type2) == TYPE_CODE_BITSTRING
68019370Spst	       || TYPE_CODE (type2) == TYPE_CODE_BOOL)
68119370Spst	{
68219370Spst	  error ("unimplemented support for bitstring/boolean repeats");
68319370Spst	}
68419370Spst      else
68519370Spst	{
68619370Spst	  error ("can't repeat values of that type");
68719370Spst	}
68819370Spst    }
68919370Spst  else if (TYPE_CODE (type1) == TYPE_CODE_STRING
69098944Sobrien	   || TYPE_CODE (type1) == TYPE_CODE_CHAR)
69119370Spst    {
69219370Spst      /* We have two character strings to concatenate. */
69319370Spst      if (TYPE_CODE (type2) != TYPE_CODE_STRING
69419370Spst	  && TYPE_CODE (type2) != TYPE_CODE_CHAR)
69519370Spst	{
69619370Spst	  error ("Strings can only be concatenated with other strings.");
69719370Spst	}
69819370Spst      inval1len = TYPE_LENGTH (type1);
69919370Spst      inval2len = TYPE_LENGTH (type2);
70019370Spst      ptr = (char *) alloca (inval1len + inval2len);
70119370Spst      if (TYPE_CODE (type1) == TYPE_CODE_CHAR)
70219370Spst	{
70319370Spst	  *ptr = (char) unpack_long (type1, VALUE_CONTENTS (inval1));
70419370Spst	}
70519370Spst      else
70619370Spst	{
70719370Spst	  memcpy (ptr, VALUE_CONTENTS (inval1), inval1len);
70819370Spst	}
70919370Spst      if (TYPE_CODE (type2) == TYPE_CODE_CHAR)
71019370Spst	{
71198944Sobrien	  *(ptr + inval1len) =
71219370Spst	    (char) unpack_long (type2, VALUE_CONTENTS (inval2));
71319370Spst	}
71419370Spst      else
71519370Spst	{
71619370Spst	  memcpy (ptr + inval1len, VALUE_CONTENTS (inval2), inval2len);
71719370Spst	}
71819370Spst      outval = value_string (ptr, inval1len + inval2len);
71919370Spst    }
72019370Spst  else if (TYPE_CODE (type1) == TYPE_CODE_BITSTRING
72119370Spst	   || TYPE_CODE (type1) == TYPE_CODE_BOOL)
72219370Spst    {
72319370Spst      /* We have two bitstrings to concatenate. */
72419370Spst      if (TYPE_CODE (type2) != TYPE_CODE_BITSTRING
72519370Spst	  && TYPE_CODE (type2) != TYPE_CODE_BOOL)
72619370Spst	{
72719370Spst	  error ("Bitstrings or booleans can only be concatenated with other bitstrings or booleans.");
72819370Spst	}
72919370Spst      error ("unimplemented support for bitstring/boolean concatenation.");
73098944Sobrien    }
73119370Spst  else
73219370Spst    {
73319370Spst      /* We don't know how to concatenate these operands. */
73419370Spst      error ("illegal operands for concatenation.");
73519370Spst    }
73619370Spst  return (outval);
73719370Spst}
73819370Spst
73919370Spst
74098944Sobrien
74119370Spst/* Perform a binary operation on two operands which have reasonable
74219370Spst   representations as integers or floats.  This includes booleans,
74319370Spst   characters, integers, or floats.
74419370Spst   Does not support addition and subtraction on pointers;
74519370Spst   use value_add or value_sub if you want to handle those possibilities.  */
74619370Spst
74798944Sobrienstruct value *
74898944Sobrienvalue_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
74919370Spst{
75098944Sobrien  struct value *val;
75119370Spst  struct type *type1, *type2;
75219370Spst
75319370Spst  COERCE_REF (arg1);
75419370Spst  COERCE_REF (arg2);
75519370Spst  COERCE_ENUM (arg1);
75619370Spst  COERCE_ENUM (arg2);
75719370Spst  type1 = check_typedef (VALUE_TYPE (arg1));
75819370Spst  type2 = check_typedef (VALUE_TYPE (arg2));
75919370Spst
76019370Spst  if ((TYPE_CODE (type1) != TYPE_CODE_FLT
76119370Spst       && TYPE_CODE (type1) != TYPE_CODE_CHAR
76219370Spst       && TYPE_CODE (type1) != TYPE_CODE_INT
76319370Spst       && TYPE_CODE (type1) != TYPE_CODE_BOOL
76419370Spst       && TYPE_CODE (type1) != TYPE_CODE_RANGE)
76519370Spst      ||
76619370Spst      (TYPE_CODE (type2) != TYPE_CODE_FLT
76719370Spst       && TYPE_CODE (type2) != TYPE_CODE_CHAR
76819370Spst       && TYPE_CODE (type2) != TYPE_CODE_INT
76919370Spst       && TYPE_CODE (type2) != TYPE_CODE_BOOL
77019370Spst       && TYPE_CODE (type2) != TYPE_CODE_RANGE))
77119370Spst    error ("Argument to arithmetic operation not a number or boolean.");
77219370Spst
77319370Spst  if (TYPE_CODE (type1) == TYPE_CODE_FLT
77419370Spst      ||
77519370Spst      TYPE_CODE (type2) == TYPE_CODE_FLT)
77619370Spst    {
77719370Spst      /* FIXME-if-picky-about-floating-accuracy: Should be doing this
77898944Sobrien         in target format.  real.c in GCC probably has the necessary
77998944Sobrien         code.  */
78098944Sobrien      DOUBLEST v1, v2, v = 0;
78119370Spst      v1 = value_as_double (arg1);
78219370Spst      v2 = value_as_double (arg2);
78319370Spst      switch (op)
78419370Spst	{
78519370Spst	case BINOP_ADD:
78619370Spst	  v = v1 + v2;
78719370Spst	  break;
78819370Spst
78919370Spst	case BINOP_SUB:
79019370Spst	  v = v1 - v2;
79119370Spst	  break;
79219370Spst
79319370Spst	case BINOP_MUL:
79419370Spst	  v = v1 * v2;
79519370Spst	  break;
79619370Spst
79719370Spst	case BINOP_DIV:
79819370Spst	  v = v1 / v2;
79919370Spst	  break;
80019370Spst
80198944Sobrien        case BINOP_EXP:
80298944Sobrien          v = pow (v1, v2);
80398944Sobrien          if (errno)
804130803Smarcel            error ("Cannot perform exponentiation: %s", safe_strerror (errno));
80598944Sobrien          break;
80698944Sobrien
80719370Spst	default:
80819370Spst	  error ("Integer-only operation on floating point number.");
80919370Spst	}
81019370Spst
81119370Spst      /* If either arg was long double, make sure that value is also long
81298944Sobrien         double.  */
81319370Spst
81498944Sobrien      if (TYPE_LENGTH (type1) * 8 > TARGET_DOUBLE_BIT
81598944Sobrien	  || TYPE_LENGTH (type2) * 8 > TARGET_DOUBLE_BIT)
81619370Spst	val = allocate_value (builtin_type_long_double);
81719370Spst      else
81819370Spst	val = allocate_value (builtin_type_double);
81919370Spst
82098944Sobrien      store_typed_floating (VALUE_CONTENTS_RAW (val), VALUE_TYPE (val), v);
82119370Spst    }
82219370Spst  else if (TYPE_CODE (type1) == TYPE_CODE_BOOL
82319370Spst	   &&
82419370Spst	   TYPE_CODE (type2) == TYPE_CODE_BOOL)
82598944Sobrien    {
82698944Sobrien      LONGEST v1, v2, v = 0;
82798944Sobrien      v1 = value_as_long (arg1);
82898944Sobrien      v2 = value_as_long (arg2);
82998944Sobrien
83098944Sobrien      switch (op)
83198944Sobrien	{
83298944Sobrien	case BINOP_BITWISE_AND:
83398944Sobrien	  v = v1 & v2;
83498944Sobrien	  break;
83598944Sobrien
83698944Sobrien	case BINOP_BITWISE_IOR:
83798944Sobrien	  v = v1 | v2;
83898944Sobrien	  break;
83998944Sobrien
84098944Sobrien	case BINOP_BITWISE_XOR:
84198944Sobrien	  v = v1 ^ v2;
84298944Sobrien          break;
84398944Sobrien
84498944Sobrien        case BINOP_EQUAL:
84598944Sobrien          v = v1 == v2;
84698944Sobrien          break;
84798944Sobrien
84898944Sobrien        case BINOP_NOTEQUAL:
84998944Sobrien          v = v1 != v2;
85098944Sobrien	  break;
85198944Sobrien
85298944Sobrien	default:
85398944Sobrien	  error ("Invalid operation on booleans.");
85498944Sobrien	}
85598944Sobrien
85698944Sobrien      val = allocate_value (type1);
85798944Sobrien      store_signed_integer (VALUE_CONTENTS_RAW (val),
85898944Sobrien			    TYPE_LENGTH (type1),
85998944Sobrien			    v);
86098944Sobrien    }
86119370Spst  else
86219370Spst    /* Integral operations here.  */
86319370Spst    /* FIXME:  Also mixed integral/booleans, with result an integer. */
86419370Spst    /* FIXME: This implements ANSI C rules (also correct for C++).
865130803Smarcel       What about FORTRAN and (the deleted) chill ?  */
86619370Spst    {
86719370Spst      unsigned int promoted_len1 = TYPE_LENGTH (type1);
86819370Spst      unsigned int promoted_len2 = TYPE_LENGTH (type2);
86919370Spst      int is_unsigned1 = TYPE_UNSIGNED (type1);
87019370Spst      int is_unsigned2 = TYPE_UNSIGNED (type2);
87119370Spst      unsigned int result_len;
87219370Spst      int unsigned_operation;
87319370Spst
87419370Spst      /* Determine type length and signedness after promotion for
87598944Sobrien         both operands.  */
87619370Spst      if (promoted_len1 < TYPE_LENGTH (builtin_type_int))
87719370Spst	{
87819370Spst	  is_unsigned1 = 0;
87919370Spst	  promoted_len1 = TYPE_LENGTH (builtin_type_int);
88019370Spst	}
88119370Spst      if (promoted_len2 < TYPE_LENGTH (builtin_type_int))
88219370Spst	{
88319370Spst	  is_unsigned2 = 0;
88419370Spst	  promoted_len2 = TYPE_LENGTH (builtin_type_int);
88519370Spst	}
88619370Spst
88719370Spst      /* Determine type length of the result, and if the operation should
88898944Sobrien         be done unsigned.
88998944Sobrien         Use the signedness of the operand with the greater length.
89098944Sobrien         If both operands are of equal length, use unsigned operation
89198944Sobrien         if one of the operands is unsigned.  */
89219370Spst      if (promoted_len1 > promoted_len2)
89319370Spst	{
89419370Spst	  unsigned_operation = is_unsigned1;
89519370Spst	  result_len = promoted_len1;
89619370Spst	}
89719370Spst      else if (promoted_len2 > promoted_len1)
89819370Spst	{
89919370Spst	  unsigned_operation = is_unsigned2;
90019370Spst	  result_len = promoted_len2;
90119370Spst	}
90219370Spst      else
90319370Spst	{
90419370Spst	  unsigned_operation = is_unsigned1 || is_unsigned2;
90519370Spst	  result_len = promoted_len1;
90619370Spst	}
90719370Spst
90819370Spst      if (unsigned_operation)
90919370Spst	{
91098944Sobrien	  ULONGEST v1, v2, v = 0;
91146283Sdfr	  v1 = (ULONGEST) value_as_long (arg1);
91246283Sdfr	  v2 = (ULONGEST) value_as_long (arg2);
91319370Spst
91419370Spst	  /* Truncate values to the type length of the result.  */
91546283Sdfr	  if (result_len < sizeof (ULONGEST))
91619370Spst	    {
91719370Spst	      v1 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1;
91819370Spst	      v2 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1;
91919370Spst	    }
92098944Sobrien
92119370Spst	  switch (op)
92219370Spst	    {
92319370Spst	    case BINOP_ADD:
92419370Spst	      v = v1 + v2;
92519370Spst	      break;
92698944Sobrien
92719370Spst	    case BINOP_SUB:
92819370Spst	      v = v1 - v2;
92919370Spst	      break;
93098944Sobrien
93119370Spst	    case BINOP_MUL:
93219370Spst	      v = v1 * v2;
93319370Spst	      break;
93498944Sobrien
93519370Spst	    case BINOP_DIV:
93619370Spst	      v = v1 / v2;
93719370Spst	      break;
93898944Sobrien
93998944Sobrien            case BINOP_EXP:
94098944Sobrien              v = pow (v1, v2);
94198944Sobrien              if (errno)
942130803Smarcel                error ("Cannot perform exponentiation: %s", safe_strerror (errno));
94398944Sobrien              break;
94498944Sobrien
94519370Spst	    case BINOP_REM:
94619370Spst	      v = v1 % v2;
94719370Spst	      break;
94898944Sobrien
94919370Spst	    case BINOP_MOD:
95019370Spst	      /* Knuth 1.2.4, integer only.  Note that unlike the C '%' op,
95119370Spst	         v1 mod 0 has a defined value, v1. */
95219370Spst	      if (v2 == 0)
95319370Spst		{
95419370Spst		  v = v1;
95519370Spst		}
95619370Spst	      else
95719370Spst		{
95898944Sobrien		  v = v1 / v2;
95919370Spst		  /* Note floor(v1/v2) == v1/v2 for unsigned. */
96019370Spst		  v = v1 - (v2 * v);
96119370Spst		}
96219370Spst	      break;
96398944Sobrien
96419370Spst	    case BINOP_LSH:
96519370Spst	      v = v1 << v2;
96619370Spst	      break;
96798944Sobrien
96819370Spst	    case BINOP_RSH:
96919370Spst	      v = v1 >> v2;
97019370Spst	      break;
97198944Sobrien
97219370Spst	    case BINOP_BITWISE_AND:
97319370Spst	      v = v1 & v2;
97419370Spst	      break;
97598944Sobrien
97619370Spst	    case BINOP_BITWISE_IOR:
97719370Spst	      v = v1 | v2;
97819370Spst	      break;
97998944Sobrien
98019370Spst	    case BINOP_BITWISE_XOR:
98119370Spst	      v = v1 ^ v2;
98219370Spst	      break;
98398944Sobrien
98419370Spst	    case BINOP_LOGICAL_AND:
98519370Spst	      v = v1 && v2;
98619370Spst	      break;
98798944Sobrien
98819370Spst	    case BINOP_LOGICAL_OR:
98919370Spst	      v = v1 || v2;
99019370Spst	      break;
99198944Sobrien
99219370Spst	    case BINOP_MIN:
99319370Spst	      v = v1 < v2 ? v1 : v2;
99419370Spst	      break;
99598944Sobrien
99619370Spst	    case BINOP_MAX:
99719370Spst	      v = v1 > v2 ? v1 : v2;
99819370Spst	      break;
99919370Spst
100019370Spst	    case BINOP_EQUAL:
100119370Spst	      v = v1 == v2;
100219370Spst	      break;
100319370Spst
100498944Sobrien            case BINOP_NOTEQUAL:
100598944Sobrien              v = v1 != v2;
100698944Sobrien              break;
100798944Sobrien
100819370Spst	    case BINOP_LESS:
100919370Spst	      v = v1 < v2;
101019370Spst	      break;
101198944Sobrien
101219370Spst	    default:
101319370Spst	      error ("Invalid binary operation on numbers.");
101419370Spst	    }
101519370Spst
101619370Spst	  /* This is a kludge to get around the fact that we don't
101719370Spst	     know how to determine the result type from the types of
101819370Spst	     the operands.  (I'm not really sure how much we feel the
101919370Spst	     need to duplicate the exact rules of the current
102019370Spst	     language.  They can get really hairy.  But not to do so
102119370Spst	     makes it hard to document just what we *do* do).  */
102219370Spst
102319370Spst	  /* Can't just call init_type because we wouldn't know what
102419370Spst	     name to give the type.  */
102519370Spst	  val = allocate_value
102619370Spst	    (result_len > TARGET_LONG_BIT / HOST_CHAR_BIT
102719370Spst	     ? builtin_type_unsigned_long_long
102819370Spst	     : builtin_type_unsigned_long);
102919370Spst	  store_unsigned_integer (VALUE_CONTENTS_RAW (val),
103019370Spst				  TYPE_LENGTH (VALUE_TYPE (val)),
103119370Spst				  v);
103219370Spst	}
103319370Spst      else
103419370Spst	{
103598944Sobrien	  LONGEST v1, v2, v = 0;
103619370Spst	  v1 = value_as_long (arg1);
103719370Spst	  v2 = value_as_long (arg2);
103898944Sobrien
103919370Spst	  switch (op)
104019370Spst	    {
104119370Spst	    case BINOP_ADD:
104219370Spst	      v = v1 + v2;
104319370Spst	      break;
104498944Sobrien
104519370Spst	    case BINOP_SUB:
104619370Spst	      v = v1 - v2;
104719370Spst	      break;
104898944Sobrien
104919370Spst	    case BINOP_MUL:
105019370Spst	      v = v1 * v2;
105119370Spst	      break;
105298944Sobrien
105319370Spst	    case BINOP_DIV:
105419370Spst	      v = v1 / v2;
105598944Sobrien              break;
105698944Sobrien
105798944Sobrien            case BINOP_EXP:
105898944Sobrien              v = pow (v1, v2);
105998944Sobrien              if (errno)
1060130803Smarcel                error ("Cannot perform exponentiation: %s", safe_strerror (errno));
106119370Spst	      break;
106298944Sobrien
106319370Spst	    case BINOP_REM:
106419370Spst	      v = v1 % v2;
106519370Spst	      break;
106698944Sobrien
106719370Spst	    case BINOP_MOD:
106819370Spst	      /* Knuth 1.2.4, integer only.  Note that unlike the C '%' op,
106919370Spst	         X mod 0 has a defined value, X. */
107019370Spst	      if (v2 == 0)
107119370Spst		{
107219370Spst		  v = v1;
107319370Spst		}
107419370Spst	      else
107519370Spst		{
107698944Sobrien		  v = v1 / v2;
107719370Spst		  /* Compute floor. */
107819370Spst		  if (TRUNCATION_TOWARDS_ZERO && (v < 0) && ((v1 % v2) != 0))
107919370Spst		    {
108019370Spst		      v--;
108119370Spst		    }
108219370Spst		  v = v1 - (v2 * v);
108319370Spst		}
108419370Spst	      break;
108598944Sobrien
108619370Spst	    case BINOP_LSH:
108719370Spst	      v = v1 << v2;
108819370Spst	      break;
108998944Sobrien
109019370Spst	    case BINOP_RSH:
109119370Spst	      v = v1 >> v2;
109219370Spst	      break;
109398944Sobrien
109419370Spst	    case BINOP_BITWISE_AND:
109519370Spst	      v = v1 & v2;
109619370Spst	      break;
109798944Sobrien
109819370Spst	    case BINOP_BITWISE_IOR:
109919370Spst	      v = v1 | v2;
110019370Spst	      break;
110198944Sobrien
110219370Spst	    case BINOP_BITWISE_XOR:
110319370Spst	      v = v1 ^ v2;
110419370Spst	      break;
110598944Sobrien
110619370Spst	    case BINOP_LOGICAL_AND:
110719370Spst	      v = v1 && v2;
110819370Spst	      break;
110998944Sobrien
111019370Spst	    case BINOP_LOGICAL_OR:
111119370Spst	      v = v1 || v2;
111219370Spst	      break;
111398944Sobrien
111419370Spst	    case BINOP_MIN:
111519370Spst	      v = v1 < v2 ? v1 : v2;
111619370Spst	      break;
111798944Sobrien
111819370Spst	    case BINOP_MAX:
111919370Spst	      v = v1 > v2 ? v1 : v2;
112019370Spst	      break;
112119370Spst
112219370Spst	    case BINOP_EQUAL:
112319370Spst	      v = v1 == v2;
112419370Spst	      break;
112519370Spst
112619370Spst	    case BINOP_LESS:
112719370Spst	      v = v1 < v2;
112819370Spst	      break;
112998944Sobrien
113019370Spst	    default:
113119370Spst	      error ("Invalid binary operation on numbers.");
113219370Spst	    }
113319370Spst
113419370Spst	  /* This is a kludge to get around the fact that we don't
113519370Spst	     know how to determine the result type from the types of
113619370Spst	     the operands.  (I'm not really sure how much we feel the
113719370Spst	     need to duplicate the exact rules of the current
113819370Spst	     language.  They can get really hairy.  But not to do so
113919370Spst	     makes it hard to document just what we *do* do).  */
114019370Spst
114119370Spst	  /* Can't just call init_type because we wouldn't know what
114219370Spst	     name to give the type.  */
114319370Spst	  val = allocate_value
114419370Spst	    (result_len > TARGET_LONG_BIT / HOST_CHAR_BIT
114519370Spst	     ? builtin_type_long_long
114619370Spst	     : builtin_type_long);
114719370Spst	  store_signed_integer (VALUE_CONTENTS_RAW (val),
114819370Spst				TYPE_LENGTH (VALUE_TYPE (val)),
114919370Spst				v);
115019370Spst	}
115119370Spst    }
115219370Spst
115319370Spst  return val;
115419370Spst}
115519370Spst
115619370Spst/* Simulate the C operator ! -- return 1 if ARG1 contains zero.  */
115719370Spst
115819370Spstint
115998944Sobrienvalue_logical_not (struct value *arg1)
116019370Spst{
1161130803Smarcel  int len;
1162130803Smarcel  char *p;
116319370Spst  struct type *type1;
116419370Spst
116519370Spst  COERCE_NUMBER (arg1);
116619370Spst  type1 = check_typedef (VALUE_TYPE (arg1));
116719370Spst
116819370Spst  if (TYPE_CODE (type1) == TYPE_CODE_FLT)
116919370Spst    return 0 == value_as_double (arg1);
117019370Spst
117119370Spst  len = TYPE_LENGTH (type1);
117219370Spst  p = VALUE_CONTENTS (arg1);
117319370Spst
117419370Spst  while (--len >= 0)
117519370Spst    {
117619370Spst      if (*p++)
117719370Spst	break;
117819370Spst    }
117919370Spst
118019370Spst  return len < 0;
118119370Spst}
118219370Spst
118398944Sobrien/* Perform a comparison on two string values (whose content are not
118498944Sobrien   necessarily null terminated) based on their length */
118598944Sobrien
118698944Sobrienstatic int
118798944Sobrienvalue_strcmp (struct value *arg1, struct value *arg2)
118898944Sobrien{
118998944Sobrien  int len1 = TYPE_LENGTH (VALUE_TYPE (arg1));
119098944Sobrien  int len2 = TYPE_LENGTH (VALUE_TYPE (arg2));
119198944Sobrien  char *s1 = VALUE_CONTENTS (arg1);
119298944Sobrien  char *s2 = VALUE_CONTENTS (arg2);
119398944Sobrien  int i, len = len1 < len2 ? len1 : len2;
119498944Sobrien
119598944Sobrien  for (i = 0; i < len; i++)
119698944Sobrien    {
119798944Sobrien      if (s1[i] < s2[i])
119898944Sobrien        return -1;
119998944Sobrien      else if (s1[i] > s2[i])
120098944Sobrien        return 1;
120198944Sobrien      else
120298944Sobrien        continue;
120398944Sobrien    }
120498944Sobrien
120598944Sobrien  if (len1 < len2)
120698944Sobrien    return -1;
120798944Sobrien  else if (len1 > len2)
120898944Sobrien    return 1;
120998944Sobrien  else
121098944Sobrien    return 0;
121198944Sobrien}
121298944Sobrien
121319370Spst/* Simulate the C operator == by returning a 1
121419370Spst   iff ARG1 and ARG2 have equal contents.  */
121519370Spst
121619370Spstint
121798944Sobrienvalue_equal (struct value *arg1, struct value *arg2)
121819370Spst{
1219130803Smarcel  int len;
1220130803Smarcel  char *p1, *p2;
122119370Spst  struct type *type1, *type2;
122219370Spst  enum type_code code1;
122319370Spst  enum type_code code2;
122419370Spst
122519370Spst  COERCE_NUMBER (arg1);
122619370Spst  COERCE_NUMBER (arg2);
122719370Spst
122819370Spst  type1 = check_typedef (VALUE_TYPE (arg1));
122919370Spst  type2 = check_typedef (VALUE_TYPE (arg2));
123019370Spst  code1 = TYPE_CODE (type1);
123119370Spst  code2 = TYPE_CODE (type2);
123219370Spst
123346283Sdfr  if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) &&
123446283Sdfr      (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
123519370Spst    return longest_to_int (value_as_long (value_binop (arg1, arg2,
123619370Spst						       BINOP_EQUAL)));
123746283Sdfr  else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)
123846283Sdfr	   && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
123919370Spst    return value_as_double (arg1) == value_as_double (arg2);
124019370Spst
124119370Spst  /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
124219370Spst     is bigger.  */
124346283Sdfr  else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
124498944Sobrien    return value_as_address (arg1) == (CORE_ADDR) value_as_long (arg2);
124546283Sdfr  else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
124698944Sobrien    return (CORE_ADDR) value_as_long (arg1) == value_as_address (arg2);
124719370Spst
124819370Spst  else if (code1 == code2
124919370Spst	   && ((len = (int) TYPE_LENGTH (type1))
125019370Spst	       == (int) TYPE_LENGTH (type2)))
125119370Spst    {
125219370Spst      p1 = VALUE_CONTENTS (arg1);
125319370Spst      p2 = VALUE_CONTENTS (arg2);
125419370Spst      while (--len >= 0)
125519370Spst	{
125619370Spst	  if (*p1++ != *p2++)
125719370Spst	    break;
125819370Spst	}
125919370Spst      return len < 0;
126019370Spst    }
126198944Sobrien  else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING)
126298944Sobrien    {
126398944Sobrien      return value_strcmp (arg1, arg2) == 0;
126498944Sobrien    }
126519370Spst  else
126619370Spst    {
126719370Spst      error ("Invalid type combination in equality test.");
126898944Sobrien      return 0;			/* For lint -- never reached */
126919370Spst    }
127019370Spst}
127119370Spst
127219370Spst/* Simulate the C operator < by returning 1
127319370Spst   iff ARG1's contents are less than ARG2's.  */
127419370Spst
127519370Spstint
127698944Sobrienvalue_less (struct value *arg1, struct value *arg2)
127719370Spst{
1278130803Smarcel  enum type_code code1;
1279130803Smarcel  enum type_code code2;
128019370Spst  struct type *type1, *type2;
128119370Spst
128219370Spst  COERCE_NUMBER (arg1);
128319370Spst  COERCE_NUMBER (arg2);
128419370Spst
128519370Spst  type1 = check_typedef (VALUE_TYPE (arg1));
128619370Spst  type2 = check_typedef (VALUE_TYPE (arg2));
128719370Spst  code1 = TYPE_CODE (type1);
128819370Spst  code2 = TYPE_CODE (type2);
128919370Spst
129046283Sdfr  if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) &&
129146283Sdfr      (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
129219370Spst    return longest_to_int (value_as_long (value_binop (arg1, arg2,
129319370Spst						       BINOP_LESS)));
129446283Sdfr  else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)
129546283Sdfr	   && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
129619370Spst    return value_as_double (arg1) < value_as_double (arg2);
129719370Spst  else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
129898944Sobrien    return value_as_address (arg1) < value_as_address (arg2);
129919370Spst
130019370Spst  /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
130119370Spst     is bigger.  */
130246283Sdfr  else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
130398944Sobrien    return value_as_address (arg1) < (CORE_ADDR) value_as_long (arg2);
130446283Sdfr  else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
130598944Sobrien    return (CORE_ADDR) value_as_long (arg1) < value_as_address (arg2);
130698944Sobrien  else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING)
130798944Sobrien    return value_strcmp (arg1, arg2) < 0;
130819370Spst  else
130919370Spst    {
131019370Spst      error ("Invalid type combination in ordering comparison.");
131119370Spst      return 0;
131219370Spst    }
131319370Spst}
131419370Spst
131519370Spst/* The unary operators - and ~.  Both free the argument ARG1.  */
131619370Spst
131798944Sobrienstruct value *
131898944Sobrienvalue_neg (struct value *arg1)
131919370Spst{
1320130803Smarcel  struct type *type;
1321130803Smarcel  struct type *result_type = VALUE_TYPE (arg1);
132219370Spst
132319370Spst  COERCE_REF (arg1);
132419370Spst  COERCE_ENUM (arg1);
132519370Spst
132619370Spst  type = check_typedef (VALUE_TYPE (arg1));
132719370Spst
132819370Spst  if (TYPE_CODE (type) == TYPE_CODE_FLT)
132998944Sobrien    return value_from_double (result_type, -value_as_double (arg1));
133046283Sdfr  else if (TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_BOOL)
133146283Sdfr    {
1332130803Smarcel      /* Perform integral promotion for ANSI C/C++.  FIXME: What about
1333130803Smarcel         FORTRAN and (the deleted) chill ?  */
133446283Sdfr      if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
133546283Sdfr	result_type = builtin_type_int;
133646283Sdfr
133798944Sobrien      return value_from_longest (result_type, -value_as_long (arg1));
133846283Sdfr    }
133998944Sobrien  else
134098944Sobrien    {
134198944Sobrien      error ("Argument to negate operation not a number.");
134298944Sobrien      return 0;			/* For lint -- never reached */
134398944Sobrien    }
134419370Spst}
134519370Spst
134698944Sobrienstruct value *
134798944Sobrienvalue_complement (struct value *arg1)
134819370Spst{
1349130803Smarcel  struct type *type;
1350130803Smarcel  struct type *result_type = VALUE_TYPE (arg1);
135198944Sobrien  int typecode;
135246283Sdfr
135319370Spst  COERCE_REF (arg1);
135419370Spst  COERCE_ENUM (arg1);
135519370Spst
135646283Sdfr  type = check_typedef (VALUE_TYPE (arg1));
135719370Spst
135846283Sdfr  typecode = TYPE_CODE (type);
135946283Sdfr  if ((typecode != TYPE_CODE_INT) && (typecode != TYPE_CODE_BOOL))
136046283Sdfr    error ("Argument to complement operation not an integer or boolean.");
136146283Sdfr
136246283Sdfr  /* Perform integral promotion for ANSI C/C++.
136346283Sdfr     FIXME: What about FORTRAN ?  */
136446283Sdfr  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
136546283Sdfr    result_type = builtin_type_int;
136646283Sdfr
136798944Sobrien  return value_from_longest (result_type, ~value_as_long (arg1));
136819370Spst}
136919370Spst
137019370Spst/* The INDEX'th bit of SET value whose VALUE_TYPE is TYPE,
137119370Spst   and whose VALUE_CONTENTS is valaddr.
137219370Spst   Return -1 if out of range, -2 other error. */
137319370Spst
137419370Spstint
137598944Sobrienvalue_bit_index (struct type *type, char *valaddr, int index)
137619370Spst{
137719370Spst  LONGEST low_bound, high_bound;
137819370Spst  LONGEST word;
137919370Spst  unsigned rel_index;
138019370Spst  struct type *range = TYPE_FIELD_TYPE (type, 0);
138119370Spst  if (get_discrete_bounds (range, &low_bound, &high_bound) < 0)
138219370Spst    return -2;
138319370Spst  if (index < low_bound || index > high_bound)
138419370Spst    return -1;
138519370Spst  rel_index = index - low_bound;
138619370Spst  word = unpack_long (builtin_type_unsigned_char,
138719370Spst		      valaddr + (rel_index / TARGET_CHAR_BIT));
138819370Spst  rel_index %= TARGET_CHAR_BIT;
138919370Spst  if (BITS_BIG_ENDIAN)
139019370Spst    rel_index = TARGET_CHAR_BIT - 1 - rel_index;
139119370Spst  return (word >> rel_index) & 1;
139219370Spst}
139319370Spst
139498944Sobrienstruct value *
139598944Sobrienvalue_in (struct value *element, struct value *set)
139619370Spst{
139719370Spst  int member;
139819370Spst  struct type *settype = check_typedef (VALUE_TYPE (set));
139919370Spst  struct type *eltype = check_typedef (VALUE_TYPE (element));
140019370Spst  if (TYPE_CODE (eltype) == TYPE_CODE_RANGE)
140119370Spst    eltype = TYPE_TARGET_TYPE (eltype);
140219370Spst  if (TYPE_CODE (settype) != TYPE_CODE_SET)
140319370Spst    error ("Second argument of 'IN' has wrong type");
140419370Spst  if (TYPE_CODE (eltype) != TYPE_CODE_INT
140519370Spst      && TYPE_CODE (eltype) != TYPE_CODE_CHAR
140619370Spst      && TYPE_CODE (eltype) != TYPE_CODE_ENUM
140719370Spst      && TYPE_CODE (eltype) != TYPE_CODE_BOOL)
140819370Spst    error ("First argument of 'IN' has wrong type");
140919370Spst  member = value_bit_index (settype, VALUE_CONTENTS (set),
141019370Spst			    value_as_long (element));
141119370Spst  if (member < 0)
141219370Spst    error ("First argument of 'IN' not in range");
141319370Spst  return value_from_longest (LA_BOOL_TYPE, member);
141419370Spst}
141519370Spst
141619370Spstvoid
141798944Sobrien_initialize_valarith (void)
141819370Spst{
141919370Spst}
1420