mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-06 05:56:53 +08:00
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:
parent
1a938e38a0
commit
5078f5eb76
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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")])
|
||||
|
Loading…
Reference in New Issue
Block a user