((type->is_unsigned () ? ax_zero_ext : ax_ext) (ax, bits));
 }
 
+/* A helper that returns the target type if TYPE is a range type, or
+   otherwise just returns TYPE.  */
+
+static struct type *
+strip_range_type (struct type *type)
+{
+  if (type->code () == TYPE_CODE_RANGE)
+    return type->target_type ();
+  return type;
+}
 
 /* Assume that the top of the stack contains a value of type "pointer
    to TYPE"; generate code to fetch its value.  Note that TYPE is the
       ax_trace_quick (ax, type->length ());
     }
 
-  if (type->code () == TYPE_CODE_RANGE)
-    type = type->target_type ();
+  type = strip_range_type (type);
 
   switch (type->code ())
     {
 gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1,
                      struct axs_value *value2)
 {
+  struct type *type1 = strip_range_type (value1->type);
+  struct type *type2 = strip_range_type (value2->type);
+
   /* Do the usual binary conversions.  */
-  if (value1->type->code () == TYPE_CODE_INT
-      && value2->type->code () == TYPE_CODE_INT)
+  if (type1->code () == TYPE_CODE_INT
+      && type2->code () == TYPE_CODE_INT)
     {
       /* The ANSI integral promotions seem to work this way: Order the
         integer types by size, and then by signedness: an n-bit
         type.  Promote to the "wider" of the two types, and always
         promote at least to int.  */
       struct type *target = max_type (builtin_type (ax->gdbarch)->builtin_int,
-                                     max_type (value1->type, value2->type));
+                                     max_type (type1, type2));
 
       /* Deal with value2, on the top of the stack.  */
-      gen_conversion (ax, value2->type, target);
+      gen_conversion (ax, type2, target);
 
       /* Deal with value1, not on the top of the stack.  Don't
         generate the `swap' instructions if we're not actually going
         to do anything.  */
-      if (is_nontrivial_conversion (value1->type, target))
+      if (is_nontrivial_conversion (type1, target))
        {
          ax_simple (ax, aop_swap);
-         gen_conversion (ax, value1->type, target);
+         gen_conversion (ax, type1, target);
          ax_simple (ax, aop_swap);
        }
 
   require_rvalue (ax, value);
   /* Dereference typedefs.  */
   type = check_typedef (type);
+  type = strip_range_type (type);
 
   switch (type->code ())
     {
            struct axs_value *value1, struct axs_value *value2)
 {
   gdb_assert (value1->type->is_pointer_or_reference ());
-  gdb_assert (value2->type->code () == TYPE_CODE_INT);
+  gdb_assert (strip_range_type (value2->type)->code () == TYPE_CODE_INT);
 
   gen_scale (ax, aop_mul, value1->type);
   ax_simple (ax, aop_add);
            struct axs_value *value1, struct axs_value *value2)
 {
   gdb_assert (value1->type->is_pointer_or_reference ());
-  gdb_assert (value2->type->code () == TYPE_CODE_INT);
+  gdb_assert (strip_range_type (value2->type)->code () == TYPE_CODE_INT);
 
   gen_scale (ax, aop_mul, value1->type);
   ax_simple (ax, aop_sub);
           int may_carry, const char *name)
 {
   /* We only handle INT op INT.  */
-  if ((value1->type->code () != TYPE_CODE_INT)
-      || (value2->type->code () != TYPE_CODE_INT))
+  struct type *type1 = strip_range_type (value1->type);
+  if ((type1->code () != TYPE_CODE_INT)
+      || (strip_range_type (value2->type)->code () != TYPE_CODE_INT))
     error (_("Invalid combination of types in %s."), name);
 
-  ax_simple (ax, value1->type->is_unsigned () ? op_unsigned : op);
+  ax_simple (ax, type1->is_unsigned () ? op_unsigned : op);
   if (may_carry)
-    gen_extend (ax, value1->type);     /* catch overflow */
-  value->type = value1->type;
+    gen_extend (ax, type1);    /* catch overflow */
+  value->type = type1;
   value->kind = axs_rvalue;
 }
 
 gen_logical_not (struct agent_expr *ax, struct axs_value *value,
                 struct type *result_type)
 {
-  if (value->type->code () != TYPE_CODE_INT
-      && value->type->code () != TYPE_CODE_PTR)
+  struct type *type = strip_range_type (value->type);
+  if (type->code () != TYPE_CODE_INT
+      && type->code () != TYPE_CODE_PTR)
     error (_("Invalid type of operand to `!'."));
 
   ax_simple (ax, aop_log_not);
 static void
 gen_complement (struct agent_expr *ax, struct axs_value *value)
 {
-  if (value->type->code () != TYPE_CODE_INT)
+  struct type *type = strip_range_type (value->type);
+  if (type->code () != TYPE_CODE_INT)
     error (_("Invalid type of operand to `~'."));
 
   ax_simple (ax, aop_bit_not);
-  gen_extend (ax, value->type);
+  gen_extend (ax, type);
 }
 \f
 
   switch (op)
     {
     case BINOP_ADD:
-      if (value1->type->code () == TYPE_CODE_INT
+      if (strip_range_type (value1->type)->code () == TYPE_CODE_INT
          && value2->type->is_pointer_or_reference ())
        {
          /* Swap the values and proceed normally.  */
          gen_ptradd (ax, value, value2, value1);
        }
       else if (value1->type->is_pointer_or_reference ()
-              && value2->type->code () == TYPE_CODE_INT)
+              && strip_range_type (value2->type)->code () == TYPE_CODE_INT)
        gen_ptradd (ax, value, value1, value2);
       else
        gen_binop (ax, value, value1, value2,
       break;
     case BINOP_SUB:
       if (value1->type->is_pointer_or_reference ()
-         && value2->type->code () == TYPE_CODE_INT)
+         && strip_range_type (value2->type)->code () == TYPE_CODE_INT)
        gen_ptrsub (ax,value, value1, value2);
       else if (value1->type->is_pointer_or_reference ()
               && value2->type->is_pointer_or_reference ())