This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gniibe@m17n.org: Re: target/4516: [SH] sh-unknown-linux-gnu: big jump table]


Hi,

Is this patch acceptable for the SH target?


-- 
Craig Rodrigues        
http://www.gis.net/~craigr    
rodrigc@attbi.com

----- Forwarded message from NIIBE Yutaka <gniibe@m17n.org> -----

Delivered-To: rodrigc@gcc.gnu.org
Date: Mon, 25 Feb 2002 15:39:06 +0900 (JST)
X-Authentication-Warning: mule.m17n.org: gniibe set sender to gniibe@m17n.org using -f
From: NIIBE Yutaka <gniibe@m17n.org>
To: rodrigc@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org,
   nobody@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Subject: Re: target/4516: [SH] sh-unknown-linux-gnu: big jump table
In-Reply-To: <20020224200831.12677.qmail@sources.redhat.com>

rodrigc@gcc.gnu.org wrote:
 > Old Synopsis: sh-unknown-linux-gnu: big jump table
 > New Synopsis: [SH] sh-unknown-linux-gnu: big jump table
 > 
 > State-Changed-From-To: open->feedback
 > State-Changed-By: rodrigc
 > State-Changed-When: Sun Feb 24 12:08:31 2002
 > State-Changed-Why:
 >     Is this solved in the current compiler?

I don't think it's fixed.

The issue here is that alignement calculation could be wrong.

I've been using following patch (re-diffed and re-wrote ChangeLog entries),
with no problem to bootstrap.

2002-02-25  NIIBE Yutaka  <gniibe@m17n.org>

	* final.c (shorten_branches): Update insn_current_address
	in the for loop.
	Set insn_current_address to be aligned.

	* doc/invoke.texi (Option Summary: SH Options): Remove -mbigtable.

	* config/sh/sh-protos.h (shl_casesi_worker_length): New function.

	* config/sh/sh.c (shl_casesi_worker_length): New function.

	* config/sh/sh.h (BIGTABLE_BIT, TARGET_BIGTABLE): Removed.
	(optimized_size): Declared.
	(TARGET_SWITCHES): Remove -mbigtable option.
	(CASE_VECTOR_MODE): Always SImode.  Starting from QImode (or
	HImode) may result assembler error of "pcrel too far" (e.g.
	compiling f/symbol.c).  It's because barrier_align depends
	on the mode.
	(CASE_VECTOR_SHORTEN_MODE): When it's 32768..65536 and -Os,
	Use HImode with offset_unsigned =1.
	(ASM_OUTPUT_ADDR_VEC_ELT): Always emit as .long.

	* config/sh/sh.md (*casesi_worker): Handle the case of
	offset_unsigned is set when HImode.
	Set length attribute with shl_casesi_worker_length.

--- gcc-HEAD/gcc/final.c	Mon Feb 25 11:26:13 2002
+++ gcc/gcc/final.c	Mon Feb 25 11:35:43 2002
@@ -1115,7 +1115,7 @@
   /* Compute initial lengths, addresses, and varying flags for each insn.  */
   for (insn_current_address = FIRST_INSN_ADDRESS, insn = first;
        insn != 0;
-       insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn))
+       insn = NEXT_INSN (insn))
     {
       uid = INSN_UID (insn);
 
@@ -1129,6 +1129,7 @@
 	      int align = 1 << log;
 	      int new_address = (insn_current_address + align - 1) & -align;
 	      insn_lengths[uid] = new_address - insn_current_address;
+	      insn_current_address = new_address;
 	    }
 	}
 
@@ -1208,6 +1209,8 @@
       if (insn_lengths[uid] < 0)
 	fatal_insn ("negative insn length", insn);
 #endif
