c4x.c: (c4x_override_options): For compatibility with old target options clear...
authorMichael Hayes <m.hayes@elec.canterbury.ac.nz>
Wed, 25 Nov 1998 19:59:39 +0000 (19:59 +0000)
committerMichael Hayes <m.hayes@gcc.gnu.org>
Wed, 25 Nov 1998 19:59:39 +0000 (19:59 +0000)
* 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

gcc/ChangeLog
gcc/config/c4x/c4x.c

index c0181a92e24bd32686f61b5fc6c6686f111e4027..f53c400a5cd4a948d3241dab9115a5c314c54bc6 100644 (file)
@@ -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>
index b63b863bd78ed08de06eea64caa8c31c037397df..b7b02c49f1bd3b373218f8c6dae3b2bc3fbdd4b3 100644 (file)
@@ -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;
 }