Convert break-catch-syscall to vtable ops
[binutils-gdb.git] / gdb / valarith.c
index 07cb5014bb2ca28d7dead6f461065d23bcaca1e1..6210267826e835041d195a1c655070178608c786 100644 (file)
@@ -1,6 +1,6 @@
 /* Perform arithmetic and other operations on values, for GDB.
 
-   Copyright (C) 1986-2020 Free Software Foundation, Inc.
+   Copyright (C) 1986-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdbsupport/byte-vector.h"
 #include "gdbarch.h"
 
+/* Forward declarations.  */
+static struct value *value_subscripted_rvalue (struct value *array,
+                                              LONGEST index,
+                                              LONGEST lowerbound);
+
 /* Define whether or not the C operator '/' truncates towards zero for
    differently signed operands (truncation direction is undefined in C).  */
 
@@ -48,19 +53,19 @@ find_size_for_pointer_math (struct type *ptr_type)
   LONGEST sz = -1;
   struct type *ptr_target;
 
-  gdb_assert (TYPE_CODE (ptr_type) == TYPE_CODE_PTR);
+  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 (TYPE_CODE (ptr_type) == TYPE_CODE_VOID)
+      if (ptr_type->code () == TYPE_CODE_VOID)
        sz = 1;
       else
        {
          const char *name;
          
-         name = TYPE_NAME (ptr_target);
+         name = ptr_target->name ();
          if (name == NULL)
            error (_("Cannot perform pointer math on incomplete types, "
                   "try casting to a known type, or void *."));
@@ -107,8 +112,8 @@ value_ptrdiff (struct value *arg1, struct value *arg2)
   type1 = check_typedef (value_type (arg1));
   type2 = check_typedef (value_type (arg2));
 
-  gdb_assert (TYPE_CODE (type1) == TYPE_CODE_PTR);
-  gdb_assert (TYPE_CODE (type2) == TYPE_CODE_PTR);
+  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))))
@@ -120,7 +125,7 @@ value_ptrdiff (struct value *arg1, struct value *arg2)
   if (sz == 0) 
     {
       warning (_("Type size unknown, assuming 1. "
-               "Try casting to a known type, or void *."));
+              "Try casting to a known type, or void *."));
       sz = 1;
     }
 
@@ -140,35 +145,43 @@ value_ptrdiff (struct value *arg1, struct value *arg2)
 struct value *
 value_subscript (struct value *array, LONGEST index)
 {
-  int c_style = current_language->c_style_arrays;
+  bool c_style = current_language->c_style_arrays_p ();
   struct type *tarray;
 
   array = coerce_ref (array);
   tarray = check_typedef (value_type (array));
 
-  if (TYPE_CODE (tarray) == TYPE_CODE_ARRAY
-      || TYPE_CODE (tarray) == TYPE_CODE_STRING)
+  if (tarray->code () == TYPE_CODE_ARRAY
+      || tarray->code () == TYPE_CODE_STRING)
     {
-      struct type *range_type = TYPE_INDEX_TYPE (tarray);
-      LONGEST lowerbound, upperbound;
+      struct type *range_type = tarray->index_type ();
+      gdb::optional<LONGEST> lowerbound = get_discrete_low_bound (range_type);
+      if (!lowerbound.has_value ())
+       lowerbound = 0;
 
-      get_discrete_bounds (range_type, &lowerbound, &upperbound);
       if (VALUE_LVAL (array) != lval_memory)
-       return value_subscripted_rvalue (array, index, lowerbound);
+       return value_subscripted_rvalue (array, index, *lowerbound);
+
+      gdb::optional<LONGEST> upperbound
+       = get_discrete_high_bound (range_type);
+
+      if (!upperbound.has_value ())
+       upperbound = -1;
 
-      if (c_style == 0)
+      if (index >= *lowerbound && index <= *upperbound)
+       return value_subscripted_rvalue (array, index, *lowerbound);
+
+      if (!c_style)
        {
-         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)
+         if (*upperbound > -1)
            warning (_("array or string index out of range"));
          /* fall doing C stuff */
-         c_style = 1;
+         c_style = true;
        }
 
-      index -= lowerbound;
+      index -= *lowerbound;
       array = value_coerce_array (array);
     }
 
@@ -182,37 +195,39 @@ value_subscript (struct value *array, LONGEST index)
    (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)
