aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hayes <m.hayes@elec.canterbury.ac.nz>1998-11-25 19:59:39 +0000
committerMichael Hayes <m.hayes@gcc.gnu.org>1998-11-25 19:59:39 +0000
commit4271f0030d108619d834b70a8930b46b51658693 (patch)
treea4ef8a956d69da307dc14b0d450d2ef3a6b34427
parent0fe69abaa1b8062525cc6a061d266fef560bf995 (diff)
downloadgcc-4271f0030d108619d834b70a8930b46b51658693.zip
gcc-4271f0030d108619d834b70a8930b46b51658693.tar.gz
gcc-4271f0030d108619d834b70a8930b46b51658693.tar.bz2
c4x.c: (c4x_override_options): For compatibility with old target options clear...
* config/c4x/c4x.c: (c4x_override_options): For compatibility with old target options clear flag_branch_on_count_reg if -mno-rptb specified and set flag_argument_alias is -mno-aliases specified. (c4x_output_cbranch): Handle a sequence of insns rather than a single insn. (c4x_rptb_insert): Do not emit a RPTB insn if the RC register has not been allocated as the loop counter. (c4x_address_conflict): Do not allow two volatile memory references. (valid_parallel_operands_4, valid_parallel_operands_5, valid_parallel_operands_6): Reject pattern if the register destination of the first set is used as part of an address in the second set. From-SVN: r23879
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/c4x/c4x.c141
2 files changed, 93 insertions, 55 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c0181a9..f53c400 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -16,9 +16,12 @@ Thu Nov 26 15:16:05 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
specified.
(c4x_output_cbranch): Handle a sequence of insns rather than a
single insn.
- (c4x_rptb_insert): Don not emit a RPTB insn if the RC register
+ (c4x_rptb_insert): Do not emit a RPTB insn if the RC register
has not been allocated as the loop counter.
- (c4x_address_conflict):
+ (c4x_address_conflict): Do not allow two volatile memory references.
+ (valid_parallel_operands_4, valid_parallel_operands_5,
+ valid_parallel_operands_6): Reject pattern if the register destination
+ of the first set is used as part of an address in the second set.
Thu Nov 26 14:56:32 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c
index b63b863..b7b02c4 100644
--- a/gcc/config/c4x/c4x.c
+++ b/gcc/config/c4x/c4x.c
@@ -159,9 +159,6 @@ tree interrupt_tree = NULL_TREE;
void
c4x_override_options ()
{
- /* Convert foo / 8.0 into foo * 0.125, etc. */
- flag_fast_math = 1;
-
if (c4x_rpts_cycles_string)
c4x_rpts_cycles = atoi (c4x_rpts_cycles_string);
else
@@ -204,8 +201,21 @@ c4x_override_options ()
else
target_flags &= ~C3X_FLAG;
+ /* Convert foo / 8.0 into foo * 0.125, etc. */
+ flag_fast_math = 1;
+
+ /* We should phase out the following at some stage.
+ This provides compatibility with the old -mno-rptb option. */
+ if (!TARGET_RPTB && flag_branch_on_count_reg)
+ flag_branch_on_count_reg = 0;
+
+ /* We should phase out the following at some stage.
+ This provides compatibility with the old -mno-aliases option. */
+ if (!TARGET_ALIASES && !flag_argument_noalias)
+ flag_argument_noalias = 1;
}
+/* This is called before c4x_override_options. */
void
c4x_optimization_options (level, size)
int level;
@@ -213,7 +223,7 @@ c4x_optimization_options (level, size)
{
/* When optimizing, enable use of RPTB instruction. */
if (level >= 1)
- flag_branch_on_count_reg = 1;
+ flag_branch_on_count_reg = 1;
}
/* Write an ASCII string. */
@@ -1419,30 +1429,26 @@ c4x_gen_compare_reg (code, x, y)
}
char *
-c4x_output_cbranch (reversed, insn)
- int reversed;
- rtx insn;
+c4x_output_cbranch (form, seq)
+ char *form;
+ rtx seq;
{
int delayed = 0;
int annultrue = 0;
int annulfalse = 0;
rtx delay;
char *cp;
- static char str[20];
+ static char str[100];
if (final_sequence)
{
delay = XVECEXP (final_sequence, 0, 1);
- delayed = !INSN_ANNULLED_BRANCH_P (insn);
- annultrue = INSN_ANNULLED_BRANCH_P (insn) && !INSN_FROM_TARGET_P (delay);
- annulfalse = INSN_ANNULLED_BRANCH_P (insn) && INSN_FROM_TARGET_P (delay);
+ delayed = !INSN_ANNULLED_BRANCH_P (seq);
+ annultrue = INSN_ANNULLED_BRANCH_P (seq) && !INSN_FROM_TARGET_P (delay);
+ annulfalse = INSN_ANNULLED_BRANCH_P (seq) && INSN_FROM_TARGET_P (delay);
}
- cp = str;
- *cp++ = 'b';
- *cp++ = '%';
- if (reversed)
- *cp++ = 'I';
- *cp++ = '0';
+ strcpy (str, form);
+ cp = &str [strlen (str)];
if (delayed)
{
*cp++ = '%';
@@ -1466,7 +1472,6 @@ c4x_output_cbranch (reversed, insn)
return str;
}
-
void
c4x_print_operand (file, op, letter)
FILE *file; /* file to write to */
@@ -2040,10 +2045,19 @@ c4x_rptb_insert (insn)
{
rtx end_label;
rtx start_label;
-
+ rtx count_reg;
+
+ /* If the count register has not been allocated to RC, say if
+ there is a movstr pattern in the loop, then do not insert a
+ RPTB instruction. Instead we emit a decrement and branch
+ at the end of the loop. */
+ count_reg = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0), 0);
+ if (REGNO (count_reg) != RC_REGNO)
+ return;
+
/* Extract the start label from the jump pattern (rptb_end). */
start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);
-
+
/* We'll have to update the basic blocks. */
end_label = gen_label_rtx ();
emit_label_after (end_label, insn);
@@ -3123,6 +3137,9 @@ c4x_address_conflict (op0, op1, store0, store1)
int disp0;
int disp1;
+ if (MEM_VOLATILE_P (op0) && MEM_VOLATILE_P (op1))
+ return 1;
+
c4x_S_address_parse (op0, &base0, &incdec0, &index0, &disp0);
c4x_S_address_parse (op1, &base1, &incdec1, &index1, &disp1);
@@ -3137,12 +3154,7 @@ c4x_address_conflict (op0, op1, store0, store1)
have an aliased address if both locations are not marked
volatile, it is probably safer to flag a potential conflict
if either location is volatile. */
- if (!TARGET_ALIASES)
- {
- if (MEM_VOLATILE_P (op0) && MEM_VOLATILE_P (op1))
- return 1;
- }
- else
+ if (!flag_argument_alias)
{
if (MEM_VOLATILE_P (op0) || MEM_VOLATILE_P (op1))
return 1;
@@ -3222,6 +3234,14 @@ valid_parallel_operands_4 (operands, mode)
par_ind_operand() operands. Thus of the 4 operands, only 2
should be REGs and the other 2 should be MEMs. */
+ /* This test prevents the multipack pass from using this pattern if
+ op0 is used as an index or base register in op3, since this combination
+ will require reloading. */
+ if (GET_CODE (op0) == REG
+ && GET_CODE (op3) == MEM
+ && reg_mentioned_p (op0, XEXP (op3, 0)))
+ return 0;
+
/* LDI||LDI */
if (GET_CODE (op0) == REG && GET_CODE (op2) == REG)
return (REGNO (op0) != REGNO (op2))
@@ -3246,6 +3266,7 @@ valid_parallel_operands_4 (operands, mode)
return 0;
}
+
/* We only use this to check operands 1 and 2 since these may be
commutative. It will need extending for the C32 opcodes. */
int
@@ -3254,23 +3275,36 @@ valid_parallel_operands_5 (operands, mode)
enum machine_mode mode ATTRIBUTE_UNUSED;
{
int regs = 0;
- rtx op0 = operands[1];
- rtx op1 = operands[2];
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx op2 = operands[2];
+ rtx op3 = operands[3];
if (GET_CODE (op0) == SUBREG)
op0 = SUBREG_REG (op0);
- if (GET_CODE (op1) == SUBREG)
- op1 = SUBREG_REG (op1);
+ if (GET_CODE (op2) == SUBREG)
+ op2 = SUBREG_REG (op2);
/* The patterns should only allow ext_low_reg_operand() or
par_ind_operand() operands. */
if (GET_CODE (op0) == REG)
regs++;
- if (GET_CODE (op1) == REG)
+ if (GET_CODE (op2) == REG)
regs++;
- return regs == 1;
+ if (regs != 1)
+ return 0;
+
+ /* This test prevents the multipack pass from using this pattern if
+ op0 is used as an index or base register in op3, since this combination
+ will require reloading. */
+ if (GET_CODE (op0) == REG
+ && GET_CODE (op3) == MEM
+ && reg_mentioned_p (op0, XEXP (op3, 0)))
+ return 0;
+
+ return 1;
}
@@ -3280,47 +3314,48 @@ valid_parallel_operands_6 (operands, mode)
enum machine_mode mode ATTRIBUTE_UNUSED;
{
int regs = 0;
- rtx op0 = operands[1];
- rtx op1 = operands[2];
- rtx op2 = operands[4];
- rtx op3 = operands[5];
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx op2 = operands[2];
+ rtx op4 = operands[4];
+ rtx op5 = operands[5];
- if (GET_CODE (op0) == SUBREG)
- op0 = SUBREG_REG (op0);
if (GET_CODE (op1) == SUBREG)
op1 = SUBREG_REG (op1);
if (GET_CODE (op2) == SUBREG)
op2 = SUBREG_REG (op2);
- if (GET_CODE (op3) == SUBREG)
- op3 = SUBREG_REG (op3);
+ if (GET_CODE (op4) == SUBREG)
+ op4 = SUBREG_REG (op4);
+ if (GET_CODE (op5) == SUBREG)
+ op5 = SUBREG_REG (op5);
/* The patterns should only allow ext_low_reg_operand() or
par_ind_operand() operands. Thus of the 4 input operands, only 2
should be REGs and the other 2 should be MEMs. */
- if (GET_CODE (op0) == REG)
- regs++;
if (GET_CODE (op1) == REG)
regs++;
if (GET_CODE (op2) == REG)
regs++;
- if (GET_CODE (op3) == REG)
+ if (GET_CODE (op4) == REG)
+ regs++;
+ if (GET_CODE (op5) == REG)
regs++;
/* The new C30/C40 silicon dies allow 3 regs of the 4 input operands.
Perhaps we should count the MEMs as well? */
- return regs == 2;
-}
+ if (regs != 2)
+ return 0;
+ /* This test prevents the multipack pass from using this pattern if
+ op0 is used as an index or base register in op4 or op5, since
+ this combination will require reloading. */
+ if (GET_CODE (op0) == REG
+ && ((GET_CODE (op4) == MEM && reg_mentioned_p (op0, XEXP (op4, 0)))
+ || (GET_CODE (op5) == MEM && reg_mentioned_p (op0, XEXP (op5, 0)))))
+ return 0;
-int
-legitimize_parallel_operands_6 (operands, mode)
- rtx *operands;
- enum machine_mode mode;
-{
- /* It's gonna be hard to legitimize operands for a parallel
- instruction... TODO... */
- return valid_parallel_operands_6 (operands, mode);
+ return 1;
}