sh.md (cond_delay_slot): New attribute.
authorJ"orn Rennecke <joern.rennecke@superh.com>
Tue, 30 Jul 2002 17:39:27 +0000 (17:39 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Tue, 30 Jul 2002 17:39:27 +0000 (18:39 +0100)
* 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.

From-SVN: r55878

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.md

index 13ed48ea24f7f4e92b7b61fb88812f76673acc5f..cd1da7b7d4c4a8f6760dc96cec49deb6f88f62cf 100644 (file)
@@ -1,3 +1,12 @@
+Tue Jul 30 18:31:31 2002  J"orn Rennecke <joern.rennecke@superh.com>
+
+       * 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.
+
 Tue Jul 30 11:21:44 2002  J"orn Rennecke <joern.rennecke@superh.com>
 
        * unroll.c (copy_loop_body): Don't copy NOTE_INSN_LOOP_CONT.
index 67215029155411dbbdb134ddd48e605a097c0554..d727a678638636fdc4f764072d14dc01e89201d7 100644 (file)
@@ -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);
 }
index aa64bf5cb813aff25461afc12a5f3e422a5f7987..7016e74ec484139cbf592ec43d47b64e3bc93ddc 100644 (file)
         (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)))
 
 (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)])
 \f
 ;; -------------------------------------------------------------------------
 ;; SImode signed integer comparisons
   "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")])
 \f
 ;; Conditional branch insns