+static 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));
+  struct type *elt_type = 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 = TYPE_ARRAY_BIT_STRIDE (array_type);
+  LONGEST stride = array_type->bit_stride ();
   if (stride != 0)
     {
-      struct gdbarch *arch = get_type_arch (elt_type);
+      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
-      || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type)
-          && elt_offs >= type_length_units (array_type))
-      || (VALUE_LVAL (array) != lval_memory
-          && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type)))
+      || (!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)"));
+       error (_("no such vector element (vector not associated)"));
       else if (type_not_allocated (array_type))
-        error (_("no such vector element (vector not allocated)"));
+       error (_("no such vector element (vector not allocated)"));
       else
-        error (_("no such vector element"));
+       error (_("no such vector element"));
     }
 
   if (is_dynamic_type (elt_type))
@@ -220,7 +235,7 @@ value_subscripted_rvalue (struct value *array, LONGEST index, LONGEST lowerbound
       CORE_ADDR address;
 
       address = value_address (array) + elt_offs;
-      elt_type = resolve_dynamic_type (elt_type, NULL, address);
+      elt_type = resolve_dynamic_type (elt_type, {}, address);
     }
 
   return value_from_component (array, elt_type, elt_offs);
@@ -237,7 +252,7 @@ int
 binop_types_user_defined_p (enum exp_opcode op,
                            struct type *type1, struct type *type2)
 {
-  if (op == BINOP_ASSIGN || op == BINOP_CONCAT)
+  if (op == BINOP_ASSIGN)
     return 0;
 
   type1 = check_typedef (type1);
@@ -248,8 +263,8 @@ binop_types_user_defined_p (enum exp_opcode op,
   if (TYPE_IS_REFERENCE (type2))
     type2 = check_typedef (TYPE_TARGET_TYPE (type2));
 
-  return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
-         || TYPE_CODE (type2) == TYPE_CODE_STRUCT);
+  return (type1->code () == TYPE_CODE_STRUCT
+         || type2->code () == TYPE_CODE_STRUCT);
 }
 
 /* Check to see if either argument is a structure, or a reference to
@@ -281,7 +296,7 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
   type1 = check_typedef (value_type (arg1));
   if (TYPE_IS_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
-  return TYPE_CODE (type1) == TYPE_CODE_STRUCT;
+  return type1->code () == TYPE_CODE_STRUCT;
 }
 
 /* Try to find an operator named OPERATOR which takes NARGS arguments
@@ -294,16 +309,16 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
 
 static struct value *
 value_user_defined_cpp_op (gdb::array_view<value *> args, char *oper,
-                           int *static_memfuncp, enum noside noside)
+                          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);
+                      &args[0] /* objp */,
+                      NULL /* pass NULL symbol since symbol is unknown */,
+                      &valp, &symp, static_memfuncp, 0, noside);
 
   if (valp)
     return valp;
@@ -311,8 +326,8 @@ value_user_defined_cpp_op (gdb::array_view<value *> args, char *oper,
   if (symp)
     {
       /* This is a non member function and does not
-         expect a reference as its first argument
-         rather the explicit structure.  */
+        expect a reference as its first argument
+        rather the explicit structure.  */
       args[0] = value_ind (args[0]);
       return value_of_variable (symp, 0);
     }
@@ -335,7 +350,7 @@ value_user_defined_op (struct value **argp, gdb::array_view<value *> args,
                                          noside);
     }
   else
-    result = value_struct_elt (argp, args.data (), name, static_memfuncp,
+    result = value_struct_elt (argp, args, name, static_memfuncp,
                               "structure");
 
   return result;
@@ -364,7 +379,7 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
   /* now we know that what we have to do is construct our
      arg vector and find the right function to call it with.  */
 
-  if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT)
+  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];
@@ -491,7 +506,7 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
          argvec[1] = argvec[0];
          argvec = argvec.slice (1);
        }
-      if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD)
+      if (value_type (argvec[0])->code () == TYPE_CODE_XMETHOD)
        {
          /* Static xmethods are not supported yet.  */
          gdb_assert (static_memfuncp == 0);
@@ -518,7 +533,7 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
                                    argvec.slice (1, 2 - static_memfuncp));
     }
   throw_error (NOT_FOUND_ERROR,
-               _("member function %s not found"), tstr);
+              _("member function %s not found"), tstr);
 }
 
 /* We know that arg1 is a structure, so try to find a unary user
@@ -530,7 +545,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 gdbarch *gdbarch = value_type (arg1)->arch ();
   char *ptr;
   char tstr[13], mangle_tstr[13];
   int static_memfuncp, nargs;
@@ -540,7 +555,7 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
   /* now we know that what we have to do is construct our
      arg vector and find the right function to call it with.  */
 
