gdb/
[deliverable/binutils-gdb.git] / gdb / valarith.c
index f38cdb842fcd40d93b9e097ee5fe81cc6ac89a2e..7c553d1ca4a2db618b5932dafa6ad6ac43a9ac2a 100644 (file)
@@ -1,8 +1,8 @@
 /* Perform arithmetic and other operations on values, for GDB.
 
    Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009,
+   2010 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -31,6 +31,7 @@
 #include "dfp.h"
 #include <math.h>
 #include "infcall.h"
+#include "exceptions.h"
 
 /* Define whether or not the C operator '/' truncates towards zero for
    differently signed operands (truncation direction is undefined in C). */
@@ -46,7 +47,7 @@ void _initialize_valarith (void);
    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_ptrsub & value_ptradd.
+   helper for value_ptradd.
 */
 
 static LONGEST
@@ -85,7 +86,7 @@ find_size_for_pointer_math (struct type *ptr_type)
    result of C-style pointer arithmetic ARG1 + ARG2.  */
 
 struct value *
-value_ptradd (struct value *arg1, struct value *arg2)
+value_ptradd (struct value *arg1, LONGEST arg2)
 {
   struct type *valptrtype;
   LONGEST sz;
@@ -94,33 +95,8 @@ value_ptradd (struct value *arg1, struct value *arg2)
   valptrtype = check_typedef (value_type (arg1));
   sz = find_size_for_pointer_math (valptrtype);
 
-  if (!is_integral_type (value_type (arg2)))
-    error (_("Argument to arithmetic operation not a number or boolean."));
-
   return value_from_pointer (valptrtype,
-                            value_as_address (arg1)
-                              + (sz * value_as_long (arg2)));
-}
-
-/* Given a pointer ARG1 and an integral value ARG2, return the
-   result of C-style pointer arithmetic ARG1 - ARG2.  */
-
-struct value *
-value_ptrsub (struct value *arg1, struct value *arg2)
-{
-  struct type *valptrtype;
-  LONGEST sz;
-
-  arg1 = coerce_array (arg1);
-  valptrtype = check_typedef (value_type (arg1));
-  sz = find_size_for_pointer_math (valptrtype);
-
-  if (!is_integral_type (value_type (arg2)))
-    error (_("Argument to arithmetic operation not a number or boolean."));
-
-  return value_from_pointer (valptrtype,
-                            value_as_address (arg1)
-                              - (sz * value_as_long (arg2)));
+                            value_as_address (arg1) + sz * arg2);
 }
 
 /* Given two compatible pointer values ARG1 and ARG2, return the
@@ -147,6 +123,13 @@ First argument of `-' is a pointer and second argument is neither\n\
 an integer nor a pointer of the same type."));
 
   sz = TYPE_LENGTH (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;
 }
 
@@ -162,9 +145,8 @@ an integer nor a pointer of the same type."));
    verbosity is set, warn about invalid indices (but still use them). */
 
 struct value *
-value_subscript (struct value *array, struct value *idx)
+value_subscript (struct value *array, LONGEST index)
 {
-  struct value *bound;
   int c_style = current_language->c_style_arrays;
   struct type *tarray;
 
@@ -176,16 +158,15 @@ value_subscript (struct value *array, struct value *idx)
     {
       struct type *range_type = TYPE_INDEX_TYPE (tarray);
       LONGEST lowerbound, upperbound;
-      get_discrete_bounds (range_type, &lowerbound, &upperbound);
 
+      get_discrete_bounds (range_type, &lowerbound, &upperbound);
       if (VALUE_LVAL (array) != lval_memory)
-       return value_subscripted_rvalue (array, idx, lowerbound);
+       return value_subscripted_rvalue (array, index, lowerbound);
 
       if (c_style == 0)
        {
-         LONGEST index = value_as_long (idx);
          if (index >= lowerbound && index <= upperbound)
-           return value_subscripted_rvalue (array, idx, lowerbound);
+           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)
@@ -194,17 +175,12 @@ value_subscript (struct value *array, struct value *idx)
          c_style = 1;
        }
 
-      if (lowerbound != 0)
-       {
-         bound = value_from_longest (value_type (idx), (LONGEST) lowerbound);
-         idx = value_binop (idx, bound, BINOP_SUB);
-       }
-
+      index -= lowerbound;
       array = value_coerce_array (array);
     }
 
   if (c_style)
-    return value_ind (value_ptradd (array, idx));
+    return value_ind (value_ptradd (array, index));
   else
     error (_("not an array or string"));
 }
