This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gniibe@m17n.org: Re: target/4516: [SH] sh-unknown-linux-gnu: big jump table]
- From: Craig Rodrigues <rodrigc at attbi dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 25 Feb 2002 01:46:16 -0500
- Subject: [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 -----