-  if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT)
+  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];
@@ -605,7 +620,7 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
          argvec[1] = argvec[0];
          argvec = argvec.slice (1);
        }
-      if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD)
+      if (value_type (argvec[0])->code () == TYPE_CODE_XMETHOD)
        {
          /* Static xmethods are not supported yet.  */
          gdb_assert (static_memfuncp == 0);
@@ -632,159 +647,70 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
                                    argvec.slice (1, nargs));
     }
   throw_error (NOT_FOUND_ERROR,
-               _("member function %s not found"), tstr);
+              _("member function %s not found"), tstr);
 }
 \f
 
-/* 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.  */
+/* Concatenate two values.  One value must be an array; and the other
+   value must either be an array with the same element type, or be of
+   the array's element type.  */
 
 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 (type1->code () != TYPE_CODE_ARRAY && type2->code () != TYPE_CODE_ARRAY)
+    error ("no array provided to concatenation");
 
-  if (TYPE_CODE (type2) == TYPE_CODE_INT)
+  LONGEST low1, high1;
+  struct type *elttype1 = type1;
+  if (elttype1->code () == TYPE_CODE_ARRAY)
     {
-      struct type *tmp = type1;
-
-      type1 = tmp;
-      tmp = type2;
-      inval1 = arg2;
-      inval2 = arg1;
+      elttype1 = TYPE_TARGET_TYPE (elttype1);
+      if (!get_array_bounds (type1, &low1, &high1))
+       error (_("could not determine array bounds on left-hand-side of "
+                "array concatenation"));
     }
   else
     {
-      inval1 = arg1;
-      inval2 = arg2;
+      low1 = 0;
+      high1 = 0;
     }
 
