Commit a406f566 by Mark Mitchell Committed by Mark Mitchell

re PR target/14040 (ARM cross compiler: error: could not split insn)

	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.

From-SVN: r80335
parent 18c6ada9
2004-04-01 Mark Mitchell <mark@codesourcery.com>
* 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.
2004-04-02 Jan Hubicka <jh@suse.cz> 2004-04-02 Jan Hubicka <jh@suse.cz>
* cgraph.c: Add overall comment. * cgraph.c: Add overall comment.
......
...@@ -46,8 +46,8 @@ extern void arm_encode_call_attribute (tree, int); ...@@ -46,8 +46,8 @@ extern void arm_encode_call_attribute (tree, int);
#ifdef RTX_CODE #ifdef RTX_CODE
extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode); extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
extern int const_ok_for_arm (HOST_WIDE_INT); extern int const_ok_for_arm (HOST_WIDE_INT);
extern int arm_split_constant (RTX_CODE, enum machine_mode, HOST_WIDE_INT, rtx, extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
rtx, int); HOST_WIDE_INT, rtx, rtx, int);
extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *); extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *);
extern int legitimate_pic_operand_p (rtx); extern int legitimate_pic_operand_p (rtx);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx); extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
......
...@@ -454,8 +454,8 @@ ...@@ -454,8 +454,8 @@
" "
if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT) if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
{ {
arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0], arm_split_constant (PLUS, SImode, NULL_RTX,
operands[1], INTVAL (operands[2]), operands[0], operands[1],
(no_new_pseudos ? 0 : preserve_subexpressions_p ())); (no_new_pseudos ? 0 : preserve_subexpressions_p ()));
DONE; DONE;
} }
...@@ -493,7 +493,8 @@ ...@@ -493,7 +493,8 @@
|| const_ok_for_arm (-INTVAL (operands[2])))" || const_ok_for_arm (-INTVAL (operands[2])))"
[(clobber (const_int 0))] [(clobber (const_int 0))]
" "
arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0], arm_split_constant (PLUS, SImode, curr_insn,
INTVAL (operands[2]), operands[0],
operands[1], 0); operands[1], 0);
DONE; DONE;
" "
...@@ -940,7 +941,8 @@ ...@@ -940,7 +941,8 @@
{ {
if (TARGET_ARM) if (TARGET_ARM)
{ {
arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0], arm_split_constant (MINUS, SImode, NULL_RTX,
INTVAL (operands[1]), operands[0],
operands[2], operands[2],
(no_new_pseudos ? 0 (no_new_pseudos ? 0
: preserve_subexpressions_p ())); : preserve_subexpressions_p ()));
...@@ -974,8 +976,8 @@ ...@@ -974,8 +976,8 @@
&& !const_ok_for_arm (INTVAL (operands[1]))" && !const_ok_for_arm (INTVAL (operands[1]))"
[(clobber (const_int 0))] [(clobber (const_int 0))]
" "
arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0], arm_split_constant (MINUS, SImode, curr_insn,
operands[2], 0); INTVAL (operands[1]), operands[0], operands[2], 0);
DONE; DONE;
" "
[(set_attr "length" "4,16") [(set_attr "length" "4,16")
...@@ -1516,7 +1518,8 @@ ...@@ -1516,7 +1518,8 @@
{ {
if (GET_CODE (operands[2]) == CONST_INT) if (GET_CODE (operands[2]) == CONST_INT)
{ {
arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0], arm_split_constant (AND, SImode, NULL_RTX,
INTVAL (operands[2]), operands[0],
operands[1], operands[1],
(no_new_pseudos (no_new_pseudos
? 0 : preserve_subexpressions_p ())); ? 0 : preserve_subexpressions_p ()));
...@@ -1583,8 +1586,8 @@ ...@@ -1583,8 +1586,8 @@
|| const_ok_for_arm (~INTVAL (operands[2])))" || const_ok_for_arm (~INTVAL (operands[2])))"
[(clobber (const_int 0))] [(clobber (const_int 0))]
" "
arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0], arm_split_constant (AND, SImode, curr_insn,
operands[1], 0); INTVAL (operands[2]), operands[0], operands[1], 0);
DONE; DONE;
" "
[(set_attr "length" "4,4,16") [(set_attr "length" "4,4,16")
...@@ -2069,8 +2072,8 @@ ...@@ -2069,8 +2072,8 @@
{ {
if (TARGET_ARM) if (TARGET_ARM)
{ {
arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0], arm_split_constant (IOR, SImode, NULL_RTX,
operands[1], INTVAL (operands[2]), operands[0], operands[1],
(no_new_pseudos (no_new_pseudos
? 0 : preserve_subexpressions_p ())); ? 0 : preserve_subexpressions_p ()));
DONE; DONE;
...@@ -2094,8 +2097,8 @@ ...@@ -2094,8 +2097,8 @@
&& !const_ok_for_arm (INTVAL (operands[2]))" && !const_ok_for_arm (INTVAL (operands[2]))"
[(clobber (const_int 0))] [(clobber (const_int 0))]
" "
arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0], arm_split_constant (IOR, SImode, curr_insn,
operands[1], 0); INTVAL (operands[2]), operands[0], operands[1], 0);
DONE; DONE;
" "
[(set_attr "length" "4,16") [(set_attr "length" "4,16")
...@@ -4146,8 +4149,8 @@ ...@@ -4146,8 +4149,8 @@
&& !(const_ok_for_arm (INTVAL (operands[1])) && !(const_ok_for_arm (INTVAL (operands[1]))
|| const_ok_for_arm (~INTVAL (operands[1])))) || const_ok_for_arm (~INTVAL (operands[1]))))
{ {
arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0], arm_split_constant (SET, SImode, NULL_RTX,
NULL_RTX, INTVAL (operands[1]), operands[0], NULL_RTX,
(no_new_pseudos ? 0 (no_new_pseudos ? 0
: preserve_subexpressions_p ())); : preserve_subexpressions_p ()));
DONE; DONE;
...@@ -4197,8 +4200,8 @@ ...@@ -4197,8 +4200,8 @@
|| const_ok_for_arm (~INTVAL (operands[1]))))" || const_ok_for_arm (~INTVAL (operands[1]))))"
[(clobber (const_int 0))] [(clobber (const_int 0))]
" "
arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0], arm_split_constant (SET, SImode, NULL_RTX,
NULL_RTX, 0); INTVAL (operands[1]), operands[0], NULL_RTX, 0);
DONE; DONE;
" "
) )
......
...@@ -599,8 +599,9 @@ gen_split (rtx split) ...@@ -599,8 +599,9 @@ gen_split (rtx split)
} }
else else
{ {
printf ("extern rtx gen_split_%d (rtx *);\n", insn_code_number); printf ("extern rtx gen_split_%d (rtx, rtx *);\n", insn_code_number);
printf ("rtx\ngen_%s_%d (rtx *operands%s)\n", name, insn_code_number, unused); printf ("rtx\ngen_split_%d (rtx curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
insn_code_number, unused);
} }
printf ("{\n"); printf ("{\n");
......
...@@ -2086,7 +2086,7 @@ write_action (struct decision *p, struct decision_test *test, ...@@ -2086,7 +2086,7 @@ write_action (struct decision *p, struct decision_test *test,
break; break;
case SPLIT: case SPLIT:
printf ("%sreturn gen_split_%d (operands);\n", printf ("%sreturn gen_split_%d (insn, operands);\n",
indent, test->u.insn.code_number); indent, test->u.insn.code_number);
break; break;
...@@ -2583,7 +2583,7 @@ make_insn_sequence (rtx insn, enum routine_type type) ...@@ -2583,7 +2583,7 @@ make_insn_sequence (rtx insn, enum routine_type type)
case SPLIT: case SPLIT:
/* Define the subroutine we will call below and emit in genemit. */ /* Define the subroutine we will call below and emit in genemit. */
printf ("extern rtx gen_split_%d (rtx *);\n", next_insn_code); printf ("extern rtx gen_split_%d (rtx, rtx *);\n", next_insn_code);
break; break;
case PEEPHOLE2: case PEEPHOLE2:
......
...@@ -58,6 +58,9 @@ struct queue_elem ...@@ -58,6 +58,9 @@ struct queue_elem
const char *filename; const char *filename;
int lineno; int lineno;
struct queue_elem *next; 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; static struct queue_elem *define_attr_queue;
...@@ -69,8 +72,8 @@ static struct queue_elem **define_cond_exec_tail = &define_cond_exec_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_queue;
static struct queue_elem **other_tail = &other_queue; static struct queue_elem **other_tail = &other_queue;
static void queue_pattern (rtx, struct queue_elem ***, static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
const char *, int); const char *, int);
/* Current maximum length of directory names in the search path /* Current maximum length of directory names in the search path
for include files. (Altered as we get more of them.) */ for include files. (Altered as we get more of them.) */
...@@ -134,9 +137,10 @@ gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED, ...@@ -134,9 +137,10 @@ gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED,
return rt; 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, queue_pattern (rtx pattern, struct queue_elem ***list_tail,
const char *filename, int lineno) const char *filename, int lineno)
{ {
...@@ -145,8 +149,10 @@ queue_pattern (rtx pattern, struct queue_elem ***list_tail, ...@@ -145,8 +149,10 @@ queue_pattern (rtx pattern, struct queue_elem ***list_tail,
e->filename = filename; e->filename = filename;
e->lineno = lineno; e->lineno = lineno;
e->next = NULL; e->next = NULL;
e->split = NULL;
**list_tail = e; **list_tail = e;
*list_tail = &e->next; *list_tail = &e->next;
return e;
} }
/* Recursively remove constraints from an rtx. */ /* Recursively remove constraints from an rtx. */
...@@ -288,6 +294,8 @@ process_rtx (rtx desc, int lineno) ...@@ -288,6 +294,8 @@ process_rtx (rtx desc, int lineno)
rtx split; rtx split;
rtvec attr; rtvec attr;
int i; int i;
struct queue_elem *insn_elem;
struct queue_elem *split_elem;
/* Create a split with values from the insn_and_split. */ /* Create a split with values from the insn_and_split. */
split = rtx_alloc (DEFINE_SPLIT); split = rtx_alloc (DEFINE_SPLIT);
...@@ -315,8 +323,12 @@ process_rtx (rtx desc, int lineno) ...@@ -315,8 +323,12 @@ process_rtx (rtx desc, int lineno)
XVEC (desc, 4) = attr; XVEC (desc, 4) = attr;
/* Queue them. */ /* Queue them. */
queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno); insn_elem
queue_pattern (split, &other_tail, read_rtx_filename, lineno); = 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; break;
} }
...@@ -755,7 +767,8 @@ process_one_cond_exec (struct queue_elem *ce_elem) ...@@ -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) for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
{ {
int alternatives, max_operand; int alternatives, max_operand;
rtx pred, insn, pattern; rtx pred, insn, pattern, split;
int i;
if (! is_predicable (insn_elem)) if (! is_predicable (insn_elem))
continue; continue;
...@@ -818,6 +831,40 @@ process_one_cond_exec (struct queue_elem *ce_elem) ...@@ -818,6 +831,40 @@ process_one_cond_exec (struct queue_elem *ce_elem)
queue_pattern (insn, &other_tail, insn_elem->filename, queue_pattern (insn, &other_tail, insn_elem->filename,
insn_elem->lineno); 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);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment