X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgensupport.c;h=74b1d256ba2389244a33d284da42dcade3d7bf3b;hb=db2761c823a5d3d268a55bd869d7877d3c2a124d;hp=bbac33a2c8863d496d827f23418ff10c5eb9d907;hpb=343695df238d8e043fe83c8b0cce11b73f2e2cba;p=pf3gnuchains%2Fgcc-fork.git
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index bbac33a2c88..74b1d256ba2 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -1,12 +1,12 @@
/* Support routines for the various generation passes.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
- Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+ 2010, 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
@@ -15,9 +15,8 @@
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
+ . */
#include "bconfig.h"
#include "system.h"
@@ -287,6 +286,10 @@ process_rtx (rtx desc, int lineno)
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;
@@ -333,7 +336,7 @@ process_rtx (rtx desc, int lineno)
/* Queue them. */
insn_elem
- = queue_pattern (desc, &define_insn_tail, read_rtx_filename,
+ = queue_pattern (desc, &define_insn_tail, read_rtx_filename,
lineno);
split_elem
= queue_pattern (split, &other_tail, read_rtx_filename, lineno);
@@ -464,6 +467,8 @@ identify_predicable_attribute (void)
message_with_line (elem->lineno,
"attribute `predicable' is not a boolean");
errors = 1;
+ if (p_false)
+ free (p_false);
return;
}
p_true[-1] = '\0';
@@ -481,12 +486,16 @@ identify_predicable_attribute (void)
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;
}
@@ -500,6 +509,8 @@ identify_predicable_attribute (void)
"unknown value `%s' for `predicable' attribute",
value);
errors = 1;
+ if (p_false)
+ free (p_false);
}
}
@@ -769,6 +780,7 @@ process_one_cond_exec (struct queue_elem *ce_elem)
{
int alternatives, max_operand;
rtx pred, insn, pattern, split;
+ char *new_name;
int i;
if (! is_predicable (insn_elem))
@@ -795,7 +807,9 @@ process_one_cond_exec (struct queue_elem *ce_elem)
/* Construct a new pattern for the new insn. */
insn = copy_rtx (insn_elem->data);
- XSTR (insn, 0) = "";
+ new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
+ sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
+ XSTR (insn, 0) = new_name;
pattern = rtx_alloc (COND_EXEC);
XEXP (pattern, 0) = pred;
if (XVECLEN (insn, 1) == 1)
@@ -864,7 +878,7 @@ process_one_cond_exec (struct queue_elem *ce_elem)
XVECEXP (split, 2, i) = pattern;
}
/* Add the new split to the queue. */
- queue_pattern (split, &other_tail, read_rtx_filename,
+ queue_pattern (split, &other_tail, read_rtx_filename,
insn_elem->split->lineno);
}
}
@@ -916,7 +930,7 @@ init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
{
if (argv[i][0] != '-')
continue;
-
+
c = argv[i][1];
switch (c)
{
@@ -985,7 +999,7 @@ init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
/* Read stdin. */
if (already_read_stdin)
fatal ("cannot read standard input twice");
-
+
base_dir = NULL;
read_rtx_filename = in_fname = "";
read_rtx_lineno = 1;
@@ -1288,6 +1302,34 @@ lookup_predicate (const char *name)
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)
{
@@ -1309,32 +1351,34 @@ struct std_pred_table
{
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, {UNKNOWN}},
+ {"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}},
+ {"ordered_comparison_operator", false, false, {EQ, NE,
+ LE, LT, GE, GT,
+ LEU, LTU, GEU, GTU}},
+ {"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)
@@ -1358,23 +1402,13 @@ init_predicate_table (void)
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, (enum rtx_code) j);
+
add_predicate (pred);
}
}
@@ -1400,13 +1434,13 @@ record_insn_name (int code, const char *name)
{
static const char *last_real_name = "insn";
static int last_real_code = 0;
- char *new;
+ char *new_name;
if (insn_name_ptr_size <= code)
{
int new_size;
new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
- insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * new_size);
+ insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
memset (insn_name_ptr + insn_name_ptr_size, 0,
sizeof(char *) * (new_size - insn_name_ptr_size));
insn_name_ptr_size = new_size;
@@ -1414,14 +1448,14 @@ record_insn_name (int code, const char *name)
if (!name || name[0] == '\0')
{
- new = xmalloc (strlen (last_real_name) + 10);
- sprintf (new, "%s+%d", last_real_name, code - last_real_code);
+ new_name = XNEWVAR (char, strlen (last_real_name) + 10);
+ sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
}
else
{
- last_real_name = new = xstrdup (name);
+ last_real_name = new_name = xstrdup (name);
last_real_code = code;
}
- insn_name_ptr[code] = new;
+ insn_name_ptr[code] = new_name;
}