+/* Find PRE/POST-INC/DEC/MODIFY operations within *R, extract the
+ operands of the equivalent add insn and pass the result to the
+ operator specified by *D. */
+
+static int
+for_each_inc_dec_find_inc_dec (rtx *r, void *d)
+{
+ rtx x = *r;
+ struct for_each_inc_dec_ops *data = (struct for_each_inc_dec_ops *)d;
+
+ switch (GET_CODE (x))
+ {
+ case PRE_INC:
+ case POST_INC:
+ {
+ int size = GET_MODE_SIZE (GET_MODE (data->mem));
+ rtx r1 = XEXP (x, 0);
+ rtx c = gen_int_mode (size, GET_MODE (r1));
+ return data->fn (data->mem, x, r1, r1, c, data->arg);
+ }
+
+ case PRE_DEC:
+ case POST_DEC:
+ {
+ int size = GET_MODE_SIZE (GET_MODE (data->mem));
+ rtx r1 = XEXP (x, 0);
+ rtx c = gen_int_mode (-size, GET_MODE (r1));
+ return data->fn (data->mem, x, r1, r1, c, data->arg);
+ }
+
+ case PRE_MODIFY:
+ case POST_MODIFY:
+ {
+ rtx r1 = XEXP (x, 0);
+ rtx add = XEXP (x, 1);
+ return data->fn (data->mem, x, r1, add, NULL, data->arg);
+ }
+
+ case MEM:
+ {
+ rtx save = data->mem;
+ int ret = for_each_inc_dec_find_mem (r, d);
+ data->mem = save;
+ return ret;
+ }
+
+ default:
+ return 0;
+ }
+}
+
+/* If *R is a MEM, find PRE/POST-INC/DEC/MODIFY operations within its
+ address, extract the operands of the equivalent add insn and pass
+ the result to the operator specified by *D. */
+
+static int
+for_each_inc_dec_find_mem (rtx *r, void *d)
+{
+ rtx x = *r;
+ if (x != NULL_RTX && MEM_P (x))
+ {
+ struct for_each_inc_dec_ops *data = (struct for_each_inc_dec_ops *) d;
+ int result;
+
+ data->mem = x;
+
+ result = for_each_rtx (&XEXP (x, 0), for_each_inc_dec_find_inc_dec,
+ data);
+ if (result)
+ return result;
+
+ return -1;
+ }
+ return 0;
+}
+
+/* Traverse *X looking for MEMs, and for autoinc operations within
+ them. For each such autoinc operation found, call FN, passing it
+ the innermost enclosing MEM, the operation itself, the RTX modified
+ by the operation, two RTXs (the second may be NULL) that, once
+ added, represent the value to be held by the modified RTX
+ afterwards, and ARG. FN is to return -1 to skip looking for other
+ autoinc operations within the visited operation, 0 to continue the
+ traversal, or any other value to have it returned to the caller of
+ for_each_inc_dec. */
+
+int
+for_each_inc_dec (rtx *x,
+ for_each_inc_dec_fn fn,
+ void *arg)
+{
+ struct for_each_inc_dec_ops data;
+
+ data.fn = fn;
+ data.arg = arg;
+ data.mem = NULL;
+
+ return for_each_rtx (x, for_each_inc_dec_find_mem, &data);
+}
+
+\f