This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Thread-local storage on IA64 in ILP32 mode
- From: Richard Henderson <rth at redhat dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: gcc at gcc dot gnu dot org, zack at codesourcery dot com, gcc-patches at gcc dot gnu dot org
- Date: Mon, 25 Aug 2003 16:46:24 -0700
- Subject: Re: Thread-local storage on IA64 in ILP32 mode
- References: <200308222023.h7MKNFrR000660@sirius.codesourcery.com>
On Fri, Aug 22, 2003 at 01:23:15PM -0700, Mark Mitchell wrote:
> This small test case (g++.dg/tls/init-1.C) fails on ILP32:
Fixed thus. Applied to mainline; re-running regression tests
for ia64-linux on 3.3 branch.
r~
* config/ia64/ia64.c (ia64_expand_tls_address): Properly truncate
result when op0 is SImode.
Index: ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.242
diff -u -p -u -r1.242 ia64.c
--- ia64.c 22 Aug 2003 17:58:05 -0000 1.242
+++ ia64.c 25 Aug 2003 23:37:13 -0000
@@ -1222,6 +1222,7 @@ static rtx
ia64_expand_tls_address (enum tls_model tls_kind, rtx op0, rtx op1)
{
rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp, insns;
+ rtx orig_op0 = op0;
switch (tls_kind)
{
@@ -1245,8 +1246,10 @@ ia64_expand_tls_address (enum tls_model
insns = get_insns ();
end_sequence ();
+ if (GET_MODE (op0) != Pmode)
+ op0 = tga_ret;
emit_libcall_block (insns, op0, tga_ret, op1);
- return NULL_RTX;
+ break;
case TLS_MODEL_LOCAL_DYNAMIC:
/* ??? This isn't the completely proper way to do local-dynamic
@@ -1274,19 +1277,16 @@ ia64_expand_tls_address (enum tls_model
tmp = gen_reg_rtx (Pmode);
emit_libcall_block (insns, tmp, tga_ret, tga_eqv);
- if (register_operand (op0, Pmode))
- tga_ret = op0;
- else
- tga_ret = gen_reg_rtx (Pmode);
+ if (!register_operand (op0, Pmode))
+ op0 = gen_reg_rtx (Pmode);
if (TARGET_TLS64)
{
- emit_insn (gen_load_dtprel (tga_ret, op1));
- emit_insn (gen_adddi3 (tga_ret, tmp, tga_ret));
+ emit_insn (gen_load_dtprel (op0, op1));
+ emit_insn (gen_adddi3 (op0, tmp, op0));
}
else
- emit_insn (gen_add_dtprel (tga_ret, tmp, op1));
-
- return (tga_ret == op0 ? NULL_RTX : tga_ret);
+ emit_insn (gen_add_dtprel (op0, tmp, op1));
+ break;
case TLS_MODEL_INITIAL_EXEC:
tmp = gen_reg_rtx (Pmode);
@@ -1295,32 +1295,32 @@ ia64_expand_tls_address (enum tls_model
RTX_UNCHANGING_P (tmp) = 1;
tmp = force_reg (Pmode, tmp);
- if (register_operand (op0, Pmode))
- op1 = op0;
- else
- op1 = gen_reg_rtx (Pmode);
- emit_insn (gen_adddi3 (op1, tmp, gen_thread_pointer ()));
-
- return (op1 == op0 ? NULL_RTX : op1);
+ if (!register_operand (op0, Pmode))
+ op0 = gen_reg_rtx (Pmode);
+ emit_insn (gen_adddi3 (op0, tmp, gen_thread_pointer ()));
+ break;
case TLS_MODEL_LOCAL_EXEC:
- if (register_operand (op0, Pmode))
- tmp = op0;
- else
- tmp = gen_reg_rtx (Pmode);
+ if (!register_operand (op0, Pmode))
+ op0 = gen_reg_rtx (Pmode);
if (TARGET_TLS64)
{
- emit_insn (gen_load_tprel (tmp, op1));
- emit_insn (gen_adddi3 (tmp, gen_thread_pointer (), tmp));
+ emit_insn (gen_load_tprel (op0, op1));
+ emit_insn (gen_adddi3 (op0, gen_thread_pointer (), op0));
}
else
- emit_insn (gen_add_tprel (tmp, gen_thread_pointer (), op1));
-
- return (tmp == op0 ? NULL_RTX : tmp);
+ emit_insn (gen_add_tprel (op0, gen_thread_pointer (), op1));
+ break;
default:
abort ();
}
+
+ if (orig_op0 == op0)
+ return NULL_RTX;
+ if (GET_MODE (orig_op0) == Pmode)
+ return op0;
+ return gen_lowpart (GET_MODE (orig_op0), op0);
}
rtx