summaryrefslogtreecommitdiff
path: root/gcc/gensupport.c
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2004-04-01 23:30:25 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2004-04-01 23:30:25 +0000
commit96f57e365c008c4825c9c88e90db818ec4c99aad (patch)
tree800c0614ebfab133a3ab5aa61799f6bcbbd0d6ab /gcc/gensupport.c
parentb0cdf64212b0111e4fc098a73ba5992bd50a24dc (diff)
downloadgcc-96f57e365c008c4825c9c88e90db818ec4c99aad.tar.gz
PR target/14040
* genemit.c (gen_split): Change prototype of generated code. * genrecog.c (write_action): Adjust prototype for and calls to gen_split_*. * gensupport.c (struct queue_elem): Add split field. (queue_pattern): Return a value. Clear the split field. (process_rtx): Maintain an association between an insn and the split generated from it for a define_insn_and_split. (process_one_cond_exec): Generate a new split for a define_insn_and_split. * config/arm/arm-protos.h (arm_split_constant): Add insn parameter. (emit_constant_insn): New function. (arm_gen_constant): Use it. * config/arm/arm.md: Adjust calls to arm_split_constant. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80335 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gensupport.c')
-rw-r--r--gcc/gensupport.c61
1 files changed, 54 insertions, 7 deletions
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index b8cf5e67a51..6cc957863bd 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -58,6 +58,9 @@ struct queue_elem
const char *filename;
int lineno;
struct queue_elem *next;
+ /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
+ points to the generated DEFINE_SPLIT. */
+ struct queue_elem *split;
};
static struct queue_elem *define_attr_queue;
@@ -69,8 +72,8 @@ static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
static struct queue_elem *other_queue;
static struct queue_elem **other_tail = &other_queue;
-static void queue_pattern (rtx, struct queue_elem ***,
- const char *, int);
+static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
+ const char *, int);
/* Current maximum length of directory names in the search path
for include files. (Altered as we get more of them.) */
@@ -134,9 +137,10 @@ gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED,
return rt;
}
-/* Queue PATTERN on LIST_TAIL. */
+/* Queue PATTERN on LIST_TAIL. Return the address of the new queue
+ element. */
-static void
+static struct queue_elem *
queue_pattern (rtx pattern, struct queue_elem ***list_tail,
const char *filename, int lineno)
{
@@ -145,8 +149,10 @@ queue_pattern (rtx pattern, struct queue_elem ***list_tail,
e->filename = filename;
e->lineno = lineno;
e->next = NULL;
+ e->split = NULL;
**list_tail = e;
*list_tail = &e->next;
+ return e;
}
/* Recursively remove constraints from an rtx. */
@@ -288,6 +294,8 @@ process_rtx (rtx desc, int lineno)
rtx split;
rtvec attr;
int i;
+ struct queue_elem *insn_elem;
+ struct queue_elem *split_elem;
/* Create a split with values from the insn_and_split. */
split = rtx_alloc (DEFINE_SPLIT);
@@ -315,8 +323,12 @@ process_rtx (rtx desc, int lineno)
XVEC (desc, 4) = attr;
/* Queue them. */
- queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
- queue_pattern (split, &other_tail, read_rtx_filename, lineno);
+ insn_elem
+ = queue_pattern (desc, &define_insn_tail, read_rtx_filename,
+ lineno);
+ split_elem
+ = queue_pattern (split, &other_tail, read_rtx_filename, lineno);
+ insn_elem->split = split_elem;
break;
}
@@ -755,7 +767,8 @@ process_one_cond_exec (struct queue_elem *ce_elem)
for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
{
int alternatives, max_operand;
- rtx pred, insn, pattern;
+ rtx pred, insn, pattern, split;
+ int i;
if (! is_predicable (insn_elem))
continue;
@@ -818,6 +831,40 @@ process_one_cond_exec (struct queue_elem *ce_elem)
queue_pattern (insn, &other_tail, insn_elem->filename,
insn_elem->lineno);
+
+ if (!insn_elem->split)
+ continue;
+
+ /* If the original insn came from a define_insn_and_split,
+ generate a new split to handle the predicated insn. */
+ split = copy_rtx (insn_elem->split->data);
+ /* Predicate the pattern matched by the split. */
+ pattern = rtx_alloc (COND_EXEC);
+ XEXP (pattern, 0) = pred;
+ if (XVECLEN (split, 0) == 1)
+ {
+ XEXP (pattern, 1) = XVECEXP (split, 0, 0);
+ XVECEXP (split, 0, 0) = pattern;
+ PUT_NUM_ELEM (XVEC (split, 0), 1);
+ }
+ else
+ {
+ XEXP (pattern, 1) = rtx_alloc (PARALLEL);
+ XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
+ XVEC (split, 0) = rtvec_alloc (1);
+ XVECEXP (split, 0, 0) = pattern;
+ }
+ /* Predicate all of the insns generated by the split. */
+ for (i = 0; i < XVECLEN (split, 2); i++)
+ {
+ pattern = rtx_alloc (COND_EXEC);
+ XEXP (pattern, 0) = pred;
+ XEXP (pattern, 1) = XVECEXP (split, 2, i);
+ XVECEXP (split, 2, i) = pattern;
+ }
+ /* Add the new split to the queue. */
+ queue_pattern (split, &other_tail, read_rtx_filename,
+ insn_elem->split->lineno);
}
}