/* Support routines for the various generation passes.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
+ the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
License for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
#include "bconfig.h"
#include "system.h"
case DEFINE_PREDICATE:
case DEFINE_SPECIAL_PREDICATE:
+ case DEFINE_CONSTRAINT:
+ case DEFINE_REGISTER_CONSTRAINT:
+ case DEFINE_MEMORY_CONSTRAINT:
+ case DEFINE_ADDRESS_CONSTRAINT:
queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno);
break;
message_with_line (elem->lineno,
"attribute `predicable' is not a boolean");
errors = 1;
+ if (p_false)
+ free (p_false);
return;
}
p_true[-1] = '\0';
message_with_line (elem->lineno,
"attribute `predicable' cannot be const");
errors = 1;
+ if (p_false)
+ free (p_false);
return;
default:
message_with_line (elem->lineno,
"attribute `predicable' must have a constant default");
errors = 1;
+ if (p_false)
+ free (p_false);
return;
}
"unknown value `%s' for `predicable' attribute",
value);
errors = 1;
+ if (p_false)
+ free (p_false);
}
}
return (struct pred_data *) htab_find (predicate_table, &key);
}
+/* Record that predicate PRED can accept CODE. */
+
+void
+add_predicate_code (struct pred_data *pred, enum rtx_code code)
+{
+ if (!pred->codes[code])
+ {
+ pred->num_codes++;
+ pred->codes[code] = true;
+
+ if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
+ pred->allows_non_const = true;
+
+ if (code != REG
+ && code != SUBREG
+ && code != MEM
+ && code != CONCAT
+ && code != PARALLEL
+ && code != STRICT_LOW_PART)
+ pred->allows_non_lvalue = true;
+
+ if (pred->num_codes == 1)
+ pred->singleton = code;
+ else if (pred->num_codes == 2)
+ pred->singleton = UNKNOWN;
+ }
+}
+
void
add_predicate (struct pred_data *pred)
{
{
const char *name;
bool special;
+ bool allows_const_p;
RTX_CODE codes[NUM_RTX_CODE];
};
static const struct std_pred_table std_preds[] = {
- {"general_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG, MEM }},
- {"address_operand", true, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG, MEM,
- PLUS, MINUS, MULT}},
- {"register_operand", false, {SUBREG, REG}},
- {"pmode_register_operand", true, {SUBREG, REG}},
- {"scratch_operand", false, {SCRATCH, REG}},
- {"immediate_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF}},
- {"const_int_operand", false, {CONST_INT}},
- {"const_double_operand", false, {CONST_INT, CONST_DOUBLE}},
- {"nonimmediate_operand", false, {SUBREG, REG, MEM}},
- {"nonmemory_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG}},
- {"push_operand", false, {MEM}},
- {"pop_operand", false, {MEM}},
- {"memory_operand", false, {SUBREG, MEM}},
- {"indirect_operand", false, {SUBREG, MEM}},
- {"comparison_operator", false, {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
- UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
- UNLT, LTGT}}
+ {"general_operand", false, true, {SUBREG, REG, MEM}},
+ {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT}},
+ {"register_operand", false, false, {SUBREG, REG}},
+ {"pmode_register_operand", true, false, {SUBREG, REG}},
+ {"scratch_operand", false, false, {SCRATCH, REG}},
+ {"immediate_operand", false, true, {0}},
+ {"const_int_operand", false, false, {CONST_INT}},
+ {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
+ {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
+ {"nonmemory_operand", false, true, {SUBREG, REG}},
+ {"push_operand", false, false, {MEM}},
+ {"pop_operand", false, false, {MEM}},
+ {"memory_operand", false, false, {SUBREG, MEM}},
+ {"indirect_operand", false, false, {SUBREG, MEM}},
+ {"comparison_operator", false, false, {EQ, NE,
+ LE, LT, GE, GT,
+ LEU, LTU, GEU, GTU,
+ UNORDERED, ORDERED,
+ UNEQ, UNGE, UNGT,
+ UNLE, UNLT, LTGT}}
};
#define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
pred->special = std_preds[i].special;
for (j = 0; std_preds[i].codes[j] != 0; j++)
- {
- enum rtx_code code = std_preds[i].codes[j];
-
- pred->codes[code] = true;
- if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
- pred->allows_non_const = true;
- if (code != REG
- && code != SUBREG
- && code != MEM
- && code != CONCAT
- && code != PARALLEL
- && code != STRICT_LOW_PART)
- pred->allows_non_lvalue = true;
- }
- if (j == 1)
- pred->singleton = std_preds[i].codes[0];
+ add_predicate_code (pred, std_preds[i].codes[j]);
+
+ if (std_preds[i].allows_const_p)
+ for (j = 0; j < NUM_RTX_CODE; j++)
+ if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
+ add_predicate_code (pred, j);
add_predicate (pred);
}