+
+      insn_current_address += insn_lengths[uid];
     }
 
   /* Now loop over all the insns finding varying length insns.  For each,
--- gcc-HEAD/gcc/doc/invoke.texi	Mon Feb 25 11:27:29 2002
+++ gcc/gcc/doc/invoke.texi	Mon Feb 25 11:38:00 2002
@@ -544,7 +544,7 @@
 -m5-32media -m5-32media-nofpu @gol
 -m5-compact -m5-compact-nofpu @gol
 -mb  -ml  -mdalign  -mrelax @gol
--mbigtable  -mfmovd  -mhitachi  -mnomacsave @gol
+-mfmovd  -mhitachi  -mnomacsave @gol
 -mieee  -misize  -mpadstruct  -mspace @gol
 -mprefergot  -musermode}
 
@@ -8545,11 +8545,6 @@
 Shorten some address references at link time, when possible; uses the
 linker option @option{-relax}.
 
-@item -mbigtable
-@opindex mbigtable
-Use 32-bit offsets in @code{switch} tables.  The default is to use
-16-bit offsets.
-
 @item -mfmovd
 @opindex mfmovd
 Enable the use of the instruction @code{fmovd}.
--- gcc-HEAD/gcc/config/sh/sh-protos.h	Mon Feb 25 11:27:19 2002
+++ gcc/gcc/config/sh/sh-protos.h	Mon Feb 25 11:42:25 2002
@@ -74,6 +74,7 @@
 extern int shl_sext_length PARAMS ((rtx));
 extern int gen_shl_sext PARAMS ((rtx, rtx, rtx, rtx));
 extern rtx gen_datalabel_ref PARAMS ((rtx));
+extern int shl_casesi_worker_length PARAMS ((rtx));
 extern int regs_used PARAMS ((rtx, int));
 extern void fixup_addr_diff_vecs PARAMS ((rtx));
 extern int get_dest_uid PARAMS ((rtx, int));
--- gcc-HEAD/gcc/config/sh/sh.c	Mon Feb 25 11:27:19 2002
+++ gcc/gcc/config/sh/sh.c	Mon Feb 25 11:46:02 2002
@@ -2143,6 +2143,48 @@
   return sym;
 }
 
+
+/* Function to be used in the length attribute of the casesi_worker
+   instruction.  Returns number of instructions, which is half of the
+   length of bytes. */
+
+int
+shl_casesi_worker_length (insn)
+     rtx insn;
+{
+  rtx set_src, label;
+  rtx diff_vec;
+
+  set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
+  if (!(GET_CODE (set_src) == UNSPEC
+	&& XINT (set_src, 1) == UNSPEC_CASESI))
+    abort ();
+
+  label = XVECEXP (set_src, 0, 2);
+  if (GET_CODE (label) != LABEL_REF)
+    abort ();
+
+  diff_vec = PATTERN (next_real_insn (XEXP (label, 0)));
+
+  if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
+    abort ();
+
+  switch (GET_MODE (diff_vec))
+    {
+    case SImode:
+      return 2;
+    case HImode:
+      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
+	return 3;
+      return 2;
+    case QImode:
+      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
+	return 2;
+      return 1;
+    default:
+      abort ();
+    }
+}
 
 /* The SH cannot load a large constant into a register, constants have to
    come from a pc relative load.  The reference of a pc relative load
--- gcc-HEAD/gcc/config/sh/sh.h	Mon Feb 25 11:27:19 2002
+++ gcc/gcc/config/sh/sh.h	Mon Feb 25 11:56:10 2002
@@ -234,9 +238,6 @@
 /* Nonzero if we should generate smaller code rather than faster code.  */
 #define TARGET_SMALLCODE   (target_flags & SPACE_BIT)
 
-/* Nonzero to use long jump tables.  */
-#define TARGET_BIGTABLE     (target_flags & BIGTABLE_BIT)
-
 /* Nonzero to generate pseudo-ops needed by the assembler and linker
    to do function call relaxing.  */
 #define TARGET_RELAX (target_flags & RELAX_BIT)
