summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2002-07-30 17:39:27 +0000
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2002-07-30 17:39:27 +0000
commit36858eff437dab8a086e9ce918520c7ab79e7672 (patch)
tree7612c3dc4c84583f8bcae27a3ea0730c2276857a /gcc/config
parent349e0af13f559a885dd152d3a08d9e9bfa3881bd (diff)
downloadgcc-36858eff437dab8a086e9ce918520c7ab79e7672.tar.gz
* sh.md (cond_delay_slot): New attribute.
(cbranch delay): Use it for anulled-true case. (stuff_delay_slot): New pattern. * sh.c (print_operand, case '.'): Don't print .s / /s fore zero-length delay slot insn. (gen_far_branch): Emit stuff_delay_slot pattern. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55878 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/sh/sh.c8
-rw-r--r--gcc/config/sh/sh.md18
2 files changed, 24 insertions, 2 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 67215029155..d727a678638 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -346,7 +346,8 @@ print_operand (stream, x, code)
{
case '.':
if (final_sequence
- && ! INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0)))
+ && ! INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))
+ && get_attr_length (XVECEXP (final_sequence, 0, 1)))
fprintf (stream, ASSEMBLER_DIALECT ? "/s" : ".s");
break;
case ',':
@@ -3212,6 +3213,11 @@ gen_far_branch (bp)
JUMP_LABEL (jump) = bp->far_label;
if (! invert_jump (insn, label, 1))
abort ();
+ (emit_insn_after
+ (gen_stuff_delay_slot
+ (GEN_INT (INSN_UID (XEXP (SET_SRC (PATTERN (jump)), 0))),
+ GEN_INT (recog_memoized (insn) == CODE_FOR_branch_false)),
+ insn));
/* Prevent reorg from undoing our splits. */
gen_block_redirect (jump, bp->address += 2, 2);
}
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index aa64bf5cb81..7016e74ec48 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -696,6 +696,10 @@
(eq_attr "length" "2") (const_string "yes")
] (const_string "no")))
+(define_attr "cond_delay_slot" "yes,no"
+ (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
+ ] (const_string "no")))
+
(define_attr "is_sfunc" ""
(if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
@@ -738,7 +742,7 @@
(define_delay
(and (eq_attr "type" "cbranch")
(ne (symbol_ref "TARGET_SH2") (const_int 0)))
- [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
+ [(eq_attr "in_delay_slot" "yes") (eq_attr "cond_delay_slot" "yes") (nil)])
;; -------------------------------------------------------------------------
;; SImode signed integer comparisons
@@ -5141,6 +5145,18 @@
"TARGET_SH1"
""
[(set_attr "length" "0")])
+
+;; This one is used to preemt an insn from beyond the bra / braf / jmp
+;; being pulled into the delay slot of a condbranch that has been made to
+;; jump around the unconditional jump because it was out of range.
+(define_insn "stuff_delay_slot"
+ [(set (pc)
+ (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
+ (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
+ "TARGET_SH1"
+ ""
+ [(set_attr "length" "0")
+ (set_attr "cond_delay_slot" "yes")])
;; Conditional branch insns