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]

[patch] Fix __attribute__ ((tls_model ())) on hppa


Hi

GCC generates wrong code on hppa when TLS registers are used. This is due
to a bug in __attribute__ ((tls_model ())) which doesn't express that it 
uses r19 or r27.

Please see this URL for a testcase:
http://lists.parisc-linux.org/pipermail/parisc-linux/2007-May/031497.html

The patch below fixes the problem by marking r19 or r27 as used. Note
that the code has to be split for pic and non-pic cases. I have tested
that gcc still bootstrap with it, and that the generated code is now
correct.

Aurelien.


2007-05-03  Aurelien Jarno  <aurelien@aurel32.net>

	* config/pa/pa.md: Split tgd_load, tld_load and tie_load
        into pic and non-pic version. Mark r19 as used for 
	tgd_load_pic, tld_load_pic and tie_load_pic. Mark r27 as used 
	for tgd_load, tld_load and tie_load .
        * config/pa/pa.c (legitimize_tls_address): Emit pic or non-pic
	version of tgd_load, tld_load and tie_load depending on the 
	value of flag_pic.


Index: gcc/config/pa/pa.md
===================================================================
--- gcc/config/pa/pa.md	(revision 124260)
+++ gcc/config/pa/pa.md	(copie de travail)
@@ -39,6 +39,9 @@
    (UNSPEC_TLSLDBASE	7)
    (UNSPEC_TLSIE	8)
    (UNSPEC_TLSLE 	9)
+   (UNSPEC_TLSGD_PIC   10)
+   (UNSPEC_TLSLDM_PIC  11)
+   (UNSPEC_TLSIE_PIC   12)
   ])
 
 ;; UNSPEC_VOLATILE:
@@ -10148,33 +10151,55 @@
 (define_insn "tgd_load"
  [(set (match_operand:SI 0 "register_operand" "=r")
        (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
-  (clobber (reg:SI 1))]
+  (clobber (reg:SI 1))
+  (use (reg:SI 27))]
   ""
   "*
 {
-  if (flag_pic)
-    return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
-  else
-    return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
+  return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
 }"
   [(set_attr "type" "multi")
    (set_attr "length" "8")])
 
+(define_insn "tgd_load_pic"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
+  (clobber (reg:SI 1))
+  (use (reg:SI 19))]
+  ""
+  "*
+{
+  return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
+}"
+  [(set_attr "type" "multi")
+   (set_attr "length" "8")])
+
 (define_insn "tld_load"
  [(set (match_operand:SI 0 "register_operand" "=r")
        (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
-  (clobber (reg:SI 1))]
+  (clobber (reg:SI 1))
+  (use (reg:SI 27))]
   ""
   "*
 {
-  if (flag_pic)
-    return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
-  else
-    return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
+  return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
 }"
   [(set_attr "type" "multi")
    (set_attr "length" "8")])
 
+(define_insn "tld_load_pic"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
+  (clobber (reg:SI 1))
+  (use (reg:SI 19))]
+  ""
+  "*
+{
+  return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
+}"
+  [(set_attr "type" "multi")
+   (set_attr "length" "8")])
+
 (define_insn "tld_offset_load"
   [(set (match_operand:SI 0 "register_operand" "=r")
         (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] 
@@ -10200,18 +10225,29 @@
 (define_insn "tie_load"
   [(set (match_operand:SI 0 "register_operand" "=r")
         (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
-   (clobber (reg:SI 1))]
+   (clobber (reg:SI 1))
+   (use (reg:SI 27))]
   ""
   "*
 {
-  if (flag_pic)
-    return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
-  else
-    return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
+  return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
 }"
   [(set_attr "type" "multi")
    (set_attr "length" "8")])
 
+(define_insn "tie_load_pic"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
+   (clobber (reg:SI 1))
+   (use (reg:SI 19))]
+  ""
+  "*
+{
+  return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
+}"
+  [(set_attr "type" "multi")
+   (set_attr "length" "8")])
+
 (define_insn "tle_load"
   [(set (match_operand:SI 0 "register_operand" "=r")
         (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")] 
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	(révision 124260)
+++ gcc/config/pa/pa.c	(copie de travail)
@@ -733,7 +733,10 @@
     {
       case TLS_MODEL_GLOBAL_DYNAMIC:
 	tmp = gen_reg_rtx (Pmode);
-	emit_insn (gen_tgd_load (tmp, addr));
+	if (flag_pic)
+	  emit_insn (gen_tgd_load_pic (tmp, addr));
+	else
+	  emit_insn (gen_tgd_load (tmp, addr));
 	ret = hppa_tls_call (tmp);
 	break;
 
@@ -741,7 +744,10 @@
 	ret = gen_reg_rtx (Pmode);
 	tmp = gen_reg_rtx (Pmode);
 	start_sequence ();
-	emit_insn (gen_tld_load (tmp, addr));
+	if (flag_pic)
+	  emit_insn (gen_tld_load_pic (tmp, addr));
+	else
+	  emit_insn (gen_tld_load (tmp, addr));
 	t1 = hppa_tls_call (tmp);
 	insn = get_insns ();
 	end_sequence ();
@@ -757,7 +763,10 @@
 	tmp = gen_reg_rtx (Pmode);
 	ret = gen_reg_rtx (Pmode);
 	emit_insn (gen_tp_load (tp));
-	emit_insn (gen_tie_load (tmp, addr));
+	if (flag_pic)
+	  emit_insn (gen_tie_load_pic (tmp, addr));
+	else
+	  emit_insn (gen_tie_load (tmp, addr));
 	emit_move_insn (ret, gen_rtx_PLUS (Pmode, tp, tmp));
 	break;
 

-- 
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   aurel32@debian.org         | aurelien@aurel32.net
   `-    people.debian.org/~aurel32 | www.aurel32.net


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