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
This commit is contained in:
Bernd Schmidt 2005-07-11 16:11:28 +00:00 committed by Bernd Schmidt
parent 2dd2d53e2c
commit 3fb192d2c7
6 changed files with 148 additions and 31 deletions

View File

@ -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.

View File

@ -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,29 +2503,109 @@ 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;
delay_needed -= cycles_since_jump;
extract_insn (last_condjump);
if (optimize_size)
{
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;
pat = single_set (insn);
if (may_trap_p (SET_SRC (pat)))
{
int num_clobbers;
rtx *op = recog_data.operand;
if (NOTE_P (target) || BARRIER_P (target) || LABEL_P (target))
continue;
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);
cycles_since_jump = INT_MAX;
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;

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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