===================================================================
@@ -997,13 +997,6 @@ check_attr_value (rtx exp, struct attr_d
break;
case COND:
- if (XVECLEN (exp, 0) % 2 != 0)
- {
- error_with_line (attr->lineno,
- "first operand of COND must have even length");
- break;
- }
-
for (i = 0; i < XVECLEN (exp, 0); i += 2)
{
XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
===================================================================
@@ -1350,6 +1350,9 @@ read_rtx_code (const char *code_name)
gcc_unreachable ();
}
+ if (code == COND && XVECLEN (return_rtx, 0) % 2 != 0)
+ fatal_with_file_and_line ("first operand of COND must have even length");
+
if (CONST_WIDE_INT_P (return_rtx))
{
read_name (&name);
===================================================================
@@ -143,6 +143,44 @@ gen_rtx_CONST_INT (enum machine_mode ARG
XWINT (rt, 0) = arg;
return rt;
}
+
+/* Expand CONDs in *LOC to IF_THEN_ELSEs. */
+
+static void
+expand_conds (rtx *loc)
+{
+ rtx x = *loc;
+
+ if (GET_CODE (x) == COND)
+ {
+ *loc = XEXP (x, 1);
+ for (int i = XVECLEN (x, 0) - 2; i >= 0; i -= 2)
+ {
+ rtx cond = rtx_alloc (IF_THEN_ELSE);
+ XEXP (cond, 0) = XVECEXP (x, 0, i);
+ XEXP (cond, 1) = XVECEXP (x, 0, i + 1);
+ XEXP (cond, 2) = *loc;
+ *loc = cond;
+ }
+ x = *loc;
+ }
+
+ const char *format_ptr = GET_RTX_FORMAT (GET_CODE (x));
+ for (int i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
+ switch (*format_ptr++)
+ {
+ case 'e':
+ case 'u':
+ expand_conds (&XEXP (x, i));
+ break;
+ case 'E':
+ if (XVEC (x, i) != NULL)
+ for (int j = 0; j < XVECLEN (x, i); j++)
+ expand_conds (&XVECEXP (x, i, j));
+ break;
+ }
+}
+
/* Predicate handling.
@@ -506,13 +544,17 @@ process_rtx (rtx desc, int lineno)
case DEFINE_PREDICATE:
case DEFINE_SPECIAL_PREDICATE:
+ expand_conds (&XEXP (desc, 1));
process_define_predicate (desc, lineno);
- /* Fall through. */
+ queue_pattern (desc, &define_pred_tail, read_md_filename, lineno);
+ break;
case DEFINE_CONSTRAINT:
- case DEFINE_REGISTER_CONSTRAINT:
case DEFINE_MEMORY_CONSTRAINT:
case DEFINE_ADDRESS_CONSTRAINT:
+ expand_conds (&XEXP (desc, 2));
+ /* Fall through. */
+ case DEFINE_REGISTER_CONSTRAINT:
queue_pattern (desc, &define_pred_tail, read_md_filename, lineno);
break;