-  /* Now process the input values.  */
-
-  if (TYPE_CODE (type1) == TYPE_CODE_INT)
+  LONGEST low2, high2;
+  struct type *elttype2 = type2;
+  if (elttype2->code () == TYPE_CODE_ARRAY)
     {
-      /* We have a repeat count.  Validate the second value and then
-         construct a value repeated that many times.  */
-      if (TYPE_CODE (type2) == TYPE_CODE_STRING
-         || TYPE_CODE (type2) == TYPE_CODE_CHAR)
-       {
-         count = longest_to_int (value_as_long (inval1));
-         inval2len = TYPE_LENGTH (type2);
-         std::vector<char> ptr (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++)
-               {
-                 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 (TYPE_CODE (type2) == TYPE_CODE_BOOL)
-       {
-         error (_("unimplemented support for boolean repeats"));
-       }
-      else
-       {
-         error (_("can't repeat values of that type"));
-       }
-    }
-  else if (TYPE_CODE (type1) == TYPE_CODE_STRING
-          || TYPE_CODE (type1) == TYPE_CODE_CHAR)
-    {
-      /* We have two character strings to concatenate.  */
-      if (TYPE_CODE (type2) != TYPE_CODE_STRING
-         && TYPE_CODE (type2) != 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 (TYPE_CODE (type1) == 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 (TYPE_CODE (type2) == 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 (TYPE_CODE (type1) == TYPE_CODE_BOOL)
-    {
-      /* We have two bitstrings to concatenate.  */
-      if (TYPE_CODE (type2) != TYPE_CODE_BOOL)
-       {
-         error (_("Booleans can only be concatenated "
-                  "with other bitstrings or booleans."));
-       }
-      error (_("unimplemented support for boolean concatenation."));
+      elttype2 = TYPE_TARGET_TYPE (elttype2);
+      if (!get_array_bounds (type2, &low2, &high2))
+       error (_("could not determine array bounds on right-hand-side of "
+                "array concatenation"));
     }
   else
     {
-      /* We don't know how to concatenate these operands.  */
-      error (_("illegal operands for concatenation."));
+      low2 = 0;
+      high2 = 0;
     }
-  return (outval);
+
+  if (!types_equal (elttype1, elttype2))
+    error (_("concatenation with different element types"));
+
+  LONGEST lowbound = current_language->c_style_arrays_p () ? 0 : 1;
+  LONGEST n_elts = (high1 - low1 + 1) + (high2 - low2 + 1);
+  struct type *atype = lookup_array_range_type (elttype1,
+                                               lowbound,
+                                               lowbound + n_elts - 1);
+
+  struct value *result = allocate_value (atype);
+  gdb::array_view<gdb_byte> contents = value_contents_raw (result);
+  gdb::array_view<const gdb_byte> lhs_contents = value_contents (arg1);
+  gdb::array_view<const gdb_byte> rhs_contents = value_contents (arg2);
+  gdb::copy (lhs_contents, contents.slice (0, lhs_contents.size ()));
+  gdb::copy (rhs_contents, contents.slice (lhs_contents.size ()));
+
+  return result;
 }
 \f
 /* Integer exponentiation: V1**V2, where both arguments are
@@ -818,37 +744,6 @@ integer_pow (LONGEST v1, LONGEST v2)
     }
 }
 
-/* Integer exponentiation: V1**V2, where both arguments are
-   integers.  Requires V1 != 0 if V2 < 0.  Returns 1 for 0 ** 0.  */
-
-static ULONGEST
-uinteger_pow (ULONGEST 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.  */
-      ULONGEST 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
@@ -865,7 +760,7 @@ value_args_as_target_float (struct value *arg1, struct value *arg2,
   gdb_assert (is_floating_type (type1) || is_floating_type (type2));
 
   if (is_floating_type (type1) && is_floating_type (type2)
-      && TYPE_CODE (type1) != TYPE_CODE (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).  */
@@ -877,38 +772,148 @@ value_args_as_target_float (struct value *arg1, struct value *arg2,
   if (is_floating_type (type1))
     {
       *eff_type_x = type1;
-      memcpy (x, value_contents (arg1), TYPE_LENGTH (type1));
+      memcpy (x, value_contents (arg1).data (), TYPE_LENGTH (type1));
     }
   else if (is_integral_type (type1))
     {
       *eff_type_x = type2;
-      if (TYPE_UNSIGNED (type1))
+      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."), TYPE_NAME (type1),
-            TYPE_NAME (type2));
+    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));
+      memcpy (y, value_contents (arg2).data (), TYPE_LENGTH (type2));
     }
   else if (is_integral_type (type2))
     {
       *eff_type_y = type1;
-      if (TYPE_UNSIGNED (type2))
+      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."), TYPE_NAME (type1),
-            TYPE_NAME (type2));
+    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 (value_contents (arg1),
+                          type_byte_order (type1), type1->is_unsigned (),
+                          type1->fixed_point_scaling_factor ());
+      v2.read_fixed_point (value_contents (arg2),
+                          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
+       (value_contents_raw (fp_val),
+        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
@@ -939,9 +944,9 @@ promotion_type (struct type *type1, struct type *type2)
        result_type = type1;
       else if (TYPE_LENGTH (type2) > TYPE_LENGTH (type1))
        result_type = type2;
-      else if (TYPE_UNSIGNED (type1))
+      else if (type1->is_unsigned ())
        result_type = type1;
-      else if (TYPE_UNSIGNED (type2))
+      else if (type2->is_unsigned ())
        result_type = type2;
       else
        result_type = type1;
@@ -962,7 +967,7 @@ complex_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   struct type *arg2_type = check_typedef (value_type (arg2));
 
   struct value *arg1_real, *arg1_imag, *arg2_real, *arg2_imag;
-  if (TYPE_CODE (arg1_type) == TYPE_CODE_COMPLEX)
+  if (arg1_type->code () == TYPE_CODE_COMPLEX)
     {
       arg1_real = value_real_part (arg1);
       arg1_imag = value_imaginary_part (arg1);
@@ -972,7 +977,7 @@ complex_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
       arg1_real = arg1;
       arg1_imag = value_zero (arg1_type, not_lval);
     }
-  if (TYPE_CODE (arg2_type) == TYPE_CODE_COMPLEX)
+  if (arg2_type->code () == TYPE_CODE_COMPLEX)
     {
       arg2_real = value_real_part (arg2);
       arg2_imag = value_imaginary_part (arg2);
@@ -985,6 +990,9 @@ complex_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 
   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);
@@ -1015,7 +1023,7 @@ complex_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 
     case BINOP_DIV:
       {
-       if (TYPE_CODE (arg2_type) == TYPE_CODE_COMPLEX)
+       if (arg2_type->code () == TYPE_CODE_COMPLEX)
          {
            struct value *conjugate = value_complement (arg2);
            /* We have to reconstruct ARG1, in case the type was
@@ -1062,6 +1070,66 @@ complex_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   return value_literal_complex (result_real, result_imag, result_type);
 }
 
+/* Return the type's length in bits.  */
+
+static int
+type_length_bits (type *type)
+{
+  int unit_size = gdbarch_addressable_memory_unit_size (type->arch ());
+  return unit_size * 8 * TYPE_LENGTH (type);
+}
+
+/* Check whether the RHS value of a shift is valid in C/C++ semantics.
+   SHIFT_COUNT is the shift amount, SHIFT_COUNT_TYPE is the type of
+   the shift count value, used to determine whether the type is
+   signed, and RESULT_TYPE is the result type.  This is used to avoid
+   both negative and too-large shift amounts, which are undefined, and
+   would crash a GDB built with UBSan.  Depending on the current
+   language, if the shift is not valid, this either warns and returns
+   false, or errors out.  Returns true if valid.  */
+
+static bool
+check_valid_shift_count (int op, type *result_type,
+                        type *shift_count_type, ULONGEST shift_count)
+{
+  if (!shift_count_type->is_unsigned () && (LONGEST) shift_count < 0)
+    {
+      auto error_or_warning = [] (const char *msg)
+      {
+       /* Shifts by a negative amount are always an error in Go.  Other
+          languages are more permissive and their compilers just warn or
+          have modes to disable the errors.  */
+       if (current_language->la_language == language_go)
+         error (("%s"), msg);
+       else
+         warning (("%s"), msg);
+      };
+
+      if (op == BINOP_RSH)
+       error_or_warning (_("right shift count is negative"));
+      else
+       error_or_warning (_("left shift count is negative"));
+      return false;
+    }
+
+  if (shift_count >= type_length_bits (result_type))
+    {
+      /* In Go, shifting by large amounts is defined.  Be silent and
+        still return false, as the caller's error path does the right
+        thing for Go.  */
+      if (current_language->la_language != language_go)
+       {
+         if (op == BINOP_RSH)
+           warning (_("right shift count >= width of type"));
+         else
+           warning (_("left shift count >= width of type"));
+       }
+      return false;
+    }
+
+  return true;
+}
+
 /* Perform a binary operation on two operands which have reasonable
    representations as integers or floats.  This includes booleans,
    characters, integers, or floats.
@@ -1080,14 +1148,21 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   type1 = check_typedef (value_type (arg1));
   type2 = check_typedef (value_type (arg2));
 
-  if (TYPE_CODE (type1) == TYPE_CODE_COMPLEX
-      || TYPE_CODE (type2) == TYPE_CODE_COMPLEX)
+  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_floating_value (arg2) && !is_integral_type (type2)))
+  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);
@@ -1103,10 +1178,10 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
                                  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);
+                             value_contents_raw (val).data (), result_type);
     }
-  else if (TYPE_CODE (type1) == TYPE_CODE_BOOL
-          || TYPE_CODE (type2) == TYPE_CODE_BOOL)
+  else if (type1->code () == TYPE_CODE_BOOL
+          || type2->code () == TYPE_CODE_BOOL)
     {
       LONGEST v1, v2, v = 0;
 
@@ -1125,14 +1200,14 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 
        case BINOP_BITWISE_XOR:
          v = v1 ^ v2;
-          break;
-              
-        case BINOP_EQUAL:
-          v = v1 == v2;
-          break;
-          
-        case BINOP_NOTEQUAL:
-          v = v1 != v2;
+         break;
+             
+       case BINOP_EQUAL:
+         v = v1 == v2;
+         break;
+         
+       case BINOP_NOTEQUAL:
+         v = v1 != v2;
          break;
 
        default:
@@ -1142,7 +1217,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
       result_type = type1;
 
       val = allocate_value (result_type);
-      store_signed_integer (value_contents_raw (val),
+      store_signed_integer (value_contents_raw (val).data (),
                            TYPE_LENGTH (result_type),
                            type_byte_order (result_type),
                            v);
@@ -1161,7 +1236,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
       else
        result_type = promotion_type (type1, type2);
 
-      if (TYPE_UNSIGNED (result_type))
+      if (result_type->is_unsigned ())
        {
          LONGEST v2_signed = value_as_long (arg2);
          ULONGEST v1, v2, v = 0;
@@ -1192,7 +1267,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
              break;
 
            case BINOP_EXP:
-              v = uinteger_pow (v1, v2_signed);
+             v = uinteger_pow (v1, v2_signed);
              break;
 
            case BINOP_REM:
@@ -1204,7 +1279,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 
            case BINOP_MOD:
              /* Knuth 1.2.4, integer only.  Note that unlike the C '%' op,
-                v1 mod 0 has a defined value, v1.  */
+                v1 mod 0 has a defined value, v1.  */
              if (v2 == 0)
                {
                  v = v1;
@@ -1218,11 +1293,17 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
              break;
 
            case BINOP_LSH:
-             v = v1 << v2;
+             if (!check_valid_shift_count (op, result_type, type2, v2))
+               v = 0;
+             else
+               v = v1 << v2;
              break;
 
            case BINOP_RSH:
-             v = v1 >> v2;
+             if (!check_valid_shift_count (op, result_type, type2, v2))
+               v = 0;
+             else
+               v = v1 >> v2;
              break;
 
            case BINOP_BITWISE_AND:
@@ -1257,9 +1338,9 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
              v = v1 == v2;
              break;
 
-            case BINOP_NOTEQUAL:
-              v = v1 != v2;
-              break;
+           case BINOP_NOTEQUAL:
+             v = v1 != v2;
+             break;
 
            case BINOP_LESS:
              v = v1 < v2;
@@ -1282,7 +1363,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
            }
 
          val = allocate_value (result_type);
-         store_unsigned_integer (value_contents_raw (val),
+         store_unsigned_integer (value_contents_raw (val).data (),
                                  TYPE_LENGTH (value_type (val)),
                                  type_byte_order (result_type),
                                  v);
@@ -1314,10 +1395,10 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
                v = v1 / v2;
              else
                error (_("Division by zero"));
-              break;
+             break;
 
            case BINOP_EXP:
-              v = integer_pow (v1, v2);
+             v = integer_pow (v1, v2);
              break;
 
            case BINOP_REM:
@@ -1329,7 +1410,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 
            case BINOP_MOD:
              /* Knuth 1.2.4, integer only.  Note that unlike the C '%' op,
-                X mod 0 has a defined value, X.  */
+                X mod 0 has a defined value, X.  */
              if (v2 == 0)
                {
                  v = v1;
@@ -1347,11 +1428,40 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
              break;
 
            case BINOP_LSH:
-             v = v1 << v2;
+             if (!check_valid_shift_count (op, result_type, type2, v2))
+               v = 0;
+             else
+               {
+                 /* Cast to unsigned to avoid undefined behavior on
+                    signed shift overflow (unless C++20 or later),
+                    which would crash GDB when built with UBSan.
+                    Note we don't warn on left signed shift overflow,
+                    because starting with C++20, that is actually
+                    defined behavior.  Also, note GDB assumes 2's
+                    complement throughout.  */
+                 v = (ULONGEST) v1 << v2;
+               }
              break;
 
            case BINOP_RSH:
-             v = v1 >> v2;
+             if (!check_valid_shift_count (op, result_type, type2, v2))
+               {
+                 /* Pretend the too-large shift was decomposed in a
+                    number of smaller shifts.  An arithmetic signed
+                    right shift of a negative number always yields -1
+                    with such semantics.  This is the right thing to
+                    do for Go, and we might as well do it for
+                    languages where it is undefined.  Also, pretend a
+                    shift by a negative number was a shift by the
+                    negative number cast to unsigned, which is the
+                    same as shifting by a too-large number.  */
+                 if (v1 < 0)
+                   v = -1;
+                 else
+                   v = 0;
+               }
+             else
+               v = v1 >> v2;
              break;
 
            case BINOP_BITWISE_AND:
@@ -1386,9 +1496,9 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
              v = v1 == v2;
              break;
 
-            case BINOP_NOTEQUAL:
-              v = v1 != v2;
-              break;
+           case BINOP_NOTEQUAL:
+             v = v1 != v2;
+             break;
 
            case BINOP_LESS:
              v = v1 < v2;
@@ -1411,7 +1521,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
            }
 
          val = allocate_value (result_type);
-         store_signed_integer (value_contents_raw (val),
+         store_signed_integer (value_contents_raw (val).data (),
                                TYPE_LENGTH (value_type (val)),
                                type_byte_order (result_type),
                                v);
@@ -1432,14 +1542,14 @@ 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;
+  struct value *elval;
   LONGEST low_bound, high_bound;
   int i;
 
   vector_type = check_typedef (vector_type);
 
-  gdb_assert (TYPE_CODE (vector_type) == TYPE_CODE_ARRAY
-             && TYPE_VECTOR (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"));
@@ -1455,11 +1565,14 @@ value_vector_widen (struct value *scalar_value, struct type *vector_type)
       && !value_equal (elval, scalar_value))
     error (_("conversion of scalar to vector involves truncation"));
 
-  val = allocate_value (vector_type);
+  value *val = allocate_value (vector_type);
+  gdb::array_view<gdb_byte> val_contents = value_contents_writeable (val);
+  int elt_len = TYPE_LENGTH (eltype);
+
   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));
+    copy (value_contents_all (elval),
+         val_contents.slice (i * elt_len, elt_len));
 
   return val;
 }
@@ -1470,7 +1583,6 @@ value_vector_widen (struct value *scalar_value, struct type *vector_type)
 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;
@@ -1478,10 +1590,10 @@ vector_binop (struct value *val1, struct value *val2, enum exp_opcode op)
   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;
+  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"));
@@ -1494,21 +1606,21 @@ vector_binop (struct value *val1, struct value *val2, enum exp_opcode op)
   eltype2 = check_typedef (TYPE_TARGET_TYPE (type2));
   elsize = TYPE_LENGTH (eltype1);
 
-  if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2)
+  if (eltype1->code () != eltype2->code ()
       || elsize != TYPE_LENGTH (eltype2)
-      || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (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 ();
+  value *val = allocate_value (type1);
+  gdb::array_view<gdb_byte> val_contents = value_contents_writeable (val);
+  value *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 *tmp = value_binop (value_subscript (val1, i),
+                               value_subscript (val2, i), op);
+      copy (value_contents_all (tmp),
+           val_contents.slice (i * elsize, elsize));
      }
   value_free_to_mark (mark);
 
@@ -1523,10 +1635,10 @@ 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));
+  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);
@@ -1538,8 +1650,8 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
       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
+      if (t->code () != TYPE_CODE_FLT
+         && t->code () != TYPE_CODE_DECFLOAT
          && !is_integral_type (t))
        error (_("Argument to operation not a number or boolean."));
 
@@ -1552,9 +1664,9 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   return val;
 }
 \f
-/* Simulate the C operator ! -- return 1 if ARG1 contains zero.  */
+/* See value.h.  */
 
-int
+bool
 value_logical_not (struct value *arg1)
 {
   int len;
@@ -1565,10 +1677,10 @@ value_logical_not (struct value *arg1)
   type1 = check_typedef (value_type (arg1));
 
   if (is_floating_value (arg1))
-    return target_float_is_zero (value_contents (arg1), type1);
+    return target_float_is_zero (value_contents (arg1).data (), type1);
 
   len = TYPE_LENGTH (type1);
-  p = value_contents (arg1);
+  p = value_contents (arg1).data ();
 
   while (--len >= 0)
     {
@@ -1587,18 +1699,18 @@ 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);
+  const gdb_byte *s1 = value_contents (arg1).data ();
+  const gdb_byte *s2 = value_contents (arg2).data ();
   int i, len = len1 < len2 ? len1 : len2;
 
   for (i = 0; i < len; i++)
     {
       if (s1[i] < s2[i])
-        return -1;
+       return -1;
       else if (s1[i] > s2[i])
-        return 1;
+       return 1;
       else
-        continue;
+       continue;
     }
 
   if (len1 < len2)
@@ -1628,8 +1740,8 @@ value_equal (struct value *arg1, struct value *arg2)
 
   type1 = check_typedef (value_type (arg1));
   type2 = check_typedef (value_type (arg2));
-  code1 = TYPE_CODE (type1);
-  code2 = TYPE_CODE (type2);
+  code1 = type1->code ();
+  code2 = type2->code ();
   is_int1 = is_integral_type (type1);
   is_int2 = is_integral_type (type2);
 
@@ -1663,8 +1775,8 @@ value_equal (struct value *arg1, struct value *arg2)
           && ((len = (int) TYPE_LENGTH (type1))
               == (int) TYPE_LENGTH (type2)))
     {
-      p1 = value_contents (arg1);
-      p2 = value_contents (arg2);
+      p1 = value_contents (arg1).data ();
+      p2 = value_contents (arg2).data ();
       while (--len >= 0)
        {
          if (*p1++ != *p2++)
@@ -1692,9 +1804,10 @@ value_equal_contents (struct value *arg1, struct value *arg2)
   type1 = check_typedef (value_type (arg1));
   type2 = check_typedef (value_type (arg2));
 
-  return (TYPE_CODE (type1) == TYPE_CODE (type2)
+  return (type1->code () == type2->code ()
          && TYPE_LENGTH (type1) == TYPE_LENGTH (type2)
-         && memcmp (value_contents (arg1), value_contents (arg2),
+         && memcmp (value_contents (arg1).data (),
+                    value_contents (arg2).data (),
                     TYPE_LENGTH (type1)) == 0);
 }
 
@@ -1714,12 +1827,13 @@ value_less (struct value *arg1, struct value *arg2)
 
   type1 = check_typedef (value_type (arg1));
   type2 = check_typedef (value_type (arg2));
-  code1 = TYPE_CODE (type1);
-  code2 = TYPE_CODE (type2);
+  code1 = type1->code ();
+  code2 = type2->code ();
   is_int1 = is_integral_type (type1);
   is_int2 = is_integral_type (type2);
 
-  if (is_int1 && is_int2)
+  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)
@@ -1766,9 +1880,9 @@ value_pos (struct value *arg1)
   type = check_typedef (value_type (arg1));
 
   if (is_integral_type (type) || is_floating_value (arg1)
-      || (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
-      || TYPE_CODE (type) == TYPE_CODE_COMPLEX)
-    return value_from_contents (type, value_contents (arg1));
+      || (type->code () == TYPE_CODE_ARRAY && type->is_vector ())
+      || type->code () == TYPE_CODE_COMPLEX)
+    return value_from_contents (type, value_contents (arg1).data ());
   else
     error (_("Argument to positive operation not a number."));
 }
@@ -1783,9 +1897,11 @@ value_neg (struct value *arg1)
 
   if (is_integral_type (type) || is_floating_type (type))
     return value_binop (value_from_longest (type, 0), arg1, BINOP_SUB);
-  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+  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 value *val = allocate_value (type);
       struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
       int i;
       LONGEST low_bound, high_bound;
@@ -1793,15 +1909,18 @@ value_neg (struct value *arg1)
       if (!get_array_bounds (type, &low_bound, &high_bound))
        error (_("Could not determine the vector bounds"));
 
+      gdb::array_view<gdb_byte> val_contents = value_contents_writeable (val);
+      int elt_len = TYPE_LENGTH (eltype);
+
       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));
+         value *tmp = value_neg (value_subscript (arg1, i));
+         copy (value_contents_all (tmp),
+               val_contents.slice (i * elt_len, elt_len));
        }
       return val;
     }
-  else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX)
+  else if (type->code () == TYPE_CODE_COMPLEX)
     {
       struct value *real = value_real_part (arg1);
       struct value *imag = value_imaginary_part (arg1);
@@ -1825,9 +1944,8 @@ value_complement (struct value *arg1)
 
   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))
+  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;
@@ -1836,14 +1954,17 @@ value_complement (struct value *arg1)
        error (_("Could not determine the vector bounds"));
 
       val = allocate_value (type);
+      gdb::array_view<gdb_byte> val_contents = value_contents_writeable (val);
+      int elt_len = TYPE_LENGTH (eltype);
+
       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));
