OSDN Git Service

* sh.c (sh_insn_length_adjustment): New function.
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Apr 2000 23:12:53 +0000 (23:12 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Apr 2000 23:12:53 +0000 (23:12 +0000)
* sh-protos.h (sh_insn_length_adjustment): Declare.
* sh.h (ADJUST_INSN_LENGTH): Use it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32942 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.h

index 2fb37dc..d37980e 100644 (file)
@@ -1,3 +1,9 @@
+Wed Apr  5 23:17:10 2000  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * sh.c (sh_insn_length_adjustment): New function.
+       * sh-protos.h (sh_insn_length_adjustment): Declare.
+       * sh.h (ADJUST_INSN_LENGTH): Use it.
+
 Wed Apr  5 12:35:18 2000  Hans-Peter Nilsson  <hp@axis.com>
 
        * optabs.c (emit_libcall_block): Remove spurious REG_EQUAL notes
index a36e4c6..acc316e 100644 (file)
@@ -90,6 +90,7 @@ extern void expand_sf_binop PARAMS ((rtx (*)(rtx, rtx, rtx, rtx), rtx *));
 extern void expand_df_unop PARAMS ((rtx (*)(rtx, rtx, rtx), rtx *));
 extern void expand_df_binop PARAMS ((rtx (*)(rtx, rtx, rtx, rtx), rtx *));
 extern void expand_fp_branch PARAMS ((rtx (*)(void), rtx (*)(void)));
+extern int sh_insn_length_adjustment PARAMS ((rtx));
 #ifdef TREE_CODE
 extern void sh_va_start PARAMS ((int, tree, rtx));
 extern rtx sh_va_arg PARAMS ((tree, tree));
index 28d199c..d4d38d3 100644 (file)
@@ -5127,3 +5127,79 @@ fpscr_set_from_mem (mode, regs_live)
   REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_DEAD, addr_reg, REG_NOTES (i));
   REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_INC, addr_reg, REG_NOTES (i));
 }
+
+/* Is the given character a logical line separator for the assembler?  */
+#ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
+#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == ';')
+#endif
+
+int
+sh_insn_length_adjustment (insn)
+     rtx insn;
+{
+  /* Instructions with unfilled delay slots take up an extra two bytes for
+     the nop in the delay slot.  */
+  if (((GET_CODE (insn) == INSN
+        && GET_CODE (PATTERN (insn)) != USE
+        && GET_CODE (PATTERN (insn)) != CLOBBER)
+       || GET_CODE (insn) == CALL_INSN
+       || (GET_CODE (insn) == JUMP_INSN
+          && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
+          && GET_CODE (PATTERN (insn)) != ADDR_VEC))
+      && GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn)))) != SEQUENCE
+      && get_attr_needs_delay_slot (insn) == NEEDS_DELAY_SLOT_YES)
+    return 2;
+
+  /* sh-dsp parallel processing insn take four bytes instead of two.  */
+     
+  if (GET_CODE (insn) == INSN)
+    {
+      int sum = 0;
+      rtx body = PATTERN (insn);
+      char *template, c;
+      int maybe_label = 1;
+
+      if (GET_CODE (body) == ASM_INPUT)
+       template = XSTR (body, 0);
+      else if (asm_noperands (body) >= 0)
+       template
+         = decode_asm_operands (body, NULL_PTR, NULL_PTR, NULL_PTR, NULL_PTR);
+      else
+       return 0;
+      do
+       {
+         int ppi_adjust = 0;
+
+         do
+           c = *template++;
+         while (c == ' ' || c == '\t');
+         /* all sh-dsp parallel-processing insns start with p.
+            The only non-ppi sh insn starting with p is pref.
+            The only ppi starting with pr is prnd.  */
+         if ((c == 'p' || c == 'P') && strncasecmp ("re", template, 2))
+           ppi_adjust = 2;
+         /* The repeat pseudo-insn expands two three insns, a total of
+            six bytes in size.  */
+         else if ((c == 'r' || c == 'R')
+                  && ! strncasecmp ("epeat", template, 5))
+           ppi_adjust = 4;
+         while (c && c != '\n' && ! IS_ASM_LOGICAL_LINE_SEPARATOR (c))
+           {
+             /* If this is a label, it is obviously not a ppi insn.  */
+             if (c == ':' && maybe_label)
+               {
+                 ppi_adjust = 0;
+                 break;
+               }
+             else if (c == '\'' || c == '"')
+               maybe_label = 0;
+             c = *template++;
+           }
+         sum += ppi_adjust;
+         maybe_label = c != ':';
+       }
+      while (c);
+      return sum;
+    }
+  return 0;
+}
index 6ae0deb..4df72bf 100644 (file)
@@ -2122,20 +2122,12 @@ extern int rtx_equal_function_value_matters;
 extern struct rtx_def *fpscr_rtx;
 
 \f
-/* Instructions with unfilled delay slots take up an extra two bytes for
-   the nop in the delay slot.  */
+/* Instructions with unfilled delay slots take up an
+   extra two bytes for the nop in the delay slot.
+   sh-dsp parallel processing insns are four bytes long.  */
 
 #define ADJUST_INSN_LENGTH(X, LENGTH)                          \
-  if (((GET_CODE (X) == INSN                                   \
-       && GET_CODE (PATTERN (X)) != USE                        \
-       && GET_CODE (PATTERN (X)) != CLOBBER)                   \
-       || GET_CODE (X) == CALL_INSN                            \
-       || (GET_CODE (X) == JUMP_INSN                           \
-          && GET_CODE (PATTERN (X)) != ADDR_DIFF_VEC           \
-          && GET_CODE (PATTERN (X)) != ADDR_VEC))              \
-      && GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (X)))) != SEQUENCE \
-      && get_attr_needs_delay_slot (X) == NEEDS_DELAY_SLOT_YES)        \
-    (LENGTH) += 2;
+  (LENGTH) += sh_insn_length_adjustment (X);
 \f
 /* Define the codes that are matched by predicates in sh.c.  */
 #define PREDICATE_CODES \