aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>2000-04-05 23:12:53 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2000-04-06 00:12:53 +0100
commit9342c0c4a93d92425e21de2b441ce623a30988a5 (patch)
tree5411fa54935493a93a2f391da0faa451fc332adc /gcc
parent65945ec1b3c5199a692e477b873cb975285cc515 (diff)
downloadgcc-9342c0c4a93d92425e21de2b441ce623a30988a5.zip
gcc-9342c0c4a93d92425e21de2b441ce623a30988a5.tar.gz
gcc-9342c0c4a93d92425e21de2b441ce623a30988a5.tar.bz2
sh.c (sh_insn_length_adjustment): New function.
* sh.c (sh_insn_length_adjustment): New function. * sh-protos.h (sh_insn_length_adjustment): Declare. * sh.h (ADJUST_INSN_LENGTH): Use it. From-SVN: r32942
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/sh/sh-protos.h1
-rw-r--r--gcc/config/sh/sh.c76
-rw-r--r--gcc/config/sh/sh.h16
4 files changed, 87 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2fb37dc..d37980e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index a36e4c6..acc316e 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -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));
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 28d199c..d4d38d3 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -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;
+}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 6ae0deb..4df72bf 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -2122,20 +2122,12 @@ extern int rtx_equal_function_value_matters;
extern struct rtx_def *fpscr_rtx;
-/* 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);
/* Define the codes that are matched by predicates in sh.c. */
#define PREDICATE_CODES \