+ error (_("Unsupported operator %s (%d) in expression."),
+ op_name (exp, op), op);
+ }
+}
+
+/* This handles the middle-to-right-side of code generation for binary
+ expressions, which is shared between regular binary operations and
+ assign-modify (+= and friends) expressions. */
+
+static void
+gen_expr_binop_rest (struct expression *exp,
+ enum exp_opcode op, union exp_element **pc,
+ struct agent_expr *ax, struct axs_value *value,
+ struct axs_value *value1, struct axs_value *value2)
+{
+ struct type *int_type = builtin_type (exp->gdbarch)->builtin_int;
+
+ gen_expr (exp, pc, ax, value2);
+ gen_usual_unary (exp, ax, value2);
+ gen_usual_arithmetic (exp, ax, value1, value2);
+ switch (op)
+ {
+ case BINOP_ADD:
+ if (TYPE_CODE (value1->type) == TYPE_CODE_INT
+ && pointer_type (value2->type))
+ {
+ /* Swap the values and proceed normally. */
+ ax_simple (ax, aop_swap);
+ gen_ptradd (ax, value, value2, value1);
+ }
+ else if (pointer_type (value1->type)
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
+ gen_ptradd (ax, value, value1, value2);
+ else
+ gen_binop (ax, value, value1, value2,
+ aop_add, aop_add, 1, "addition");
+ break;
+ case BINOP_SUB:
+ if (pointer_type (value1->type)
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
+ gen_ptrsub (ax,value, value1, value2);
+ else if (pointer_type (value1->type)
+ && pointer_type (value2->type))
+ /* FIXME --- result type should be ptrdiff_t */
+ gen_ptrdiff (ax, value, value1, value2,
+ builtin_type (exp->gdbarch)->builtin_long);
+ else
+ gen_binop (ax, value, value1, value2,
+ aop_sub, aop_sub, 1, "subtraction");
+ break;
+ case BINOP_MUL:
+ gen_binop (ax, value, value1, value2,
+ aop_mul, aop_mul, 1, "multiplication");
+ break;
+ case BINOP_DIV:
+ gen_binop (ax, value, value1, value2,
+ aop_div_signed, aop_div_unsigned, 1, "division");
+ break;
+ case BINOP_REM:
+ gen_binop (ax, value, value1, value2,
+ aop_rem_signed, aop_rem_unsigned, 1, "remainder");
+ break;
+ case BINOP_LSH:
+ gen_binop (ax, value, value1, value2,
+ aop_lsh, aop_lsh, 1, "left shift");
+ break;
+ case BINOP_RSH:
+ gen_binop (ax, value, value1, value2,
+ aop_rsh_signed, aop_rsh_unsigned, 1, "right shift");
+ break;
+ case BINOP_SUBSCRIPT:
+ {
+ struct type *type;
+
+ if (binop_types_user_defined_p (op, value1->type, value2->type))
+ {
+ error (_("cannot subscript requested type: "
+ "cannot call user defined functions"));
+ }
+ else
+ {
+ /* If the user attempts to subscript something that is not
+ an array or pointer type (like a plain int variable for
+ example), then report this as an error. */
+ type = check_typedef (value1->type);
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_PTR)
+ {
+ if (TYPE_NAME (type))
+ error (_("cannot subscript something of type `%s'"),
+ TYPE_NAME (type));
+ else
+ error (_("cannot subscript requested type"));
+ }
+ }
+
+ if (!is_integral_type (value2->type))
+ error (_("Argument to arithmetic operation "
+ "not a number or boolean."));
+
+ gen_ptradd (ax, value, value1, value2);
+ gen_deref (ax, value);
+ break;
+ }
+ case BINOP_BITWISE_AND:
+ gen_binop (ax, value, value1, value2,
+ aop_bit_and, aop_bit_and, 0, "bitwise and");
+ break;
+
+ case BINOP_BITWISE_IOR:
+ gen_binop (ax, value, value1, value2,
+ aop_bit_or, aop_bit_or, 0, "bitwise or");
+ break;
+
+ case BINOP_BITWISE_XOR:
+ gen_binop (ax, value, value1, value2,
+ aop_bit_xor, aop_bit_xor, 0, "bitwise exclusive-or");
+ break;
+
+ case BINOP_EQUAL:
+ gen_equal (ax, value, value1, value2, int_type);
+ break;
+
+ case BINOP_NOTEQUAL:
+ gen_equal (ax, value, value1, value2, int_type);
+ gen_logical_not (ax, value, int_type);
+ break;
+
+ case BINOP_LESS:
+ gen_less (ax, value, value1, value2, int_type);
+ break;
+
+ case BINOP_GTR:
+ ax_simple (ax, aop_swap);
+ gen_less (ax, value, value1, value2, int_type);
+ break;
+
+ case BINOP_LEQ:
+ ax_simple (ax, aop_swap);
+ gen_less (ax, value, value1, value2, int_type);
+ gen_logical_not (ax, value, int_type);
+ break;
+
+ case BINOP_GEQ:
+ gen_less (ax, value, value1, value2, int_type);
+ gen_logical_not (ax, value, int_type);
+ break;
+
+ default:
+ /* We should only list operators in the outer case statement
+ that we actually handle in the inner case statement. */
+ internal_error (__FILE__, __LINE__,
+ _("gen_expr: op case sets don't match"));