-/* Return TRUE if the operand constraint STR is commutative. */
-static bool
-commutative_constraint_p (const char *str)
-{
- int curr_alt, c;
- bool ignore_p;
-
- for (ignore_p = false, curr_alt = 0;;)
- {
- c = *str;
- if (c == '\0')
- break;
- str += CONSTRAINT_LEN (c, str);
- if (c == '#' || !recog_data.alternative_enabled_p[curr_alt])
- ignore_p = true;
- else if (c == ',')
- {
- curr_alt++;
- ignore_p = false;
- }
- else if (! ignore_p)
- {
- /* Usually `%' is the first constraint character but the
- documentation does not require this. */
- if (c == '%')
- return true;
- }
- }
- return false;
-}
-
-/* Return the number of the operand which should be the same in any
- case as operand with number OP_NUM (or negative value if there is
- no such operand). If USE_COMMUT_OP_P is TRUE, the function makes
- temporarily commutative operand exchange before this. The function
- takes only really possible alternatives into consideration. */
-static int
-get_dup_num (int op_num, bool use_commut_op_p)
-{
- int curr_alt, c, original, dup;
- bool ignore_p, commut_op_used_p;
- const char *str;
- rtx op;
-
- if (op_num < 0 || recog_data.n_alternatives == 0)
- return -1;
- op = recog_data.operand[op_num];
- commut_op_used_p = true;
- if (use_commut_op_p)
- {
- if (commutative_constraint_p (recog_data.constraints[op_num]))
- op_num++;
- else if (op_num > 0 && commutative_constraint_p (recog_data.constraints
- [op_num - 1]))
- op_num--;
- else
- commut_op_used_p = false;
- }
- str = recog_data.constraints[op_num];
- for (ignore_p = false, original = -1, curr_alt = 0;;)
- {
- c = *str;
- if (c == '\0')
- break;
- if (c == '#' || !recog_data.alternative_enabled_p[curr_alt])
- ignore_p = true;
- else if (c == ',')
- {
- curr_alt++;
- ignore_p = false;
- }
- else if (! ignore_p)
- switch (c)
- {
- case 'X':
- return -1;
-
- case 'm':
- case 'o':
- /* Accept a register which might be placed in memory. */
- return -1;
- break;
-
- case 'V':
- case '<':
- case '>':
- break;
-
- case 'p':
- if (address_operand (op, VOIDmode))
- return -1;
- break;
-
- case 'g':
- return -1;
-
- case 'r':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'h': case 'j': case 'k': case 'l':
- case 'q': case 't': case 'u':
- case 'v': case 'w': case 'x': case 'y': case 'z':
- case 'A': case 'B': case 'C': case 'D':
- case 'Q': case 'R': case 'S': case 'T': case 'U':
- case 'W': case 'Y': case 'Z':
- {
- enum reg_class cl;
-
- cl = (c == 'r'
- ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, str));
- if (cl != NO_REGS)
- return -1;
-#ifdef EXTRA_CONSTRAINT_STR
- else if (EXTRA_CONSTRAINT_STR (op, c, str))
- return -1;
-#endif
- break;
- }
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (original != -1 && original != c)
- return -1;
- original = c;
- break;
- }
- str += CONSTRAINT_LEN (c, str);
- }
- if (original == -1)
- return -1;
- dup = original - '0';
- if (use_commut_op_p)
- {
- if (commutative_constraint_p (recog_data.constraints[dup]))
- dup++;
- else if (dup > 0
- && commutative_constraint_p (recog_data.constraints[dup -1]))
- dup--;
- else if (! commut_op_used_p)
- return -1;
- }
- return dup;
-}
-