-        }
+       {
+         value *tmp = value_complement (value_subscript (arg1, i));
+         copy (value_contents_all (tmp),
+               val_contents.slice (i * elt_len, elt_len));
+       }
     }
-  else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX)
+  else if (type->code () == TYPE_CODE_COMPLEX)
     {
       /* GCC has an extension that treats ~complex as the complex
         conjugate.  */
@@ -1866,13 +1987,13 @@ 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);
+  struct gdbarch *gdbarch = type->arch ();
   LONGEST low_bound, high_bound;
   LONGEST word;
   unsigned rel_index;
-  struct type *range = TYPE_INDEX_TYPE (type);
+  struct type *range = type->index_type ();
 
-  if (get_discrete_bounds (range, &low_bound, &high_bound) < 0)
+  if (!get_discrete_bounds (range, &low_bound, &high_bound))
     return -2;
   if (index < low_bound || index > high_bound)
     return -1;
@@ -1892,16 +2013,16 @@ value_in (struct value *element, struct value *set)
   struct type *settype = check_typedef (value_type (set));
   struct type *eltype = check_typedef (value_type (element));
 
-  if (TYPE_CODE (eltype) == TYPE_CODE_RANGE)
+  if (eltype->code () == TYPE_CODE_RANGE)
     eltype = TYPE_TARGET_TYPE (eltype);
-  if (TYPE_CODE (settype) != TYPE_CODE_SET)
+  if (settype->code () != TYPE_CODE_SET)
     error (_("Second argument of 'IN' has wrong type"));
-  if (TYPE_CODE (eltype) != TYPE_CODE_INT
-      && TYPE_CODE (eltype) != TYPE_CODE_CHAR
-      && TYPE_CODE (eltype) != TYPE_CODE_ENUM
-      && TYPE_CODE (eltype) != TYPE_CODE_BOOL)
+  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),
+  member = value_bit_index (settype, value_contents (set).data (),
                            value_as_long (element));
   if (member < 0)
     error (_("First argument of 'IN' not in range"));