c4x.c (c4x_check_legit_addr): Only check CONST.

* c4x.c (c4x_check_legit_addr): Only check CONST.  Not if CONST
	contains SYMBOL_REF, LABEL_REF and CONST_INT.
	(c4x_U_constraint, symbolic_address_operand): Likewise.
	(c4x_immed_float_constant): Do not check if CONST_DOUBLE is in
	memory.
	(c4x_r11_set_p, c4x_check_laj_p): New functions.
	* c4x-protos.h (c4x_check_laj_p): Add prototype.
	* c4x.md (in_annul_slot_3): Do not allow auto-increment in last
	anulling slot because of silicon bug.
	(laj, lajv): Call c4x_check_laj_p to check for silicon bug.

From-SVN: r39180
This commit is contained in:
Herman A.J. ten Brugge 2001-01-22 11:29:14 +01:00 committed by Michael Hayes
parent 1a938e38a0
commit 5078f5eb76
4 changed files with 102 additions and 29 deletions

View File

@ -1,3 +1,16 @@
2001-01-22 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
* c4x.c (c4x_check_legit_addr): Only check CONST. Not if CONST
contains SYMBOL_REF, LABEL_REF and CONST_INT.
(c4x_U_constraint, symbolic_address_operand): Likewise.
(c4x_immed_float_constant): Do not check if CONST_DOUBLE is in
memory.
(c4x_r11_set_p, c4x_check_laj_p): New functions.
* c4x-protos.h (c4x_check_laj_p): Add prototype.
* c4x.md (in_annul_slot_3): Do not allow auto-increment in last
anulling slot because of silicon bug.
(laj, lajv): Call c4x_check_laj_p to check for silicon bug.
2001-01-22 Alan Modra <alan@linuxcare.com.au>
* cppexp.c (parse_charconst): Change `mask' type to agree

View File

@ -121,6 +121,8 @@ extern int c4x_rptb_nop_p PARAMS ((rtx));
extern int c4x_rptb_rpts_p PARAMS ((rtx, rtx));
extern int c4x_check_laj_p PARAMS ((rtx));
extern int c4x_autoinc_operand PARAMS ((rtx, enum machine_mode));
extern int any_operand PARAMS ((rtx, enum machine_mode));

View File

@ -186,6 +186,7 @@ static int c4x_arn_reg_operand PARAMS ((rtx, enum machine_mode, unsigned int));
static int c4x_arn_mem_operand PARAMS ((rtx, enum machine_mode, unsigned int));
static void c4x_check_attribute PARAMS ((const char *, tree, tree, tree *));
static int c4x_parse_pragma PARAMS ((const char *, tree *, tree *));
static int c4x_r11_set_p PARAMS ((rtx));
/* Called to register all of our global variables with the garbage
collector. */
@ -1558,15 +1559,7 @@ c4x_check_legit_addr (mode, addr, strict)
return 1;
if (GET_CODE (op1) == CONST)
{
addr = XEXP (op1, 0);
if (GET_CODE (addr) == PLUS
&& (GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (addr, 0)) == LABEL_REF)
&& GET_CODE (XEXP (addr, 1)) == CONST_INT)
return 1;
}
return 1;
return 0;
}
break;
@ -2432,8 +2425,9 @@ c4x_immed_float_constant (op)
if (GET_CODE (op) != CONST_DOUBLE)
return 0;
if (GET_CODE (XEXP (op, 0)) == MEM)
return 0;
/* Do not check if the CONST_DOUBLE is in memory. If there is a MEM
present this only means that a MEM rtx has been generated. It does
not mean the rtx is really in memory. */
return GET_MODE (op) == QFmode || GET_MODE (op) == HFmode;
}
@ -2835,14 +2829,9 @@ c4x_U_constraint (op)
rtx op;
{
/* Don't allow direct addressing to an arbitrary constant. */
if (GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
&& (GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
|| GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF)
&& GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
return 1;
return GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF;
return GET_CODE (op) == CONST
|| GET_CODE (op) == SYMBOL_REF
|| GET_CODE (op) == LABEL_REF;
}
@ -3228,14 +3217,10 @@ symbolic_address_operand (op, mode)
{
switch (GET_CODE (op))
{
case CONST:
case SYMBOL_REF:
case LABEL_REF:
return 1;
case CONST:
op = XEXP (op, 0);
return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
default:
return 0;
}
@ -4720,6 +4705,75 @@ c4x_rptb_rpts_p (insn, op)
}
/* Check if register r11 is used as the destination of an insn. */
static int
c4x_r11_set_p(x)
rtx x;
{
RTX_CODE code;
rtx set;
int i, j;
const char *fmt;
if (x == 0)
return 0;
code = GET_CODE (x);
if (code == INSN && GET_CODE (PATTERN (x)) == SEQUENCE)
x = XVECEXP (PATTERN (x), 0, XVECLEN (PATTERN (x), 0) - 1);
if (code == INSN && (set = single_set (x)))
return c4x_r11_set_p (SET_DEST (set));
if (code == REG && REGNO (x) == R11_REGNO)
return 1;
fmt = GET_RTX_FORMAT (GET_CODE (x));
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
if (c4x_r11_set_p (XEXP (x, i)))
return 1;
}
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
if (c4x_r11_set_p (XVECEXP (x, i, j)))
return 1;
}
return 0;
}
/* The c4x sometimes has a problem when the insn before the laj insn
sets the r11 register. Check for this situation. */
int
c4x_check_laj_p (insn)
rtx insn;
{
insn = prev_nonnote_insn (insn);
/* If this is the start of the function no nop is needed. */
if (insn == 0)
return 0;
/* If the previous insn is a code label we have to insert a nop. This
could be a jump or table jump. We can find the normal jumps by
scanning the function but this will not find table jumps. */
if (GET_CODE (insn) == CODE_LABEL)
return 1;
/* If the previous insn sets register r11 we have to insert a nop. */
if (c4x_r11_set_p (insn))
return 1;
/* No nop needed. */
return 0;
}
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost.
A set of an address register followed by a use occurs a 2 cycle

View File

@ -377,10 +377,12 @@
(const_string "false")))
/* Disable ldp because the c4x contains a bug. The ldp insn modifies
the dp register when the insn is anulled or not. */
the dp register when the insn is anulled or not.
Also disable autoincrement insns because of a silicon bug. */
(define_attr "in_annul_slot_3" "false,true"
(if_then_else (and (eq_attr "cpu" "c4x")
(eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,ldp,multi"))
(if_then_else (and (and (eq_attr "cpu" "c4x")
(eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,ldp,multi"))
(eq_attr "onlyreg_nomod" "true"))
(const_string "true")
(const_string "false")))
@ -5133,7 +5135,8 @@
"! TARGET_C3X"
"*
if (final_sequence)
return \"laj%U0\\t%C0\";
return c4x_check_laj_p (insn)
? \"nop\\n\\tlaj%U0\\t%C0\" : \"laj%U0\\t%C0\";
else
return \"call%U0\\t%C0\";"
[(set_attr "type" "laj")])
@ -5181,7 +5184,8 @@
"! TARGET_C3X"
"*
if (final_sequence)
return \"laj%U1\\t%C1\";
return c4x_check_laj_p (insn)
? \"nop\\n\\tlaj%U1\\t%C1\" : \"laj%U1\\t%C1\";
else
return \"call%U1\\t%C1\";"
[(set_attr "type" "laj")])