[PATCH/RFC] SH: bootstrap failure sh4-unknown-linux-gnu

Kaz Kojima kkojima@rr.iij4u.or.jp
Mon Aug 23 02:52:00 GMT 2004


Hi,

The sh-linux native c++ compiler fails in building libstdc++
with reporting that cc1plus executes an illegal instruction.
It seems that cp/mangle.c is compiled to an assembler source
having a sequence like

	...
	bf/s	.LF100
	bra	.L2231
	...

which has a bad instruction in the delayed slot of bf/s.  This
sequence was put by output_branch where FINAL_SEQUENCE is

(sequence [
        (jump_insn:TI 62 60 710 (set (pc)
                (if_then_else (ne (reg:SI 147 t)
                        (const_int 0 [0x0]))
                    (label_ref 63)
                    (pc))) 160 {branch_true} (insn_list 61 (nil))
            (expr_list:REG_BR_PRED (const_int 18 [0x12])
                (expr_list (reg:SI 147 t)
                    (expr_list:REG_BR_PROB (const_int 1900 [0x76c])
                        (nil)))))
        (insn 710 62 709 (parallel [
                    (set (pc)
                        (unspec [
                                (const_int 72 [0x48])
                                (pc)
                            ] 4))
                    (set (reg:SI 147 t)
                        (const_int 0 [0x0]))
                ]) 164 {stuff_delay_slot} (nil)
            (nil))
    ])


which has no real instruction in the delayed slot.  The patch below
checks the insn length possibly in the delayed slot and uses the
conditional branch without a delayed slot for the case like above.
The patch is tested with bootstrap on native sh4-unknown-linux-gnu
and there are no new failures in regtest on x86 cross sh4-unknown-
linux-gnu.

Regards,
	kaz
--
2004-08-22  Kaz Kojima  <kkojima@gcc.gnu.org>

	* config/sh/sh.c (output_branch): Check the insn length possibly
	in the delayed slot.

diff -uprN ORIG/gcc/gcc/config/sh/sh.c LOCAL/gcc/gcc/config/sh/sh.c
--- ORIG/gcc/gcc/config/sh/sh.c	2004-08-19 09:46:07.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh.c	2004-08-20 11:20:33.000000000 +0900
@@ -1376,7 +1380,8 @@ output_branch (int logic, rtx insn, rtx 
 	     place for it is after the label.  final will do that by default.  */
     
 	  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)))
 	    {
 	      asm_fprintf (asm_out_file, "\tb%s%ss\t%LLF%d\n", logic ? "f" : "t",
 	                   ASSEMBLER_DIALECT ? "/" : ".", label);



More information about the Gcc-patches mailing list