diff options
author | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-07-30 17:39:27 +0000 |
---|---|---|
committer | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-07-30 17:39:27 +0000 |
commit | 36858eff437dab8a086e9ce918520c7ab79e7672 (patch) | |
tree | 7612c3dc4c84583f8bcae27a3ea0730c2276857a /gcc/config | |
parent | 349e0af13f559a885dd152d3a08d9e9bfa3881bd (diff) | |
download | gcc-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.c | 8 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 18 |
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 |