aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBernd Schmidt <bernd.schmidt@analog.com>2005-07-11 16:11:28 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2005-07-11 16:11:28 +0000
commit3fb192d2c7fd3ac8080d335d62ac9ad6754cd36f (patch)
treec7f52b707d3f9c206e1169f8eb194b6e9bfca2cc /gcc
parent2dd2d53e2c8c049a08ce582ee9354c884e5dd857 (diff)
downloadgcc-3fb192d2c7fd3ac8080d335d62ac9ad6754cd36f.zip
gcc-3fb192d2c7fd3ac8080d335d62ac9ad6754cd36f.tar.gz
gcc-3fb192d2c7fd3ac8080d335d62ac9ad6754cd36f.tar.bz2
bfin.md (define_attr "type"): Add "sync".
* config/bfin/bfin.md (define_attr "type"): Add "sync". (define_insn_reservation "alu"): Likewise. (csync, ssync): Now of type sync. * config/bfin/bfin.h (TARGET_DEFAULT): Defaults to -mcsync-anomaly -mspecld-anomaly. * config/bfin/bfin.opt (mcsync): Remove. (mcsync-anomaly, mspecld-anomaly): Add. * config/bfin/bfin.c: Include "insn-codes.h". (bfin_reorg): Extend to handle the CSYNC anomaly as well. (TARGET_DEFAULT_TARGET_FLAGS): New. * doc/invoke.texi: Document -mcsync-anomaly, -mspecld-anomaly. From-SVN: r101880
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/bfin/bfin.c118
-rw-r--r--gcc/config/bfin/bfin.h2
-rw-r--r--gcc/config/bfin/bfin.md8
-rw-r--r--gcc/config/bfin/bfin.opt11
-rw-r--r--gcc/doc/invoke.texi24
6 files changed, 147 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7199ddd..b5147ab 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2005-07-11 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * config/bfin/bfin.md (define_attr "type"): Add "sync".
+ (define_insn_reservation "alu"): Likewise.
+ (csync, ssync): Now of type sync.
+ * config/bfin/bfin.h (TARGET_DEFAULT): Defaults to
+ -mcsync-anomaly -mspecld-anomaly.
+ * config/bfin/bfin.opt (mcsync): Remove.
+ (mcsync-anomaly, mspecld-anomaly): Add.
+ * config/bfin/bfin.c: Include "insn-codes.h".
+ (bfin_reorg): Extend to handle the CSYNC anomaly as well.
+ (TARGET_DEFAULT_TARGET_FLAGS): New.
+ * doc/invoke.texi: Document -mcsync-anomaly, -mspecld-anomaly.
+
2005-07-11 Steven Bosscher <stevenb@suse.de>
* basic-block.h: Give the BB flags enum a name, bb_flags.
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 1b43e1f..5be76bb 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -28,6 +28,7 @@
#include "hard-reg-set.h"
#include "real.h"
#include "insn-config.h"
+#include "insn-codes.h"
#include "conditions.h"
#include "insn-flags.h"
#include "output.h"
@@ -2470,9 +2471,11 @@ bfin_reorg (void)
rtx insn, last_condjump = NULL_RTX;
int cycles_since_jump = INT_MAX;
- if (! TARGET_CSYNC)
+ if (! TARGET_SPECLD_ANOMALY || ! TARGET_CSYNC_ANOMALY)
return;
+ /* First pass: find predicted-false branches; if something after them
+ needs nops, insert them or change the branch to predict true. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
rtx pat;
@@ -2500,30 +2503,110 @@ bfin_reorg (void)
else if (INSN_P (insn))
{
enum attr_type type = get_attr_type (insn);
+ int delay_needed = 0;
if (cycles_since_jump < INT_MAX)
cycles_since_jump++;
- if (type == TYPE_MCLD && cycles_since_jump < 3)
+ if (type == TYPE_MCLD && TARGET_SPECLD_ANOMALY)
+ {
+ rtx pat = single_set (insn);
+ if (may_trap_p (SET_SRC (pat)))
+ delay_needed = 3;
+ }
+ else if (type == TYPE_SYNC && TARGET_CSYNC_ANOMALY)
+ delay_needed = 4;
+
+ if (delay_needed > cycles_since_jump)
{
rtx pat;
+ int num_clobbers;
+ rtx *op = recog_data.operand;
- pat = single_set (insn);
- if (may_trap_p (SET_SRC (pat)))
+ delay_needed -= cycles_since_jump;
+
+ extract_insn (last_condjump);
+ if (optimize_size)
{
- int num_clobbers;
- rtx *op = recog_data.operand;
-
- extract_insn (last_condjump);
- if (optimize_size)
- pat = gen_cbranch_predicted_taken (op[0], op[1], op[2],
- op[3]);
- else
- pat = gen_cbranch_with_nops (op[0], op[1], op[2], op[3],
- GEN_INT (3 - cycles_since_jump));
- PATTERN (last_condjump) = pat;
- INSN_CODE (last_condjump) = recog (pat, insn, &num_clobbers);
+ pat = gen_cbranch_predicted_taken (op[0], op[1], op[2],
+ op[3]);
cycles_since_jump = INT_MAX;
}
+ else
+ /* Do not adjust cycles_since_jump in this case, so that
+ we'll increase the number of NOPs for a subsequent insn
+ if necessary. */
+ pat = gen_cbranch_with_nops (op[0], op[1], op[2], op[3],
+ GEN_INT (delay_needed));
+ PATTERN (last_condjump) = pat;
+ INSN_CODE (last_condjump) = recog (pat, insn, &num_clobbers);
+ }
+ }
+ }
+ /* Second pass: for predicted-true branches, see if anything at the
+ branch destination needs extra nops. */
+ if (! TARGET_CSYNC_ANOMALY)
+ return;
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ if (JUMP_P (insn)
+ && any_condjump_p (insn)
+ && (INSN_CODE (insn) == CODE_FOR_cbranch_predicted_taken
+ || cbranch_predicted_taken_p (insn)))
+ {
+ rtx target = JUMP_LABEL (insn);
+ rtx label = target;
+ cycles_since_jump = 0;
+ for (; target && cycles_since_jump < 3; target = NEXT_INSN (target))
+ {
+ rtx pat;
+
+ if (NOTE_P (target) || BARRIER_P (target) || LABEL_P (target))
+ continue;
+
+ pat = PATTERN (target);
+ if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
+ || GET_CODE (pat) == ASM_INPUT || GET_CODE (pat) == ADDR_VEC
+ || GET_CODE (pat) == ADDR_DIFF_VEC || asm_noperands (pat) >= 0)
+ continue;
+
+ if (INSN_P (target))
+ {
+ enum attr_type type = get_attr_type (target);
+ int delay_needed = 0;
+ if (cycles_since_jump < INT_MAX)
+ cycles_since_jump++;
+
+ if (type == TYPE_SYNC && TARGET_CSYNC_ANOMALY)
+ delay_needed = 2;
+
+ if (delay_needed > cycles_since_jump)
+ {
+ rtx prev = prev_real_insn (label);
+ delay_needed -= cycles_since_jump;
+ if (dump_file)
+ fprintf (dump_file, "Adding %d nops after %d\n",
+ delay_needed, INSN_UID (label));
+ if (JUMP_P (prev)
+ && INSN_CODE (prev) == CODE_FOR_cbranch_with_nops)
+ {
+ rtx x;
+ HOST_WIDE_INT v;
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Reducing nops on insn %d.\n",
+ INSN_UID (prev));
+ x = PATTERN (prev);
+ x = XVECEXP (x, 0, 1);
+ v = INTVAL (XVECEXP (x, 0, 0)) - delay_needed;
+ XVECEXP (x, 0, 0) = GEN_INT (v);
+ }
+ while (delay_needed-- > 0)
+ emit_insn_after (gen_nop (), label);
+ break;
+ }
+ }
}
}
}
@@ -2792,4 +2875,7 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION bfin_handle_option
+#undef TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
+
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index 830222d..7ced865 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -48,7 +48,7 @@ extern int target_flags;
/* Generate DSP instructions, like DSP halfword loads */
#define TARGET_DSP (1)
-#define TARGET_DEFAULT MASK_CSYNC
+#define TARGET_DEFAULT (MASK_SPECLD_ANOMALY | MASK_CSYNC_ANOMALY)
/* Maximum number of library ids we permit */
#define MAX_LIBRARY_ID 255
diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md
index 76d6e13..be430c8 100644
--- a/gcc/config/bfin/bfin.md
+++ b/gcc/config/bfin/bfin.md
@@ -125,7 +125,7 @@
(UNSPEC_VOLATILE_SSYNC 2)])
(define_attr "type"
- "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,compare,dummy"
+ "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
(const_string "misc"))
;; Scheduling definitions
@@ -135,7 +135,7 @@
(define_cpu_unit "core" "bfin")
(define_insn_reservation "alu" 1
- (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,compare")
+ (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,sync,compare")
"core")
(define_insn_reservation "imul" 3
@@ -1931,13 +1931,13 @@
[(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
""
"csync;"
- [(set_attr "type" "misc")])
+ [(set_attr "type" "sync")])
(define_insn "ssync"
[(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
""
"ssync;"
- [(set_attr "type" "misc")])
+ [(set_attr "type" "sync")])
;;; Vector instructions
diff --git a/gcc/config/bfin/bfin.opt b/gcc/config/bfin/bfin.opt
index da5fd59..43f56c4 100644
--- a/gcc/config/bfin/bfin.opt
+++ b/gcc/config/bfin/bfin.opt
@@ -27,9 +27,14 @@ mlow64k
Target Report Mask(LOW_64K)
Program is entirely located in low 64k of memory
-mcsync
-Target Report Mask(CSYNC)
-Avoid speculative loads by inserting CSYNC or equivalent
+mcsync-anomaly
+Target Report Mask(CSYNC_ANOMALY)
+Work around a hardware anomaly by adding a number of NOPs before a
+CSYNC or SSYNC instruction.
+
+mspecld-anomaly
+Target Report Mask(SPECLD_ANOMALY)
+Avoid speculative loads to work around a hardware anomaly.
mid-shared-library
Target Report Mask(ID_SHARED_LIBRARY)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index fb9c64d..8fa9860 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -414,8 +414,9 @@ Objective-C and Objective-C++ Dialects}.
-mcall-prologues -mno-tablejump -mtiny-stack -mint8}
@emph{Blackfin Options}
-@gccoptlist{-momit-leaf-frame-pointer -mno-omit-leaf-frame-pointer -mcsync @gol
--mno-csync -mlow-64k -mno-low64k -mid-shared-library @gol
+@gccoptlist{-momit-leaf-frame-pointer -mno-omit-leaf-frame-pointer @gol
+-mspecld-anomaly -mno-specld-anomaly -mcsync-anomaly -mno-csync-anomaly @gol
+-mlow-64k -mno-low64k -mid-shared-library @gol
-mno-id-shared-library -mshared-library-id=@var{n} @gol
-mlong-calls -mno-long-calls}
@@ -7403,16 +7404,27 @@ makes an extra register available in leaf functions. The option
@option{-fomit-frame-pointer} removes the frame pointer for all functions
which might make debugging harder.
-@item -mcsync
-@opindex mcsync
+@item -mspecld-anomaly
+@opindex mspecld-anomaly
When enabled, the compiler will ensure that the generated code does not
contain speculative loads after jump instructions. This option is enabled
by default.
-@item -mno-csync
-@opindex mno-csync
+@item -mno-specld-anomaly
+@opindex mno-specld-anomaly
Don't generate extra code to prevent speculative loads from occurring.
+@item -mcsync-anomaly
+@opindex mspecld-anomaly
+When enabled, the compiler will ensure that the generated code does not
+contain CSYNC or SSYNC instructions too soon after conditional branches.
+This option is enabled by default.
+
+@item -mno-csync-anomaly
+@opindex mno-specld-anomaly
+Don't generate extra code to prevent CSYNC or SSYNC instructions from
+occurring too soon after a conditional branch.
+
@item -mlow-64k
@opindex mlow-64k
When enabled, the compiler is free to take advantage of the knowledge that