This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH/RFA] SH: Cleanup TLS handling
- From: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: gcc-patches at gcc dot gnu dot org
- Cc: joern dot rennecke at st dot com, aoliva at redhat dot com
- Date: Mon, 28 Feb 2005 13:21:08 +0900 (JST)
- Subject: [PATCH/RFA] SH: Cleanup TLS handling
Hi,
The attached patch is to cleanup TLS handling of SH. It was suggested
by Joern and waiting stage1 for a while. Bootstrapped and tested with
"make -k check" on sh4-unknown-linux-gnu with no regressions. It's also
tested with build&test of the latest glibc for the same target.
Ok for mainline?
Regards,
kaz
--
2005-02-28 Kaz Kojima <kkojima@gcc.gnu.org>
* config/sh/sh-protos.h (legitimize_tls_address): Add prototype.
* config/sh/sh.c (legitimize_tls_address): New.
(prepare_move_operands): Use legitimize_tls_address.
* config/sh/sh.h: (LEGITIMIZE_ADDRESS): Call legitimize_tls_address
for TLS symbolic operands.
diff -uprN ORIG/gcc/gcc/config/sh/sh-protos.h LOCAL/gcc/gcc/config/sh/sh-protos.h
--- ORIG/gcc/gcc/config/sh/sh-protos.h 2004-09-29 08:49:55.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh-protos.h 2005-02-24 13:48:41.000000000 +0900
@@ -47,6 +47,7 @@ extern int fp_one_operand (rtx);
extern int fp_int_operand (rtx);
extern rtx get_fpscr_rtx (void);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
+extern rtx legitimize_tls_address (rtx, enum machine_mode);
extern int nonpic_symbol_mentioned_p (rtx);
extern void emit_sf_insn (rtx);
extern void emit_df_insn (rtx);
diff -uprN ORIG/gcc/gcc/config/sh/sh.c LOCAL/gcc/gcc/config/sh/sh.c
--- ORIG/gcc/gcc/config/sh/sh.c 2005-02-17 09:03:05.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh.c 2005-02-26 20:31:49.745536808 +0900
@@ -1006,82 +1006,10 @@ prepare_move_operands (rtx operands[], e
&& GET_CODE (XEXP (operands[0], 0)) == PLUS
&& GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == REG)
operands[1] = copy_to_mode_reg (mode, operands[1]);
- }
-
- if (mode == Pmode || mode == ptr_mode)
- {
- rtx op0, op1;
- enum tls_model tls_kind;
-
- op0 = operands[0];
- op1 = operands[1];
- if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
- {
- rtx tga_op1, tga_ret, tmp, tmp2;
-
- switch (tls_kind)
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- tga_ret = gen_rtx_REG (Pmode, R0_REG);
- emit_call_insn (gen_tls_global_dynamic (tga_ret, op1));
- op1 = tga_ret;
- break;
-
- case TLS_MODEL_LOCAL_DYNAMIC:
- tga_ret = gen_rtx_REG (Pmode, R0_REG);
- emit_call_insn (gen_tls_local_dynamic (tga_ret, op1));
-
- tmp = gen_reg_rtx (Pmode);
- emit_move_insn (tmp, tga_ret);
-
- if (register_operand (op0, Pmode))
- tmp2 = op0;
- else
- tmp2 = gen_reg_rtx (Pmode);
-
- emit_insn (gen_symDTPOFF2reg (tmp2, op1, tmp));
- op1 = tmp2;
- break;
-
- case TLS_MODEL_INITIAL_EXEC:
- if (! flag_pic)
- {
- /* Don't schedule insns for getting GOT address when
- the first scheduling is enabled, to avoid spill
- failures for R0. */
- if (flag_schedule_insns)
- emit_insn (gen_blockage ());
- emit_insn (gen_GOTaddr2picreg ());
- emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode,
- PIC_REG)));
- if (flag_schedule_insns)
- emit_insn (gen_blockage ());
- }
- tga_op1 = no_new_pseudos ? op0 : gen_reg_rtx (Pmode);
- tmp = gen_sym2GOTTPOFF (op1);
- emit_insn (gen_tls_initial_exec (tga_op1, tmp));
- op1 = tga_op1;
- break;
- case TLS_MODEL_LOCAL_EXEC:
- tmp2 = gen_reg_rtx (Pmode);
- emit_insn (gen_load_gbr (tmp2));
- tmp = gen_reg_rtx (Pmode);
- emit_insn (gen_symTPOFF2reg (tmp, op1));
-
- if (register_operand (op0, Pmode))
- op1 = op0;
- else
- op1 = gen_reg_rtx (Pmode);
-
- emit_insn (gen_addsi3 (op1, tmp, tmp2));
- break;
-
- default:
- abort ();
- }
- operands[1] = op1;
- }
+ if ((mode == Pmode || mode == ptr_mode)
+ && tls_symbolic_operand (operands[1], Pmode) != 0)
+ operands[1] = legitimize_tls_address (operands[1], mode);
}
return 0;
@@ -8441,6 +8369,79 @@ legitimize_pic_address (rtx orig, enum m
return orig;
}
+/* A subroutine for LEGITIMIZE_ADDRESS. Generate the TLS sequence for
+ TLS addresses and return X itself othrewise. */
+rtx
+legitimize_tls_address (rtx x, enum machine_mode mode)
+{
+
+ if (mode == Pmode || mode == ptr_mode)
+ {
+ enum tls_model tls_kind;
+
+ if ((tls_kind = tls_symbolic_operand (x, Pmode)))
+ {
+ rtx dest, tga_dest, tga_ret, tmp, tmp2;
+
+ switch (tls_kind)
+ {
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ tga_ret = gen_rtx_REG (Pmode, R0_REG);
+ emit_call_insn (gen_tls_global_dynamic (tga_ret, x));
+ dest = tga_ret;
+ break;
+
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ tga_ret = gen_rtx_REG (Pmode, R0_REG);
+ emit_call_insn (gen_tls_local_dynamic (tga_ret, x));
+
+ tmp = gen_reg_rtx (Pmode);
+ emit_move_insn (tmp, tga_ret);
+ tmp2 = gen_reg_rtx (Pmode);
+ emit_insn (gen_symDTPOFF2reg (tmp2, x, tmp));
+ dest = tmp2;
+ break;
+
+ case TLS_MODEL_INITIAL_EXEC:
+ if (! flag_pic)
+ {
+ /* Don't schedule insns for getting GOT address when
+ the first scheduling is enabled, to avoid spill
+ failures for R0. */
+ if (flag_schedule_insns)
+ emit_insn (gen_blockage ());
+ emit_insn (gen_GOTaddr2picreg ());
+ emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode,
+ PIC_REG)));
+ if (flag_schedule_insns)
+ emit_insn (gen_blockage ());
+ }
+ tga_dest = gen_reg_rtx (Pmode);
+ tmp = gen_sym2GOTTPOFF (x);
+ emit_insn (gen_tls_initial_exec (tga_dest, tmp));
+ dest = tga_dest;
+ break;
+
+ case TLS_MODEL_LOCAL_EXEC:
+ tmp2 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_gbr (tmp2));
+ tmp = gen_reg_rtx (Pmode);
+ emit_insn (gen_symTPOFF2reg (tmp, x));
+ dest = gen_reg_rtx (Pmode);
+ emit_insn (gen_addsi3 (dest, tmp, tmp2));
+ break;
+
+ default:
+ abort ();
+ }
+
+ return dest;
+ }
+ }
+
+ return x;
+}
+
/* Mark the use of a constant in the literal table. If the constant
has multiple labels, make it unique. */
static rtx
diff -uprN ORIG/gcc/gcc/config/sh/sh.h LOCAL/gcc/gcc/config/sh/sh.h
--- ORIG/gcc/gcc/config/sh/sh.h 2005-01-04 10:48:38.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh.h 2005-02-24 13:56:51.000000000 +0900
@@ -2673,7 +2673,9 @@ struct sh_args {
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
{ \
- if (flag_pic) \
+ if (tls_symbolic_operand (X, MODE) != 0) \
+ (X) = legitimize_tls_address (X, MODE); \
+ else if (flag_pic) \
(X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
if (GET_CODE (X) == PLUS \
&& (GET_MODE_SIZE (MODE) == 4 \