@@ -214,16 +190,16 @@ value_subscript (struct value *array, struct value *idx)
    to doubles, but no longer does.  */
 
 struct value *
-value_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound)
+value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound)
 {
   struct type *array_type = check_typedef (value_type (array));
   struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
   unsigned int elt_size = TYPE_LENGTH (elt_type);
-  LONGEST index = value_as_long (idx);
   unsigned int elt_offs = elt_size * longest_to_int (index - lowerbound);
   struct value *v;
 
-  if (index < lowerbound || elt_offs >= TYPE_LENGTH (array_type))
+  if (index < lowerbound || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type)
+                            && elt_offs >= TYPE_LENGTH (array_type)))
     error (_("no such vector element"));
 
   v = allocate_value (elt_type);
@@ -244,11 +220,10 @@ value_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound
 
 struct value *
 value_bitstring_subscript (struct type *type,
-                          struct value *bitstring, struct value *idx)
+                          struct value *bitstring, LONGEST index)
 {
 
   struct type *bitstring_type, *range_type;
-  LONGEST index = value_as_long (idx);
   struct value *v;
   int offset, byte, bit_index;
   LONGEST lowerbound, upperbound;
@@ -266,7 +241,7 @@ value_bitstring_subscript (struct type *type,
   byte = *((char *) value_contents (bitstring) + offset);
 
   bit_index = index % TARGET_CHAR_BIT;
-  byte >>= (gdbarch_bits_big_endian (current_gdbarch) ?
+  byte >>= (gdbarch_bits_big_endian (get_type_arch (bitstring_type)) ?
            TARGET_CHAR_BIT - 1 - bit_index : bit_index);
 
   v = value_from_longest (type, byte & 1);
@@ -289,17 +264,17 @@ value_bitstring_subscript (struct type *type,
    For now, we do not overload the `=' operator.  */
 
 int
-binop_user_defined_p (enum exp_opcode op, struct value *arg1, struct value *arg2)
+binop_types_user_defined_p (enum exp_opcode op,
+                           struct type *type1, struct type *type2)
 {
-  struct type *type1, *type2;
   if (op == BINOP_ASSIGN || op == BINOP_CONCAT)
     return 0;
 
-  type1 = check_typedef (value_type (arg1));
+  type1 = check_typedef (type1);
   if (TYPE_CODE (type1) == TYPE_CODE_REF)
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
 
-  type2 = check_typedef (value_type (arg2));
+  type2 = check_typedef (type1);
   if (TYPE_CODE (type2) == TYPE_CODE_REF)
     type2 = check_typedef (TYPE_TARGET_TYPE (type2));
 
@@ -307,6 +282,19 @@ binop_user_defined_p (enum exp_opcode op, struct value *arg1, struct value *arg2
          || TYPE_CODE (type2) == 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.
@@ -317,6 +305,7 @@ 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));
@@ -331,6 +320,67 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
     }
 }
 
+/* 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 (struct value **args, int nargs, char *operator,
+                           int *static_memfuncp)
+{
+
+  struct symbol *symp = NULL;
+  struct value *valp = NULL;
+  struct type **arg_types;
+  int i;
+
+  arg_types = (struct type **) alloca (nargs * (sizeof (struct type *)));
+  /* Prepare list of argument types for overload resolution */
+  for (i = 0; i < nargs; i++)
+    arg_types[i] = value_type (args[i]);
+
+  find_overload_match (arg_types, nargs, operator, BOTH /* could be method */,
+                       0 /* strict match */, &args[0], /* objp */
+                       NULL /* pass NULL symbol since symbol is unknown */,
+                       &valp, &symp, static_memfuncp, 0);
+
+  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."), operator);
+}
+
+/* Lookup user defined operator NAME.  Return a value representing the
+   function, otherwise return NULL.  */
+
+static struct value *
+value_user_defined_op (struct value **argp, struct value **args, char *name,
+                       int *static_memfuncp, int nargs)
+{
+  struct value *result = NULL;
+
+  if (current_language->la_language == language_cplus)
+    result = value_user_defined_cpp_op (args, nargs, name, static_memfuncp);
+  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
@@ -471,7 +521,8 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
       error (_("Invalid binary operation specified."));
     }
 
-  argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
+  argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
+                                     &static_memfuncp, 2);
 
   if (argvec[0])
     {
@@ -483,13 +534,15 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
       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], 2 - static_memfuncp, argvec + 1);
     }
-  error (_("member function %s not found"), tstr);
+  throw_error (NOT_FOUND_ERROR,
+               _("member function %s not found"), tstr);
 #ifdef lint
   return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1);
 #endif
@@ -504,6 +557,7 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
 struct value *
 value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
 {
+  struct gdbarch *gdbarch = get_type_arch (value_type (arg1));
   struct value **argvec;
   char *ptr, *mangle_ptr;
   char tstr[13], mangle_tstr[13];
@@ -538,13 +592,13 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
       break;
     case UNOP_POSTINCREMENT:
       strcpy (ptr, "++");
-      argvec[2] = value_from_longest (builtin_type_int8, 0);
+      argvec[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
       argvec[3] = 0;
       nargs ++;
       break;
     case UNOP_POSTDECREMENT:
       strcpy (ptr, "--");
-      argvec[2] = value_from_longest (builtin_type_int8, 0);
+      argvec[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
       argvec[3] = 0;
       nargs ++;
       break;
@@ -563,11 +617,15 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
     case UNOP_IND:
       strcpy (ptr, "*");
       break;
+    case STRUCTOP_PTR:
+      strcpy (ptr, "->");
+      break;
     default:
       error (_("Invalid unary operation specified."));
     }
 
-  argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
+  argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
+                                     &static_memfuncp, nargs);
 
   if (argvec[0])
     {
@@ -580,13 +638,16 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
       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], nargs, argvec + 1);
     }
-  error (_("member function %s not found"), tstr);
+  throw_error (NOT_FOUND_ERROR,
+               _("member function %s not found"), tstr);
+
   return 0;                    /* For lint -- never reached */
 }
 \f
@@ -624,6 +685,7 @@ value_concat (struct value *arg1, struct value *arg2)
   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
@@ -634,6 +696,7 @@ value_concat (struct value *arg1, struct value *arg2)
   if (TYPE_CODE (type2) == TYPE_CODE_INT)
     {
       struct type *tmp = type1;
+
       type1 = tmp;
       tmp = type2;
       inval1 = arg2;
@@ -659,6 +722,8 @@ value_concat (struct value *arg1, struct value *arg2)
          ptr = (char *) alloca (count * inval2len);
          if (TYPE_CODE (type2) == TYPE_CODE_CHAR)
            {
+             char_type = type2;
+
              inchar = (char) unpack_long (type2,
                                           value_contents (inval2));
              for (idx = 0; idx < count; idx++)
@@ -668,13 +733,15 @@ value_concat (struct value *arg1, struct value *arg2)
            }
          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, count * inval2len);
+         outval = value_string (ptr, count * inval2len, char_type);
        }
       else if (TYPE_CODE (type2) == TYPE_CODE_BITSTRING
               || TYPE_CODE (type2) == TYPE_CODE_BOOL)
@@ -700,10 +767,14 @@ value_concat (struct value *arg1, struct value *arg2)
       ptr = (char *) alloca (inval1len + inval2len);
       if (TYPE_CODE (type1) == TYPE_CODE_CHAR)
        {
+         char_type = type1;
+
          *ptr = (char) unpack_long (type1, value_contents (inval1));
        }
       else
        {
+         char_type = TYPE_TARGET_TYPE (type1);
+
          memcpy (ptr, value_contents (inval1), inval1len);
        }
       if (TYPE_CODE (type2) == TYPE_CODE_CHAR)
@@ -715,7 +786,7 @@ value_concat (struct value *arg1, struct value *arg2)
        {
          memcpy (ptr + inval1len, value_contents (inval2), inval2len);
        }
-      outval = value_string (ptr, inval1len + inval2len);
+      outval = value_string (ptr, inval1len + inval2len, char_type);
     }
   else if (TYPE_CODE (type1) == TYPE_CODE_BITSTRING
           || TYPE_CODE (type1) == TYPE_CODE_BOOL)
@@ -800,7 +871,8 @@ uinteger_pow (ULONGEST v1, LONGEST v2)
    other types if one of them is not decimal floating point.  */
 static void
 value_args_as_decimal (struct value *arg1, struct value *arg2,
-                      gdb_byte *x, int *len_x, gdb_byte *y, int *len_y)
+                      gdb_byte *x, int *len_x, enum bfd_endian *byte_order_x,
+                      gdb_byte *y, int *len_y, enum bfd_endian *byte_order_y)
 {
   struct type *type1, *type2;
 
@@ -823,13 +895,15 @@ value_args_as_decimal (struct value *arg1, struct value *arg2,
 
   if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT)
     {
+      *byte_order_x = gdbarch_byte_order (get_type_arch (type1));
       *len_x = TYPE_LENGTH (type1);
       memcpy (x, value_contents (arg1), *len_x);
     }
   else if (is_integral_type (type1))
     {
+      *byte_order_x = gdbarch_byte_order (get_type_arch (type2));
       *len_x = TYPE_LENGTH (type2);
-      decimal_from_integral (arg1, x, *len_x);
+      decimal_from_integral (arg1, x, *len_x, *byte_order_x);
     }
   else
     error (_("Don't know how to convert from %s to %s."), TYPE_NAME (type1),
@@ -840,13 +914,15 @@ value_args_as_decimal (struct value *arg1, struct value *arg2,
 
   if (TYPE_CODE (type2) == TYPE_CODE_DECFLOAT)
     {
+      *byte_order_y = gdbarch_byte_order (get_type_arch (type2));
       *len_y = TYPE_LENGTH (type2);
       memcpy (y, value_contents (arg2), *len_y);
     }
   else if (is_integral_type (type2))
     {
+      *byte_order_y = gdbarch_byte_order (get_type_arch (type1));
       *len_y = TYPE_LENGTH (type1);
-      decimal_from_integral (arg2, y, *len_y);
+      decimal_from_integral (arg2, y, *len_y, *byte_order_y);
     }
   else
     error (_("Don't know how to convert from %s to %s."), TYPE_NAME (type1),
@@ -859,8 +935,8 @@ value_args_as_decimal (struct value *arg1, struct value *arg2,
    Does not support addition and subtraction on pointers;
    use value_ptradd, value_ptrsub or value_ptrdiff for those operations.  */
 
-struct value *
-value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
+static struct value *
+scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 {
   struct value *val;
   struct type *type1, *type2, *result_type;
@@ -882,12 +958,27 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT
       || TYPE_CODE (type2) == TYPE_CODE_DECFLOAT)
     {
-      struct type *v_type;
       int len_v1, len_v2, len_v;
+      enum bfd_endian byte_order_v1, byte_order_v2, byte_order_v;
       gdb_byte v1[16], v2[16];
       gdb_byte v[16];
 
-      value_args_as_decimal (arg1, arg2, v1, &len_v1, v2, &len_v2);
+      /* If only one type is decimal float, use its type.
+        Otherwise use the bigger type.  */
+      if (TYPE_CODE (type1) != TYPE_CODE_DECFLOAT)
+       result_type = type2;
+      else if (TYPE_CODE (type2) != TYPE_CODE_DECFLOAT)
+       result_type = type1;
+      else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1))
+       result_type = type2;
+      else
+       result_type = type1;
+
+      len_v = TYPE_LENGTH (result_type);
+      byte_order_v = gdbarch_byte_order (get_type_arch (result_type));
+
+      value_args_as_decimal (arg1, arg2, v1, &len_v1, &byte_order_v1,
+                                        v2, &len_v2, &byte_order_v2);
 
       switch (op)
        {
@@ -896,24 +987,15 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
        case BINOP_MUL:
        case BINOP_DIV:
        case BINOP_EXP:
-         decimal_binop (op, v1, len_v1, v2, len_v2, v, &len_v);
+         decimal_binop (op, v1, len_v1, byte_order_v1,
+                            v2, len_v2, byte_order_v2,
+                            v, len_v, byte_order_v);
          break;
 
        default:
          error (_("Operation not valid for decimal floating point number."));
        }
 
-      /* If only one type is decimal float, use its type.
-        Otherwise use the bigger type.  */
-      if (TYPE_CODE (type1) != TYPE_CODE_DECFLOAT)
-       result_type = type2;
-      else if (TYPE_CODE (type2) != TYPE_CODE_DECFLOAT)
-       result_type = type1;
-      else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1))
-       result_type = type2;
-      else
-       result_type = type1;
-
       val = value_from_decfloat (result_type, v);
     }
   else if (TYPE_CODE (type1) == TYPE_CODE_FLT
@@ -923,6 +1005,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
          in target format.  real.c in GCC probably has the necessary
          code.  */
       DOUBLEST v1, v2, v = 0;
+
       v1 = value_as_double (arg1);
       v2 = value_as_double (arg2);
 
@@ -981,6 +1064,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
           || TYPE_CODE (type2) == TYPE_CODE_BOOL)
     {
       LONGEST v1, v2, v = 0;
+
       v1 = value_as_long (arg1);
       v2 = value_as_long (arg2);
 
@@ -1015,6 +1099,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
       val = allocate_value (result_type);
       store_signed_integer (value_contents_raw (val),
                            TYPE_LENGTH (result_type),
+                           gdbarch_byte_order (get_type_arch (result_type)),
                            v);
     }
   else
@@ -1043,6 +1128,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
        {
          LONGEST v2_signed = value_as_long (arg2);
          ULONGEST v1, v2, v = 0;
+
          v1 = (ULONGEST) value_as_long (arg1);
          v2 = (ULONGEST) v2_signed;
 
@@ -1142,6 +1228,18 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
              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."));
            }
@@ -1149,11 +1247,14 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
          val = allocate_value (result_type);
          store_unsigned_integer (value_contents_raw (val),
                                  TYPE_LENGTH (value_type (val)),
+                                 gdbarch_byte_order
+                                   (get_type_arch (result_type)),
                                  v);
        }
       else
        {
          LONGEST v1, v2, v = 0;
+
          v1 = value_as_long (arg1);
          v2 = value_as_long (arg2);
 
@@ -1249,10 +1350,26 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
              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."));
            }
@@ -1260,12 +1377,100 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
          val = allocate_value (result_type);
          store_signed_integer (value_contents_raw (val),
                                TYPE_LENGTH (value_type (val)),
+                               gdbarch_byte_order
+                                 (get_type_arch (result_type)),
                                v);
        }
     }
 
   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, *result_type;
+  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 = (TYPE_CODE (type1) == TYPE_CODE_ARRAY
+              && TYPE_VECTOR (type1)) ? 1 : 0;
+  t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY
+              && TYPE_VECTOR (type2)) ? 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 (TYPE_CODE (eltype1) != TYPE_CODE (eltype2)
+      || elsize != TYPE_LENGTH (eltype2)
+      || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)
+      || 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 = (TYPE_CODE (type1) == TYPE_CODE_ARRAY
+                  && TYPE_VECTOR (type1));
+  int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY
+                  && TYPE_VECTOR (type2));
+
+  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 (TYPE_CODE (t) != TYPE_CODE_FLT
+         && TYPE_CODE (t) != TYPE_CODE_DECFLOAT
+         && !is_integral_type (t))
+       error (_("Argument to operation not a number or boolean."));
+
+      *v = value_cast (t1_is_vec ? type1 : type2, *v);
+      val = vector_binop (arg1, arg2, op);
+    }
+
+  return val;
+}
 \f
 /* Simulate the C operator ! -- return 1 if ARG1 contains zero.  */
 
@@ -1282,7 +1487,8 @@ value_logical_not (struct value *arg1)
   if (TYPE_CODE (type1) == TYPE_CODE_FLT)
     return 0 == value_as_double (arg1);
   else if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT)
-    return decimal_is_zero (value_contents (arg1), TYPE_LENGTH (type1));
+    return decimal_is_zero (value_contents (arg1), TYPE_LENGTH (type1),
+                           gdbarch_byte_order (get_type_arch (type1)));
 
   len = TYPE_LENGTH (type1);
   p = value_contents (arg1);
@@ -1359,6 +1565,7 @@ value_equal (struct value *arg1, struct value *arg2)
       /* NOTE: kettenis/20050816: Avoid compiler bug on systems where
         `long double' values are returned in static storage (m68k).  */
       DOUBLEST d = value_as_double (arg1);
+
       return d == value_as_double (arg2);
     }
   else if ((code1 == TYPE_CODE_DECFLOAT || is_int1)
@@ -1366,10 +1573,13 @@ value_equal (struct value *arg1, struct value *arg2)
     {
       gdb_byte v1[16], v2[16];
       int len_v1, len_v2;
+      enum bfd_endian byte_order_v1, byte_order_v2;
 
-      value_args_as_decimal (arg1, arg2, v1, &len_v1, v2, &len_v2);
+      value_args_as_decimal (arg1, arg2, v1, &len_v1, &byte_order_v1,
+                                        v2, &len_v2, &byte_order_v2);
 
-      return decimal_compare (v1, len_v1, v2, len_v2) == 0;
+      return decimal_compare (v1, len_v1, byte_order_v1,
+                             v2, len_v2, byte_order_v2) == 0;
     }
 
   /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
@@ -1403,6 +1613,24 @@ value_equal (struct value *arg1, struct value *arg2)
     }
 }
 
+/* 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 (TYPE_CODE (type1) == TYPE_CODE (type2)
+         && 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.  */
 
@@ -1433,6 +1661,7 @@ value_less (struct value *arg1, struct value *arg2)
       /* NOTE: kettenis/20050816: Avoid compiler bug on systems where
         `long double' values are returned in static storage (m68k).  */
       DOUBLEST d = value_as_double (arg1);
+
       return d < value_as_double (arg2);
     }
   else if ((code1 == TYPE_CODE_DECFLOAT || is_int1)
@@ -1440,10 +1669,13 @@ value_less (struct value *arg1, struct value *arg2)
     {
       gdb_byte v1[16], v2[16];
       int len_v1, len_v2;
+      enum bfd_endian byte_order_v1, byte_order_v2;
 
-      value_args_as_decimal (arg1, arg2, v1, &len_v1, v2, &len_v2);
+      value_args_as_decimal (arg1, arg2, v1, &len_v1, &byte_order_v1,
+                                        v2, &len_v2, &byte_order_v2);
 
-      return decimal_compare (v1, len_v1, v2, len_v2) == -1;
+      return decimal_compare (v1, len_v1, byte_order_v1,
+                             v2, len_v2, byte_order_v2) == -1;
     }
   else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
     return value_as_address (arg1) < value_as_address (arg2);
@@ -1481,6 +1713,14 @@ value_pos (struct value *arg1)
     {
       return value_from_longest (type, value_as_long (arg1));
     }
+  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+    {
+      struct value *val = allocate_value (type);
+
+      memcpy (value_contents_raw (val), value_contents (arg1),
+              TYPE_LENGTH (type));
+      return val;
+    }
   else
     {
       error ("Argument to positive operation not a number.");
@@ -1504,7 +1744,7 @@ value_neg (struct value *arg1)
 
       memcpy (decbytes, value_contents (arg1), len);
 
-      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
+      if (gdbarch_byte_order (get_type_arch (type)) == BFD_ENDIAN_LITTLE)
        decbytes[len-1] = decbytes[len - 1] | 0x80;
       else
        decbytes[0] = decbytes[0] | 0x80;
@@ -1518,6 +1758,20 @@ value_neg (struct value *arg1)
     {
       return value_from_longest (type, -value_as_long (arg1));
     }
+  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+    {
+      struct value *tmp, *val = allocate_value (type);
+      struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
+      int i, n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype);
+
+      for (i = 0; i < n; 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
     {
       error (_("Argument to negate operation not a number."));
@@ -1529,14 +1783,31 @@ 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))
-    error (_("Argument to complement operation not an integer or boolean."));
+  if (is_integral_type (type))
+    val = value_from_longest (type, ~value_as_long (arg1));
+  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+    {
+      struct value *tmp;
+      struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
+      int i, n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype);
+
+      val = allocate_value (type);
+      for (i = 0; i < n; 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
+    error (_("Argument to complement operation not an integer, boolean."));
 
-  return value_from_longest (type, ~value_as_long (arg1));
+  return val;
 }
 \f
 /* The INDEX'th bit of SET value whose value_type is TYPE,
@@ -1546,18 +1817,21 @@ value_complement (struct value *arg1)
 int
 value_bit_index (struct type *type, const gdb_byte *valaddr, int index)
 {
+  struct gdbarch *gdbarch = get_type_arch (type);
   LONGEST low_bound, high_bound;
   LONGEST word;
   unsigned rel_index;
   struct type *range = TYPE_INDEX_TYPE (type);
+
   if (get_discrete_bounds (range, &low_bound, &high_bound) < 0)
     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);
+  word = extract_unsigned_integer (valaddr + (rel_index / TARGET_CHAR_BIT), 1,
+                                  gdbarch_byte_order (gdbarch));
   rel_index %= TARGET_CHAR_BIT;
-  if (gdbarch_bits_big_endian (current_gdbarch))
+  if (gdbarch_bits_big_endian (gdbarch))
     rel_index = TARGET_CHAR_BIT - 1 - rel_index;
   return (word >> rel_index) & 1;
 }
@@ -1568,6 +1842,7 @@ 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 (TYPE_CODE (eltype) == TYPE_CODE_RANGE)
     eltype = TYPE_TARGET_TYPE (eltype);
   if (TYPE_CODE (settype) != TYPE_CODE_SET)
This page took 0.035975 seconds and 4 git commands to generate.