]> git.pld-linux.org Git - packages/gcc.git/blame - gcc32-tls.patch
- amd64 files
[packages/gcc.git] / gcc32-tls.patch
CommitLineData
5384b728 1--- gcc/cp/lex.c.jj Sat May 25 00:02:23 2002
2+++ gcc/cp/lex.c Wed Jun 19 19:33:51 2002
3@@ -396,6 +396,7 @@ static const struct resword reswords[] =
4 { "__restrict__", RID_RESTRICT, 0 },
5 { "__signed", RID_SIGNED, 0 },
6 { "__signed__", RID_SIGNED, 0 },
7+ { "__thread", RID_THREAD, 0 },
8 { "__typeof", RID_TYPEOF, 0 },
9 { "__typeof__", RID_TYPEOF, 0 },
10 { "__volatile", RID_VOLATILE, 0 },
11@@ -502,6 +503,7 @@ const short rid_to_yy[RID_MAX] =
12 /* RID_BOUNDED */ 0,
13 /* RID_UNBOUNDED */ 0,
14 /* RID_COMPLEX */ TYPESPEC,
15+ /* RID_THREAD */ SCSPEC,
16
17 /* C++ */
18 /* RID_FRIEND */ SCSPEC,
19--- gcc/cp/decl.c.jj Wed Jun 19 19:33:51 2002
20+++ gcc/cp/decl.c Wed Jun 19 19:33:51 2002
21@@ -7122,7 +7122,8 @@ check_tag_decl (declspecs)
22 || value == ridpointers[(int) RID_VIRTUAL]
23 || value == ridpointers[(int) RID_CONST]
24 || value == ridpointers[(int) RID_VOLATILE]
25- || value == ridpointers[(int) RID_EXPLICIT])
26+ || value == ridpointers[(int) RID_EXPLICIT]
27+ || value == ridpointers[(int) RID_THREAD])
28 ob_modifier = value;
29 }
30
31@@ -7596,6 +7597,12 @@ static tree
32 obscure_complex_init (decl, init)
33 tree decl, init;
34 {
35+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
36+ {
37+ error ("run-time initialization of thread-local storage");
38+ return NULL_TREE;
39+ }
40+
41 if (! flag_no_inline && TREE_STATIC (decl))
42 {
43 if (extract_init (decl, init))
44@@ -9290,6 +9297,16 @@ grokvardecl (type, declarator, specbits_
45 TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
46 }
47
48+ if (RIDBIT_SETP (RID_THREAD, specbits))
49+ {
50+ if (targetm.have_tls)
51+ DECL_THREAD_LOCAL (decl) = 1;
52+ else
53+ /* A mere warning is sure to result in improper semantics
54+ at runtime. Don't bother to allow this to compile. */
55+ error ("thread-local storage not supported for this target");
56+ }
57+
58 if (TREE_PUBLIC (decl))
59 {
60 /* [basic.link]: A name with no linkage (notably, the name of a class
61@@ -10192,10 +10209,22 @@ grokdeclarator (declarator, declspecs, d
62 }
63 else if (RIDBIT_SETP (i, specbits))
64 pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
65+
66+ /* Diagnose "__thread extern". Recall that this list
67+ is in the reverse order seen in the text. */
68+ if (i == (int)RID_THREAD)
69+ {
70+ if (RIDBIT_SETP (RID_EXTERN, specbits))
71+ error ("`__thread' before `extern'");
72+ if (RIDBIT_SETP (RID_STATIC, specbits))
73+ error ("`__thread' before `static'");
74+ }
75+
76 if (i == (int)RID_EXTERN
77 && TREE_PURPOSE (spec) == error_mark_node)
78 /* This extern was part of a language linkage. */
79 extern_langp = 1;
80+
81 RIDBIT_SET (i, specbits);
82 goto found;
83 }
84@@ -10492,6 +10521,7 @@ grokdeclarator (declarator, declspecs, d
85 {
86 if (RIDBIT_SETP (RID_STATIC, specbits)) nclasses++;
87 if (RIDBIT_SETP (RID_EXTERN, specbits) && !extern_langp) nclasses++;
88+ if (RIDBIT_SETP (RID_THREAD, specbits)) nclasses++;
89 if (decl_context == PARM && nclasses > 0)
90 error ("storage class specifiers invalid in parameter declarations");
91 if (RIDBIT_SETP (RID_TYPEDEF, specbits))
92@@ -10523,6 +10553,13 @@ grokdeclarator (declarator, declspecs, d
93 /* Warn about storage classes that are invalid for certain
94 kinds of declarations (parameters, typenames, etc.). */
95
96+ /* "static __thread" and "extern __thread" are allowed. */
97+ if (nclasses == 2
98+ && RIDBIT_SETP (RID_THREAD, specbits)
99+ && (RIDBIT_SETP (RID_EXTERN, specbits)
100+ || RIDBIT_SETP (RID_STATIC, specbits)))
101+ nclasses = 1;
102+
103 if (nclasses > 1)
104 error ("multiple storage classes in declaration of `%s'", name);
105 else if (decl_context != NORMAL && nclasses > 0)
106@@ -10578,6 +10615,7 @@ grokdeclarator (declarator, declspecs, d
107 RIDBIT_RESET (RID_REGISTER, specbits);
108 RIDBIT_RESET (RID_AUTO, specbits);
109 RIDBIT_RESET (RID_EXTERN, specbits);
110+ RIDBIT_RESET (RID_THREAD, specbits);
111 }
112 }
113 else if (RIDBIT_SETP (RID_EXTERN, specbits) && initialized && !funcdef_flag)
114@@ -10600,6 +10638,14 @@ grokdeclarator (declarator, declspecs, d
115 if (RIDBIT_SETP (RID_AUTO, specbits))
116 error ("top-level declaration of `%s' specifies `auto'", name);
117 }
118+ else if (RIDBIT_SETP (RID_THREAD, specbits)
119+ && !RIDBIT_SETP (RID_EXTERN, specbits)
120+ && !RIDBIT_SETP (RID_STATIC, specbits))
121+ {
122+ error ("function-scope `%s' implicitly auto and declared `__thread'",
123+ name);
124+ RIDBIT_RESET (RID_THREAD, specbits);
125+ }
126
127 if (nclasses > 0 && friendp)
128 error ("storage class specifiers invalid in friend function declarations");
129@@ -11800,6 +11846,8 @@ friend declaration requires class-key, i
130 error ("storage class `auto' invalid for function `%s'", name);
131 else if (RIDBIT_SETP (RID_REGISTER, specbits))
132 error ("storage class `register' invalid for function `%s'", name);
133+ else if (RIDBIT_SETP (RID_THREAD, specbits))
134+ error ("storage class `__thread' invalid for function `%s'", name);
135
136 /* Function declaration not at top level.
137 Storage classes other than `extern' are not allowed
138--- gcc/doc/extend.texi.jj Wed Jun 19 19:33:51 2002
139+++ gcc/doc/extend.texi Wed Jun 19 19:33:51 2002
140@@ -432,6 +432,7 @@ extensions, accepted by GCC in C89 mode
141 * Target Builtins:: Built-in functions specific to particular targets.
142 * Pragmas:: Pragmas accepted by GCC.
143 * Unnamed Fields:: Unnamed struct/union fields within structs/unions.
144+* Thread-Local:: Per-thread variables.
145 @end menu
146
147 @node Statement Exprs
148@@ -6119,6 +6120,265 @@ It is ambiguous which @code{a} is being
149 Such constructs are not supported and must be avoided. In the future,
150 such constructs may be detected and treated as compilation errors.
151
152+@node Thread-Local
153+@section Thread-Local Storage
154+@cindex Thread-Local Storage
155+@cindex TLS
156+@cindex __thread
157+
158+Thread-local storage (@acronym{TLS}) is a mechanism by which variables
159+are allocated such that there is one instance of the variable per extant
160+thread. The run-time model GCC uses to implement this originates
161+in the IA-64 processor-specific ABI, but has since been migrated
162+to other processors as well. It requires significant support from
163+the linker (@command{ld}), dynamic linker (@command{ld.so}), and
164+system libraries (@file{libc.so} and @file{libpthread.so}), so it
165+is not available everywhere.
166+
167+At the user level, the extension is visible with a new storage
168+class keyword: @code{__thread}. For example:
169+
170+@example
171+__thread int i;
172+extern __thread struct state s;
173+static __thread char *p;
174+@end example
175+
176+The @code{__thread} specifier may be used alone, with the @code{extern}
177+or @code{static} specifiers, but with no other storage class specifier.
178+When used with @code{extern} or @code{static}, @code{__thread} must appear
179+immediately after the other storage class specifier.
180+
181+The @code{__thread} specifier may be applied to any global, file-scoped
182+static, function-scoped static, or static data member of a class. It may
183+not be applied to block-scoped automatic or non-static data member.
184+
185+When the address-of operator is applied to a thread-local variable, it is
186+evaluated at run-time and returns the address of the current thread's
187+instance of that variable. An address so obtained may be used by any
188+thread. When a thread terminates, any pointers to thread-local variables
189+in that thread become invalid.
190+
191+No static initialization may refer to the address of a thread-local variable.
192+
193+In C++, if an initializer is present for a thread-local variable, it must
194+be a @var{constant-expression}, as defined in 5.19.2 of the ANSI/ISO C++
195+standard.
196+
197+See @uref{http://people.redhat.com/drepper/tls.pdf,
198+ELF Handling For Thread-Local Storage} for a detailed explanation of
199+the four thread-local storage addressing models, and how the run-time
200+is expected to function.
201+
202+@menu
203+* C99 Thread-Local Edits::
204+* C++98 Thread-Local Edits::
205+@end menu
206+
207+@node C99 Thread-Local Edits
208+@subsection ISO/IEC 9899:1999 Edits for Thread-Local Storage
209+
210+The following are a set of changes to ISO/IEC 9899:1999 (aka C99)
211+that document the exact semantics of the language extension.
212+
213+@itemize @bullet
214+@item
215+@cite{5.1.2 Execution environments}
216+
217+Add new text after paragraph 1
218+
219+@quotation
220+Within either execution environment, a @dfn{thread} is a flow of
221+control within a program. It is implementation defined whether
222+or not there may be more than one thread associated with a program.
223+It is implementation defined how threads beyond the first are
224+created, the name and type of the function called at thread
225+startup, and how threads may be terminated. However, objects
226+with thread storage duration shall be initialized before thread
227+startup.
228+@end quotation
229+
230+@item
231+@cite{6.2.4 Storage durations of objects}
232+
233+Add new text before paragraph 3
234+
235+@quotation
236+An object whose identifier is declared with the storage-class
237+specifier @w{@code{__thread}} has @dfn{thread storage duration}.
238+Its lifetime is the entire execution of the thread, and its
239+stored value is initialized only once, prior to thread startup.
240+@end quotation
241+
242+@item
243+@cite{6.4.1 Keywords}
244+
245+Add @code{__thread}.
246+
247+@item
248+@cite{6.7.1 Storage-class specifiers}
249+
250+Add @code{__thread} to the list of storage class specifiers in
251+paragraph 1.
252+
253+Change paragraph 2 to
254+
255+@quotation
256+With the exception of @code{__thread}, at most one storage-class
257+specifier may be given [@dots{}]. The @code{__thread} specifier may
258+be used alone, or immediately following @code{extern} or
259+@code{static}.
260+@end quotation
261+
262+Add new text after paragraph 6
263+
264+@quotation
265+The declaration of an identifier for a variable that has
266+block scope that specifies @code{__thread} shall also
267+specify either @code{extern} or @code{static}.
268+
269+The @code{__thread} specifier shall be used only with
270+variables.
271+@end quotation
272+@end itemize
273+
274+@node C++98 Thread-Local Edits
275+@subsection ISO/IEC 14882:1998 Edits for Thread-Local Storage
276+
277+The following are a set of changes to ISO/IEC 14882:1998 (aka C++98)
278+that document the exact semantics of the language extension.
279+
280+@itemize @bullet
281+@b{[intro.execution]}
282+
283+New text after paragraph 4
284+
285+@quotation
286+A @dfn{thread} is a flow of control within the abstract machine.
287+It is implementation defined whether or not there may be more than
288+one thread.
289+@end quotation
290+
291+New text after paragraph 7
292+
293+@quotation
294+It is unspecified whether additional action must be taken to
295+ensure when and whether side effects are visible to other threads.
296+@end quotation
297+
298+@item
299+@b{[lex.key]}
300+
301+Add @code{__thread}.
302+
303+@item
304+@b{[basic.start.main]}
305+
306+Add after paragraph 5
307+
308+@quotation
309+The thread that begins execution at the @code{main} function is called
310+the @dfn{main thread}. It is implementation defined how functions
311+beginning threads other than the main thread are designated or typed.
312+A function so designated, as well as the @code{main} function, is called
313+a @dfn{thread startup function}. It is implementation defined what
314+happens if a thread startup function returns. It is implementation
315+defined what happens to other threads when any thread calls @code{exit}.
316+@end quotation
317+
318+@item
319+@b{[basic.start.init]}
320+
321+Add after paragraph 4
322+
323+@quotation
324+The storage for an object of thread storage duration shall be
325+staticly initialized before the first statement of the thread startup
326+function. An object of thread storage duration shall not require
327+dynamic initialization.
328+@end quotation
329+
330+@item
331+@b{[basic.start.term]}
332+
333+Add after paragraph 3
334+
335+@quotation
336+The type of an object with thread storage duration shall not have a
337+non-trivial destructor, nor shall it be an array type whose elements
338+(directly or indirectly) have non-trivial destructors.
339+@end quotation
340+
341+@item
342+@b{[basic.stc]}
343+
344+Add ``thread storage duration'' to the list in paragraph 1.
345+
346+Change paragraph 2
347+
348+@quotation
349+Thread, static, and automatic storage durations are associated with
350+objects introduced by declarations [@dots{}].
351+@end quotation
352+
353+Add @code{__thread} to the list of specifiers in paragraph 3.
354+
355+@item
356+@b{[basic.stc.thread]}
357+
358+New section before @b{[basic.stc.static]}
359+
360+@quotation
361+The keyword @code{__thread} applied to an non-local object gives the
362+object thread storage duration.
363+
364+A local variable or class data member declared both @code{static}
365+and @code{__thread} gives the variable or member thread storage
366+duration.
367+@end quotation
368+
369+@item
370+@b{[basic.stc.static]}
371+
372+Change paragraph 1
373+
374+@quotation
375+All objects which have neither thread storage duration, dynamic
376+storage duration nor are local [@dots{}].
377+@end quotation
378+
379+@item
380+@b{[dcl.stc]}
381+
382+Add @code{__thread} to the list in paragraph 1.
383+
384+Change paragraph 1
385+
386+@quotation
387+With the exception of @code{__thread}, at most one
388+@var{storage-class-specifier} shall appear in a given
389+@var{decl-specifier-seq}. The @code{__thread} specifier may
390+be used alone, or immediately following the @code{extern} or
391+@code{static} specifiers. [@dots{}]
392+@end quotation
393+
394+Add after paragraph 5
395+
396+@quotation
397+The @code{__thread} specifier can be applied only to the names of objects
398+and to anonymous unions.
399+@end quotation
400+
401+@item
402+@b{[class.mem]}
403+
404+Add after paragraph 6
405+
406+@quotation
407+Non-@code{static} members shall not be @code{__thread}.
408+@end quotation
409+@end itemize
410+
411 @node C++ Extensions
412 @chapter Extensions to the C++ Language
413 @cindex extensions, C++ language
414--- gcc/doc/invoke.texi.jj Tue May 21 20:27:44 2002
415+++ gcc/doc/invoke.texi Wed Jun 19 19:33:52 2002
416@@ -674,7 +674,7 @@ in the following sections.
417 -fverbose-asm -fpack-struct -fstack-check @gol
418 -fstack-limit-register=@var{reg} -fstack-limit-symbol=@var{sym} @gol
419 -fargument-alias -fargument-noalias @gol
420--fargument-noalias-global -fleading-underscore}
421+-fargument-noalias-global -fleading-underscore -ftls-model=@var{model}}
422 @end table
423
424 @menu
2ee7d7b3 425@@ -9988,6 +9988,14 @@
426 generate code that is not binary compatible with code generated without that
427 switch. Use it to conform to a non-default application binary interface.
428 Not all targets provide complete support for this switch.
5384b728 429+
430+@item -ftls-model=@var{model}
431+Alter the thread-local storage model to be used (@pxref{Thread-Local}).
432+The @var{model} argument should be one of @code{global-dynamic},
433+@code{local-dynamic}, @code{initial-exec} or @code{local-exec}.
2ee7d7b3 434+
5384b728 435+The default without @option{-fpic} is @code{initial-exec}; with
436+@option{-fpic} the default is @code{global-dynamic}.
437 @end table
438
439 @c man end
440--- gcc/config/i386/i386.c.jj Wed Jun 19 19:33:51 2002
441+++ gcc/config/i386/i386.c Wed Jun 19 23:18:18 2002
442@@ -536,6 +536,10 @@ int const svr4_dbx_register_map[FIRST_PS
443 rtx ix86_compare_op0 = NULL_RTX;
444 rtx ix86_compare_op1 = NULL_RTX;
445
446+/* The encoding characters for the four TLS models present in ELF. */
447+
448+static char const tls_model_chars[] = " GLil";
449+
450 #define MAX_386_STACK_LOCALS 3
451 /* Size of the register save area. */
452 #define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
453@@ -544,6 +548,7 @@ rtx ix86_compare_op1 = NULL_RTX;
454 struct machine_function
455 {
456 rtx stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
457+ const char *some_ld_name;
458 int save_varrargs_registers;
459 int accesses_prev_frame;
460 };
461@@ -596,6 +601,9 @@ enum cmodel ix86_cmodel;
462 /* Asm dialect. */
463 const char *ix86_asm_string;
464 enum asm_dialect ix86_asm_dialect = ASM_ATT;
465+/* TLS dialext. */
466+const char *ix86_tls_dialect_string;
467+enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
468
469 /* which cpu are we scheduling for */
470 enum processor_type ix86_cpu;
471@@ -646,12 +654,17 @@ static char internal_label_prefix[16];
472 static int internal_label_prefix_len;
473 \f
474 static int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
475+static int tls_symbolic_operand_1 PARAMS ((rtx, enum tls_model));
476 static void output_pic_addr_const PARAMS ((FILE *, rtx, int));
477 static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
478 int, int, FILE *));
479+static const char *get_some_local_dynamic_name PARAMS ((void));
480+static int get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
481+static rtx maybe_get_pool_constant PARAMS ((rtx));
482 static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx));
483 static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code,
484 rtx *, rtx *));
485+static rtx get_thread_pointer PARAMS ((void));
486 static rtx gen_push PARAMS ((rtx));
487 static int memory_address_length PARAMS ((rtx addr));
488 static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type));
489@@ -820,6 +833,11 @@ static enum x86_64_reg_class merge_class
490 #undef TARGET_SCHED_REORDER
491 #define TARGET_SCHED_REORDER ix86_sched_reorder
492
493+#ifdef HAVE_AS_TLS
494+#undef TARGET_HAVE_TLS
495+#define TARGET_HAVE_TLS true
496+#endif
497+
498 struct gcc_target targetm = TARGET_INITIALIZER;
499 \f
500 /* Sometimes certain combinations of command options do not make
501@@ -1109,6 +1127,17 @@ override_options ()
502 ix86_branch_cost = i;
503 }
504
505+ if (ix86_tls_dialect_string)
506+ {
507+ if (strcmp (ix86_tls_dialect_string, "gnu") == 0)
508+ ix86_tls_dialect = TLS_DIALECT_GNU;
509+ else if (strcmp (ix86_tls_dialect_string, "sun") == 0)
510+ ix86_tls_dialect = TLS_DIALECT_SUN;
511+ else
512+ error ("bad value (%s) for -mtls-dialect= switch",
513+ ix86_tls_dialect_string);
514+ }
515+
516 /* Keep nonleaf frame pointers. */
517 if (TARGET_OMIT_LEAF_FRAME_POINTER)
518 flag_omit_frame_pointer = 1;
519@@ -3007,6 +3036,70 @@ local_symbolic_operand (op, mode)
520 return 0;
521 }
522
523+/* Test for various thread-local symbols. See ix86_encode_section_info. */
524+
525+int
526+tls_symbolic_operand (op, mode)
527+ register rtx op;
528+ enum machine_mode mode ATTRIBUTE_UNUSED;
529+{
530+ const char *symbol_str;
531+
532+ if (GET_CODE (op) != SYMBOL_REF)
533+ return 0;
534+ symbol_str = XSTR (op, 0);
535+
536+ if (symbol_str[0] != '%')
537+ return 0;
538+ return strchr (tls_model_chars, symbol_str[1]) - tls_model_chars;
539+}
540+
541+static int
542+tls_symbolic_operand_1 (op, kind)
543+ rtx op;
544+ enum tls_model kind;
545+{
546+ const char *symbol_str;
547+
548+ if (GET_CODE (op) != SYMBOL_REF)
549+ return 0;
550+ symbol_str = XSTR (op, 0);
551+
552+ return symbol_str[0] == '%' && symbol_str[1] == tls_model_chars[kind];
553+}
554+
555+int
556+global_dynamic_symbolic_operand (op, mode)
557+ register rtx op;
558+ enum machine_mode mode ATTRIBUTE_UNUSED;
559+{
560+ return tls_symbolic_operand_1 (op, TLS_MODEL_GLOBAL_DYNAMIC);
561+}
562+
563+int
564+local_dynamic_symbolic_operand (op, mode)
565+ register rtx op;
566+ enum machine_mode mode ATTRIBUTE_UNUSED;
567+{
568+ return tls_symbolic_operand_1 (op, TLS_MODEL_LOCAL_DYNAMIC);
569+}
570+
571+int
572+initial_exec_symbolic_operand (op, mode)
573+ register rtx op;
574+ enum machine_mode mode ATTRIBUTE_UNUSED;
575+{
576+ return tls_symbolic_operand_1 (op, TLS_MODEL_INITIAL_EXEC);
577+}
578+
579+int
580+local_exec_symbolic_operand (op, mode)
581+ register rtx op;
582+ enum machine_mode mode ATTRIBUTE_UNUSED;
583+{
584+ return tls_symbolic_operand_1 (op, TLS_MODEL_LOCAL_EXEC);
585+}
586+
587 /* Test for a valid operand for a call instruction. Don't allow the
588 arg pointer register or virtual regs since they may decay into
589 reg + const, which the patterns can't handle. */
590@@ -3858,7 +3951,7 @@ ix86_asm_file_end (file)
591 {
592 rtx xops[2];
593
594- if (! TARGET_DEEP_BRANCH_PREDICTION || pic_label_name[0] == 0)
595+ if (pic_label_name[0] == 0)
596 return;
597
598 /* The trick here is to create a linkonce section containing the
599@@ -3896,17 +3989,33 @@ ix86_asm_file_end (file)
600 output_asm_insn ("ret", xops);
601 }
602
603-void
604-load_pic_register ()
605+/* Emit code for the SET_GOT patterns. */
606+
607+const char *
608+output_set_got (dest)
609+ rtx dest;
610 {
611- rtx gotsym, pclab;
612+ rtx xops[3];
613
614- if (TARGET_64BIT)
615- abort ();
616+ xops[0] = dest;
617+ xops[1] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
618+
619+ if (! TARGET_DEEP_BRANCH_PREDICTION || !flag_pic)
620+ {
621+ xops[2] = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
622+
623+ if (!flag_pic)
624+ output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
625+ else
626+ output_asm_insn ("call\t%a2", xops);
627
628- gotsym = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
629+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
630+ CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
631
632- if (TARGET_DEEP_BRANCH_PREDICTION)
633+ if (flag_pic)
634+ output_asm_insn ("pop{l}\t%0", xops);
635+ }
636+ else
637 {
638 if (! pic_label_name[0])
639 {
640@@ -3915,16 +4024,17 @@ load_pic_register ()
641 else
642 ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
643 }
644- pclab = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, pic_label_name));
645- }
646+ xops[2] = gen_rtx_SYMBOL_REF (Pmode, pic_label_name);
647+ xops[2] = gen_rtx_MEM (QImode, xops[2]);
648+ output_asm_insn ("call\t%X2", xops);
649+ }
650+
651+ if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION)
652+ output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops);
653 else
654- {
655- pclab = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
656- }
657-
658- emit_insn (gen_prologue_get_pc (pic_offset_table_rtx, pclab));
659-
660- emit_insn (gen_prologue_set_got (pic_offset_table_rtx, gotsym, pclab));
661+ output_asm_insn ("add{l}\t{%1+[.-%a2], %0|%0, %a1+(.-%a2)}", xops);
662+
663+ return "";
664 }
665
666 /* Generate an "push" pattern for input ARG. */
667@@ -4253,7 +4363,15 @@ ix86_expand_prologue ()
668 #endif
669
670 if (pic_reg_used)
671- load_pic_register ();
672+ {
673+ insn = emit_insn (gen_set_got (pic_offset_table_rtx));
674+
675+ /* ??? The current_function_uses_pic_offset_table flag is woefully
676+ inaccurate, as it isn't updated as code gets deleted. Allow the
677+ thing to be removed. A better solution would be to actually get
678+ proper liveness for ebx, as then we won't save/restore it too. */
679+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx, NULL);
680+ }
681
682 /* If we are profiling, make sure no instructions are scheduled before
683 the call to mcount. However, if -fpic, the above call will have
684@@ -4694,6 +4812,114 @@ ix86_find_base_term (x)
685 return term;
686 }
687 \f
688+/* Determine if a given RTX is a valid constant. We already know this
689+ satisfies CONSTANT_P. */
690+
691+bool
692+legitimate_constant_p (x)
693+ rtx x;
694+{
695+ rtx inner;
696+
697+ switch (GET_CODE (x))
698+ {
699+ case SYMBOL_REF:
700+ /* TLS symbols are not constant. */
701+ if (tls_symbolic_operand (x, Pmode))
702+ return false;
703+ break;
704+
705+ case CONST:
706+ inner = XEXP (x, 0);
707+
708+ /* Offsets of TLS symbols are never valid.
709+ Discourage CSE from creating them. */
710+ if (GET_CODE (inner) == PLUS
711+ && tls_symbolic_operand (XEXP (inner, 0), Pmode))
712+ return false;
713+
714+ /* Only some unspecs are valid as "constants". */
715+ if (GET_CODE (inner) == UNSPEC)
716+ switch (XINT (inner, 1))
717+ {
718+ case UNSPEC_TPOFF:
719+ return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
720+ case UNSPEC_TP:
721+ return true;
722+ default:
723+ return false;
724+ }
725+ break;
726+
727+ default:
728+ break;
729+ }
730+
731+ /* Otherwise we handle everything else in the move patterns. */
732+ return true;
733+}
734+
735+/* Determine if a given RTX is a valid constant address. */
736+
737+bool
738+constant_address_p (x)
739+ rtx x;
740+{
741+ switch (GET_CODE (x))
742+ {
743+ case LABEL_REF:
744+ case CONST_INT:
745+ return true;
746+
747+ case CONST_DOUBLE:
748+ return TARGET_64BIT;
749+
750+ case CONST:
751+ case SYMBOL_REF:
752+ return !flag_pic && legitimate_constant_p (x);
753+
754+ default:
755+ return false;
756+ }
757+}
758+
759+/* Nonzero if the constant value X is a legitimate general operand
760+ when generating PIC code. It is given that flag_pic is on and
761+ that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
762+
763+bool
764+legitimate_pic_operand_p (x)
765+ rtx x;
766+{
767+ rtx inner;
768+
769+ switch (GET_CODE (x))
770+ {
771+ case CONST:
772+ inner = XEXP (x, 0);
773+
774+ /* Only some unspecs are valid as "constants". */
775+ if (GET_CODE (inner) == UNSPEC)
776+ switch (XINT (inner, 1))
777+ {
778+ case UNSPEC_TPOFF:
779+ return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
780+ case UNSPEC_TP:
781+ return true;
782+ default:
783+ return false;
784+ }
785+ /* FALLTHRU */
786+
787+ case SYMBOL_REF:
788+ case LABEL_REF:
789+ return legitimate_pic_address_disp_p (x);
790+
791+ default:
792+ return true;
793+ }
794+}
795+
796 /* Determine if a given CONST RTX is a valid memory displacement
797 in PIC mode. */
798
799@@ -4701,6 +4927,8 @@ int
800 legitimate_pic_address_disp_p (disp)
801 register rtx disp;
802 {
803+ bool saw_plus;
804+
805 /* In 64bit mode we can allow direct addresses of symbols and labels
806 when they are not dynamic symbols. */
807 if (TARGET_64BIT)
808@@ -4737,25 +4965,39 @@ legitimate_pic_address_disp_p (disp)
809 return 1;
810 }
811
812+ saw_plus = false;
813 if (GET_CODE (disp) == PLUS)
814 {
815 if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
816 return 0;
817 disp = XEXP (disp, 0);
818+ saw_plus = true;
819 }
820
821 if (GET_CODE (disp) != UNSPEC
822 || XVECLEN (disp, 0) != 1)
823 return 0;
824
825- /* Must be @GOT or @GOTOFF. */
826 switch (XINT (disp, 1))
827 {
828- case 6: /* @GOT */
829+ case UNSPEC_GOT:
830+ if (saw_plus)
831+ return false;
832 return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
833-
834- case 7: /* @GOTOFF */
835+ case UNSPEC_GOTOFF:
836 return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
837+ case UNSPEC_GOTTPOFF:
838+ if (saw_plus)
839+ return false;
840+ return initial_exec_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
841+ case UNSPEC_NTPOFF:
842+ if (saw_plus)
843+ return false;
844+ return local_exec_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
845+ case UNSPEC_DTPOFF:
846+ if (saw_plus)
847+ return false;
848+ return local_dynamic_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
849 }
850
851 return 0;
852@@ -4882,12 +5124,6 @@ legitimate_address_p (mode, addr, strict
853 {
854 reason_rtx = disp;
855
856- if (!CONSTANT_ADDRESS_P (disp))
857- {
858- reason = "displacement is not constant";
859- goto report_error;
860- }
861-
862 if (TARGET_64BIT)
863 {
864 if (!x86_64_sign_extended_value (disp))
865@@ -4905,8 +5141,30 @@ legitimate_address_p (mode, addr, strict
866 }
867 }
868
869- if (flag_pic && SYMBOLIC_CONST (disp))
870+ if (GET_CODE (disp) == CONST
871+ && GET_CODE (XEXP (disp, 0)) == UNSPEC)
872+ switch (XINT (XEXP (disp, 0), 1))
873+ {
874+ case UNSPEC_GOT:
875+ case UNSPEC_GOTOFF:
876+ case UNSPEC_GOTPCREL:
877+ if (!flag_pic)
878+ abort ();
879+ goto is_legitimate_pic;
880+
881+ case UNSPEC_GOTTPOFF:
882+ case UNSPEC_NTPOFF:
883+ case UNSPEC_DTPOFF:
884+ break;
885+
886+ default:
887+ reason = "invalid address unspec";
888+ goto report_error;
889+ }
890+
891+ else if (flag_pic && SYMBOLIC_CONST (disp))
892 {
893+ is_legitimate_pic:
894 if (TARGET_64BIT && (index || base))
895 {
896 reason = "non-constant pic memory reference";
897@@ -4949,6 +5207,11 @@ legitimate_address_p (mode, addr, strict
898 goto report_error;
899 }
900 }
901+ else if (!CONSTANT_ADDRESS_P (disp))
902+ {
903+ reason = "displacement is not constant";
904+ goto report_error;
905+ }
906 }
907
908 /* Everything looks valid. */
909@@ -5129,7 +5392,102 @@ legitimize_pic_address (orig, reg)
910 }
911 return new;
912 }
913+
914+void
915+ix86_encode_section_info (decl)
916+ tree decl;
917+{
918+ bool local_p;
919+ rtx rtl, symbol;
920+
921+ rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
922+ if (GET_CODE (rtl) != MEM)
923+ return;
924+ symbol = XEXP (rtl, 0);
925+ if (GET_CODE (symbol) != SYMBOL_REF)
926+ return;
927+
928+ local_p = !DECL_P (decl) || !TREE_PUBLIC (decl) || MODULE_LOCAL_P (decl);
929+
930+ /* For basic x86, if using PIC, mark a SYMBOL_REF for a non-global
931+ symbol so that we may access it directly in the GOT. */
932+
933+ if (flag_pic)
934+ SYMBOL_REF_FLAG (symbol) = local_p;
935+
936+ /* For ELF, encode thread-local data with %[GLil] for "global dynamic",
937+ "local dynamic", "initial exec" or "local exec" TLS models
938+ respectively. */
939+
940+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
941+ {
942+ const char *symbol_str;
943+ char *newstr;
944+ size_t len;
945+ enum tls_model kind;
946+
947+ if (!flag_pic)
948+ {
949+ if (local_p)
950+ kind = TLS_MODEL_LOCAL_EXEC;
951+ else
952+ kind = TLS_MODEL_INITIAL_EXEC;
953+ }
954+ /* Local dynamic is inefficient when we're not combining the
955+ parts of the address. */
956+ else if (optimize && local_p)
957+ kind = TLS_MODEL_LOCAL_DYNAMIC;
958+ else
959+ kind = TLS_MODEL_GLOBAL_DYNAMIC;
960+ if (kind < flag_tls_default)
961+ kind = flag_tls_default;
962+
963+ symbol_str = XSTR (symbol, 0);
964+
965+ if (symbol_str[0] == '%')
966+ {
967+ if (symbol_str[1] == tls_model_chars[kind])
968+ return;
969+ symbol_str += 2;
970+ }
971+ len = strlen (symbol_str) + 1;
972+ newstr = alloca (len + 2);
973+
974+ newstr[0] = '%';
975+ newstr[1] = tls_model_chars[kind];
976+ memcpy (newstr + 2, symbol_str, len);
977+
978+ XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
979+ }
980+}
981+
982+/* Undo the above when printing symbol names. */
983+
984+const char *
985+ix86_strip_name_encoding (str)
986+ const char *str;
987+{
988+ if (str[0] == '%')
989+ str += 2;
990+ if (str [0] == '*')
991+ str += 1;
992+ return str;
993+}
994 \f
995+/* Load the thread pointer into a register. */
996+
997+static rtx
998+get_thread_pointer ()
999+{
1000+ rtx tp;
1001+
1002+ tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
1003+ tp = gen_rtx_CONST (Pmode, tp);
1004+ tp = force_reg (Pmode, tp);
1005+
1006+ return tp;
1007+}
1008+
1009 /* Try machine-dependent ways of modifying an illegitimate address
1010 to be legitimate. If we find one, return the new, valid address.
1011 This macro is used in only one place: `memory_address' in explow.c.
1012@@ -5167,6 +5525,84 @@ legitimize_address (x, oldx, mode)
1013 debug_rtx (x);
1014 }
1015
1016+ log = tls_symbolic_operand (x, mode);
1017+ if (log)
1018+ {
1019+ rtx dest, base, off, pic;
1020+
1021+ switch (log)
1022+ {
1023+ case TLS_MODEL_GLOBAL_DYNAMIC:
1024+ dest = gen_reg_rtx (Pmode);
1025+ emit_insn (gen_tls_global_dynamic (dest, x));
1026+ break;
1027+
1028+ case TLS_MODEL_LOCAL_DYNAMIC:
1029+ base = gen_reg_rtx (Pmode);
1030+ emit_insn (gen_tls_local_dynamic_base (base));
1031+
1032+ off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
1033+ off = gen_rtx_CONST (Pmode, off);
1034+
1035+ return gen_rtx_PLUS (Pmode, base, off);
1036+
1037+ case TLS_MODEL_INITIAL_EXEC:
1038+ if (flag_pic)
1039+ {
1040+ current_function_uses_pic_offset_table = 1;
1041+ pic = pic_offset_table_rtx;
1042+ }
1043+ else
1044+ {
1045+ pic = gen_reg_rtx (Pmode);
1046+ emit_insn (gen_set_got (pic));
1047+ }
1048+
1049+ base = get_thread_pointer ();
1050+
1051+ off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_GOTTPOFF);
1052+ off = gen_rtx_CONST (Pmode, off);
1053+ off = gen_rtx_PLUS (Pmode, pic, off);
1054+ off = gen_rtx_MEM (Pmode, off);
1055+ RTX_UNCHANGING_P (off) = 1;
1056+ set_mem_alias_set (off, ix86_GOT_alias_set ());
1057+
1058+ /* Damn Sun for specifing a set of dynamic relocations without
1059+ considering the two-operand nature of the architecture!
1060+ We'd be much better off with a "GOTNTPOFF" relocation that
1061+ already contained the negated constant. */
1062+ /* ??? Using negl and reg+reg addressing appears to be a lose
1063+ size-wise. The negl is two bytes, just like the extra movl
1064+ incurred by the two-operand subl, but reg+reg addressing
1065+ uses the two-byte modrm form, unlike plain reg. */
1066+
1067+ dest = gen_reg_rtx (Pmode);
1068+ emit_insn (gen_subsi3 (dest, base, off));
1069+ break;
1070+
1071+ case TLS_MODEL_LOCAL_EXEC:
1072+ base = get_thread_pointer ();
1073+
1074+ off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
1075+ TARGET_GNU_TLS ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
1076+ off = gen_rtx_CONST (Pmode, off);
1077+
1078+ if (TARGET_GNU_TLS)
1079+ return gen_rtx_PLUS (Pmode, base, off);
1080+ else
1081+ {
1082+ dest = gen_reg_rtx (Pmode);
1083+ emit_insn (gen_subsi3 (dest, base, off));
1084+ }
1085+ break;
1086+
1087+ default:
1088+ abort ();
1089+ }
1090+
1091+ return dest;
1092+ }
1093+
1094 if (flag_pic && SYMBOLIC_CONST (x))
1095 return legitimize_pic_address (x, 0);
1096
1097@@ -5410,18 +5846,30 @@ output_pic_addr_const (file, x, code)
1098 output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
1099 switch (XINT (x, 1))
1100 {
1101- case 6:
1102+ case UNSPEC_GOT:
1103 fputs ("@GOT", file);
1104 break;
1105- case 7:
1106+ case UNSPEC_GOTOFF:
1107 fputs ("@GOTOFF", file);
1108 break;
1109- case 8:
1110+ case UNSPEC_PLT:
1111 fputs ("@PLT", file);
1112 break;
1113- case 15:
1114+ case UNSPEC_GOTPCREL:
1115 fputs ("@GOTPCREL(%RIP)", file);
1116 break;
1117+ case UNSPEC_GOTTPOFF:
1118+ fputs ("@GOTTPOFF", file);
1119+ break;
1120+ case UNSPEC_TPOFF:
1121+ fputs ("@TPOFF", file);
1122+ break;
1123+ case UNSPEC_NTPOFF:
1124+ fputs ("@NTPOFF", file);
1125+ break;
1126+ case UNSPEC_DTPOFF:
1127+ fputs ("@DTPOFF", file);
1128+ break;
1129 default:
1130 output_operand_lossage ("invalid UNSPEC as operand");
1131 break;
1132@@ -5710,6 +6158,43 @@ print_reg (x, code, file)
1133 }
1134 }
1135
1136+/* Locate some local-dynamic symbol still in use by this function
1137+ so that we can print its name in some tls_local_dynamic_base
1138+ pattern. */
1139+
1140+static const char *
1141+get_some_local_dynamic_name ()
1142+{
1143+ rtx insn;
1144+
1145+ if (cfun->machine->some_ld_name)
1146+ return cfun->machine->some_ld_name;
1147+
1148+ for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1149+ if (INSN_P (insn)
1150+ && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
1151+ return cfun->machine->some_ld_name;
1152+
1153+ abort ();
1154+}
1155+
1156+static int
1157+get_some_local_dynamic_name_1 (px, data)
1158+ rtx *px;
1159+ void *data ATTRIBUTE_UNUSED;
1160+{
1161+ rtx x = *px;
1162+
1163+ if (GET_CODE (x) == SYMBOL_REF
1164+ && local_dynamic_symbolic_operand (x, Pmode))
1165+ {
1166+ cfun->machine->some_ld_name = XSTR (x, 0);
1167+ return 1;
1168+ }
1169+
1170+ return 0;
1171+}
1172+
1173 /* Meaning of CODE:
1174 L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
1175 C -- print opcode suffix for set/cmov insn.
1176@@ -5734,6 +6219,7 @@ print_reg (x, code, file)
1177 D -- print condition for SSE cmp instruction.
1178 P -- if PIC, print an @PLT suffix.
1179 X -- don't print any sort of PIC '@' suffix for a symbol.
1180+ & -- print some in-use local-dynamic symbol name.
1181 */
1182
1183 void
1184@@ -5751,6 +6237,10 @@ print_operand (file, x, code)
1185 putc ('*', file);
1186 return;
1187
1188+ case '&':
1189+ assemble_name (file, get_some_local_dynamic_name ());
1190+ return;
1191+
1192 case 'A':
1193 if (ASSEMBLER_DIALECT == ASM_ATT)
1194 putc ('*', file);
1195@@ -6078,6 +6568,18 @@ print_operand (file, x, code)
1196 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
1197 fprintf (file, "%s", dstr);
1198 }
1199+
1200+ else if (GET_CODE (x) == CONST
1201+ && GET_CODE (XEXP (x, 0)) == UNSPEC
1202+ && XINT (XEXP (x, 0), 1) == UNSPEC_TP)
1203+ {
1204+ if (ASSEMBLER_DIALECT == ASM_INTEL)
1205+ fputs ("DWORD PTR ", file);
1206+ if (ASSEMBLER_DIALECT == ASM_ATT || USER_LABEL_PREFIX[0] == 0)
1207+ putc ('%', file);
1208+ fputs ("gs:0", file);
1209+ }
1210+
1211 else
1212 {
1213 if (code != 'P')
1214@@ -6226,6 +6728,43 @@ print_operand_address (file, addr)
1215 }
1216 }
1217 }
1218+
1219+bool
1220+output_addr_const_extra (file, x)
1221+ FILE *file;
1222+ rtx x;
1223+{
1224+ rtx op;
1225+
1226+ if (GET_CODE (x) != UNSPEC)
1227+ return false;
1228+
1229+ op = XVECEXP (x, 0, 0);
1230+ switch (XINT (x, 1))
1231+ {
1232+ case UNSPEC_GOTTPOFF:
1233+ output_addr_const (file, op);
1234+ fputs ("@GOTTPOFF", file);
1235+ break;
1236+ case UNSPEC_TPOFF:
1237+ output_addr_const (file, op);
1238+ fputs ("@TPOFF", file);
1239+ break;
1240+ case UNSPEC_NTPOFF:
1241+ output_addr_const (file, op);
1242+ fputs ("@NTPOFF", file);
1243+ break;
1244+ case UNSPEC_DTPOFF:
1245+ output_addr_const (file, op);
1246+ fputs ("@DTPOFF", file);
1247+ break;
1248+
1249+ default:
1250+ return false;
1251+ }
1252+
1253+ return true;
1254+}
1255 \f
1256 /* Split one or more DImode RTL references into pairs of SImode
1257 references. The RTL can be REG, offsettable MEM, integer constant, or
1258@@ -6763,51 +7302,117 @@ ix86_expand_clear (dest)
1259 emit_insn (tmp);
1260 }
1261
1262+/* X is an unchanging MEM. If it is a constant pool reference, return
1263+ the constant pool rtx, else NULL. */
1264+
1265+static rtx
1266+maybe_get_pool_constant (x)
1267+ rtx x;
1268+{
1269+ x = XEXP (x, 0);
1270+
1271+ if (flag_pic)
1272+ {
1273+ if (GET_CODE (x) != PLUS)
1274+ return NULL_RTX;
1275+ if (XEXP (x, 0) != pic_offset_table_rtx)
1276+ return NULL_RTX;
1277+ x = XEXP (x, 1);
1278+ if (GET_CODE (x) != CONST)
1279+ return NULL_RTX;
1280+ x = XEXP (x, 0);
1281+ if (GET_CODE (x) != UNSPEC)
1282+ return NULL_RTX;
1283+ if (XINT (x, 1) != UNSPEC_GOTOFF)
1284+ return NULL_RTX;
1285+ x = XVECEXP (x, 0, 0);
1286+ }
1287+
1288+ if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
1289+ return get_pool_constant (x);
1290+
1291+ return NULL_RTX;
1292+}
1293+
1294 void
1295 ix86_expand_move (mode, operands)
1296 enum machine_mode mode;
1297 rtx operands[];
1298 {
1299 int strict = (reload_in_progress || reload_completed);
1300- rtx insn;
1301+ rtx insn, op0, op1, tmp;
1302+
1303+ op0 = operands[0];
1304+ op1 = operands[1];
1305
1306- if (flag_pic && mode == Pmode && symbolic_operand (operands[1], Pmode))
1307+ /* ??? We have a slight problem. We need to say that tls symbols are
1308+ not legitimate constants so that reload does not helpfully reload
1309+ these constants from a REG_EQUIV, which we cannot handle. (Recall
1310+ that general- and local-dynamic address resolution requires a
1311+ function call.)
1312+
1313+ However, if we say that tls symbols are not legitimate constants,
1314+ then emit_move_insn helpfully drop them into the constant pool.
1315+
1316+ It is far easier to work around emit_move_insn than reload. Recognize
1317+ the MEM that we would have created and extract the symbol_ref. */
1318+
1319+ if (mode == Pmode
1320+ && GET_CODE (op1) == MEM
1321+ && RTX_UNCHANGING_P (op1))
1322 {
1323- /* Emit insns to move operands[1] into operands[0]. */
1324+ tmp = maybe_get_pool_constant (op1);
1325+ /* Note that we only care about symbolic constants here, which
1326+ unlike CONST_INT will always have a proper mode. */
1327+ if (tmp && GET_MODE (tmp) == Pmode)
1328+ op1 = tmp;
1329+ }
1330
1331- if (GET_CODE (operands[0]) == MEM)
1332- operands[1] = force_reg (Pmode, operands[1]);
1333+ if (tls_symbolic_operand (op1, Pmode))
1334+ {
1335+ op1 = legitimize_address (op1, op1, VOIDmode);
1336+ if (GET_CODE (op0) == MEM)
1337+ {
1338+ tmp = gen_reg_rtx (mode);
1339+ emit_insn (gen_rtx_SET (VOIDmode, tmp, op1));
1340+ op1 = tmp;
1341+ }
1342+ }
1343+ else if (flag_pic && mode == Pmode && symbolic_operand (op1, Pmode))
1344+ {
1345+ if (GET_CODE (op0) == MEM)
1346+ op1 = force_reg (Pmode, op1);
1347 else
1348 {
1349- rtx temp = operands[0];
1350+ rtx temp = op0;
1351 if (GET_CODE (temp) != REG)
1352 temp = gen_reg_rtx (Pmode);
1353- temp = legitimize_pic_address (operands[1], temp);
1354- if (temp == operands[0])
1355+ temp = legitimize_pic_address (op1, temp);
1356+ if (temp == op0)
1357 return;
1358- operands[1] = temp;
1359+ op1 = temp;
1360 }
1361 }
1362 else
1363 {
1364- if (GET_CODE (operands[0]) == MEM
1365+ if (GET_CODE (op0) == MEM
1366 && (PUSH_ROUNDING (GET_MODE_SIZE (mode)) != GET_MODE_SIZE (mode)
1367- || !push_operand (operands[0], mode))
1368- && GET_CODE (operands[1]) == MEM)
1369- operands[1] = force_reg (mode, operands[1]);
1370-
1371- if (push_operand (operands[0], mode)
1372- && ! general_no_elim_operand (operands[1], mode))
1373- operands[1] = copy_to_mode_reg (mode, operands[1]);
1374+ || !push_operand (op0, mode))
1375+ && GET_CODE (op1) == MEM)
1376+ op1 = force_reg (mode, op1);
1377+
1378+ if (push_operand (op0, mode)
1379+ && ! general_no_elim_operand (op1, mode))
1380+ op1 = copy_to_mode_reg (mode, op1);
1381
1382 /* Force large constants in 64bit compilation into register
1383 to get them CSEed. */
1384 if (TARGET_64BIT && mode == DImode
1385- && immediate_operand (operands[1], mode)
1386- && !x86_64_zero_extended_value (operands[1])
1387- && !register_operand (operands[0], mode)
1388+ && immediate_operand (op1, mode)
1389+ && !x86_64_zero_extended_value (op1)
1390+ && !register_operand (op0, mode)
1391 && optimize && !reload_completed && !reload_in_progress)
1392- operands[1] = copy_to_mode_reg (mode, operands[1]);
1393+ op1 = copy_to_mode_reg (mode, op1);
1394
1395 if (FLOAT_MODE_P (mode))
1396 {
1397@@ -6817,13 +7422,13 @@ ix86_expand_move (mode, operands)
1398
1399 if (strict)
1400 ;
1401- else if (GET_CODE (operands[1]) == CONST_DOUBLE
1402- && register_operand (operands[0], mode))
1403- operands[1] = validize_mem (force_const_mem (mode, operands[1]));
1404+ else if (GET_CODE (op1) == CONST_DOUBLE
1405+ && register_operand (op0, mode))
1406+ op1 = validize_mem (force_const_mem (mode, op1));
1407 }
1408 }
1409
1410- insn = gen_rtx_SET (VOIDmode, operands[0], operands[1]);
1411+ insn = gen_rtx_SET (VOIDmode, op0, op1);
1412
1413 emit_insn (insn);
1414 }
1415@@ -8588,13 +9193,14 @@ ix86_split_to_parts (operand, parts, mod
1416 if (size < 2 || size > 3)
1417 abort ();
1418
1419- /* Optimize constant pool reference to immediates. This is used by fp moves,
1420- that force all constants to memory to allow combining. */
1421-
1422- if (GET_CODE (operand) == MEM
1423- && GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
1424- && CONSTANT_POOL_ADDRESS_P (XEXP (operand, 0)))
1425- operand = get_pool_constant (XEXP (operand, 0));
1426+ /* Optimize constant pool reference to immediates. This is used by fp
1427+ moves, that force all constants to memory to allow combining. */
1428+ if (GET_CODE (operand) == MEM && RTX_UNCHANGING_P (operand))
1429+ {
1430+ rtx tmp = maybe_get_pool_constant (operand);
1431+ if (tmp)
1432+ operand = tmp;
1433+ }
1434
1435 if (GET_CODE (operand) == MEM && !offsettable_memref_p (operand))
1436 {
1437@@ -9790,6 +10396,55 @@ ix86_expand_strlensi_unroll_1 (out, alig
1438
1439 emit_label (end_0_label);
1440 }
1441+
1442+void
1443+ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
1444+ rtx retval, fnaddr, callarg1, callarg2, pop;
1445+{
1446+ rtx use = NULL, call;
1447+
1448+ if (pop == const0_rtx)
1449+ pop = NULL;
1450+ if (TARGET_64BIT && pop)
1451+ abort ();
1452+
1453+ /* Static functions and indirect calls don't need the pic register. */
1454+ if (! TARGET_64BIT && flag_pic
1455+ && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
1456+ && ! SYMBOL_REF_FLAG (XEXP (fnaddr, 0)))
1457+ {
1458+ current_function_uses_pic_offset_table = 1;
1459+ use_reg (&use, pic_offset_table_rtx);
1460+ }
1461+
1462+ if (TARGET_64BIT && INTVAL (callarg2) >= 0)
1463+ {
1464+ rtx al = gen_rtx_REG (QImode, 0);
1465+ emit_move_insn (al, callarg2);
1466+ use_reg (&use, al);
1467+ }
1468+
1469+ if (! call_insn_operand (XEXP (fnaddr, 0), Pmode))
1470+ {
1471+ fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
1472+ fnaddr = gen_rtx_MEM (QImode, fnaddr);
1473+ }
1474+
1475+ call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
1476+ if (retval)
1477+ call = gen_rtx_SET (VOIDmode, retval, call);
1478+ if (pop)
1479+ {
1480+ pop = gen_rtx_PLUS (Pmode, stack_pointer_rtx, pop);
1481+ pop = gen_rtx_SET (VOIDmode, stack_pointer_rtx, pop);
1482+ call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, call, pop));
1483+ }
1484+
1485+ call = emit_call_insn (call);
1486+ if (use)
1487+ CALL_INSN_FUNCTION_USAGE (call) = use;
1488+}
1489+
1490 \f
1491 /* Clear stack slot assignments remembered from previous functions.
1492 This is called from INIT_EXPANDERS once before RTL is emitted for each
1493@@ -9849,6 +10504,24 @@ assign_386_stack_local (mode, n)
1494
1495 return ix86_stack_locals[(int) mode][n];
1496 }
1497+
1498+/* Construct the SYMBOL_REF for the tls_get_addr function. */
1499+
1500+rtx
1501+ix86_tls_get_addr ()
1502+{
1503+ static rtx symbol;
1504+
1505+ if (!symbol)
1506+ {
1507+ symbol = gen_rtx_SYMBOL_REF (Pmode, (TARGET_GNU_TLS
1508+ ? "___tls_get_addr"
1509+ : "__tls_get_addr"));
1510+ ggc_add_rtx_root (&symbol, 1);
1511+ }
1512+
1513+ return symbol;
1514+}
1515 \f
1516 /* Calculate the length of the memory address in the instruction
1517 encoding. Does not include the one-byte modrm, opcode, or prefix. */
1518--- gcc/config/i386/i386-protos.h.jj Wed Jun 19 15:18:02 2002
1519+++ gcc/config/i386/i386-protos.h Wed Jun 19 19:33:52 2002
1520@@ -28,7 +28,6 @@ extern int ix86_frame_pointer_required P
1521 extern void ix86_setup_frame_addresses PARAMS ((void));
1522
1523 extern void ix86_asm_file_end PARAMS ((FILE *));
1524-extern void load_pic_register PARAMS ((void));
1525 extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
1526 extern void ix86_expand_prologue PARAMS ((void));
1527 extern void ix86_expand_epilogue PARAMS ((int));
1528@@ -36,6 +35,9 @@ extern void ix86_expand_epilogue PARAMS
1529 extern void ix86_output_addr_vec_elt PARAMS ((FILE *, int));
1530 extern void ix86_output_addr_diff_elt PARAMS ((FILE *, int, int));
1531
1532+extern void ix86_encode_section_info PARAMS ((tree));
1533+extern const char *ix86_strip_name_encoding PARAMS ((const char *));
1534+
1535 #ifdef RTX_CODE
1536 extern int ix86_aligned_p PARAMS ((rtx));
1537
1538@@ -51,6 +53,11 @@ extern int x86_64_immediate_operand PARA
1539 extern int x86_64_zext_immediate_operand PARAMS ((rtx, enum machine_mode));
1540 extern int const_int_1_operand PARAMS ((rtx, enum machine_mode));
1541 extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
1542+extern int tls_symbolic_operand PARAMS ((rtx, enum machine_mode));
1543+extern int global_dynamic_symbolic_operand PARAMS ((rtx, enum machine_mode));
1544+extern int local_dynamic_symbolic_operand PARAMS ((rtx, enum machine_mode));
1545+extern int initial_exec_symbolic_operand PARAMS ((rtx, enum machine_mode));
1546+extern int local_exec_symbolic_operand PARAMS ((rtx, enum machine_mode));
1547 extern int pic_symbolic_operand PARAMS ((rtx, enum machine_mode));
1548 extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
1549 extern int constant_call_address_operand PARAMS ((rtx, enum machine_mode));
1550@@ -84,6 +91,9 @@ extern int ix86_expand_movstr PARAMS ((r
1551 extern int ix86_expand_clrstr PARAMS ((rtx, rtx, rtx));
1552 extern int ix86_expand_strlen PARAMS ((rtx, rtx, rtx, rtx));
1553
1554+extern bool legitimate_constant_p PARAMS ((rtx));
1555+extern bool constant_address_p PARAMS ((rtx));
1556+extern bool legitimate_pic_operand_p PARAMS ((rtx));
1557 extern int legitimate_pic_address_disp_p PARAMS ((rtx));
1558 extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
1559 extern rtx legitimize_pic_address PARAMS ((rtx, rtx));
1560@@ -92,10 +102,12 @@ extern rtx legitimize_address PARAMS ((r
1561 extern void print_reg PARAMS ((rtx, int, FILE*));
1562 extern void print_operand PARAMS ((FILE*, rtx, int));
1563 extern void print_operand_address PARAMS ((FILE*, rtx));
1564+extern bool output_addr_const_extra PARAMS ((FILE*, rtx));
1565
1566 extern void split_di PARAMS ((rtx[], int, rtx[], rtx[]));
1567 extern void split_ti PARAMS ((rtx[], int, rtx[], rtx[]));
1568
1569+extern const char *output_set_got PARAMS ((rtx));
1570 extern const char *output_387_binary_op PARAMS ((rtx, rtx*));
1571 extern const char *output_fix_trunc PARAMS ((rtx, rtx*));
1572 extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int));
1573@@ -121,6 +133,7 @@ extern void ix86_expand_branch PARAMS ((
1574 extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
1575 extern int ix86_expand_int_movcc PARAMS ((rtx[]));
1576 extern int ix86_expand_fp_movcc PARAMS ((rtx[]));
1577+extern void ix86_expand_call PARAMS ((rtx, rtx, rtx, rtx, rtx));
1578 extern void x86_initialize_trampoline PARAMS ((rtx, rtx, rtx));
1579 extern rtx ix86_zero_extend_to_Pmode PARAMS ((rtx));
1580 extern void ix86_split_long_move PARAMS ((rtx[]));
1581@@ -181,6 +194,8 @@ extern rtx ix86_expand_builtin PARAMS ((
1582
1583 #endif
1584
1585+extern rtx ix86_tls_get_addr PARAMS ((void));
1586+
1587 #ifdef TREE_CODE
1588 extern int ix86_return_pops_args PARAMS ((tree, tree, int));
1589 extern tree ix86_build_va_list PARAMS ((void));
1590--- gcc/config/i386/i386.h.jj Wed Jun 19 19:33:51 2002
1591+++ gcc/config/i386/i386.h Wed Jun 19 20:20:56 2002
1592@@ -282,6 +282,9 @@ extern int x86_prefetch_sse;
1593
1594 #define TARGET_RED_ZONE (!(target_flags & MASK_NO_RED_ZONE))
1595
1596+#define TARGET_GNU_TLS (ix86_tls_dialect == TLS_DIALECT_GNU)
1597+#define TARGET_SUN_TLS (ix86_tls_dialect == TLS_DIALECT_SUN)
1598+
1599 /* WARNING: Do not mark empty strings for translation, as calling
1600 gettext on an empty string does NOT return an empty
1601 string. */
1602@@ -451,6 +454,8 @@ extern int ix86_arch;
1603 "" /* Undocumented. */ }, \
1604 { "asm=", &ix86_asm_string, \
1605 N_("Use given assembler dialect") }, \
1606+ { "tls-dialect=", &ix86_tls_dialect_string, \
1607+ N_("Use given thread-local storage dialect") }, \
1608 SUBTARGET_OPTIONS \
1609 }
1610
1611@@ -1934,15 +1939,12 @@ do { \
1612
1613 #define MAX_REGS_PER_ADDRESS 2
1614
1615-#define CONSTANT_ADDRESS_P(X) \
1616- (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
1617- || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
1618- || GET_CODE (X) == CONST_DOUBLE)
1619+#define CONSTANT_ADDRESS_P(X) constant_address_p (X)
1620
1621 /* Nonzero if the constant value X is a legitimate general operand.
1622 It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
1623
1624-#define LEGITIMATE_CONSTANT_P(X) 1
1625+#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
1626
1627 #ifdef REG_OK_STRICT
1628 #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
1629@@ -2005,9 +2007,7 @@ do { \
1630 when generating PIC code. It is given that flag_pic is on and
1631 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
1632
1633-#define LEGITIMATE_PIC_OPERAND_P(X) \
1634- (! SYMBOLIC_CONST (X) \
1635- || legitimate_pic_address_disp_p (X))
1636+#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
1637
1638 #define SYMBOLIC_CONST(X) \
1639 (GET_CODE (X) == SYMBOL_REF \
1640@@ -2251,33 +2251,23 @@ enum ix86_builtins
1641 On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol
1642 so that we may access it directly in the GOT. */
1643
1644-#define ENCODE_SECTION_INFO(DECL) \
1645-do { \
1646- if (flag_pic) \
1647- { \
1648- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
1649- ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \
1650- \
1651- if (GET_CODE (rtl) == MEM) \
1652- { \
1653- if (TARGET_DEBUG_ADDR \
1654- && TREE_CODE_CLASS (TREE_CODE (DECL)) == 'd') \
1655- { \
1656- fprintf (stderr, "Encode %s, public = %d\n", \
1657- IDENTIFIER_POINTER (DECL_NAME (DECL)), \
1658- TREE_PUBLIC (DECL)); \
1659- } \
1660- \
1661- SYMBOL_REF_FLAG (XEXP (rtl, 0)) \
1662- = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
1663- || ! TREE_PUBLIC (DECL) \
1664- || MODULE_LOCAL_P (DECL)); \
1665- } \
1666- } \
1667-} while (0)
1668-
1669+#define ENCODE_SECTION_INFO(DECL) ix86_encode_section_info(DECL)
1670 #define REDO_SECTION_INFO_P(DECL) 1
1671
1672+#define STRIP_NAME_ENCODING(VAR,STR) ((VAR) = ix86_strip_name_encoding (STR))
1673+
1674+#define ASM_OUTPUT_LABELREF(FILE,NAME) \
1675+ do { \
1676+ const char *xname = (NAME); \
1677+ if (xname[0] == '%') \
1678+ xname += 2; \
1679+ if (xname[0] == '*') \
1680+ xname += 1; \
1681+ else \
1682+ fputs (user_label_prefix, FILE); \
1683+ fputs (xname, FILE); \
1684+ } while (0)
1685+
1686 /* The `FINALIZE_PIC' macro serves as a hook to emit these special
1687 codes once the function is being compiled into assembly code, but
1688 not before. (It is not done before, because in the case of
1689@@ -2923,7 +2913,7 @@ extern int const svr4_dbx_register_map[F
1690 print_operand function. */
1691
1692 #define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
1693- ((CODE) == '*' || (CODE) == '+')
1694+ ((CODE) == '*' || (CODE) == '+' || (CODE) == '&')
1695
1696 /* Print the name of a register based on its machine mode and number.
1697 If CODE is 'w', pretend the mode is HImode.
1698@@ -2942,6 +2932,12 @@ extern int const svr4_dbx_register_map[F
1699 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
1700 print_operand_address ((FILE), (ADDR))
1701
1702+#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \
1703+do { \
1704+ if (! output_addr_const_extra (FILE, (X))) \
1705+ goto FAIL; \
1706+} while (0);
1707+
1708 /* Print the name of a register for based on its machine mode and number.
1709 This macro is used to print debugging output.
1710 This macro is different from PRINT_REG in that it may be used in
1711@@ -3071,7 +3067,12 @@ extern int const svr4_dbx_register_map[F
1712 {"memory_displacement_operand", {MEM}}, \
1713 {"cmpsi_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
1714 LABEL_REF, SUBREG, REG, MEM, AND}}, \
1715- {"long_memory_operand", {MEM}},
1716+ {"long_memory_operand", {MEM}}, \
1717+ {"tls_symbolic_operand", {SYMBOL_REF}}, \
1718+ {"global_dynamic_symbolic_operand", {SYMBOL_REF}}, \
1719+ {"local_dynamic_symbolic_operand", {SYMBOL_REF}}, \
1720+ {"initial_exec_symbolic_operand", {SYMBOL_REF}}, \
1721+ {"local_exec_symbolic_operand", {SYMBOL_REF}},
1722
1723 /* A list of predicates that do special things with modes, and so
1724 should not elicit warnings for VOIDmode match_operand. */
1725@@ -3112,6 +3113,16 @@ enum asm_dialect {
1726 };
1727 extern const char *ix86_asm_string;
1728 extern enum asm_dialect ix86_asm_dialect;
1729+
1730+enum tls_dialect
1731+{
1732+ TLS_DIALECT_GNU,
1733+ TLS_DIALECT_SUN
1734+};
1735+
1736+extern enum tls_dialect ix86_tls_dialect;
1737+extern const char *ix86_tls_dialect_string;
1738+
1739 /* Value of -mcmodel specified by user. */
1740 extern const char *ix86_cmodel_string;
1741 extern enum cmodel ix86_cmodel;
1742--- gcc/config/i386/i386.md.jj Tue Jun 4 20:28:36 2002
1743+++ gcc/config/i386/i386.md Wed Jun 19 19:33:52 2002
1744@@ -49,55 +49,59 @@
1745 ;; 'k' Likewise, print the SImode name of the register.
1746 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
1747 ;; 'y' Print "st(0)" instead of "st" as a register.
1748-;;
1749+
1750 ;; UNSPEC usage:
1751-;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode.
1752-;; operand 0 is the memory address to scan.
1753-;; operand 1 is a register containing the value to scan for. The mode
1754-;; of the scas opcode will be the same as the mode of this operand.
1755-;; operand 2 is the known alignment of operand 0.
1756-;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.
1757-;; operand 0 is the argument for `sin'.
1758-;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.
1759-;; operand 0 is the argument for `cos'.
1760-;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is
1761-;; always SImode. operand 0 is the size of the stack allocation.
1762-;; 4 This is the source of a fake SET of the frame pointer which is used to
1763-;; prevent insns referencing it being scheduled across the initial
1764-;; decrement of the stack pointer.
1765-;; 5 This is a `bsf' operation.
1766-;; 6 This is the @GOT offset of a PIC address.
1767-;; 7 This is the @GOTOFF offset of a PIC address.
1768-;; 8 This is a reference to a symbol's @PLT address.
1769-;; 9 This is an `fnstsw' operation.
1770-;; 10 This is a `sahf' operation.
1771-;; 11 This is a `fstcw' operation
1772-;; 12 This is behaviour of add when setting carry flag.
1773-;; 13 This is a `eh_return' placeholder.
1774-
1775-;; For SSE/MMX support:
1776-;; 30 This is `fix', guaranteed to be truncating.
1777-;; 31 This is a `emms' operation.
1778-;; 32 This is a `maskmov' operation.
1779-;; 33 This is a `movmsk' operation.
1780-;; 34 This is a `non-temporal' move.
1781-;; 36 This is used to distinguish COMISS from UCOMISS.
1782-;; 37 This is a `ldmxcsr' operation.
1783-;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
1784-;; 39 This is a forced `movups' instruction (rather than whatever movti does)
1785-;; 40 This is a `stmxcsr' operation.
1786-;; 41 This is a `shuffle' operation.
1787-;; 42 This is a `rcp' operation.
1788-;; 43 This is a `rsqsrt' operation.
1789-;; 44 This is a `sfence' operation.
1790-;; 45 This is a noop to prevent excessive combiner cleverness.
1791-;; 46 This is a `femms' operation.
1792-;; 49 This is a 'pavgusb' operation.
1793-;; 50 This is a `pfrcp' operation.
1794-;; 51 This is a `pfrcpit1' operation.
1795-;; 52 This is a `pfrcpit2' operation.
1796-;; 53 This is a `pfrsqrt' operation.
1797-;; 54 This is a `pfrsqrit1' operation.
1798+;; ??? Note that the 3.1 branch, unlike mainline, has not had all
1799+;; of the uses of UNSPEC replaced with their symbolic constants.
1800+;; Thus you cannot change these arbitrarily without pain.
1801+
1802+(define_constants
1803+ [(UNSPEC_SCAS 0)
1804+ (UNSPEC_SIN 1)
1805+ (UNSPEC_COS 2)
1806+ (UNSPEC_STACK_PROBE 3)
1807+ (UNSPEC_STACK_ALLOC 4)
1808+ (UNSPEC_BSF 5)
1809+ (UNSPEC_GOT 6)
1810+ (UNSPEC_GOTOFF 7)
1811+ (UNSPEC_PLT 8)
1812+ (UNSPEC_FNSTSW 9)
1813+ (UNSPEC_SAHF 10)
1814+ (UNSPEC_FSTCW 11)
1815+ (UNSPEC_FLDCW 12)
1816+ (UNSPEC_ADD_CARRY 12)
1817+ (UNSPEC_EH_RETURN 13)
1818+ (UNSPEC_GOTPCREL 15)
1819+ (UNSPEC_SET_GOT 16)
1820+
1821+ ; For TLS support:
1822+ (UNSPEC_GOTTPOFF 20)
1823+ (UNSPEC_TPOFF 21)
1824+ (UNSPEC_NTPOFF 22)
1825+ (UNSPEC_DTPOFF 23)
1826+ (UNSPEC_TP 24)
1827+ (UNSPEC_TLS_GD 25)
1828+ (UNSPEC_TLS_LD_BASE 26)
1829+
1830+ ; For SSE/MMX support:
1831+ (UNSPEC_FIX 30)
1832+ (UNSPEC_MASKMOV 32)
1833+ (UNSPEC_MOVMSK 33)
1834+ (UNSPEC_MOVNT 34)
1835+ (UNSPEC_MOVA 38)
1836+ (UNSPEC_MOVU 39)
1837+ (UNSPEC_SHUFFLE 41)
1838+ (UNSPEC_RCP 42)
1839+ (UNSPEC_RSQRT 43)
1840+ (UNSPEC_SFENCE 44)
1841+ (UNSPEC_NOP 45) ; prevents combiner cleverness
1842+ (UNSPEC_PAVGUSB 49)
1843+ (UNSPEC_PFRCP 50)
1844+ (UNSPEC_PFRCPIT1 51)
1845+ (UNSPEC_PFRCPIT2 52)
1846+ (UNSPEC_PFRSQRT 53)
1847+ (UNSPEC_PFRSQIT1 54)
1848+ ])
1849
1850 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
1851 ;; from i386.c.
1852@@ -1759,7 +1763,7 @@
1853 return "lea{l}\t{%1, %0|%0, %1}";
1854
1855 default:
1856- if (flag_pic && SYMBOLIC_CONST (operands[1]))
1857+ if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1858 abort();
1859 return "mov{l}\t{%1, %0|%0, %1}";
1860 }
1861@@ -2525,7 +2529,7 @@
1862 case TYPE_LEA:
1863 return "lea{q}\t{%a1, %0|%0, %a1}";
1864 default:
1865- if (flag_pic && SYMBOLIC_CONST (operands[1]))
1866+ if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1867 abort ();
1868 if (get_attr_mode (insn) == MODE_SI)
1869 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1870@@ -13474,21 +13478,8 @@
1871 (match_operand:SI 3 "" "")))])]
1872 "!TARGET_64BIT"
1873 {
1874- if (operands[3] == const0_rtx)
1875- {
1876- emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
1877- DONE;
1878- }
1879- /* Static functions and indirect calls don't need
1880- current_function_uses_pic_offset_table. */
1881- if (flag_pic
1882- && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1883- && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1884- current_function_uses_pic_offset_table = 1;
1885- if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
1886- XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1887- if (TARGET_64BIT)
1888- abort();
1889+ ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3]);
1890+ DONE;
1891 })
1892
1893 (define_insn "*call_pop_0"
1894@@ -13530,37 +13521,12 @@
1895 [(call (match_operand:QI 0 "" "")
1896 (match_operand 1 "" ""))
1897 (use (match_operand 2 "" ""))]
1898- ;; Operand 1 not used on the i386.
1899 ""
1900 {
1901- rtx insn;
1902- /* Static functions and indirect calls don't need
1903- current_function_uses_pic_offset_table. */
1904- if (flag_pic
1905- && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1906- && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1907- current_function_uses_pic_offset_table = 1;
1908-
1909- if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
1910- XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1911- if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
1912- {
1913- rtx reg = gen_rtx_REG (QImode, 0);
1914- emit_move_insn (reg, operands[2]);
1915- insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
1916- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
1917- DONE;
1918- }
1919- insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
1920- DONE;
1921+ ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL);
1922+ DONE;
1923 })
1924
1925-(define_expand "call_exp"
1926- [(call (match_operand:QI 0 "" "")
1927- (match_operand 1 "" ""))]
1928- ""
1929- "")
1930-
1931 (define_insn "*call_0"
1932 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
1933 (match_operand 1 "" ""))]
1934@@ -13612,7 +13578,6 @@
1935 [(set_attr "type" "call")])
1936
1937 ;; Call subroutine, returning value in operand 0
1938-;; (which must be a hard register).
1939
1940 (define_expand "call_value_pop"
1941 [(parallel [(set (match_operand 0 "" "")
1942@@ -13623,20 +13588,9 @@
1943 (match_operand:SI 4 "" "")))])]
1944 "!TARGET_64BIT"
1945 {
1946- if (operands[4] == const0_rtx)
1947- {
1948- emit_insn (gen_call_value (operands[0], operands[1], operands[2],
1949- constm1_rtx));
1950- DONE;
1951- }
1952- /* Static functions and indirect calls don't need
1953- current_function_uses_pic_offset_table. */
1954- if (flag_pic
1955- && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1956- && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1957- current_function_uses_pic_offset_table = 1;
1958- if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
1959- XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1960+ ix86_expand_call (operands[0], operands[1], operands[2],
1961+ operands[3], operands[4]);
1962+ DONE;
1963 })
1964
1965 (define_expand "call_value"
1966@@ -13647,36 +13601,10 @@
1967 ;; Operand 2 not used on the i386.
1968 ""
1969 {
1970- rtx insn;
1971- /* Static functions and indirect calls don't need
1972- current_function_uses_pic_offset_table. */
1973- if (flag_pic
1974- && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1975- && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1976- current_function_uses_pic_offset_table = 1;
1977- if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
1978- XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1979- if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
1980- {
1981- rtx reg = gen_rtx_REG (QImode, 0);
1982- emit_move_insn (reg, operands[3]);
1983- insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
1984- operands[2]));
1985- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
1986- DONE;
1987- }
1988- insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
1989- operands[2]));
1990+ ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL);
1991 DONE;
1992 })
1993
1994-(define_expand "call_value_exp"
1995- [(set (match_operand 0 "" "")
1996- (call (match_operand:QI 1 "" "")
1997- (match_operand:SI 2 "" "")))]
1998- ""
1999- "")
2000-
2001 ;; Call subroutine returning any type.
2002
2003 (define_expand "untyped_call"
2004@@ -13693,12 +13621,10 @@
2005 simply pretend the untyped call returns a complex long double
2006 value. */
2007
2008- emit_call_insn (TARGET_FLOAT_RETURNS_IN_80387
2009- ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
2010- operands[0], const0_rtx,
2011- GEN_INT (SSE_REGPARM_MAX - 1))
2012- : gen_call (operands[0], const0_rtx,
2013- GEN_INT (SSE_REGPARM_MAX - 1)));
2014+ ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
2015+ ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
2016+ operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
2017+ NULL);
2018
2019 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2020 {
2021@@ -13781,45 +13707,39 @@
2022 ""
2023 "ix86_expand_prologue (); DONE;")
2024
2025-(define_insn "prologue_set_got"
2026+(define_expand "set_got"
2027+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
2028+ (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
2029+ (clobber (reg:CC 17))])]
2030+ "!TARGET_64BIT"
2031+ "")
2032+
2033+(define_insn "*set_got_nopic"
2034 [(set (match_operand:SI 0 "register_operand" "=r")
2035- (unspec_volatile:SI
2036- [(plus:SI (match_dup 0)
2037- (plus:SI (match_operand:SI 1 "symbolic_operand" "")
2038- (minus:SI (pc) (match_operand 2 "" ""))))] 1))
2039+ (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
2040 (clobber (reg:CC 17))]
2041- "!TARGET_64BIT"
2042-{
2043- if (GET_CODE (operands[2]) == LABEL_REF)
2044- operands[2] = XEXP (operands[2], 0);
2045- if (TARGET_DEEP_BRANCH_PREDICTION)
2046- return "add{l}\t{%1, %0|%0, %1}";
2047- else
2048- return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
2049-}
2050- [(set_attr "type" "alu")
2051- ; Since this insn may have two constant operands, we must set the
2052- ; length manually.
2053- (set_attr "length_immediate" "4")
2054- (set_attr "mode" "SI")])
2055+ "!TARGET_64BIT && !flag_pic"
2056+ { return output_set_got (operands[0]); }
2057+ [(set_attr "type" "multi")
2058+ (set_attr "length" "11")])
2059+
2060+(define_insn "*set_got_deep"
2061+ [(set (match_operand:SI 0 "register_operand" "=b")
2062+ (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
2063+ (clobber (reg:CC 17))]
2064+ "!TARGET_64BIT && TARGET_DEEP_BRANCH_PREDICTION"
2065+ { return output_set_got (operands[0]); }
2066+ [(set_attr "type" "multi")
2067+ (set_attr "length" "11")])
2068
2069-(define_insn "prologue_get_pc"
2070+(define_insn "*set_got_nodeep"
2071 [(set (match_operand:SI 0 "register_operand" "=r")
2072- (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
2073+ (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
2074+ (clobber (reg:CC 17))]
2075 "!TARGET_64BIT"
2076-{
2077- if (GET_CODE (operands[1]) == LABEL_REF)
2078- operands[1] = XEXP (operands[1], 0);
2079- output_asm_insn ("call\t%X1", operands);
2080- if (! TARGET_DEEP_BRANCH_PREDICTION)
2081- {
2082- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
2083- CODE_LABEL_NUMBER (operands[1]));
2084- return "pop{l}\t%0";
2085- }
2086- RET;
2087-}
2088- [(set_attr "type" "multi")])
2089+ { return output_set_got (operands[0]); }
2090+ [(set_attr "type" "multi")
2091+ (set_attr "length" "12")])
2092
2093 (define_expand "epilogue"
2094 [(const_int 1)]
2095@@ -13996,6 +13916,127 @@
2096 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
2097 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
2098 \f
2099+;; Thread-local storage patterns for ELF.
2100+;;
2101+;; Note that these code sequences must appear exactly as shown
2102+;; in order to allow linker relaxation.
2103+
2104+(define_insn "*tls_global_dynamic_gnu"
2105+ [(set (match_operand:SI 0 "register_operand" "=a")
2106+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
2107+ (match_operand:SI 2 "tls_symbolic_operand" "")
2108+ (match_operand:SI 3 "call_insn_operand" "")]
2109+ UNSPEC_TLS_GD))
2110+ (clobber (match_scratch:SI 4 "=d"))
2111+ (clobber (match_scratch:SI 5 "=c"))
2112+ (clobber (reg:CC 17))]
2113+ "TARGET_GNU_TLS"
2114+ "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
2115+ [(set_attr "type" "multi")
2116+ (set_attr "length" "12")])
2117+
2118+(define_insn "*tls_global_dynamic_sun"
2119+ [(set (match_operand:SI 0 "register_operand" "=a")
2120+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
2121+ (match_operand:SI 2 "tls_symbolic_operand" "")
2122+ (match_operand:SI 3 "call_insn_operand" "")]
2123+ UNSPEC_TLS_GD))
2124+ (clobber (match_scratch:SI 4 "=d"))
2125+ (clobber (match_scratch:SI 5 "=c"))
2126+ (clobber (reg:CC 17))]
2127+ "TARGET_SUN_TLS"
2128+ "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
2129+ push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
2130+ [(set_attr "type" "multi")
2131+ (set_attr "length" "14")])
2132+
2133+(define_expand "tls_global_dynamic"
2134+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
2135+ (unspec:SI
2136+ [(match_dup 2)
2137+ (match_operand:SI 1 "tls_symbolic_operand" "")
2138+ (match_dup 3)]
2139+ UNSPEC_TLS_GD))
2140+ (clobber (match_scratch:SI 4 ""))
2141+ (clobber (match_scratch:SI 5 ""))
2142+ (clobber (reg:CC 17))])]
2143+ ""
2144+{
2145+ if (!flag_pic)
2146+ abort ();
2147+ current_function_uses_pic_offset_table = 1;
2148+ operands[2] = pic_offset_table_rtx;
2149+ operands[3] = ix86_tls_get_addr ();
2150+})
2151+
2152+(define_insn "*tls_local_dynamic_base_gnu"
2153+ [(set (match_operand:SI 0 "register_operand" "=a")
2154+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
2155+ (match_operand:SI 2 "call_insn_operand" "")]
2156+ UNSPEC_TLS_LD_BASE))
2157+ (clobber (match_scratch:SI 3 "=d"))
2158+ (clobber (match_scratch:SI 4 "=c"))
2159+ (clobber (reg:CC 17))]
2160+ "TARGET_GNU_TLS"
2161+ "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
2162+ [(set_attr "type" "multi")
2163+ (set_attr "length" "11")])
2164+
2165+(define_insn "*tls_local_dynamic_base_sun"
2166+ [(set (match_operand:SI 0 "register_operand" "=a")
2167+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
2168+ (match_operand:SI 2 "call_insn_operand" "")]
2169+ UNSPEC_TLS_LD_BASE))
2170+ (clobber (match_scratch:SI 3 "=d"))
2171+ (clobber (match_scratch:SI 4 "=c"))
2172+ (clobber (reg:CC 17))]
2173+ "TARGET_SUN_TLS"
2174+ "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
2175+ push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
2176+ [(set_attr "type" "multi")
2177+ (set_attr "length" "13")])
2178+
2179+(define_expand "tls_local_dynamic_base"
2180+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
2181+ (unspec:SI [(match_dup 1) (match_dup 2)]
2182+ UNSPEC_TLS_LD_BASE))
2183+ (clobber (match_scratch:SI 3 ""))
2184+ (clobber (match_scratch:SI 4 ""))
2185+ (clobber (reg:CC 17))])]
2186+ ""
2187+{
2188+ if (!flag_pic)
2189+ abort ();
2190+ current_function_uses_pic_offset_table = 1;
2191+ operands[1] = pic_offset_table_rtx;
2192+ operands[2] = ix86_tls_get_addr ();
2193+})
2194+
2195+;; Local dynamic of a single variable is a lose. Show combine how
2196+;; to convert that back to global dynamic.
2197+
2198+(define_insn_and_split "*tls_local_dynamic_once"
2199+ [(set (match_operand:SI 0 "register_operand" "=a")
2200+ (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
2201+ (match_operand:SI 2 "call_insn_operand" "")]
2202+ UNSPEC_TLS_LD_BASE)
2203+ (const:SI (unspec:SI
2204+ [(match_operand:SI 3 "tls_symbolic_operand" "")]
2205+ UNSPEC_DTPOFF))))
2206+ (clobber (match_scratch:SI 4 "=d"))
2207+ (clobber (match_scratch:SI 5 "=c"))
2208+ (clobber (reg:CC 17))]
2209+ ""
2210+ "#"
2211+ ""
2212+ [(parallel [(set (match_dup 0)
2213+ (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
2214+ UNSPEC_TLS_GD))
2215+ (clobber (match_dup 4))
2216+ (clobber (match_dup 5))
2217+ (clobber (reg:CC 17))])]
2218+ "")
2219+\f
2220 ;; These patterns match the binary 387 instructions for addM3, subM3,
2221 ;; mulM3 and divM3. There are three patterns for each of DFmode and
2222 ;; SFmode. The first is the normal insn, the second the same insn but
2223@@ -16835,7 +16876,7 @@
2224 [(label_ref (match_operand 0 "" ""))]
2225 "!TARGET_64BIT && flag_pic"
2226 {
2227- load_pic_register ();
2228+ emit_insn (gen_set_got (pic_offset_table_rtx));
2229 DONE;
2230 })
2231 \f
2232--- gcc/config/ia64/ia64-protos.h.jj Tue Apr 23 20:28:20 2002
2233+++ gcc/config/ia64/ia64-protos.h Wed Jun 19 19:33:52 2002
2234@@ -31,6 +31,7 @@ extern int call_operand PARAMS((rtx, enu
2235 extern int sdata_symbolic_operand PARAMS((rtx, enum machine_mode));
2236 extern int got_symbolic_operand PARAMS((rtx, enum machine_mode));
2237 extern int symbolic_operand PARAMS((rtx, enum machine_mode));
2238+extern int tls_symbolic_operand PARAMS((rtx, enum machine_mode));
2239 extern int function_operand PARAMS((rtx, enum machine_mode));
2240 extern int setjmp_operand PARAMS((rtx, enum machine_mode));
2241 extern int move_operand PARAMS((rtx, enum machine_mode));
2242@@ -67,6 +68,7 @@ extern int general_tfmode_operand PARAMS
2243 extern int destination_tfmode_operand PARAMS((rtx, enum machine_mode));
2244 extern int tfreg_or_fp01_operand PARAMS((rtx, enum machine_mode));
2245
2246+extern rtx ia64_expand_move PARAMS ((rtx, rtx));
2247 extern int ia64_move_ok PARAMS((rtx, rtx));
2248 extern int ia64_depz_field_mask PARAMS((rtx, rtx));
2249 extern rtx ia64_gp_save_reg PARAMS((int));
2250--- gcc/config/ia64/ia64.c.jj Wed Jun 19 22:36:54 2002
2251+++ gcc/config/ia64/ia64.c Wed Jun 19 22:46:07 2002
2252@@ -95,6 +95,13 @@ static const char * const ia64_output_re
2253 /* String used with the -mfixed-range= option. */
2254 const char *ia64_fixed_range_string;
2255
2256+/* Determines whether we use adds, addl, or movl to generate our
2257+ TLS immediate offsets. */
2258+int ia64_tls_size = 22;
2259+
2260+/* String used with the -mtls-size= option. */
2261+const char *ia64_tls_size_string;
2262+
2263 /* Determines whether we run our final scheduling pass or not. We always
2264 avoid the normal second scheduling pass. */
2265 static int ia64_flag_schedule_insns2;
2266@@ -104,6 +111,8 @@ static int ia64_flag_schedule_insns2;
2267
2268 unsigned int ia64_section_threshold;
2269 \f
2270+static rtx gen_tls_get_addr PARAMS ((void));
2271+static rtx gen_thread_pointer PARAMS ((void));
2272 static int find_gr_spill PARAMS ((int));
2273 static int next_scratch_gr_reg PARAMS ((void));
2274 static void mark_reg_gr_used_mask PARAMS ((rtx, void *));
2275@@ -214,6 +223,11 @@ static const struct attribute_spec ia64_
2276 #undef TARGET_SCHED_CYCLE_DISPLAY
2277 #define TARGET_SCHED_CYCLE_DISPLAY ia64_cycle_display
2278
2279+#ifdef HAVE_AS_TLS
2280+#undef TARGET_HAVE_TLS
2281+#define TARGET_HAVE_TLS true
2282+#endif
2283+
2284 struct gcc_target targetm = TARGET_INITIALIZER;
2285 \f
2286 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
2287@@ -250,7 +264,10 @@ sdata_symbolic_operand (op, mode)
2288 if (CONSTANT_POOL_ADDRESS_P (op))
2289 return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;
2290 else
2291- return XSTR (op, 0)[0] == SDATA_NAME_FLAG_CHAR;
2292+ {
2293+ const char *str = XSTR (op, 0);
2294+ return (str[0] == ENCODE_SECTION_INFO_CHAR && str[1] == 's');
2295+ }
2296
2297 default:
2298 break;
2299@@ -324,6 +341,35 @@ symbolic_operand (op, mode)
2300 return 0;
2301 }
2302
2303+/* Return tls_model if OP refers to a TLS symbol. */
2304+
2305+int
2306+tls_symbolic_operand (op, mode)
2307+ rtx op;
2308+ enum machine_mode mode ATTRIBUTE_UNUSED;
2309+{
2310+ const char *str;
2311+
2312+ if (GET_CODE (op) != SYMBOL_REF)
2313+ return 0;
2314+ str = XSTR (op, 0);
2315+ if (str[0] != ENCODE_SECTION_INFO_CHAR)
2316+ return 0;
2317+ switch (str[1])
2318+ {
2319+ case 'G':
2320+ return TLS_MODEL_GLOBAL_DYNAMIC;
2321+ case 'L':
2322+ return TLS_MODEL_LOCAL_DYNAMIC;
2323+ case 'i':
2324+ return TLS_MODEL_INITIAL_EXEC;
2325+ case 'l':
2326+ return TLS_MODEL_LOCAL_EXEC;
2327+ }
2328+ return 0;
2329+}
2330+
2331+
2332 /* Return 1 if OP refers to a function. */
2333
2334 int
2335@@ -922,6 +968,9 @@ ia64_expand_load_address (dest, src, scr
2336 else
2337 temp = dest;
2338
2339+ if (tls_symbolic_operand (src, Pmode))
2340+ abort ();
2341+
2342 if (TARGET_AUTO_PIC)
2343 emit_insn (gen_load_gprel64 (temp, src));
2344 else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FLAG (src))
2345@@ -964,6 +1013,185 @@ ia64_expand_load_address (dest, src, scr
2346 emit_move_insn (dest, temp);
2347 }
2348
2349+static rtx
2350+gen_tls_get_addr ()
2351+{
2352+ static rtx tga;
2353+ if (!tga)
2354+ {
2355+ tga = init_one_libfunc ("__tls_get_addr");
2356+ ggc_add_rtx_root (&tga, 1);
2357+ }
2358+ return tga;
2359+}
2360+
2361+static rtx
2362+gen_thread_pointer ()
2363+{
2364+ static rtx tp;
2365+ if (!tp)
2366+ {
2367+ tp = gen_rtx_REG (Pmode, 13);
2368+ RTX_UNCHANGING_P (tp) = 1;
2369+ ggc_add_rtx_root (&tp, 1);
2370+ }
2371+ return tp;
2372+}
2373+
2374+rtx
2375+ia64_expand_move (op0, op1)
2376+ rtx op0, op1;
2377+{
2378+ enum machine_mode mode = GET_MODE (op0);
2379+
2380+ if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
2381+ op1 = force_reg (mode, op1);
2382+
2383+ if (mode == Pmode)
2384+ {
2385+ enum tls_model tls_kind;
2386+ if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
2387+ {
2388+ rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp, insns;
2389+
2390+ switch (tls_kind)
2391+ {
2392+ case TLS_MODEL_GLOBAL_DYNAMIC:
2393+ start_sequence ();
2394+
2395+ tga_op1 = gen_reg_rtx (Pmode);
2396+ emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
2397+ tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
2398+ RTX_UNCHANGING_P (tga_op1) = 1;
2399+
2400+ tga_op2 = gen_reg_rtx (Pmode);
2401+ emit_insn (gen_load_ltoff_dtprel (tga_op2, op1));
2402+ tga_op2 = gen_rtx_MEM (Pmode, tga_op2);
2403+ RTX_UNCHANGING_P (tga_op2) = 1;
2404+
2405+ tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
2406+ LCT_CONST, Pmode, 2, tga_op1,
2407+ Pmode, tga_op2, Pmode);
2408+
2409+ insns = get_insns ();
2410+ end_sequence ();
2411+
2412+ emit_libcall_block (insns, op0, tga_ret, op1);
2413+ return NULL_RTX;
2414+
2415+ case TLS_MODEL_LOCAL_DYNAMIC:
2416+ /* ??? This isn't the completely proper way to do local-dynamic
2417+ If the call to __tls_get_addr is used only by a single symbol,
2418+ then we should (somehow) move the dtprel to the second arg
2419+ to avoid the extra add. */
2420+ start_sequence ();
2421+
2422+ tga_op1 = gen_reg_rtx (Pmode);
2423+ emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
2424+ tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
2425+ RTX_UNCHANGING_P (tga_op1) = 1;
2426+
2427+ tga_op2 = const0_rtx;
2428+
2429+ tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
2430+ LCT_CONST, Pmode, 2, tga_op1,
2431+ Pmode, tga_op2, Pmode);
2432+
2433+ insns = get_insns ();
2434+ end_sequence ();
2435+
2436+ tga_eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
2437+ UNSPEC_LD_BASE);
2438+ tmp = gen_reg_rtx (Pmode);
2439+ emit_libcall_block (insns, tmp, tga_ret, tga_eqv);
2440+
2441+ if (register_operand (op0, Pmode))
2442+ tga_ret = op0;
2443+ else
2444+ tga_ret = gen_reg_rtx (Pmode);
2445+ if (TARGET_TLS64)
2446+ {
2447+ emit_insn (gen_load_dtprel (tga_ret, op1));
2448+ emit_insn (gen_adddi3 (tga_ret, tmp, tga_ret));
2449+ }
2450+ else
2451+ emit_insn (gen_add_dtprel (tga_ret, tmp, op1));
2452+ if (tga_ret == op0)
2453+ return NULL_RTX;
2454+ op1 = tga_ret;
2455+ break;
2456+
2457+ case TLS_MODEL_INITIAL_EXEC:
2458+ tmp = gen_reg_rtx (Pmode);
2459+ emit_insn (gen_load_ltoff_tprel (tmp, op1));
2460+ tmp = gen_rtx_MEM (Pmode, tmp);
2461+ RTX_UNCHANGING_P (tmp) = 1;
2462+ tmp = force_reg (Pmode, tmp);
2463+
2464+ if (register_operand (op0, Pmode))
2465+ op1 = op0;
2466+ else
2467+ op1 = gen_reg_rtx (Pmode);
2468+ emit_insn (gen_adddi3 (op1, tmp, gen_thread_pointer ()));
2469+ if (op1 == op0)
2470+ return NULL_RTX;
2471+ break;
2472+
2473+ case TLS_MODEL_LOCAL_EXEC:
2474+ if (register_operand (op0, Pmode))
2475+ tmp = op0;
2476+ else
2477+ tmp = gen_reg_rtx (Pmode);
2478+ if (TARGET_TLS64)
2479+ {
2480+ emit_insn (gen_load_tprel (tmp, op1));
2481+ emit_insn (gen_adddi3 (tmp, gen_thread_pointer (), tmp));
2482+ }
2483+ else
2484+ emit_insn (gen_add_tprel (tmp, gen_thread_pointer (), op1));
2485+ if (tmp == op0)
2486+ return NULL_RTX;
2487+ op1 = tmp;
2488+ break;
2489+
2490+ default:
2491+ abort ();
2492+ }
2493+ }
2494+ else if (!TARGET_NO_PIC && symbolic_operand (op1, DImode))
2495+ {
2496+ /* Before optimization starts, delay committing to any particular
2497+ type of PIC address load. If this function gets deferred, we
2498+ may acquire information that changes the value of the
2499+ sdata_symbolic_operand predicate.
2500+
2501+ But don't delay for function pointers. Loading a function address
2502+ actually loads the address of the descriptor not the function.
2503+ If we represent these as SYMBOL_REFs, then they get cse'd with
2504+ calls, and we end up with calls to the descriptor address instead
2505+ of calls to the function address. Functions are not candidates
2506+ for sdata anyways.
2507+
2508+ Don't delay for LABEL_REF because the splitter loses REG_LABEL
2509+ notes. Don't delay for pool addresses on general principals;
2510+ they'll never become non-local behind our back. */
2511+
2512+ if (rtx_equal_function_value_matters
2513+ && GET_CODE (op1) != LABEL_REF
2514+ && ! (GET_CODE (op1) == SYMBOL_REF
2515+ && (SYMBOL_REF_FLAG (op1)
2516+ || CONSTANT_POOL_ADDRESS_P (op1)
2517+ || STRING_POOL_ADDRESS_P (op1))))
2518+ emit_insn (gen_movdi_symbolic (op0, op1));
2519+ else
2520+ ia64_expand_load_address (op0, op1, NULL_RTX);
2521+ return NULL_RTX;
2522+ }
2523+ }
2524+
2525+ return op1;
2526+}
2527+
2528 rtx
2529 ia64_gp_save_reg (setjmp_p)
2530 int setjmp_p;
2531@@ -3944,6 +4172,16 @@ ia64_override_options ()
2532 if (ia64_fixed_range_string)
2533 fix_range (ia64_fixed_range_string);
2534
2535+ if (ia64_tls_size_string)
2536+ {
2537+ char *end;
2538+ unsigned long tmp = strtoul (ia64_tls_size_string, &end, 10);
2539+ if (*end || (tmp != 14 && tmp != 22 && tmp != 64))
2540+ error ("bad value (%s) for -mtls-size= switch", ia64_tls_size_string);
2541+ else
2542+ ia64_tls_size = tmp;
2543+ }
2544+
2545 ia64_flag_schedule_insns2 = flag_schedule_insns_after_reload;
2546 flag_schedule_insns_after_reload = 0;
2547
2548@@ -4607,6 +4845,13 @@ rtx_needs_barrier (x, flags, pred)
2549 need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 2), flags, pred);
2550 break;
2551
2552+ case UNSPEC_LTOFF_DTPMOD:
2553+ case UNSPEC_LTOFF_DTPREL:
2554+ case UNSPEC_DTPREL:
2555+ case UNSPEC_LTOFF_TPREL:
2556+ case UNSPEC_TPREL:
2557+ break;
2558+
2559 default:
2560 abort ();
2561 }
2562@@ -6872,6 +7117,9 @@ ia64_encode_section_info (decl)
2563 tree decl;
2564 {
2565 const char *symbol_str;
2566+ bool is_local, is_small;
2567+ rtx symbol;
2568+ char encoding = 0;
2569
2570 if (TREE_CODE (decl) == FUNCTION_DECL)
2571 {
2572@@ -6885,75 +7133,111 @@ ia64_encode_section_info (decl)
2573 || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
2574 return;
2575
2576- symbol_str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
2577+ symbol = XEXP (DECL_RTL (decl), 0);
2578+ symbol_str = XSTR (symbol, 0);
2579+
2580+ /* A non-decl is an entry in the constant pool. */
2581+ if (!DECL_P (decl))
2582+ is_local = true;
2583+ /* Static variables are always local. */
2584+ else if (! TREE_PUBLIC (decl))
2585+ is_local = true;
2586+ /* A variable is local if the user tells us so. */
2587+ else if (MODULE_LOCAL_P (decl))
2588+ is_local = true;
2589+ /* Otherwise, variables defined outside this object may not be local. */
2590+ else if (DECL_EXTERNAL (decl))
2591+ is_local = false;
2592+ /* Linkonce and weak data are never local. */
2593+ else if (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
2594+ is_local = false;
2595+ /* If PIC, then assume that any global name can be overridden by
2596+ symbols resolved from other modules. */
2597+ else if (flag_pic)
2598+ is_local = false;
2599+ /* Uninitialized COMMON variable may be unified with symbols
2600+ resolved from other modules. */
2601+ else if (DECL_COMMON (decl)
2602+ && (DECL_INITIAL (decl) == NULL
2603+ || DECL_INITIAL (decl) == error_mark_node))
2604+ is_local = false;
2605+ /* Otherwise we're left with initialized (or non-common) global data
2606+ which is of necessity defined locally. */
2607+ else
2608+ is_local = true;
2609
2610- /* We assume that -fpic is used only to create a shared library (dso).
2611- With -fpic, no global data can ever be sdata.
2612- Without -fpic, global common uninitialized data can never be sdata, since
2613- it can unify with a real definition in a dso. */
2614- /* ??? Actually, we can put globals in sdata, as long as we don't use gprel
2615- to access them. The linker may then be able to do linker relaxation to
2616- optimize references to them. Currently sdata implies use of gprel. */
2617- /* We need the DECL_EXTERNAL check for C++. static class data members get
2618- both TREE_STATIC and DECL_EXTERNAL set, to indicate that they are
2619- statically allocated, but the space is allocated somewhere else. Such
2620- decls can not be own data. */
2621- if (! TARGET_NO_SDATA
2622- && ((TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)
2623- && ! (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
2624- && ! (TREE_PUBLIC (decl)
2625- && (flag_pic
2626- || (DECL_COMMON (decl)
2627- && (DECL_INITIAL (decl) == 0
2628- || DECL_INITIAL (decl) == error_mark_node)))))
2629- || MODULE_LOCAL_P (decl))
2630- /* Either the variable must be declared without a section attribute,
2631- or the section must be sdata or sbss. */
2632- && (DECL_SECTION_NAME (decl) == 0
2633- || ! strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
2634- ".sdata")
2635- || ! strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
2636- ".sbss")))
2637+ is_small = false;
2638+ if (TARGET_NO_SDATA)
2639+ ;
2640+ else if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
2641+ {
2642+ const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
2643+ if (strcmp (section, ".sdata") == 0
2644+ || strcmp (section, ".sbss") == 0)
2645+ is_small = true;
2646+ }
2647+ else
2648 {
2649 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
2650
2651- /* If the variable has already been defined in the output file, then it
2652- is too late to put it in sdata if it wasn't put there in the first
2653- place. The test is here rather than above, because if it is already
2654- in sdata, then it can stay there. */
2655-
2656- if (TREE_ASM_WRITTEN (decl))
2657- ;
2658-
2659- /* If this is an incomplete type with size 0, then we can't put it in
2660- sdata because it might be too big when completed.
2661- Objects bigger than threshold should have SDATA_NAME_FLAG_CHAR
2662- added if they are in .sdata or .sbss explicitely. */
2663- else if (((size > 0
2664- && size <= (HOST_WIDE_INT) ia64_section_threshold)
2665- || DECL_SECTION_NAME (decl))
2666- && symbol_str[0] != SDATA_NAME_FLAG_CHAR)
2667- {
2668- size_t len = strlen (symbol_str);
2669- char *newstr = alloca (len + 1);
2670- const char *string;
2671+ /* If this is an incomplete type with size 0, then we can't put it
2672+ in sdata because it might be too big when completed. */
2673+ if (size > 0 && size <= ia64_section_threshold)
2674+ is_small = true;
2675+ }
2676
2677- *newstr = SDATA_NAME_FLAG_CHAR;
2678- memcpy (newstr + 1, symbol_str, len + 1);
2679-
2680- string = ggc_alloc_string (newstr, len + 1);
2681- XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
2682+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
2683+ {
2684+ enum tls_model kind;
2685+ if (!flag_pic)
2686+ {
2687+ if (is_local)
2688+ kind = TLS_MODEL_LOCAL_EXEC;
2689+ else
2690+ kind = TLS_MODEL_INITIAL_EXEC;
2691 }
2692- }
2693- /* This decl is marked as being in small data/bss but it shouldn't
2694- be; one likely explanation for this is that the decl has been
2695- moved into a different section from the one it was in when
2696- ENCODE_SECTION_INFO was first called. Remove the '@'. */
2697- else if (symbol_str[0] == SDATA_NAME_FLAG_CHAR)
2698+ else if (is_local)
2699+ kind = TLS_MODEL_LOCAL_DYNAMIC;
2700+ else
2701+ kind = TLS_MODEL_GLOBAL_DYNAMIC;
2702+ if (kind < flag_tls_default)
2703+ kind = flag_tls_default;
2704+
2705+ encoding = " GLil"[kind];
2706+ }
2707+ /* Determine if DECL will wind up in .sdata/.sbss. */
2708+ else if (is_local && is_small)
2709+ encoding = 's';
2710+
2711+ /* Finally, encode this into the symbol string. */
2712+ if (encoding)
2713 {
2714- XSTR (XEXP (DECL_RTL (decl), 0), 0)
2715- = ggc_strdup (symbol_str + 1);
2716+ char *newstr;
2717+ size_t len;
2718+
2719+ if (symbol_str[0] == ENCODE_SECTION_INFO_CHAR)
2720+ {
2721+ if (encoding == symbol_str[1])
2722+ return;
2723+ /* ??? Sdata became thread or thread becaome not thread. Lose. */
2724+ abort ();
2725+ }
2726+
2727+ len = strlen (symbol_str);
2728+ newstr = alloca (len + 3);
2729+ newstr[0] = ENCODE_SECTION_INFO_CHAR;
2730+ newstr[1] = encoding;
2731+ memcpy (newstr + 2, symbol_str, len + 1);
2732+
2733+ XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2);
2734 }
2735+
2736+ /* This decl is marked as being in small data/bss but it shouldn't be;
2737+ one likely explanation for this is that the decl has been moved into
2738+ a different section from the one it was in when encode_section_info
2739+ was first called. Remove the encoding. */
2740+ else if (symbol_str[0] == ENCODE_SECTION_INFO_CHAR)
2741+ XSTR (symbol, 0) = ggc_strdup (symbol_str + 2);
2742 }
2743 \f
2744 /* Output assembly directives for prologue regions. */
2745--- gcc/config/ia64/ia64.h.jj Tue Apr 23 20:28:21 2002
2746+++ gcc/config/ia64/ia64.h Wed Jun 19 19:33:52 2002
2747@@ -109,6 +109,11 @@ extern int target_flags;
2748
2749 #define TARGET_DWARF2_ASM (target_flags & MASK_DWARF2_ASM)
2750
2751+extern int ia64_tls_size;
2752+#define TARGET_TLS14 (ia64_tls_size == 14)
2753+#define TARGET_TLS22 (ia64_tls_size == 22)
2754+#define TARGET_TLS64 (ia64_tls_size == 64)
2755+
2756 /* This macro defines names of command options to set and clear bits in
2757 `target_flags'. Its definition is an initializer with a subgrouping for
2758 each command option. */
2759@@ -177,10 +182,13 @@ extern int target_flags;
2760 subgrouping for each command option. */
2761
2762 extern const char *ia64_fixed_range_string;
2763+extern const char *ia64_tls_size_string;
2764 #define TARGET_OPTIONS \
2765 { \
2766 { "fixed-range=", &ia64_fixed_range_string, \
2767 N_("Specify range of registers to make fixed")}, \
2768+ { "tls-size=", &ia64_tls_size_string, \
2769+ N_("Specify bit size of immediate TLS offsets")}, \
2770 }
2771
2772 /* Sometimes certain combinations of command options do not make sense on a
2773@@ -1801,7 +1809,7 @@ do { \
2774 && (DECL_ONE_ONLY (DECL) || DECL_WEAK (DECL) || DECL_COMMON (DECL) \
2775 || DECL_SECTION_NAME (DECL) != 0))
2776
2777-#define SDATA_NAME_FLAG_CHAR '@'
2778+#define ENCODE_SECTION_INFO_CHAR '@'
2779
2780 #define IA64_DEFAULT_GVALUE 8
2781
2782@@ -1811,8 +1819,8 @@ do { \
2783 #define STRIP_NAME_ENCODING(VAR, SYMBOL_NAME) \
2784 do { \
2785 (VAR) = (SYMBOL_NAME); \
2786- if ((VAR)[0] == SDATA_NAME_FLAG_CHAR) \
2787- (VAR)++; \
2788+ if ((VAR)[0] == ENCODE_SECTION_INFO_CHAR) \
2789+ (VAR) += 2; \
2790 if ((VAR)[0] == '*') \
2791 (VAR)++; \
2792 } while (0)
2793--- gcc/config/ia64/ia64.md.jj Tue Apr 23 20:28:21 2002
2794+++ gcc/config/ia64/ia64.md Wed Jun 19 19:33:52 2002
2795@@ -68,7 +68,19 @@
2796 ;; 23 cycle display
2797 ;; 24 addp4
2798 ;; 25 prologue_use
2799-;;
2800+
2801+;; More unspec:
2802+
2803+(define_constants
2804+ [; Relocations
2805+ (UNSPEC_LTOFF_DTPMOD 14)
2806+ (UNSPEC_LTOFF_DTPREL 15)
2807+ (UNSPEC_DTPREL 16)
2808+ (UNSPEC_LTOFF_TPREL 17)
2809+ (UNSPEC_TPREL 18)
2810+ (UNSPEC_LD_BASE 26)
2811+ ])
2812+
2813 ;; unspec_volatile:
2814 ;; 0 alloc
2815 ;; 1 blockage
2816@@ -272,12 +284,12 @@
2817 [(set (match_operand:QI 0 "general_operand" "")
2818 (match_operand:QI 1 "general_operand" ""))]
2819 ""
2820- "
2821 {
2822- if (! reload_in_progress && ! reload_completed
2823- && ! ia64_move_ok (operands[0], operands[1]))
2824- operands[1] = force_reg (QImode, operands[1]);
2825-}")
2826+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
2827+ if (!op1)
2828+ DONE;
2829+ operands[1] = op1;
2830+})
2831
2832 (define_insn "*movqi_internal"
2833 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
2834@@ -297,12 +309,12 @@
2835 [(set (match_operand:HI 0 "general_operand" "")
2836 (match_operand:HI 1 "general_operand" ""))]
2837 ""
2838- "
2839 {
2840- if (! reload_in_progress && ! reload_completed
2841- && ! ia64_move_ok (operands[0], operands[1]))
2842- operands[1] = force_reg (HImode, operands[1]);
2843-}")
2844+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
2845+ if (!op1)
2846+ DONE;
2847+ operands[1] = op1;
2848+})
2849
2850 (define_insn "*movhi_internal"
2851 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
2852@@ -322,12 +334,12 @@
2853 [(set (match_operand:SI 0 "general_operand" "")
2854 (match_operand:SI 1 "general_operand" ""))]
2855 ""
2856- "
2857 {
2858- if (! reload_in_progress && ! reload_completed
2859- && ! ia64_move_ok (operands[0], operands[1]))
2860- operands[1] = force_reg (SImode, operands[1]);
2861-}")
2862+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
2863+ if (!op1)
2864+ DONE;
2865+ operands[1] = op1;
2866+})
2867
2868 (define_insn "*movsi_internal"
2869 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
2870@@ -351,32 +363,12 @@
2871 [(set (match_operand:DI 0 "general_operand" "")
2872 (match_operand:DI 1 "general_operand" ""))]
2873 ""
2874- "
2875 {
2876- if (! reload_in_progress && ! reload_completed
2877- && ! ia64_move_ok (operands[0], operands[1]))
2878- operands[1] = force_reg (DImode, operands[1]);
2879- if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
2880- {
2881- /* Before optimization starts, delay committing to any particular
2882- type of PIC address load. If this function gets deferred, we
2883- may acquire information that changes the value of the
2884- sdata_symbolic_operand predicate. */
2885- /* But don't delay for function pointers. Loading a function address
2886- actually loads the address of the descriptor not the function.
2887- If we represent these as SYMBOL_REFs, then they get cse'd with
2888- calls, and we end up with calls to the descriptor address instead of
2889- calls to the function address. Functions are not candidates for
2890- sdata anyways. */
2891- if (rtx_equal_function_value_matters
2892- && ! (GET_CODE (operands[1]) == SYMBOL_REF
2893- && SYMBOL_REF_FLAG (operands[1])))
2894- emit_insn (gen_movdi_symbolic (operands[0], operands[1], gen_reg_rtx (DImode)));
2895- else
2896- ia64_expand_load_address (operands[0], operands[1], NULL_RTX);
2897- DONE;
2898- }
2899-}")
2900+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
2901+ if (!op1)
2902+ DONE;
2903+ operands[1] = op1;
2904+})
2905
2906 ;; This is used during early compilation to delay the decision on
2907 ;; how to refer to a variable as long as possible. This is especially
2908@@ -384,19 +376,22 @@
2909 ;; deferred functions, since we may acquire additional information
2910 ;; on the variables used in the meantime.
2911
2912-;; ??? This causes us to lose REG_LABEL notes, because the insn splitter
2913-;; does not attempt to preserve any REG_NOTES on the input instruction.
2914-
2915 (define_insn_and_split "movdi_symbolic"
2916 [(set (match_operand:DI 0 "register_operand" "=r")
2917 (match_operand:DI 1 "symbolic_operand" "s"))
2918- (clobber (match_operand:DI 2 "register_operand" "+r"))
2919+ (clobber (match_scratch:DI 2 "=r"))
2920 (use (reg:DI 1))]
2921 ""
2922 "* abort ();"
2923- ""
2924+ "!no_new_pseudos || reload_completed"
2925 [(const_int 0)]
2926- "ia64_expand_load_address (operands[0], operands[1], operands[2]); DONE;")
2927+{
2928+ rtx scratch = operands[2];
2929+ if (!reload_completed)
2930+ gen_reg_rtx (Pmode);
2931+ ia64_expand_load_address (operands[0], operands[1], scratch);
2932+ DONE;
2933+})
2934
2935 (define_insn "*movdi_internal"
2936 [(set (match_operand:DI 0 "destination_operand"
2937@@ -510,6 +505,131 @@
2938 "addl %0 = @ltoff(%1), gp"
2939 [(set_attr "itanium_class" "ialu")])
2940
2941+(define_insn "load_ltoff_dtpmod"
2942+ [(set (match_operand:DI 0 "register_operand" "=r")
2943+ (plus:DI (reg:DI 1)
2944+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2945+ UNSPEC_LTOFF_DTPMOD)))]
2946+ ""
2947+ "addl %0 = @ltoff(@dtpmod(%1)), gp"
2948+ [(set_attr "itanium_class" "ialu")])
2949+
2950+(define_insn "load_ltoff_dtprel"
2951+ [(set (match_operand:DI 0 "register_operand" "=r")
2952+ (plus:DI (reg:DI 1)
2953+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2954+ UNSPEC_LTOFF_DTPREL)))]
2955+ ""
2956+ "addl %0 = @ltoff(@dtprel(%1)), gp"
2957+ [(set_attr "itanium_class" "ialu")])
2958+
2959+(define_expand "load_dtprel"
2960+ [(set (match_operand:DI 0 "register_operand" "")
2961+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2962+ UNSPEC_DTPREL))]
2963+ ""
2964+ "")
2965+
2966+(define_insn "*load_dtprel64"
2967+ [(set (match_operand:DI 0 "register_operand" "=r")
2968+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2969+ UNSPEC_DTPREL))]
2970+ "TARGET_TLS64"
2971+ "movl %0 = @dtprel(%1)"
2972+ [(set_attr "itanium_class" "long_i")])
2973+
2974+(define_insn "*load_dtprel22"
2975+ [(set (match_operand:DI 0 "register_operand" "=r")
2976+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2977+ UNSPEC_DTPREL))]
2978+ ""
2979+ "addl %0 = @dtprel(%1), r0"
2980+ [(set_attr "itanium_class" "ialu")])
2981+
2982+(define_expand "add_dtprel"
2983+ [(set (match_operand:DI 0 "register_operand" "")
2984+ (plus:DI (match_operand:DI 1 "register_operand" "")
2985+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
2986+ UNSPEC_DTPREL)))]
2987+ "!TARGET_TLS64"
2988+ "")
2989+
2990+(define_insn "*add_dtprel14"
2991+ [(set (match_operand:DI 0 "register_operand" "=r")
2992+ (plus:DI (match_operand:DI 1 "register_operand" "r")
2993+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
2994+ UNSPEC_DTPREL)))]
2995+ "TARGET_TLS14"
2996+ "adds %0 = @dtprel(%2), %1"
2997+ [(set_attr "itanium_class" "ialu")])
2998+
2999+(define_insn "*add_dtprel22"
3000+ [(set (match_operand:DI 0 "register_operand" "=r")
3001+ (plus:DI (match_operand:DI 1 "register_operand" "a")
3002+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
3003+ UNSPEC_DTPREL)))]
3004+ "TARGET_TLS22"
3005+ "addl %0 = @dtprel(%2), %1"
3006+ [(set_attr "itanium_class" "ialu")])
3007+
3008+(define_insn "load_ltoff_tprel"
3009+ [(set (match_operand:DI 0 "register_operand" "=r")
3010+ (plus:DI (reg:DI 1)
3011+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
3012+ UNSPEC_LTOFF_TPREL)))]
3013+ ""
3014+ "addl %0 = @ltoff(@tprel(%1)), gp"
3015+ [(set_attr "itanium_class" "ialu")])
3016+
3017+(define_expand "load_tprel"
3018+ [(set (match_operand:DI 0 "register_operand" "")
3019+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
3020+ UNSPEC_TPREL))]
3021+ ""
3022+ "")
3023+
3024+(define_insn "*load_tprel64"
3025+ [(set (match_operand:DI 0 "register_operand" "=r")
3026+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
3027+ UNSPEC_TPREL))]
3028+ "TARGET_TLS64"
3029+ "movl %0 = @tprel(%1)"
3030+ [(set_attr "itanium_class" "long_i")])
3031+
3032+(define_insn "*load_tprel22"
3033+ [(set (match_operand:DI 0 "register_operand" "=r")
3034+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
3035+ UNSPEC_TPREL))]
3036+ ""
3037+ "addl %0 = @tprel(%1), r0"
3038+ [(set_attr "itanium_class" "ialu")])
3039+
3040+(define_expand "add_tprel"
3041+ [(set (match_operand:DI 0 "register_operand" "")
3042+ (plus:DI (match_operand:DI 1 "register_operand" "")
3043+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
3044+ UNSPEC_TPREL)))]
3045+ "!TARGET_TLS64"
3046+ "")
3047+
3048+(define_insn "*add_tprel14"
3049+ [(set (match_operand:DI 0 "register_operand" "=r")
3050+ (plus:DI (match_operand:DI 1 "register_operand" "r")
3051+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
3052+ UNSPEC_TPREL)))]
3053+ "TARGET_TLS14"
3054+ "adds %0 = @tprel(%2), %1"
3055+ [(set_attr "itanium_class" "ialu")])
3056+
3057+(define_insn "*add_tprel22"
3058+ [(set (match_operand:DI 0 "register_operand" "=r")
3059+ (plus:DI (match_operand:DI 1 "register_operand" "a")
3060+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
3061+ UNSPEC_TPREL)))]
3062+ "TARGET_TLS22"
3063+ "addl %0 = @tprel(%2), %1"
3064+ [(set_attr "itanium_class" "ialu")])
3065+
3066 ;; With no offsettable memory references, we've got to have a scratch
3067 ;; around to play with the second word.
3068 (define_expand "movti"
3069@@ -517,12 +637,12 @@
3070 (match_operand:TI 1 "general_operand" ""))
3071 (clobber (match_scratch:DI 2 ""))])]
3072 ""
3073- "
3074 {
3075- if (! reload_in_progress && ! reload_completed
3076- && ! ia64_move_ok (operands[0], operands[1]))
3077- operands[1] = force_reg (TImode, operands[1]);
3078-}")
3079+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
3080+ if (!op1)
3081+ DONE;
3082+ operands[1] = op1;
3083+})
3084
3085 (define_insn_and_split "*movti_internal"
3086 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
3087@@ -639,12 +759,12 @@
3088 [(set (match_operand:SF 0 "general_operand" "")
3089 (match_operand:SF 1 "general_operand" ""))]
3090 ""
3091- "
3092 {
3093- if (! reload_in_progress && ! reload_completed
3094- && ! ia64_move_ok (operands[0], operands[1]))
3095- operands[1] = force_reg (SFmode, operands[1]);
3096-}")
3097+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
3098+ if (!op1)
3099+ DONE;
3100+ operands[1] = op1;
3101+})
3102
3103 (define_insn "*movsf_internal"
3104 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
3105@@ -665,12 +785,12 @@
3106 [(set (match_operand:DF 0 "general_operand" "")
3107 (match_operand:DF 1 "general_operand" ""))]
3108 ""
3109- "
3110 {
3111- if (! reload_in_progress && ! reload_completed
3112- && ! ia64_move_ok (operands[0], operands[1]))
3113- operands[1] = force_reg (DFmode, operands[1]);
3114-}")
3115+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
3116+ if (!op1)
3117+ DONE;
3118+ operands[1] = op1;
3119+})
3120
3121 (define_insn "*movdf_internal"
3122 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
3123--- gcc/config/ia64/sysv4.h.jj Mon Jun 3 17:24:18 2002
3124+++ gcc/config/ia64/sysv4.h Wed Jun 19 19:33:52 2002
3125@@ -42,8 +42,7 @@ extern int size_directive_output;
3126 #undef ASM_OUTPUT_ALIGNED_LOCAL
3127 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
3128 do { \
3129- if ((DECL) \
3130- && XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] == SDATA_NAME_FLAG_CHAR) \
3131+ if ((DECL) && sdata_symbolic_operand (XEXP (DECL_RTL (DECL), 0), Pmode)) \
3132 sbss_section (); \
3133 else \
3134 bss_section (); \
3135@@ -62,8 +61,8 @@ do { \
3136 #define ASM_OUTPUT_LABELREF(STREAM, NAME) \
3137 do { \
3138 const char *name_ = NAME; \
3139- if (*name_ == SDATA_NAME_FLAG_CHAR) \
3140- name_++; \
3141+ if (*name_ == ENCODE_SECTION_INFO_CHAR) \
3142+ name_ += 2; \
3143 if (*name_ == '*') \
3144 name_++; \
3145 else \
3146@@ -149,9 +148,11 @@ do { \
3147 0 .text
3148 1 .rodata
3149 2 .data
3150- 3 .sdata
3151- 4 .bss
3152+ 3 .bss
3153+ 4 .sdata
3154 5 .sbss
3155+ 6 .tdata
3156+ 7 .tbss
3157 */
3158 #define DO_SELECT_SECTION(SECNUM, DECL, RELOC) \
3159 do \
3160@@ -167,9 +168,10 @@ do { \
3161 } \
3162 else if (TREE_CODE (DECL) == VAR_DECL) \
3163 { \
3164- if (XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] \
3165- == SDATA_NAME_FLAG_CHAR) \
3166- SECNUM = 3; \
3167+ if (DECL_THREAD_LOCAL (DECL)) \
3168+ SECNUM = 6; \
3169+ else if (sdata_symbolic_operand (XEXP (DECL_RTL (DECL), 0), Pmode))\
3170+ SECNUM = 4; \
3171 /* ??? We need the extra RELOC check, because the default \
3172 is to only check RELOC if flag_pic is set, and we don't \
3173 set flag_pic (yet?). */ \
3174@@ -184,13 +186,18 @@ do { \
3175 SECNUM = 0x201; \
3176 else \
3177 SECNUM = 0x301; \
3178+ \
3179+ if (SECNUM >= 2 \
3180+ && (!DECL_INITIAL (DECL) \
3181+ || DECL_INITIAL (DECL) == error_mark_node)) \
3182+ SECNUM++; \
3183 } \
3184 /* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL, \
3185 in which case we can't put it in a shared library rodata. */ \
3186 else if (flag_pic && (RELOC)) \
3187- SECNUM = 3; \
3188- else \
3189 SECNUM = 2; \
3190+ else \
3191+ SECNUM = 1; \
3192 } \
3193 while (0)
3194
3195@@ -206,8 +213,8 @@ do { \
3196 text_section, \
3197 const_section, \
3198 data_section, \
3199- sdata_section, \
3200 bss_section, \
3201+ sdata_section, \
3202 sbss_section \
3203 }; \
3204 \
3205@@ -217,6 +224,12 @@ do { \
3206 \
3207 switch (sec) \
3208 { \
3209+ case 6: \
3210+ named_section (NULL_TREE, ".tdata", RELOC); \
3211+ break; \
3212+ case 7: \
3213+ named_section (NULL_TREE, ".tbss", RELOC); \
3214+ break; \
3215 case 0x101: \
3216 mergeable_string_section (DECL, ALIGN, 0); \
3217 break; \
3218@@ -244,9 +257,11 @@ do { \
3219 { ".text.", ".gnu.linkonce.t." }, \
3220 { ".rodata.", ".gnu.linkonce.r." }, \
3221 { ".data.", ".gnu.linkonce.d." }, \
3222- { ".sdata.", ".gnu.linkonce.s." }, \
3223 { ".bss.", ".gnu.linkonce.b." }, \
3224- { ".sbss.", ".gnu.linkonce.sb." } \
3225+ { ".sdata.", ".gnu.linkonce.s." }, \
3226+ { ".sbss.", ".gnu.linkonce.sb." }, \
3227+ { ".tdata.", ".gnu.linkonce.td." }, \
3228+ { ".tbss.", ".gnu.linkonce.tb." } \
3229 }; \
3230 \
3231 int nlen, plen, sec; \
3232--- gcc/config/elfos.h.jj Tue Dec 18 01:30:48 2001
3233+++ gcc/config/elfos.h Wed Jun 19 19:33:52 2002
3234@@ -288,24 +288,28 @@ const_section () \
3235 const char *name; \
3236 char *string; \
3237 const char *prefix; \
3238- static const char *const prefixes[4][2] = \
3239+ static const char *const prefixes[][2] = \
3240 { \
3241 { ".text.", ".gnu.linkonce.t." }, \
3242 { ".rodata.", ".gnu.linkonce.r." }, \
3243 { ".data.", ".gnu.linkonce.d." }, \
3244- { ".bss.", ".gnu.linkonce.b." } \
3245+ { ".bss.", ".gnu.linkonce.b." }, \
3246+ { ".tdata", ".gnu.linkonce.td." }, \
3247+ { ".tbss", ".gnu.linkonce.tb." }, \
3248 }; \
3249 \
3250 if (TREE_CODE (DECL) == FUNCTION_DECL) \
3251 sec = 0; \
3252 else if (DECL_INITIAL (DECL) == 0 \
3253 || DECL_INITIAL (DECL) == error_mark_node) \
3254- sec = 3; \
3255+ sec = 3; \
3256 else if (DECL_READONLY_SECTION (DECL, RELOC)) \
3257 sec = 1; \
3258 else \
3259 sec = 2; \
3260- \
3261+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) \
3262+ sec = (sec == 3 ? 5 : 4); \
3263+ \
3264 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
3265 /* Strip off any encoding in name. */ \
3266 STRIP_NAME_ENCODING (name, name); \
3267@@ -367,10 +371,18 @@ const_section () \
3268 } \
3269 else if (TREE_CODE (DECL) == VAR_DECL) \
3270 { \
3271- if (!TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \
3272- || !DECL_INITIAL (DECL) \
3273- || (DECL_INITIAL (DECL) != error_mark_node \
3274- && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \
3275+ if (DECL_THREAD_LOCAL (DECL)) \
3276+ { \
3277+ if (!DECL_INITIAL (DECL) \
3278+ || DECL_INITIAL (DECL) == error_mark_node) \
3279+ named_section (NULL_TREE, ".tbss", RELOC); \
3280+ else \
3281+ named_section (NULL_TREE, ".tdata", RELOC); \
3282+ } \
3283+ else if (!TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \
3284+ || !DECL_INITIAL (DECL) \
3285+ || (DECL_INITIAL (DECL) != error_mark_node \
3286+ && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \
3287 { \
3288 if (flag_pic && ((RELOC) & 2)) \
3289 named_section (NULL_TREE, ".data.rel", RELOC); \
3290--- gcc/fixinc/fixincl.x.jj Thu May 2 12:15:15 2002
3291+++ gcc/fixinc/fixincl.x Wed Jun 19 19:33:52 2002
3292@@ -5,7 +5,7 @@
3293 * files which are fixed to work correctly with ANSI C and placed in a
3294 * directory that GNU C will search.
3295 *
3c74150d
JB
3296- * This file contains 151 fixup descriptions.
3297+ * This file contains 152 fixup descriptions.
5384b728 3298 *
3299 * See README for more information.
3300 *
3301@@ -4568,6 +4568,41 @@ static const char* apzSysz_Stdlib_For_Su
3302
3303 /* * * * * * * * * * * * * * * * * * * * * * * * * *
3304 *
3305+ * Description of Thread_Keyword fix
3306+ */
3307+tSCC zThread_KeywordName[] =
3308+ "thread_keyword";
3309+
3310+/*
3311+ * File name selection pattern
3312+ */
3313+tSCC zThread_KeywordList[] =
3314+ "|pthread.h|bits/sigthread.h|";
3315+/*
3316+ * Machine/OS name selection pattern
3317+ */
3318+#define apzThread_KeywordMachs (const char**)NULL
3319+
3320+/*
3321+ * content selection pattern - do fix if pattern found
3322+ */
3323+tSCC zThread_KeywordSelect0[] =
3324+ " __thread([,)])";
3325+
3326+#define THREAD_KEYWORD_TEST_CT 1
3327+static tTestDesc aThread_KeywordTests[] = {
3328+ { TT_EGREP, zThread_KeywordSelect0, (regex_t*)NULL }, };
3329+
3330+/*
3331+ * Fix Command Arguments for Thread_Keyword
3332+ */
3333+static const char* apzThread_KeywordPatch[] = {
3334+ "format",
3335+ " __thr%1",
3336+ (char*)NULL };
3337+
3338+/* * * * * * * * * * * * * * * * * * * * * * * * * *
3339+ *
3340 * Description of Tinfo_Cplusplus fix
3341 */
3342 tSCC zTinfo_CplusplusName[] =
3343@@ -5581,9 +5616,9 @@ static const char* apzX11_SprintfPatch[]
3344 *
3345 * List of all fixes
3346 */
3c74150d
JB
3347-#define REGEX_COUNT 163
3348+#define REGEX_COUNT 164
5384b728 3349 #define MACH_LIST_SIZE_LIMIT 279
3c74150d
JB
3350-#define FIX_COUNT 151
3351+#define FIX_COUNT 152
5384b728 3352
3353 /*
3354 * Enumerate the fixes
3355@@ -5705,6 +5740,7 @@ typedef enum {
3356 SVR4_PROFIL_FIXIDX,
3357 SYSV68_STRING_FIXIDX,
3358 SYSZ_STDLIB_FOR_SUN_FIXIDX,
3359+ THREAD_KEYWORD_FIXIDX,
3360 TINFO_CPLUSPLUS_FIXIDX,
3361 ULTRIX_ATEXIT_PARAM_FIXIDX,
3362 ULTRIX_ATOF_PARAM_FIXIDX,
3363@@ -6314,6 +6350,11 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
3364 SYSZ_STDLIB_FOR_SUN_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
3365 aSysz_Stdlib_For_SunTests, apzSysz_Stdlib_For_SunPatch, 0 },
3366
3367+ { zThread_KeywordName, zThread_KeywordList,
3368+ apzThread_KeywordMachs,
3369+ THREAD_KEYWORD_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
3370+ aThread_KeywordTests, apzThread_KeywordPatch, 0 },
3371+
3372 { zTinfo_CplusplusName, zTinfo_CplusplusList,
3373 apzTinfo_CplusplusMachs,
3374 TINFO_CPLUSPLUS_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
3375--- gcc/fixinc/inclhack.def.jj Thu May 2 12:15:17 2002
3376+++ gcc/fixinc/inclhack.def Wed Jun 19 19:33:52 2002
3377@@ -1,4 +1,3 @@
3378-
3379 /* -*- Mode: C -*- */
3380
3381 autogen definitions fixincl;
3382@@ -2886,6 +2885,24 @@ fix = {
3383 };
3384
3385
3386+/*
3387+ * __thread is now a keyword.
3388+ */
3389+fix = {
3390+ hackname = thread_keyword;
3391+ files = "pthread.h";
3392+ files = "bits/sigthread.h";
3393+ select = " __thread([,)])";
3394+ c_fix = format;
3395+ c_fix_arg = " __thr%1";
3396+
3397+ test_text =
3398+ "extern int pthread_create (pthread_t *__restrict __thread,\n"
3399+ "extern int pthread_kill (pthread_t __thread, int __signo);\n"
3400+ "extern int pthread_cancel (pthread_t __thread);";
3401+};
3402+
3403+
3404 /*
3405 * if the #if says _cplusplus, not the double underscore __cplusplus
3406 * that it should be
3407--- gcc/testsuite/g++.dg/dg.exp.jj Thu Feb 14 13:26:12 2002
3408+++ gcc/testsuite/g++.dg/dg.exp Wed Jun 19 19:33:52 2002
3409@@ -28,10 +28,12 @@ if ![info exists DEFAULT_CXXFLAGS] then
3410 # Initialize `dg'.
3411 dg-init
3412
3413-# Gather a list of all tests, excluding those in special/; those are handled
3414-# well, specially.
3415-set all [lsort [find $srcdir/$subdir *.C]]
3416-set tests [prune [prune $all $srcdir/$subdir/special/*] $srcdir/$subdir/debug/*]
3417+# Gather a list of all tests, with the exception of those in directories
3418+# that are handled specially.
3419+set tests [lsort [find $srcdir/$subdir *.C]]
3420+set tests [prune $tests $srcdir/$subdir/debug/*]
3421+set tests [prune $tests $srcdir/$subdir/special/*]
3422+set tests [prune $tests $srcdir/$subdir/tls/*]
3423
3424 # Main loop.
3425 dg-runtest $tests "" $DEFAULT_CXXFLAGS
3426--- gcc/testsuite/g++.dg/tls/diag-1.C.jj Wed Jun 19 19:33:52 2002
3427+++ gcc/testsuite/g++.dg/tls/diag-1.C Wed Jun 19 19:33:52 2002
3428@@ -0,0 +1,30 @@
3429+/* Valid __thread specifiers. */
3430+
3431+__thread int g1;
3432+extern __thread int g2;
3433+static __thread int g3;
3434+
3435+void foo()
3436+{
3437+ extern __thread int l1;
3438+ static __thread int l2;
3439+}
3440+
3441+struct A {
3442+ static __thread int i;
3443+};
3444+
3445+__thread int A::i = 42;
3446+
3447+template <typename T> struct B {
3448+ static __thread T t;
3449+};
3450+
3451+template <typename T>
3452+__thread T B<T>::t = 42;
3453+
3454+void bar ()
3455+{
3456+ int j = B<int>::t;
3457+ int k = B<const int>::t;
3458+}
3459--- gcc/testsuite/g++.dg/tls/diag-2.C.jj Wed Jun 19 19:33:52 2002
3460+++ gcc/testsuite/g++.dg/tls/diag-2.C Wed Jun 19 19:33:52 2002
3461@@ -0,0 +1,25 @@
3462+/* Invalid __thread specifiers. */
3463+
3464+__thread extern int g1; /* { dg-error "`__thread' before `extern'" } */
3465+__thread static int g2; /* { dg-error "`__thread' before `static'" } */
3466+__thread __thread int g3; /* { dg-error "duplicate `__thread'" } */
3467+typedef __thread int g4; /* { dg-error "multiple storage classes" } */
3468+
3469+void foo()
3470+{
3471+ __thread int l1; /* { dg-error "implicitly auto and declared `__thread'" } */
3472+ auto __thread int l2; /* { dg-error "multiple storage classes" } */
3473+ __thread extern int l3; /* { dg-error "`__thread' before `extern'" } */
3474+ register __thread int l4; /* { dg-error "multiple storage classes" } */
3475+}
3476+
3477+__thread void f1 (); /* { dg-error "invalid for function" } */
3478+extern __thread void f2 (); /* { dg-error "invalid for function" } */
3479+static __thread void f3 (); /* { dg-error "invalid for function" } */
3480+__thread void f4 () { } /* { dg-error "invalid for function" } */
3481+
3482+void bar(__thread int p1); /* { dg-error "(invalid in parameter)|(specified for parameter)" } */
3483+
3484+struct A {
3485+ __thread int i; /* { dg-error "specified for field" } */
3486+};
3487--- gcc/testsuite/g++.dg/tls/init-1.C.jj Wed Jun 19 19:33:52 2002
3488+++ gcc/testsuite/g++.dg/tls/init-1.C Wed Jun 19 19:33:52 2002
3489@@ -0,0 +1,13 @@
3490+/* Valid initializations. */
3491+
3492+__thread int i = 42;
3493+
3494+static int j;
3495+__thread int *p = &j;
3496+
3497+/* Note that this is valid in C++ (unlike C) as a run-time initialization. */
3498+int *q = &i;
3499+
3500+/* Valid because "const int k" is an integral constant expression in C++. */
3501+__thread const int k = 42;
3502+__thread const int l = k;
3503--- gcc/testsuite/g++.dg/tls/init-2.C.jj Wed Jun 19 19:33:52 2002
3504+++ gcc/testsuite/g++.dg/tls/init-2.C Wed Jun 19 19:33:52 2002
3505@@ -0,0 +1,13 @@
3506+/* Invalid initializations. */
3507+
3508+extern __thread int i;
3509+__thread int *p = &i; /* { dg-error "run-time initialization" } */
3510+
3511+extern int f();
3512+__thread int j = f(); /* { dg-error "run-time initialization" } */
3513+
3514+struct S
3515+{
3516+ S();
3517+};
3518+__thread S s; /* { dg-error "run-time initialization" } */
3519--- gcc/testsuite/g++.dg/tls/tls.exp.jj Wed Jun 19 19:33:52 2002
3520+++ gcc/testsuite/g++.dg/tls/tls.exp Wed Jun 19 19:33:52 2002
3521@@ -0,0 +1,44 @@
3522+# Copyright (C) 2002 Free Software Foundation, Inc.
3523+
3524+# This program is free software; you can redistribute it and/or modify
3525+# it under the terms of the GNU General Public License as published by
3526+# the Free Software Foundation; either version 2 of the License, or
3527+# (at your option) any later version.
3528+#
3529+# This program is distributed in the hope that it will be useful,
3530+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3531+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3532+# GNU General Public License for more details.
3533+#
3534+# You should have received a copy of the GNU General Public License
3535+# along with this program; if not, write to the Free Software
3536+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3537+
3538+# GCC testsuite that uses the `dg.exp' driver.
3539+
3540+# Load support procs.
3541+load_lib g++-dg.exp
3542+
3543+# Test for thread-local data supported by the platform. If it
3544+# isn't, everything will fail with the "not supported" message.
3545+
3546+set comp_output [g++_target_compile \
3547+ "$srcdir/$subdir/trivial.C" "trivial.S" assembly ""]
3548+if { [string match "*not supported*" $comp_output] } {
3549+ return 0
3550+}
3551+
3552+# If a testcase doesn't have special options, use these.
3553+global DEFAULT_CXXFLAGS
3554+if ![info exists DEFAULT_CXXFLAGS] then {
3555+ set DEFAULT_CXXFLAGS " -ansi -pedantic-errors -Wno-long-long"
3556+}
3557+
3558+# Initialize `dg'.
3559+dg-init
3560+
3561+# Main loop.
3562+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] "" $DEFAULT_CXXFLAGS
3563+
3564+# All done.
3565+dg-finish
3566--- gcc/testsuite/g++.dg/tls/trivial.C.jj Wed Jun 19 19:33:52 2002
3567+++ gcc/testsuite/g++.dg/tls/trivial.C Wed Jun 19 19:33:52 2002
3568@@ -0,0 +1 @@
3569+__thread int i;
3570--- gcc/testsuite/gcc.dg/tls/diag-1.c.jj Wed Jun 19 19:33:52 2002
3571+++ gcc/testsuite/gcc.dg/tls/diag-1.c Wed Jun 19 19:33:52 2002
3572@@ -0,0 +1,11 @@
3573+/* Valid __thread specifiers. */
3574+
3575+__thread int g1;
3576+extern __thread int g2;
3577+static __thread int g3;
3578+
3579+void foo()
3580+{
3581+ extern __thread int l1;
3582+ static __thread int l2;
3583+}
3584--- gcc/testsuite/gcc.dg/tls/diag-2.c.jj Wed Jun 19 19:33:52 2002
3585+++ gcc/testsuite/gcc.dg/tls/diag-2.c Wed Jun 19 19:33:52 2002
3586@@ -0,0 +1,21 @@
3587+/* Invalid __thread specifiers. */
3588+
3589+__thread extern int g1; /* { dg-error "`__thread' before `extern'" } */
3590+__thread static int g2; /* { dg-error "`__thread' before `static'" } */
3591+__thread __thread int g3; /* { dg-error "duplicate `__thread'" } */
3592+typedef __thread int g4; /* { dg-error "multiple storage classes" } */
3593+
3594+void foo()
3595+{
3596+ __thread int l1; /* { dg-error "implicitly auto and declared `__thread'" } */
3597+ auto __thread int l2; /* { dg-error "multiple storage classes" } */
3598+ __thread extern int l3; /* { dg-error "`__thread' before `extern'" } */
3599+ register __thread int l4; /* { dg-error "multiple storage classes" } */
3600+}
3601+
3602+__thread void f1 (); /* { dg-error "invalid storage class for function" } */
3603+extern __thread void f2 (); /* { dg-error "invalid storage class for function" } */
3604+static __thread void f3 (); /* { dg-error "invalid storage class for function" } */
3605+__thread void f4 () { } /* { dg-error "function definition declared `__thread'" } */
3606+
3607+void bar(__thread int p1); /* { dg-error "storage class specified for parameter" } */
3608--- gcc/testsuite/gcc.dg/tls/init-1.c.jj Wed Jun 19 19:33:52 2002
3609+++ gcc/testsuite/gcc.dg/tls/init-1.c Wed Jun 19 19:33:52 2002
3610@@ -0,0 +1,4 @@
3611+/* Invalid initializations. */
3612+
3613+extern __thread int i;
3614+int *p = &i; /* { dg-error "initializer element is not constant" } */
3615--- gcc/testsuite/gcc.dg/tls/tls.exp.jj Wed Jun 19 19:33:52 2002
3616+++ gcc/testsuite/gcc.dg/tls/tls.exp Wed Jun 19 19:33:52 2002
3617@@ -0,0 +1,45 @@
3618+# Copyright (C) 2002 Free Software Foundation, Inc.
3619+
3620+# This program is free software; you can redistribute it and/or modify
3621+# it under the terms of the GNU General Public License as published by
3622+# the Free Software Foundation; either version 2 of the License, or
3623+# (at your option) any later version.
3624+#
3625+# This program is distributed in the hope that it will be useful,
3626+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3627+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3628+# GNU General Public License for more details.
3629+#
3630+# You should have received a copy of the GNU General Public License
3631+# along with this program; if not, write to the Free Software
3632+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3633+
3634+# GCC testsuite that uses the `dg.exp' driver.
3635+
3636+# Load support procs.
3637+load_lib gcc-dg.exp
3638+
3639+# Test for thread-local data supported by the platform. If it
3640+# isn't, everything will fail with the "not supported" message.
3641+
3642+set comp_output [gcc_target_compile \
3643+ "$srcdir/$subdir/trivial.c" "trivial.S" assembly ""]
3644+if { [string match "*not supported*" $comp_output] } {
3645+ return 0
3646+}
3647+
3648+# If a testcase doesn't have special options, use these.
3649+global DEFAULT_CFLAGS
3650+if ![info exists DEFAULT_CFLAGS] then {
3651+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
3652+}
3653+
3654+# Initialize `dg'.
3655+dg-init
3656+
3657+# Main loop.
3658+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
3659+ "" $DEFAULT_CFLAGS
3660+
3661+# All done.
3662+dg-finish
3663--- gcc/testsuite/gcc.dg/tls/trivial.c.jj Wed Jun 19 19:33:52 2002
3664+++ gcc/testsuite/gcc.dg/tls/trivial.c Wed Jun 19 19:33:52 2002
3665@@ -0,0 +1 @@
3666+__thread int i;
3667--- gcc/c-common.h.jj Wed Apr 17 15:34:36 2002
3668+++ gcc/c-common.h Wed Jun 19 19:33:52 2002
3669@@ -58,7 +58,7 @@ enum rid
3670 RID_VOLATILE, RID_SIGNED, RID_AUTO, RID_RESTRICT,
3671
3672 /* C extensions */
3673- RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX,
3674+ RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX, RID_THREAD,
3675
3676 /* C++ */
3677 RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE,
3678--- gcc/c-decl.c.jj Wed Jun 19 19:33:50 2002
3679+++ gcc/c-decl.c Wed Jun 19 19:33:52 2002
3680@@ -3571,9 +3571,19 @@ start_decl (declarator, declspecs, initi
3681 /* ANSI specifies that a tentative definition which is not merged with
3682 a non-tentative definition behaves exactly like a definition with an
3683 initializer equal to zero. (Section 3.7.2)
3684- -fno-common gives strict ANSI behavior. Usually you don't want it.
3685- This matters only for variables with external linkage. */
3686- if (! flag_no_common || ! TREE_PUBLIC (decl))
3687+
3688+ -fno-common gives strict ANSI behavior, though this tends to break
3689+ a large body of code that grew up without this rule.
3690+
3691+ Thread-local variables are never common, since there's no entrenched
3692+ body of code to break, and it allows more efficient variable references
3693+ in the presense of dynamic linking. */
3694+
3695+ if (TREE_CODE (decl) == VAR_DECL
3696+ && !initialized
3697+ && TREE_PUBLIC (decl)
3698+ && !DECL_THREAD_LOCAL (decl)
3699+ && !flag_no_common)
3700 DECL_COMMON (decl) = 1;
3701
3702 /* Set attributes here so if duplicate decl, will have proper attributes. */
3703@@ -4172,7 +4182,7 @@ grokdeclarator (declarator, declspecs, d
3704 enum rid i = C_RID_CODE (id);
3705 if ((int) i <= (int) RID_LAST_MODIFIER)
3706 {
3707- if (i == RID_LONG && (specbits & (1 << (int) i)))
3708+ if (i == RID_LONG && (specbits & (1 << (int) RID_LONG)))
3709 {
3710 if (longlong)
3711 error ("`long long long' is too long for GCC");
3712@@ -4186,6 +4196,19 @@ grokdeclarator (declarator, declspecs, d
3713 }
3714 else if (specbits & (1 << (int) i))
3715 pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
3716+
3717+ /* Diagnose "__thread extern". Recall that this list
3718+ is in the reverse order seen in the text. */
3719+ if (i == RID_THREAD
3720+ && (specbits & (1 << (int) RID_EXTERN
3721+ | 1 << (int) RID_STATIC)))
3722+ {
3723+ if (specbits & 1 << (int) RID_EXTERN)
3724+ error ("`__thread' before `extern'");
3725+ else
3726+ error ("`__thread' before `static'");
3727+ }
3728+
3729 specbits |= 1 << (int) i;
3730 goto found;
3731 }
3732@@ -4438,6 +4461,12 @@ grokdeclarator (declarator, declspecs, d
3733 if (specbits & 1 << (int) RID_REGISTER) nclasses++;
3734 if (specbits & 1 << (int) RID_TYPEDEF) nclasses++;
3735
3736+ /* "static __thread" and "extern __thread" are allowed. */
3737+ if ((specbits & (1 << (int) RID_THREAD
3738+ | 1 << (int) RID_STATIC
3739+ | 1 << (int) RID_EXTERN)) == (1 << (int) RID_THREAD))
3740+ nclasses++;
3741+
3742 /* Warn about storage classes that are invalid for certain
3743 kinds of declarations (parameters, typenames, etc.). */
3744
3745@@ -4447,7 +4476,8 @@ grokdeclarator (declarator, declspecs, d
3746 && (specbits
3747 & ((1 << (int) RID_REGISTER)
3748 | (1 << (int) RID_AUTO)
3749- | (1 << (int) RID_TYPEDEF))))
3750+ | (1 << (int) RID_TYPEDEF)
3751+ | (1 << (int) RID_THREAD))))
3752 {
3753 if (specbits & 1 << (int) RID_AUTO
3754 && (pedantic || current_binding_level == global_binding_level))
3755@@ -4456,8 +4486,10 @@ grokdeclarator (declarator, declspecs, d
3756 error ("function definition declared `register'");
3757 if (specbits & 1 << (int) RID_TYPEDEF)
3758 error ("function definition declared `typedef'");
3759+ if (specbits & 1 << (int) RID_THREAD)
3760+ error ("function definition declared `__thread'");
3761 specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
3762- | (1 << (int) RID_AUTO));
3763+ | (1 << (int) RID_AUTO) | (1 << (int) RID_THREAD));
3764 }
3765 else if (decl_context != NORMAL && nclasses > 0)
3766 {
3767@@ -4480,7 +4512,7 @@ grokdeclarator (declarator, declspecs, d
3768 }
3769 specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
3770 | (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
3771- | (1 << (int) RID_EXTERN));
3772+ | (1 << (int) RID_EXTERN) | (1 << (int) RID_THREAD));
3773 }
3774 }
3775 else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
3776@@ -4491,12 +4523,25 @@ grokdeclarator (declarator, declspecs, d
3777 else
3778 error ("`%s' has both `extern' and initializer", name);
3779 }
3780- else if (specbits & 1 << (int) RID_EXTERN && funcdef_flag
3781- && current_binding_level != global_binding_level)
3782- error ("nested function `%s' declared `extern'", name);
3783- else if (current_binding_level == global_binding_level
3784- && specbits & (1 << (int) RID_AUTO))
3785- error ("top-level declaration of `%s' specifies `auto'", name);
3786+ else if (current_binding_level == global_binding_level)
3787+ {
3788+ if (specbits & 1 << (int) RID_AUTO)
3789+ error ("top-level declaration of `%s' specifies `auto'", name);
3790+ }
3791+ else
3792+ {
3793+ if (specbits & 1 << (int) RID_EXTERN && funcdef_flag)
3794+ error ("nested function `%s' declared `extern'", name);
3795+ else if ((specbits & (1 << (int) RID_THREAD
3796+ | 1 << (int) RID_EXTERN
3797+ | 1 << (int) RID_STATIC))
3798+ == (1 << (int) RID_THREAD))
3799+ {
3800+ error ("function-scope `%s' implicitly auto and declared `__thread'",
3801+ name);
3802+ specbits &= ~(1 << (int) RID_THREAD);
3803+ }
3804+ }
3805 }
3806
3807 /* Now figure out the structure of the declarator proper.
3808@@ -5095,6 +5140,8 @@ grokdeclarator (declarator, declspecs, d
3809 pedwarn ("invalid storage class for function `%s'", name);
3810 if (specbits & (1 << (int) RID_REGISTER))
3811 error ("invalid storage class for function `%s'", name);
3812+ if (specbits & (1 << (int) RID_THREAD))
3813+ error ("invalid storage class for function `%s'", name);
3814 /* Function declaration not at top level.
3815 Storage classes other than `extern' are not allowed
3816 and `extern' makes no difference. */
3817@@ -5187,22 +5234,32 @@ grokdeclarator (declarator, declspecs, d
3818 pedwarn_with_decl (decl, "variable `%s' declared `inline'");
3819
3820 DECL_EXTERNAL (decl) = extern_ref;
3821+
3822 /* At top level, the presence of a `static' or `register' storage
3823 class specifier, or the absence of all storage class specifiers
3824 makes this declaration a definition (perhaps tentative). Also,
3825 the absence of both `static' and `register' makes it public. */
3826 if (current_binding_level == global_binding_level)
3827 {
3828- TREE_PUBLIC (decl)
3829- = !(specbits
3830- & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)));
3831- TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
3832+ TREE_PUBLIC (decl) = !(specbits & ((1 << (int) RID_STATIC)
3833+ | (1 << (int) RID_REGISTER)));
3834+ TREE_STATIC (decl) = !extern_ref;
3835 }
3836 /* Not at top level, only `static' makes a static definition. */
3837 else
3838 {
3839 TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
3840- TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
3841+ TREE_PUBLIC (decl) = extern_ref;
3842+ }
3843+
3844+ if (specbits & 1 << (int) RID_THREAD)
3845+ {
3846+ if (targetm.have_tls)
3847+ DECL_THREAD_LOCAL (decl) = 1;
3848+ else
3849+ /* A mere warning is sure to result in improper semantics
3850+ at runtime. Don't bother to allow this to compile. */
3851+ error ("thread-local storage not supported for this target");
3852 }
3853 }
3854
3855--- gcc/c-parse.in.jj Wed Apr 17 15:34:46 2002
3856+++ gcc/c-parse.in Wed Jun 19 19:33:52 2002
3857@@ -3329,6 +3329,7 @@ static const struct resword reswords[] =
3858 { "__restrict__", RID_RESTRICT, 0 },
3859 { "__signed", RID_SIGNED, 0 },
3860 { "__signed__", RID_SIGNED, 0 },
3861+ { "__thread", RID_THREAD, 0 },
3862 { "__typeof", RID_TYPEOF, 0 },
3863 { "__typeof__", RID_TYPEOF, 0 },
3864 { "__unbounded", RID_UNBOUNDED, 0 },
3865@@ -3424,6 +3425,7 @@ static const short rid_to_yy[RID_MAX] =
3866 /* RID_BOUNDED */ TYPE_QUAL,
3867 /* RID_UNBOUNDED */ TYPE_QUAL,
3868 /* RID_COMPLEX */ TYPESPEC,
3869+ /* RID_THREAD */ SCSPEC,
3870
3871 /* C++ */
3872 /* RID_FRIEND */ 0,
3873--- gcc/config.in.jj Sat Jun 8 00:38:25 2002
3874+++ gcc/config.in Wed Jun 19 19:33:52 2002
3875@@ -523,6 +523,9 @@
3876 /* Define if your assembler supports marking sections with SHF_MERGE flag. */
3877 #undef HAVE_GAS_SHF_MERGE
3878
3879+/* Define if your assembler supports thread-local storage. */
3880+#undef HAVE_AS_TLS
3881+
3882 /* Define if your assembler supports explicit relocations. */
3883 #undef HAVE_AS_EXPLICIT_RELOCS
3884
3885--- gcc/flags.h.jj Sat Mar 23 12:02:51 2002
3886+++ gcc/flags.h Wed Jun 19 19:33:52 2002
3887@@ -450,11 +450,22 @@ extern int flag_pretend_float;
3888
3889 extern int flag_pedantic_errors;
3890
3891-/* Nonzero means generate position-independent code.
3892- This is not fully implemented yet. */
3893+/* Nonzero means generate position-independent code. 1 vs 2 for a
3894+ target-dependent "small" or "large" mode. */
3895
3896 extern int flag_pic;
3897
3898+/* Set to the default thread-local storage (tls) model to use. */
3899+
3900+enum tls_model {
3901+ TLS_MODEL_GLOBAL_DYNAMIC = 1,
3902+ TLS_MODEL_LOCAL_DYNAMIC,
3903+ TLS_MODEL_INITIAL_EXEC,
3904+ TLS_MODEL_LOCAL_EXEC
3905+};
3906+
3907+extern enum tls_model flag_tls_default;
3908+
3909 /* Nonzero means generate extra code for exception handling and enable
3910 exception handling. */
3911
3912--- gcc/configure.in.jj Sat Jun 8 00:38:27 2002
3913+++ gcc/configure.in Wed Jun 19 19:33:52 2002
3914@@ -1715,6 +1715,72 @@ if test x"$gcc_cv_as_shf_merge" = xyes;
3915 fi
3916 AC_MSG_RESULT($gcc_cv_as_shf_merge)
3917
3918+AC_MSG_CHECKING(assembler thread-local storage support)
3919+gcc_cv_as_tls=no
3920+conftest_s=
3921+tls_first_major=
3922+tls_first_minor=
3923+case "$target" in
3924+changequote(,)dnl
3925+ i[34567]86-*-*)
3926+changequote([,])dnl
3927+ conftest_s='
3928+ .section ".tdata","awT",@progbits
3929+foo: .long 25
3930+ .text
3931+ movl %gs:0, %eax
3932+ leal foo@TLSGD(,%ebx,1), %eax
3933+ leal foo@TLSLDM(%ebx), %eax
3934+ leal foo@DTPOFF(%eax), %edx
3935+ movl foo@GOTTPOFF(%ebx), %eax
3936+ subl foo@GOTTPOFF(%ebx), %eax
3937+ movl $foo@TPOFF, %eax
3938+ subl $foo@TPOFF, %eax
3939+ leal foo@NTPOFF(%ecx), %eax'
3940+ tls_first_major=2
3941+ tls_first_minor=13
3942+ ;;
3943+ ia64-*-*)
3944+ conftest_s='
3945+ .section ".tdata","awT",@progbits
3946+foo: data8 25
3947+ .text
3948+ addl r16 = @ltoff(@dtpmod(foo#)), gp
3949+ addl r17 = @ltoff(@dtprel(foo#)), gp
3950+ addl r18 = @ltoff(@tprel(foo#)), gp
3951+ addl r19 = @dtprel(foo#), gp
3952+ adds r21 = @dtprel(foo#), r13
3953+ movl r23 = @dtprel(foo#)
3954+ addl r20 = @tprel(foo#), gp
3955+ adds r22 = @tprel(foo#), r13
3956+ movl r24 = @tprel(foo#)'
3957+ tls_first_major=2
3958+ tls_first_minor=13
3959+ ;;
3960+esac
3961+if test -z "$tls_first_major"; then
3962+ :
3963+elif test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x
3964+then
3965+ if test "$gcc_cv_gas_major_version" -eq "$tls_first_major" \
3966+ -a "$gcc_cv_gas_minor_version" -ge "$tls_first_minor" \
3967+ -o "$gcc_cv_gas_major_version" -gt "$tls_first_major"; then
3968+ gcc_cv_as_tls=yes
3969+ fi
3970+elif test x$gcc_cv_as != x; then
3971+ echo "$conftest_s" > conftest.s
3972+ if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1
3973+ then
3974+ gcc_cv_as_tls=yes
3975+ fi
3976+ rm -f conftest.s conftest.o
3977+fi
3978+if test "$gcc_cv_as_tls" = yes; then
3979+ AC_DEFINE(HAVE_AS_TLS, 1,
3980+ [Define if your assembler supports thread-local storage.])
3981+fi
3982+AC_MSG_RESULT($gcc_cv_as_tls)
3983+
3984 case "$target" in
3985 # All TARGET_ABI_OSF targets.
3986 alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*)
3987--- gcc/configure.jj Sat Jun 8 00:38:27 2002
3988+++ gcc/configure Wed Jun 19 22:28:09 2002
3989@@ -7391,6 +7391,73 @@ EOF
3990 fi
3991 echo "$ac_t""$gcc_cv_as_shf_merge" 1>&6
3992
3993+echo $ac_n "checking assembler thread-local storage support""... $ac_c" 1>&6
3994+echo "configure:7399: checking assembler thread-local storage support" >&5
3995+gcc_cv_as_tls=no
3996+conftest_s=
3997+tls_first_major=
3998+tls_first_minor=
3999+case "$target" in
4000+ i[34567]86-*-*)
4001+ conftest_s='
4002+ .section ".tdata","awT",@progbits
4003+foo: .long 25
4004+ .text
4005+ movl %gs:0, %eax
4006+ leal foo@TLSGD(,%ebx,1), %eax
4007+ leal foo@TLSLDM(%ebx), %eax
4008+ leal foo@DTPOFF(%eax), %edx
4009+ movl foo@GOTTPOFF(%ebx), %eax
4010+ subl foo@GOTTPOFF(%ebx), %eax
4011+ movl $foo@TPOFF, %eax
4012+ subl $foo@TPOFF, %eax
4013+ leal foo@NTPOFF(%ecx), %eax'
4014+ tls_first_major=2
4015+ tls_first_minor=13
4016+ ;;
4017+ ia64-*-*)
4018+ conftest_s='
4019+ .section ".tdata","awT",@progbits
4020+foo: data8 25
4021+ .text
4022+ addl r16 = @ltoff(@dtpmod(foo#)), gp
4023+ addl r17 = @ltoff(@dtprel(foo#)), gp
4024+ addl r18 = @ltoff(@tprel(foo#)), gp
4025+ addl r19 = @dtprel(foo#), gp
4026+ adds r21 = @dtprel(foo#), r13
4027+ movl r23 = @dtprel(foo#)
4028+ addl r20 = @tprel(foo#), gp
4029+ adds r22 = @tprel(foo#), r13
4030+ movl r24 = @tprel(foo#)'
4031+ tls_first_major=2
4032+ tls_first_minor=13
4033+ ;;
4034+esac
4035+if test -z "$tls_first_major"; then
4036+ :
4037+elif test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x
4038+then
4039+ if test "$gcc_cv_gas_major_version" -eq "$tls_first_major" \
4040+ -a "$gcc_cv_gas_minor_version" -ge "$tls_first_minor" \
4041+ -o "$gcc_cv_gas_major_version" -gt "$tls_first_major"; then
4042+ gcc_cv_as_tls=yes
4043+ fi
4044+elif test x$gcc_cv_as != x; then
4045+ echo "$conftest_s" > conftest.s
4046+ if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1
4047+ then
4048+ gcc_cv_as_tls=yes
4049+ fi
4050+ rm -f conftest.s conftest.o
4051+fi
4052+if test "$gcc_cv_as_tls" = yes; then
4053+ cat >> confdefs.h <<\EOF
4054+#define HAVE_AS_TLS 1
4055+EOF
4056+
4057+fi
4058+echo "$ac_t""$gcc_cv_as_tls" 1>&6
4059+
4060 case "$target" in
4061 # All TARGET_ABI_OSF targets.
4062 alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*)
4063--- gcc/output.h.jj Wed Jun 19 19:33:50 2002
4064+++ gcc/output.h Wed Jun 19 19:33:52 2002
4065@@ -514,7 +514,8 @@ extern void no_asm_to_stream PARAMS ((FI
4066 #define SECTION_STRINGS 0x10000 /* contains zero terminated strings without
4067 embedded zeros */
4068 #define SECTION_OVERRIDE 0x20000 /* allow override of default flags */
4069-#define SECTION_MACH_DEP 0x40000 /* subsequent bits reserved for target */
4070+#define SECTION_TLS 0x40000 /* contains thread-local storage */
4071+#define SECTION_MACH_DEP 0x80000 /* subsequent bits reserved for target */
4072
4073 extern unsigned int get_named_section_flags PARAMS ((const char *));
4074 extern bool set_named_section_flags PARAMS ((const char *, unsigned int));
4075--- gcc/print-tree.c.jj Mon Mar 18 23:19:57 2002
4076+++ gcc/print-tree.c Wed Jun 19 19:33:52 2002
4077@@ -363,6 +363,8 @@ print_node (file, prefix, node, indent)
4078
4079 if (TREE_CODE (node) == VAR_DECL && DECL_IN_TEXT_SECTION (node))
4080 fputs (" in-text-section", file);
4081+ if (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL (node))
4082+ fputs (" thread-local", file);
4083
4084 if (TREE_CODE (node) == PARM_DECL && DECL_TRANSPARENT_UNION (node))
4085 fputs (" transparent-union", file);
4086--- gcc/target-def.h.jj Tue Feb 12 16:19:14 2002
4087+++ gcc/target-def.h Wed Jun 19 19:33:52 2002
4088@@ -98,6 +98,10 @@ Foundation, 59 Temple Place - Suite 330,
4089 #define TARGET_HAVE_NAMED_SECTIONS false
4090 #endif
4091
4092+#ifndef TARGET_HAVE_TLS
4093+#define TARGET_HAVE_TLS false
4094+#endif
4095+
4096 #ifndef TARGET_ASM_EXCEPTION_SECTION
4097 #define TARGET_ASM_EXCEPTION_SECTION default_exception_section
4098 #endif
4099@@ -194,9 +198,10 @@ Foundation, 59 Temple Place - Suite 330,
4100 TARGET_INIT_BUILTINS, \
4101 TARGET_EXPAND_BUILTIN, \
4102 TARGET_SECTION_TYPE_FLAGS, \
4103+ TARGET_CANNOT_MODIFY_JUMPS_P, \
4104 TARGET_HAVE_NAMED_SECTIONS, \
4105 TARGET_HAVE_CTORS_DTORS, \
4106- TARGET_CANNOT_MODIFY_JUMPS_P \
4107+ TARGET_HAVE_TLS \
4108 }
4109
4110 #include "hooks.h"
4111--- gcc/target.h.jj Tue Feb 12 16:19:14 2002
4112+++ gcc/target.h Wed Jun 19 19:33:52 2002
4113@@ -178,6 +178,10 @@ struct gcc_target
4114 /* ??? Should be merged with SELECT_SECTION and UNIQUE_SECTION. */
4115 unsigned int (* section_type_flags) PARAMS ((tree, const char *, int));
4116
4117+ /* True if new jumps cannot be created, to replace existing ones or
4118+ not, at the current point in the compilation. */
4119+ bool (* cannot_modify_jumps_p) PARAMS ((void));
4120+
4121 /* True if arbitrary sections are supported. */
4122 bool have_named_sections;
4123
4124@@ -185,9 +189,8 @@ struct gcc_target
4125 false if we're using collect2 for the job. */
4126 bool have_ctors_dtors;
4127
4128- /* True if new jumps cannot be created, to replace existing ones or
4129- not, at the current point in the compilation. */
4130- bool (* cannot_modify_jumps_p) PARAMS ((void));
4131+ /* True if thread-local storage is supported. */
4132+ bool have_tls;
4133 };
4134
4135 extern struct gcc_target targetm;
4136--- gcc/toplev.c.jj Thu May 30 11:08:44 2002
4137+++ gcc/toplev.c Wed Jun 19 19:33:52 2002
4138@@ -682,12 +682,15 @@ int flag_shared_data;
4139 int flag_delayed_branch;
4140
4141 /* Nonzero if we are compiling pure (sharable) code.
4142- Value is 1 if we are doing reasonable (i.e. simple
4143- offset into offset table) pic. Value is 2 if we can
4144- only perform register offsets. */
4145+ Value is 1 if we are doing "small" pic; value is 2 if we're doing
4146+ "large" pic. */
4147
4148 int flag_pic;
4149
4150+/* Set to the default thread-local storage (tls) model to use. */
4151+
4152+enum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
4153+
4154 /* Nonzero means generate extra code for exception handling and enable
4155 exception handling. */
4156
4157@@ -3609,6 +3612,7 @@ display_help ()
4158 printf (_(" -finline-limit=<number> Limits the size of inlined functions to <number>\n"));
4159 printf (_(" -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line. 0 suppresses line-wrapping\n"));
4160 printf (_(" -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
4161+ printf (_(" -ftls-model=[global-dynamic | local-dynamic | initial-exec | local-exec] Indicates the default thread-local storage code generation model\n"));
4162
4163 for (i = ARRAY_SIZE (f_options); i--;)
4164 {
4165@@ -3887,6 +3891,19 @@ decode_f_option (arg)
4166 MAX_INLINE_INSNS);
4167 set_param_value ("max-inline-insns", val);
4168 }
4169+ else if ((option_value = skip_leading_substring (arg, "tls-model=")))
4170+ {
4171+ if (strcmp (option_value, "global-dynamic") == 0)
4172+ flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
4173+ else if (strcmp (option_value, "local-dynamic") == 0)
4174+ flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
4175+ else if (strcmp (option_value, "initial-exec") == 0)
4176+ flag_tls_default = TLS_MODEL_INITIAL_EXEC;
4177+ else if (strcmp (option_value, "local-exec") == 0)
4178+ flag_tls_default = TLS_MODEL_LOCAL_EXEC;
4179+ else
4180+ warning ("`%s': unknown tls-model option", arg - 2);
4181+ }
4182 #ifdef INSN_SCHEDULING
4183 else if ((option_value = skip_leading_substring (arg, "sched-verbose=")))
4184 fix_sched_param ("verbose", option_value);
4185--- gcc/tree.c.jj Sun Apr 28 23:20:20 2002
4186+++ gcc/tree.c Wed Jun 19 19:33:52 2002
4187@@ -1510,12 +1510,13 @@ staticp (arg)
4188 case FUNCTION_DECL:
4189 /* Nested functions aren't static, since taking their address
4190 involves a trampoline. */
4191- return (decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg))
4192- && ! DECL_NON_ADDR_CONST_P (arg);
4193+ return ((decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg))
4194+ && ! DECL_NON_ADDR_CONST_P (arg));
4195
4196 case VAR_DECL:
4197- return (TREE_STATIC (arg) || DECL_EXTERNAL (arg))
4198- && ! DECL_NON_ADDR_CONST_P (arg);
4199+ return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
4200+ && ! DECL_THREAD_LOCAL (arg)
4201+ && ! DECL_NON_ADDR_CONST_P (arg));
4202
4203 case CONSTRUCTOR:
4204 return TREE_STATIC (arg);
4205--- gcc/tree.h.jj Wed Jun 19 19:33:50 2002
4206+++ gcc/tree.h Wed Jun 19 19:33:52 2002
4207@@ -1614,6 +1614,10 @@ struct tree_type
4208 /* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */
4209 #define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable)
4210
4211+/* In a VAR_DECL, nonzero if the data should be allocated from
4212+ thread-local storage. */
4213+#define DECL_THREAD_LOCAL(NODE) (VAR_DECL_CHECK (NODE)->decl.thread_local_flag)
4214+
4215 /* In a FUNCTION_DECL, the saved representation of the body of the
4216 entire function. Usually a COMPOUND_STMT, but in C++ this may also
4217 be a RETURN_INIT, CTOR_INITIALIZER, or TRY_BLOCK. */
4218@@ -1792,7 +1796,8 @@ struct tree_decl
4219 unsigned non_addressable : 1;
4220 unsigned user_align : 1;
4221 unsigned uninlinable : 1;
4222- /* Three unused bits. */
4223+ unsigned thread_local_flag : 1;
4224+ /* Two unused bits. */
4225
4226 unsigned lang_flag_0 : 1;
4227 unsigned lang_flag_1 : 1;
4228--- gcc/varasm.c.jj Wed Jun 19 19:33:51 2002
4229+++ gcc/varasm.c Wed Jun 19 19:33:52 2002
4230@@ -1599,14 +1599,24 @@ assemble_variable (decl, top_level, at_e
4231
4232 /* Handle uninitialized definitions. */
4233
4234- if ((DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node)
4235- /* If the target can't output uninitialized but not common global data
4236- in .bss, then we have to use .data. */
4237-#if ! defined ASM_EMIT_BSS
4238- && DECL_COMMON (decl)
4239+ /* If the decl has been given an explicit section name, then it
4240+ isn't common, and shouldn't be handled as such. */
4241+ if (DECL_SECTION_NAME (decl) || dont_output_data)
4242+ ;
4243+ /* We don't implement common thread-local data at present. */
4244+ else if (DECL_THREAD_LOCAL (decl))
4245+ {
4246+ if (DECL_COMMON (decl))
4247+ sorry ("thread-local COMMON data not implemented");
4248+ }
4249+#ifndef ASM_EMIT_BSS
4250+ /* If the target can't output uninitialized but not common global data
4251+ in .bss, then we have to use .data. */
4252+ else if (!DECL_COMMON (decl))
4253+ ;
4254 #endif
4255- && DECL_SECTION_NAME (decl) == NULL_TREE
4256- && ! dont_output_data)
4257+ else if (DECL_INITIAL (decl) == 0
4258+ || DECL_INITIAL (decl) == error_mark_node)
4259 {
4260 unsigned HOST_WIDE_INT size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
4261 unsigned HOST_WIDE_INT rounded = size;
4262@@ -5324,14 +5334,22 @@ default_section_type_flags (decl, name,
4263 if (decl && DECL_ONE_ONLY (decl))
4264 flags |= SECTION_LINKONCE;
4265
4266+ if (decl && TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
4267+ flags |= SECTION_TLS | SECTION_WRITE;
4268+
4269 if (strcmp (name, ".bss") == 0
4270 || strncmp (name, ".bss.", 5) == 0
4271 || strncmp (name, ".gnu.linkonce.b.", 16) == 0
4272 || strcmp (name, ".sbss") == 0
4273 || strncmp (name, ".sbss.", 6) == 0
4274- || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
4275+ || strncmp (name, ".gnu.linkonce.sb.", 17) == 0
4276+ || strcmp (name, ".tbss") == 0)
4277 flags |= SECTION_BSS;
4278
4279+ if (strcmp (name, ".tdata") == 0
4280+ || strcmp (name, ".tbss") == 0)
4281+ flags |= SECTION_TLS;
4282+
4283 return flags;
4284 }
4285
4286@@ -5374,6 +5392,8 @@ default_elf_asm_named_section (name, fla
4287 *f++ = 'M';
4288 if (flags & SECTION_STRINGS)
4289 *f++ = 'S';
4290+ if (flags & SECTION_TLS)
4291+ *f++ = 'T';
4292 *f = '\0';
4293
4294 if (flags & SECTION_BSS)
This page took 0.655491 seconds and 4 git commands to generate.