@@ -297,7 +298,6 @@
   {"5-compact-nofpu", TARGET_NONE, "" },	\
   {"5-compact-nofpu", SH5_BIT|SH3_BIT|SH2_BIT|SH1_BIT, "Generate FPU-less SHcompact code" }, \
   {"b",		-LITTLE_ENDIAN_BIT, "" },  	\
-  {"bigtable", 	BIGTABLE_BIT, "" },		\
   {"dalign",  	DALIGN_BIT, "" },		\
   {"fmovd",  	FMOVD_BIT, "" },		\
   {"hitachi",	HITACHI_BIT, "" },		\
@@ -2493,16 +2494,22 @@
     goto LABEL;								\
 }
 
+extern int optimize; /* needed for gen_casesi.  */
+extern int optimize_size;
+
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
-#define CASE_VECTOR_MODE (TARGET_BIGTABLE ? SImode : HImode)
+#define CASE_VECTOR_MODE SImode
 
 #define CASE_VECTOR_SHORTEN_MODE(MIN_OFFSET, MAX_OFFSET, BODY) \
 ((MIN_OFFSET) >= 0 && (MAX_OFFSET) <= 127 \
  ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 0, QImode) \
  : (MIN_OFFSET) >= 0 && (MAX_OFFSET) <= 255 \
  ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 1, QImode) \
- : (MIN_OFFSET) >= -32768 && (MAX_OFFSET) <= 32767 ? HImode \
+ : (MIN_OFFSET) >= -32768 && (MAX_OFFSET) <= 32767 \
+ ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 0, HImode) \
+ : optimize_size && (MIN_OFFSET) >= 0 && (MAX_OFFSET) <= 65535 \
+ ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 1, HImode) \
  : SImode)
 
 /* Define as C expression which evaluates to nonzero if the tablejump
@@ -3038,10 +3045,7 @@
 /* Output an absolute table element.  */
 
 #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE)  				\
-  if (TARGET_BIGTABLE) 							\
-    asm_fprintf ((STREAM), "\t.long\t%LL%d\n", (VALUE)); 			\
-  else									\
-    asm_fprintf ((STREAM), "\t.word\t%LL%d\n", (VALUE)); 			\
+    asm_fprintf ((STREAM), "\t.long\t%LL%d\n", (VALUE))
 
 /* Output various types of constants.  */
 
@@ -3166,8 +3170,6 @@
 
 #define sh_cpu_attr ((enum attr_cpu)sh_cpu)
 extern enum processor_type sh_cpu;
-
-extern int optimize; /* needed for gen_casesi.  */
 
 enum mdep_reorg_phase_e
 {
--- gcc-HEAD/gcc/config/sh/sh.md	Mon Feb 25 11:27:19 2002
+++ gcc/gcc/config/sh/sh.md	Mon Feb 25 11:49:04 2002
@@ -6446,6 +6446,8 @@
     case SImode:
       return \"shll2	%1\;mov.l	@(r0,%1),%0\";
     case HImode:
+      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
+	return \"add	%1,%1\;mov.w	@(r0,%1),%0\;extu.w	%0,%0\";
       return \"add	%1,%1\;mov.w	@(r0,%1),%0\";
     case QImode:
       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
@@ -6455,7 +6457,15 @@
       abort ();
     }
 }"
-  [(set_attr "length" "4")])
+  [(set (attr "length")
+	(cond [(eq (symbol_ref "shl_casesi_worker_length (insn)") (const_int 1))
+	       (const_string "2")
+	       (eq (symbol_ref "shl_casesi_worker_length (insn)") (const_int 2))
+	       (const_string "4")
+	       ;; Put "match_dup" here so that insn_variable_length_p return 1.
+	       (ne (match_dup 2) (match_dup 2))
+	       (const_string "4")]
+	      (const_string "6")))])
 
 (define_insn "casesi_shift_media"
   [(set (match_operand 0 "arith_reg_operand" "=r")
-- 

----- End forwarded message -----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]