OSDN Git Service

* gcc/config/i386/i386.md (set_got): Update.
[pf3gnuchains/gcc-fork.git] / gcc / config / darwin.c
1 /* Functions for generic Darwin as target machine for GNU C compiler.
2    Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003, 2004,
3    2005
4    Free Software Foundation, Inc.
5    Contributed by Apple Computer Inc.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.  */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "real.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "insn-flags.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "tree.h"
39 #include "expr.h"
40 #include "reload.h"
41 #include "function.h"
42 #include "ggc.h"
43 #include "langhooks.h"
44 #include "target.h"
45 #include "tm_p.h"
46 #include "toplev.h"
47 #include "hashtab.h"
48
49 /* Darwin supports a feature called fix-and-continue, which is used
50    for rapid turn around debugging.  When code is compiled with the
51    -mfix-and-continue flag, two changes are made to the generated code
52    that allow the system to do things that it would normally not be
53    able to do easily.  These changes allow gdb to load in
54    recompilation of a translation unit that has been changed into a
55    running program and replace existing functions and methods of that
56    translation unit with versions of those functions and methods
57    from the newly compiled translation unit.  The new functions access
58    the existing static symbols from the old translation unit, if the
59    symbol existed in the unit to be replaced, and from the new
60    translation unit, otherwise.
61
62    The changes are to insert 5 nops at the beginning of all functions
63    and to use indirection to get at static symbols.  The 5 nops
64    are required by consumers of the generated code.  Currently, gdb
65    uses this to patch in a jump to the overriding function, this
66    allows all uses of the old name to forward to the replacement,
67    including existing function pointers and virtual methods.  See
68    rs6000_emit_prologue for the code that handles the nop insertions.
69
70    The added indirection allows gdb to redirect accesses to static
71    symbols from the newly loaded translation unit to the existing
72    symbol, if any.  @code{static} symbols are special and are handled by
73    setting the second word in the .non_lazy_symbol_pointer data
74    structure to symbol.  See indirect_data for the code that handles
75    the extra indirection, and machopic_output_indirection and its use
76    of MACHO_SYMBOL_STATIC for the code that handles @code{static}
77    symbol indirection.  */
78
79 /* Section names.  */
80 section * darwin_sections[NUM_DARWIN_SECTIONS];
81
82 /* A get_unnamed_section callback used to switch to an ObjC section.
83    DIRECTIVE is as for output_section_asm_op.  */
84
85 static void
86 output_objc_section_asm_op (const void *directive)
87 {
88   static bool been_here = false;
89
90   if (! been_here)
91     {
92       static const enum darwin_section_enum tomark[] =
93         {
94           /* written, cold -> hot */
95           objc_cat_cls_meth_section,
96           objc_cat_inst_meth_section,
97           objc_string_object_section,
98           objc_constant_string_object_section,
99           objc_selector_refs_section,
100           objc_selector_fixup_section,
101           objc_cls_refs_section,
102           objc_class_section,
103           objc_meta_class_section,
104           /* shared, hot -> cold */
105           objc_cls_meth_section,
106           objc_inst_meth_section,
107           objc_protocol_section,
108           objc_class_names_section,
109           objc_meth_var_types_section,
110           objc_meth_var_names_section,
111           objc_category_section,
112           objc_class_vars_section,
113           objc_instance_vars_section,
114           objc_module_info_section,
115           objc_symbols_section
116         };
117       size_t i;
118
119       been_here = true;
120       for (i = 0; i < ARRAY_SIZE (tomark); i++)
121         switch_to_section (darwin_sections[tomark[i]]);
122     }
123   output_section_asm_op (directive);
124 }
125
126 /* Implement TARGET_ASM_INIT_SECTIONS.  */
127
128 void
129 darwin_init_sections (void)
130 {
131 #define DEF_SECTION(NAME, FLAGS, DIRECTIVE, OBJC)               \
132   darwin_sections[NAME] =                                       \
133     get_unnamed_section (FLAGS, (OBJC                           \
134                                  ? output_objc_section_asm_op   \
135                                  : output_section_asm_op),      \
136                          "\t" DIRECTIVE);
137 #include "config/darwin-sections.def"
138 #undef DEF_SECTION
139
140   readonly_data_section = darwin_sections[const_section];
141   exception_section = darwin_sections[darwin_exception_section];
142   eh_frame_section = darwin_sections[darwin_eh_frame_section];
143 }
144
145 int
146 name_needs_quotes (const char *name)
147 {
148   int c;
149   while ((c = *name++) != '\0')
150     if (! ISIDNUM (c) && c != '.' && c != '$')
151       return 1;
152   return 0;
153 }
154
155 /* Return true if SYM_REF can be used without an indirection.  */
156 static int
157 machopic_symbol_defined_p (rtx sym_ref)
158 {
159   if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
160     return true;
161
162   /* If a symbol references local and is not an extern to this
163      file, then the symbol might be able to declared as defined.  */
164   if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
165     {
166       /* If the symbol references a variable and the variable is a
167          common symbol, then this symbol is not defined.  */
168       if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_VARIABLE)
169         {
170           tree decl = SYMBOL_REF_DECL (sym_ref);
171           if (!decl)
172             return true;
173           if (DECL_COMMON (decl))
174             return false;
175         }
176       return true;
177     }
178   return false;
179 }
180
181 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
182    reference, which will not be changed.  */
183
184 enum machopic_addr_class
185 machopic_classify_symbol (rtx sym_ref)
186 {
187   int flags;
188   bool function_p;
189
190   flags = SYMBOL_REF_FLAGS (sym_ref);
191   function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
192   if (machopic_symbol_defined_p (sym_ref))
193     return (function_p
194             ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
195   else
196     return (function_p
197             ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
198 }
199
200 #ifndef TARGET_FIX_AND_CONTINUE
201 #define TARGET_FIX_AND_CONTINUE 0
202 #endif
203
204 /* Indicate when fix-and-continue style code generation is being used
205    and when a reference to data should be indirected so that it can be
206    rebound in a new translation unit to reference the original instance
207    of that data.  Symbol names that are for code generation local to
208    the translation unit are bound to the new translation unit;
209    currently this means symbols that begin with L or _OBJC_;
210    otherwise, we indicate that an indirect reference should be made to
211    permit the runtime to rebind new instances of the translation unit
212    to the original instance of the data.  */
213
214 static int
215 indirect_data (rtx sym_ref)
216 {
217   int lprefix;
218   const char *name;
219
220   /* If we aren't generating fix-and-continue code, don't do anything special.  */
221   if (TARGET_FIX_AND_CONTINUE == 0)
222     return 0;
223
224   /* Otherwise, all symbol except symbols that begin with L or _OBJC_
225      are indirected.  Symbols that begin with L and _OBJC_ are always
226      bound to the current translation unit as they are used for
227      generated local data of the translation unit.  */
228
229   name = XSTR (sym_ref, 0);
230
231   lprefix = (((name[0] == '*' || name[0] == '&')
232               && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
233              || (strncmp (name, "_OBJC_", 6) == 0));
234
235   return ! lprefix;
236 }
237
238
239 static int
240 machopic_data_defined_p (rtx sym_ref)
241 {
242   if (indirect_data (sym_ref))
243     return 0;
244
245   switch (machopic_classify_symbol (sym_ref))
246     {
247     case MACHOPIC_DEFINED_DATA:
248     case MACHOPIC_DEFINED_FUNCTION:
249       return 1;
250     default:
251       return 0;
252     }
253 }
254
255 void
256 machopic_define_symbol (rtx mem)
257 {
258   rtx sym_ref;
259
260   gcc_assert (GET_CODE (mem) == MEM);
261   sym_ref = XEXP (mem, 0);
262   SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
263 }
264
265 static GTY(()) char * function_base;
266
267 const char *
268 machopic_function_base_name (void)
269 {
270   /* if dynamic-no-pic is on, we should not get here */
271   gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
272
273   if (function_base == NULL)
274     function_base =
275       (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
276
277   current_function_uses_pic_offset_table = 1;
278
279   return function_base;
280 }
281
282 /* Return a SYMBOL_REF for the PIC function base.  */
283
284 rtx
285 machopic_function_base_sym (void)
286 {
287   rtx sym_ref;
288
289   sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
290   SYMBOL_REF_FLAGS (sym_ref)
291     |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
292   return sym_ref;
293 }
294
295 /* Return either ORIG or (const:P (minus:P ORIG PIC_BASE)), depending
296    on whether pic_base is NULL or not.  */
297 static inline rtx
298 gen_pic_offset (rtx orig, rtx pic_base)
299 {
300   if (!pic_base)
301     return orig;
302   else
303     return gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, pic_base));
304 }
305
306 static GTY(()) const char * function_base_func_name;
307 static GTY(()) int current_pic_label_num;
308
309 void
310 machopic_output_function_base_name (FILE *file)
311 {
312   const char *current_name;
313
314   /* If dynamic-no-pic is on, we should not get here.  */
315   gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
316   current_name =
317     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
318   if (function_base_func_name != current_name)
319     {
320       ++current_pic_label_num;
321       function_base_func_name = current_name;
322     }
323   fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
324 }
325
326 /* The suffix attached to non-lazy pointer symbols.  */
327 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
328 /* The suffix attached to stub symbols.  */
329 #define STUB_SUFFIX "$stub"
330
331 typedef struct machopic_indirection GTY (())
332 {
333   /* The SYMBOL_REF for the entity referenced.  */
334   rtx symbol;
335   /* The name of the stub or non-lazy pointer.  */
336   const char * ptr_name;
337   /* True iff this entry is for a stub (as opposed to a non-lazy
338      pointer).  */
339   bool stub_p;
340   /* True iff this stub or pointer pointer has been referenced.  */
341   bool used;
342 } machopic_indirection;
343
344 /* A table mapping stub names and non-lazy pointer names to
345    SYMBOL_REFs for the stubbed-to and pointed-to entities.  */
346
347 static GTY ((param_is (struct machopic_indirection))) htab_t
348   machopic_indirections;
349
350 /* Return a hash value for a SLOT in the indirections hash table.  */
351
352 static hashval_t
353 machopic_indirection_hash (const void *slot)
354 {
355   const machopic_indirection *p = (const machopic_indirection *) slot;
356   return htab_hash_string (p->ptr_name);
357 }
358
359 /* Returns true if the KEY is the same as that associated with
360    SLOT.  */
361
362 static int
363 machopic_indirection_eq (const void *slot, const void *key)
364 {
365   return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0;
366 }
367
368 /* Return the name of the non-lazy pointer (if STUB_P is false) or
369    stub (if STUB_B is true) corresponding to the given name.  */
370
371 const char *
372 machopic_indirection_name (rtx sym_ref, bool stub_p)
373 {
374   char *buffer;
375   const char *name = XSTR (sym_ref, 0);
376   size_t namelen = strlen (name);
377   machopic_indirection *p;
378   void ** slot;
379   bool saw_star = false;
380   bool needs_quotes;
381   const char *suffix;
382   const char *prefix = user_label_prefix;
383   const char *quote = "";
384   tree id;
385
386   id = maybe_get_identifier (name);
387   if (id)
388     {
389       tree id_orig = id;
390
391       while (IDENTIFIER_TRANSPARENT_ALIAS (id))
392         id = TREE_CHAIN (id);
393       if (id != id_orig)
394         {
395           name = IDENTIFIER_POINTER (id);
396           namelen = strlen (name);
397         }
398     }
399
400   if (name[0] == '*')
401     {
402       saw_star = true;
403       prefix = "";
404       ++name;
405       --namelen;
406     }
407
408   needs_quotes = name_needs_quotes (name);
409   if (needs_quotes)
410     {
411       quote = "\"";
412     }
413
414   if (stub_p)
415     suffix = STUB_SUFFIX;
416   else
417     suffix = NON_LAZY_POINTER_SUFFIX;
418
419   buffer = alloca (strlen ("&L")
420                    + strlen (prefix)
421                    + namelen
422                    + strlen (suffix)
423                    + 2 * strlen (quote)
424                    + 1 /* '\0' */);
425
426   /* Construct the name of the non-lazy pointer or stub.  */
427   sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
428
429   if (!machopic_indirections)
430     machopic_indirections = htab_create_ggc (37,
431                                              machopic_indirection_hash,
432                                              machopic_indirection_eq,
433                                              /*htab_del=*/NULL);
434
435   slot = htab_find_slot_with_hash (machopic_indirections, buffer,
436                                    htab_hash_string (buffer), INSERT);
437   if (*slot)
438     {
439       p = (machopic_indirection *) *slot;
440     }
441   else
442     {
443       p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
444       p->symbol = sym_ref;
445       p->ptr_name = xstrdup (buffer);
446       p->stub_p = stub_p;
447       p->used = false;
448       *slot = p;
449     }
450
451   return p->ptr_name;
452 }
453
454 /* Return the name of the stub for the mcount function.  */
455
456 const char*
457 machopic_mcount_stub_name (void)
458 {
459   rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
460   return machopic_indirection_name (symbol, /*stub_p=*/true);
461 }
462
463 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
464    or non-lazy pointer as used -- and mark the object to which the
465    pointer/stub refers as used as well, since the pointer/stub will
466    emit a reference to it.  */
467
468 void
469 machopic_validate_stub_or_non_lazy_ptr (const char *name)
470 {
471   machopic_indirection *p;
472
473   p = ((machopic_indirection *)
474        (htab_find_with_hash (machopic_indirections, name,
475                              htab_hash_string (name))));
476   if (p && ! p->used)
477     {
478       const char *real_name;
479       tree id;
480
481       p->used = true;
482
483       /* Do what output_addr_const will do when we actually call it.  */
484       if (SYMBOL_REF_DECL (p->symbol))
485         mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
486
487       real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
488
489       id = maybe_get_identifier (real_name);
490       if (id)
491         mark_referenced (id);
492     }
493 }
494
495 /* Transform ORIG, which may be any data source, to the corresponding
496    source using indirections.  */
497
498 rtx
499 machopic_indirect_data_reference (rtx orig, rtx reg)
500 {
501   rtx ptr_ref = orig;
502
503   if (! MACHOPIC_INDIRECT)
504     return orig;
505
506   if (GET_CODE (orig) == SYMBOL_REF)
507     {
508       int defined = machopic_data_defined_p (orig);
509
510       if (defined && MACHO_DYNAMIC_NO_PIC_P)
511         {
512 #if defined (TARGET_TOC)
513           /* Create a new register for CSE opportunities.  */
514           rtx hi_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
515           emit_insn (gen_macho_high (hi_reg, orig));
516           emit_insn (gen_macho_low (reg, hi_reg, orig));
517 #else
518            /* some other cpu -- writeme!  */
519            gcc_unreachable ();
520 #endif
521            return reg;
522         }
523       else if (defined)
524         {
525 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
526           rtx pic_base = machopic_function_base_sym ();
527           rtx offset = gen_pic_offset (orig, pic_base);
528 #endif
529
530 #if defined (TARGET_TOC) /* i.e., PowerPC */
531           rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
532
533           gcc_assert (reg);
534
535           emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
536                               gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
537                                        gen_rtx_HIGH (Pmode, offset))));
538           emit_insn (gen_rtx_SET (Pmode, reg,
539                                   gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
540
541           orig = reg;
542 #else
543 #if defined (HAVE_lo_sum)
544           gcc_assert (reg);
545
546           emit_insn (gen_rtx_SET (VOIDmode, reg,
547                                   gen_rtx_HIGH (Pmode, offset)));
548           emit_insn (gen_rtx_SET (VOIDmode, reg,
549                                   gen_rtx_LO_SUM (Pmode, reg, offset)));
550           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
551
552           orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
553 #endif
554 #endif
555           return orig;
556         }
557
558       ptr_ref = (gen_rtx_SYMBOL_REF
559                  (Pmode,
560                   machopic_indirection_name (orig, /*stub_p=*/false)));
561
562       SYMBOL_REF_DECL (ptr_ref) = SYMBOL_REF_DECL (orig);
563
564       ptr_ref = gen_const_mem (Pmode, ptr_ref);
565       machopic_define_symbol (ptr_ref);
566
567       return ptr_ref;
568     }
569   else if (GET_CODE (orig) == CONST)
570     {
571       rtx base, result;
572
573       /* legitimize both operands of the PLUS */
574       if (GET_CODE (XEXP (orig, 0)) == PLUS)
575         {
576           base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
577                                                    reg);
578           orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
579                                                    (base == reg ? 0 : reg));
580         }
581       else
582         return orig;
583
584       if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
585         result = plus_constant (base, INTVAL (orig));
586       else
587         result = gen_rtx_PLUS (Pmode, base, orig);
588
589       if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
590         {
591           if (reg)
592             {
593               emit_move_insn (reg, result);
594               result = reg;
595             }
596           else
597             {
598               result = force_reg (GET_MODE (result), result);
599             }
600         }
601
602       return result;
603
604     }
605   else if (GET_CODE (orig) == MEM)
606     XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
607   /* When the target is i386, this code prevents crashes due to the
608      compiler's ignorance on how to move the PIC base register to
609      other registers.  (The reload phase sometimes introduces such
610      insns.)  */
611   else if (GET_CODE (orig) == PLUS
612            && GET_CODE (XEXP (orig, 0)) == REG
613            && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
614 #ifdef I386
615            /* Prevent the same register from being erroneously used
616               as both the base and index registers.  */
617            && GET_CODE (XEXP (orig, 1)) == CONST
618 #endif
619            && reg)
620     {
621       emit_move_insn (reg, XEXP (orig, 0));
622       XEXP (ptr_ref, 0) = reg;
623     }
624   return ptr_ref;
625 }
626
627 /* Transform TARGET (a MEM), which is a function call target, to the
628    corresponding symbol_stub if necessary.  Return a new MEM.  */
629
630 rtx
631 machopic_indirect_call_target (rtx target)
632 {
633   if (GET_CODE (target) != MEM)
634     return target;
635
636   if (MACHOPIC_INDIRECT
637       && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
638       && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
639            & MACHO_SYMBOL_FLAG_DEFINED))
640     {
641       rtx sym_ref = XEXP (target, 0);
642       const char *stub_name = machopic_indirection_name (sym_ref,
643                                                          /*stub_p=*/true);
644       enum machine_mode mode = GET_MODE (sym_ref);
645       tree decl = SYMBOL_REF_DECL (sym_ref);
646
647       XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
648       SYMBOL_REF_DECL (XEXP (target, 0)) = decl;
649       MEM_READONLY_P (target) = 1;
650       MEM_NOTRAP_P (target) = 1;
651     }
652
653   return target;
654 }
655
656 rtx
657 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
658 {
659   rtx pic_ref = orig;
660
661   if (! MACHOPIC_INDIRECT)
662     return orig;
663
664   /* First handle a simple SYMBOL_REF or LABEL_REF */
665   if (GET_CODE (orig) == LABEL_REF
666       || (GET_CODE (orig) == SYMBOL_REF
667           ))
668     {
669       /* addr(foo) = &func+(foo-func) */
670       rtx pic_base;
671
672       orig = machopic_indirect_data_reference (orig, reg);
673
674       if (GET_CODE (orig) == PLUS
675           && GET_CODE (XEXP (orig, 0)) == REG)
676         {
677           if (reg == 0)
678             return force_reg (mode, orig);
679
680           emit_move_insn (reg, orig);
681           return reg;
682         }
683
684       /* if dynamic-no-pic we don't have a pic base  */
685       if (MACHO_DYNAMIC_NO_PIC_P)
686         pic_base = NULL;
687       else
688         pic_base = machopic_function_base_sym ();
689
690       if (GET_CODE (orig) == MEM)
691         {
692           if (reg == 0)
693             {
694               gcc_assert (!reload_in_progress);
695               reg = gen_reg_rtx (Pmode);
696             }
697
698 #ifdef HAVE_lo_sum
699           if (MACHO_DYNAMIC_NO_PIC_P
700               && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
701                   || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
702             {
703 #if defined (TARGET_TOC)        /* ppc  */
704               rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
705               rtx asym = XEXP (orig, 0);
706               rtx mem;
707
708               emit_insn (gen_macho_high (temp_reg, asym));
709               mem = gen_const_mem (GET_MODE (orig),
710                                    gen_rtx_LO_SUM (Pmode, temp_reg, asym));
711               emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
712 #else
713               /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic  */
714               gcc_unreachable ();
715 #endif
716               pic_ref = reg;
717             }
718           else
719           if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
720               || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
721             {
722               rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
723 #if defined (TARGET_TOC) /* i.e., PowerPC */
724               /* Generating a new reg may expose opportunities for
725                  common subexpression elimination.  */
726               rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
727               rtx mem;
728               rtx insn;
729               rtx sum;
730
731               sum = gen_rtx_HIGH (Pmode, offset);
732               if (! MACHO_DYNAMIC_NO_PIC_P)
733                 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
734
735               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
736
737               mem = gen_const_mem (GET_MODE (orig),
738                                   gen_rtx_LO_SUM (Pmode,
739                                                   hi_sum_reg, offset));
740               insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
741               REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
742                                                     REG_NOTES (insn));
743
744               pic_ref = reg;
745 #else
746               emit_insn (gen_rtx_USE (VOIDmode,
747                                       gen_rtx_REG (Pmode,
748                                                    PIC_OFFSET_TABLE_REGNUM)));
749
750               emit_insn (gen_rtx_SET (VOIDmode, reg,
751                                       gen_rtx_HIGH (Pmode,
752                                                     gen_rtx_CONST (Pmode,
753                                                                    offset))));
754               emit_insn (gen_rtx_SET (VOIDmode, reg,
755                                   gen_rtx_LO_SUM (Pmode, reg,
756                                            gen_rtx_CONST (Pmode, offset))));
757               pic_ref = gen_rtx_PLUS (Pmode,
758                                       pic_offset_table_rtx, reg);
759 #endif
760             }
761           else
762 #endif  /* HAVE_lo_sum */
763             {
764               rtx pic = pic_offset_table_rtx;
765               if (GET_CODE (pic) != REG)
766                 {
767                   emit_move_insn (reg, pic);
768                   pic = reg;
769                 }
770 #if 0
771               emit_insn (gen_rtx_USE (VOIDmode,
772                                       gen_rtx_REG (Pmode,
773                                                    PIC_OFFSET_TABLE_REGNUM)));
774 #endif
775
776               if (reload_in_progress)
777                 regs_ever_live[REGNO (pic)] = 1;
778               pic_ref = gen_rtx_PLUS (Pmode, pic,
779                                       gen_pic_offset (XEXP (orig, 0),
780                                                       pic_base));
781             }
782
783 #if !defined (TARGET_TOC)
784           emit_move_insn (reg, pic_ref);
785           pic_ref = gen_const_mem (GET_MODE (orig), reg);
786 #endif
787         }
788       else
789         {
790
791 #ifdef HAVE_lo_sum
792           if (GET_CODE (orig) == SYMBOL_REF
793               || GET_CODE (orig) == LABEL_REF)
794             {
795               rtx offset = gen_pic_offset (orig, pic_base);
796 #if defined (TARGET_TOC) /* i.e., PowerPC */
797               rtx hi_sum_reg;
798
799               if (reg == 0)
800                 {
801                   gcc_assert (!reload_in_progress);
802                   reg = gen_reg_rtx (Pmode);
803                 }
804
805               hi_sum_reg = reg;
806
807               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
808                                       (MACHO_DYNAMIC_NO_PIC_P)
809                                       ? gen_rtx_HIGH (Pmode, offset)
810                                       : gen_rtx_PLUS (Pmode,
811                                                       pic_offset_table_rtx,
812                                                       gen_rtx_HIGH (Pmode,
813                                                                     offset))));
814               emit_insn (gen_rtx_SET (VOIDmode, reg,
815                                       gen_rtx_LO_SUM (Pmode,
816                                                       hi_sum_reg, offset)));
817               pic_ref = reg;
818 #else
819               emit_insn (gen_rtx_SET (VOIDmode, reg,
820                                       gen_rtx_HIGH (Pmode, offset)));
821               emit_insn (gen_rtx_SET (VOIDmode, reg,
822                                       gen_rtx_LO_SUM (Pmode, reg, offset)));
823               pic_ref = gen_rtx_PLUS (Pmode,
824                                       pic_offset_table_rtx, reg);
825 #endif
826             }
827           else
828 #endif  /*  HAVE_lo_sum  */
829             {
830               if (REG_P (orig)
831                   || GET_CODE (orig) == SUBREG)
832                 {
833                   return orig;
834                 }
835               else
836                 {
837                   rtx pic = pic_offset_table_rtx;
838                   if (GET_CODE (pic) != REG)
839                     {
840                       emit_move_insn (reg, pic);
841                       pic = reg;
842                     }
843 #if 0
844                   emit_insn (gen_rtx_USE (VOIDmode,
845                                           pic_offset_table_rtx));
846 #endif
847                   if (reload_in_progress)
848                     regs_ever_live[REGNO (pic)] = 1;
849                   pic_ref = gen_rtx_PLUS (Pmode,
850                                           pic,
851                                           gen_pic_offset (orig, pic_base));
852                 }
853             }
854         }
855
856       if (GET_CODE (pic_ref) != REG)
857         {
858           if (reg != 0)
859             {
860               emit_move_insn (reg, pic_ref);
861               return reg;
862             }
863           else
864             {
865               return force_reg (mode, pic_ref);
866             }
867         }
868       else
869         {
870           return pic_ref;
871         }
872     }
873
874   else if (GET_CODE (orig) == SYMBOL_REF)
875     return orig;
876
877   else if (GET_CODE (orig) == PLUS
878            && (GET_CODE (XEXP (orig, 0)) == MEM
879                || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
880                || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
881            && XEXP (orig, 0) != pic_offset_table_rtx
882            && GET_CODE (XEXP (orig, 1)) != REG)
883
884     {
885       rtx base;
886       int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
887
888       base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
889       orig = machopic_legitimize_pic_address (XEXP (orig, 1),
890                                               Pmode, (base == reg ? 0 : reg));
891       if (GET_CODE (orig) == CONST_INT)
892         {
893           pic_ref = plus_constant (base, INTVAL (orig));
894           is_complex = 1;
895         }
896       else
897         pic_ref = gen_rtx_PLUS (Pmode, base, orig);
898
899       if (reg && is_complex)
900         {
901           emit_move_insn (reg, pic_ref);
902           pic_ref = reg;
903         }
904       /* Likewise, should we set special REG_NOTEs here?  */
905     }
906
907   else if (GET_CODE (orig) == CONST)
908     {
909       return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
910     }
911
912   else if (GET_CODE (orig) == MEM
913            && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
914     {
915       rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
916       addr = replace_equiv_address (orig, addr);
917       emit_move_insn (reg, addr);
918       pic_ref = reg;
919     }
920
921   return pic_ref;
922 }
923
924 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
925    DATA is the FILE* for assembly output.  Called from
926    htab_traverse.  */
927
928 static int
929 machopic_output_indirection (void **slot, void *data)
930 {
931   machopic_indirection *p = *((machopic_indirection **) slot);
932   FILE *asm_out_file = (FILE *) data;
933   rtx symbol;
934   const char *sym_name;
935   const char *ptr_name;
936
937   if (!p->used)
938     return 1;
939
940   symbol = p->symbol;
941   sym_name = XSTR (symbol, 0);
942   ptr_name = p->ptr_name;
943
944   if (p->stub_p)
945     {
946       char *sym;
947       char *stub;
948       tree id;
949
950       id = maybe_get_identifier (sym_name);
951       if (id)
952         {
953           tree id_orig = id;
954
955           while (IDENTIFIER_TRANSPARENT_ALIAS (id))
956             id = TREE_CHAIN (id);
957           if (id != id_orig)
958             sym_name = IDENTIFIER_POINTER (id);
959         }
960
961       sym = alloca (strlen (sym_name) + 2);
962       if (sym_name[0] == '*' || sym_name[0] == '&')
963         strcpy (sym, sym_name + 1);
964       else if (sym_name[0] == '-' || sym_name[0] == '+')
965         strcpy (sym, sym_name);
966       else
967         sprintf (sym, "%s%s", user_label_prefix, sym_name);
968
969       stub = alloca (strlen (ptr_name) + 2);
970       if (ptr_name[0] == '*' || ptr_name[0] == '&')
971         strcpy (stub, ptr_name + 1);
972       else
973         sprintf (stub, "%s%s", user_label_prefix, ptr_name);
974
975       machopic_output_stub (asm_out_file, sym, stub);
976     }
977   else if (! indirect_data (symbol)
978            && (machopic_symbol_defined_p (symbol)
979                || SYMBOL_REF_LOCAL_P (symbol)))
980     {
981       switch_to_section (data_section);
982       assemble_align (GET_MODE_ALIGNMENT (Pmode));
983       assemble_label (ptr_name);
984       assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
985                         GET_MODE_SIZE (Pmode),
986                         GET_MODE_ALIGNMENT (Pmode), 1);
987     }
988   else
989     {
990       rtx init = const0_rtx;
991
992       switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
993       assemble_name (asm_out_file, ptr_name);
994       fprintf (asm_out_file, ":\n");
995
996       fprintf (asm_out_file, "\t.indirect_symbol ");
997       assemble_name (asm_out_file, sym_name);
998       fprintf (asm_out_file, "\n");
999
1000       /* Variables that are marked with MACHO_SYMBOL_STATIC need to
1001          have their symbol name instead of 0 in the second entry of
1002          the non-lazy symbol pointer data structure when they are
1003          defined.  This allows the runtime to rebind newer instances
1004          of the translation unit with the original instance of the
1005          symbol.  */
1006
1007       if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
1008           && machopic_symbol_defined_p (symbol))
1009         init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
1010
1011       assemble_integer (init, GET_MODE_SIZE (Pmode),
1012                         GET_MODE_ALIGNMENT (Pmode), 1);
1013     }
1014
1015   return 1;
1016 }
1017
1018 void
1019 machopic_finish (FILE *asm_out_file)
1020 {
1021   if (machopic_indirections)
1022     htab_traverse_noresize (machopic_indirections,
1023                             machopic_output_indirection,
1024                             asm_out_file);
1025 }
1026
1027 int
1028 machopic_operand_p (rtx op)
1029 {
1030   if (MACHOPIC_JUST_INDIRECT)
1031     {
1032       while (GET_CODE (op) == CONST)
1033         op = XEXP (op, 0);
1034
1035       if (GET_CODE (op) == SYMBOL_REF)
1036         return machopic_symbol_defined_p (op);
1037       else
1038         return 0;
1039     }
1040
1041   while (GET_CODE (op) == CONST)
1042     op = XEXP (op, 0);
1043
1044   if (GET_CODE (op) == MINUS
1045       && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1046       && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
1047       && machopic_symbol_defined_p (XEXP (op, 0))
1048       && machopic_symbol_defined_p (XEXP (op, 1)))
1049       return 1;
1050
1051   return 0;
1052 }
1053
1054 /* This function records whether a given name corresponds to a defined
1055    or undefined function or variable, for machopic_classify_ident to
1056    use later.  */
1057
1058 void
1059 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
1060 {
1061   rtx sym_ref;
1062
1063   /* Do the standard encoding things first.  */
1064   default_encode_section_info (decl, rtl, first);
1065
1066   if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
1067     return;
1068
1069   sym_ref = XEXP (rtl, 0);
1070   if (TREE_CODE (decl) == VAR_DECL)
1071     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
1072
1073   if (!DECL_EXTERNAL (decl)
1074       && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
1075       && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1076       && ((TREE_STATIC (decl)
1077            && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1078           || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
1079               && DECL_INITIAL (decl) != error_mark_node)))
1080     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
1081
1082   if (! TREE_PUBLIC (decl))
1083     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
1084 }
1085
1086 void
1087 darwin_mark_decl_preserved (const char *name)
1088 {
1089   fprintf (asm_out_file, ".no_dead_strip ");
1090   assemble_name (asm_out_file, name);
1091   fputc ('\n', asm_out_file);
1092 }
1093
1094 section *
1095 machopic_select_section (tree exp, int reloc,
1096                          unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1097 {
1098   section *base_section;
1099   bool weak_p = (DECL_P (exp) && DECL_WEAK (exp)
1100                  && (lookup_attribute ("weak", DECL_ATTRIBUTES (exp))
1101                      || ! lookup_attribute ("weak_import",
1102                                             DECL_ATTRIBUTES (exp))));
1103
1104   if (TREE_CODE (exp) == FUNCTION_DECL)
1105     {
1106       if (reloc == 1)
1107         base_section = (weak_p
1108                         ? darwin_sections[text_unlikely_coal_section]
1109                         : unlikely_text_section ());
1110       else
1111         base_section = weak_p ? darwin_sections[text_coal_section] : text_section;
1112     }
1113   else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1114     base_section = weak_p ? darwin_sections[const_coal_section] : darwin_sections[const_section];
1115   else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1116     base_section = weak_p ? darwin_sections[const_data_coal_section] : darwin_sections[const_data_section];
1117   else
1118     base_section = weak_p ? darwin_sections[data_coal_section] : data_section;
1119
1120   if (TREE_CODE (exp) == STRING_CST
1121       && ((size_t) TREE_STRING_LENGTH (exp)
1122           == strlen (TREE_STRING_POINTER (exp)) + 1))
1123     return darwin_sections[cstring_section];
1124   else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1125            && flag_merge_constants)
1126     {
1127       tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1128
1129       if (TREE_CODE (size) == INTEGER_CST &&
1130           TREE_INT_CST_LOW (size) == 4 &&
1131           TREE_INT_CST_HIGH (size) == 0)
1132         return darwin_sections[literal4_section];
1133       else if (TREE_CODE (size) == INTEGER_CST &&
1134                TREE_INT_CST_LOW (size) == 8 &&
1135                TREE_INT_CST_HIGH (size) == 0)
1136         return darwin_sections[literal8_section];
1137       else
1138         return base_section;
1139     }
1140   else if (TREE_CODE (exp) == CONSTRUCTOR
1141            && TREE_TYPE (exp)
1142            && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1143            && TYPE_NAME (TREE_TYPE (exp)))
1144     {
1145       tree name = TYPE_NAME (TREE_TYPE (exp));
1146       if (TREE_CODE (name) == TYPE_DECL)
1147         name = DECL_NAME (name);
1148
1149       if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1150         {
1151           if (flag_next_runtime)
1152             return darwin_sections[objc_constant_string_object_section];
1153           else
1154             return darwin_sections[objc_string_object_section];
1155         }
1156       else
1157         return base_section;
1158     }
1159   else if (TREE_CODE (exp) == VAR_DECL &&
1160            DECL_NAME (exp) &&
1161            TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1162            IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1163            !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1164     {
1165       const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1166
1167       if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1168         return darwin_sections[objc_cls_meth_section];
1169       else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1170         return darwin_sections[objc_inst_meth_section];
1171       else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1172         return darwin_sections[objc_cat_cls_meth_section];
1173       else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1174         return darwin_sections[objc_cat_inst_meth_section];
1175       else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1176         return darwin_sections[objc_class_vars_section];
1177       else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1178         return darwin_sections[objc_instance_vars_section];
1179       else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1180         return darwin_sections[objc_cat_cls_meth_section];
1181       else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1182         return darwin_sections[objc_class_names_section];
1183       else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1184         return darwin_sections[objc_meth_var_names_section];
1185       else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1186         return darwin_sections[objc_meth_var_types_section];
1187       else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1188         return darwin_sections[objc_cls_refs_section];
1189       else if (!strncmp (name, "_OBJC_CLASS_", 12))
1190         return darwin_sections[objc_class_section];
1191       else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1192         return darwin_sections[objc_meta_class_section];
1193       else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1194         return darwin_sections[objc_category_section];
1195       else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1196         return darwin_sections[objc_selector_refs_section];
1197       else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1198         return darwin_sections[objc_selector_fixup_section];
1199       else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1200         return darwin_sections[objc_symbols_section];
1201       else if (!strncmp (name, "_OBJC_MODULES", 13))
1202         return darwin_sections[objc_module_info_section];
1203       else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1204         return darwin_sections[objc_image_info_section];
1205       else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1206         return darwin_sections[objc_cat_inst_meth_section];
1207       else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1208         return darwin_sections[objc_cat_cls_meth_section];
1209       else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1210         return darwin_sections[objc_cat_cls_meth_section];
1211       else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1212         return darwin_sections[objc_protocol_section];
1213       else
1214         return base_section;
1215     }
1216   else
1217     return base_section;
1218 }
1219
1220 /* This can be called with address expressions as "rtx".
1221    They must go in "const".  */
1222
1223 section *
1224 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1225                              unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1226 {
1227   if (GET_MODE_SIZE (mode) == 8
1228       && (GET_CODE (x) == CONST_INT
1229           || GET_CODE (x) == CONST_DOUBLE))
1230     return darwin_sections[literal8_section];
1231   else if (GET_MODE_SIZE (mode) == 4
1232            && (GET_CODE (x) == CONST_INT
1233                || GET_CODE (x) == CONST_DOUBLE))
1234     return darwin_sections[literal4_section];
1235   else if (MACHOPIC_INDIRECT
1236            && (GET_CODE (x) == SYMBOL_REF
1237                || GET_CODE (x) == CONST
1238                || GET_CODE (x) == LABEL_REF))
1239     return darwin_sections[const_data_section];
1240   else
1241     return darwin_sections[const_section];
1242 }
1243
1244 void
1245 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1246 {
1247   if (MACHOPIC_INDIRECT)
1248     switch_to_section (darwin_sections[mod_init_section]);
1249   else
1250     switch_to_section (darwin_sections[constructor_section]);
1251   assemble_align (POINTER_SIZE);
1252   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1253
1254   if (! MACHOPIC_INDIRECT)
1255     fprintf (asm_out_file, ".reference .constructors_used\n");
1256 }
1257
1258 void
1259 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1260 {
1261   if (MACHOPIC_INDIRECT)
1262     switch_to_section (darwin_sections[mod_term_section]);
1263   else
1264     switch_to_section (darwin_sections[destructor_section]);
1265   assemble_align (POINTER_SIZE);
1266   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1267
1268   if (! MACHOPIC_INDIRECT)
1269     fprintf (asm_out_file, ".reference .destructors_used\n");
1270 }
1271
1272 void
1273 darwin_globalize_label (FILE *stream, const char *name)
1274 {
1275   if (!!strncmp (name, "_OBJC_", 6))
1276     default_globalize_label (stream, name);
1277 }
1278
1279 void
1280 darwin_asm_named_section (const char *name,
1281                           unsigned int flags ATTRIBUTE_UNUSED,
1282                           tree decl ATTRIBUTE_UNUSED)
1283 {
1284   fprintf (asm_out_file, "\t.section %s\n", name);
1285 }
1286
1287 void
1288 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1289 {
1290   /* Darwin does not use unique sections.  */
1291 }
1292
1293 /* Handle a "weak_import" attribute; arguments as in
1294    struct attribute_spec.handler.  */
1295
1296 tree
1297 darwin_handle_weak_import_attribute (tree *node, tree name,
1298                                      tree ARG_UNUSED (args),
1299                                      int ARG_UNUSED (flags),
1300                                      bool * no_add_attrs)
1301 {
1302   if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1303     {
1304       warning (OPT_Wattributes, "%qs attribute ignored",
1305                IDENTIFIER_POINTER (name));
1306       *no_add_attrs = true;
1307     }
1308   else
1309     declare_weak (*node);
1310
1311   return NULL_TREE;
1312 }
1313
1314 static void
1315 no_dead_strip (FILE *file, const char *lab)
1316 {
1317   fprintf (file, ".no_dead_strip %s\n", lab);
1318 }
1319
1320 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1321    The third parameter is nonzero if this is for exception handling.
1322    The fourth parameter is nonzero if this is just a placeholder for an
1323    FDE that we are omitting. */
1324
1325 void
1326 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1327 {
1328   tree id = DECL_ASSEMBLER_NAME (decl)
1329     ? DECL_ASSEMBLER_NAME (decl)
1330     : DECL_NAME (decl);
1331
1332   const char *prefix = user_label_prefix;
1333
1334   const char *base = IDENTIFIER_POINTER (id);
1335   unsigned int base_len = IDENTIFIER_LENGTH (id);
1336
1337   const char *suffix = ".eh";
1338
1339   int need_quotes = name_needs_quotes (base);
1340   int quotes_len = need_quotes ? 2 : 0;
1341   char *lab;
1342
1343   if (! for_eh)
1344     suffix = ".eh1";
1345
1346   lab = xmalloc (strlen (prefix)
1347                  + base_len + strlen (suffix) + quotes_len + 1);
1348   lab[0] = '\0';
1349
1350   if (need_quotes)
1351     strcat(lab, "\"");
1352   strcat(lab, prefix);
1353   strcat(lab, base);
1354   strcat(lab, suffix);
1355   if (need_quotes)
1356     strcat(lab, "\"");
1357
1358   if (TREE_PUBLIC (decl))
1359     fprintf (file, "\t%s %s\n",
1360              (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1361               ? ".globl"
1362               : ".private_extern"),
1363              lab);
1364
1365   if (DECL_WEAK (decl))
1366     fprintf (file, "\t.weak_definition %s\n", lab);
1367
1368   if (empty)
1369     {
1370       fprintf (file, "%s = 0\n", lab);
1371
1372       /* Mark the absolute .eh and .eh1 style labels as needed to
1373          ensure that we don't dead code strip them and keep such
1374          labels from another instantiation point until we can fix this
1375          properly with group comdat support.  */
1376       no_dead_strip (file, lab);
1377     }
1378   else
1379     fprintf (file, "%s:\n", lab);
1380
1381   free (lab);
1382 }
1383
1384 static GTY(()) unsigned long except_table_label_num;
1385
1386 void
1387 darwin_emit_except_table_label (FILE *file)
1388 {
1389   char section_start_label[30];
1390
1391   ASM_GENERATE_INTERNAL_LABEL (section_start_label, "GCC_except_table",
1392                                except_table_label_num++);
1393   ASM_OUTPUT_LABEL (file, section_start_label);
1394 }
1395 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */
1396
1397 void
1398 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1399 {
1400   const char *nlp_name;
1401
1402   gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1403
1404   nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1405   fputs ("\t.long\t", file);
1406   ASM_OUTPUT_LABELREF (file, nlp_name);
1407   fputs ("-.", file);
1408 }
1409
1410 /* Emit an assembler directive to set visibility for a symbol.  The
1411    only supported visibilities are VISIBILITY_DEFAULT and
1412    VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1413    extern".  There is no MACH-O equivalent of ELF's
1414    VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1415
1416 void
1417 darwin_assemble_visibility (tree decl, int vis)
1418 {
1419   if (vis == VISIBILITY_DEFAULT)
1420     ;
1421   else if (vis == VISIBILITY_HIDDEN)
1422     {
1423       fputs ("\t.private_extern ", asm_out_file);
1424       assemble_name (asm_out_file,
1425                      (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1426       fputs ("\n", asm_out_file);
1427     }
1428   else
1429     warning (OPT_Wattributes, "internal and protected visibility attributes "
1430              "not supported in this configuration; ignored");
1431 }
1432
1433 /* Output a difference of two labels that will be an assembly time
1434    constant if the two labels are local.  (.long lab1-lab2 will be
1435    very different if lab1 is at the boundary between two sections; it
1436    will be relocated according to the second section, not the first,
1437    so one ends up with a difference between labels in different
1438    sections, which is bad in the dwarf2 eh context for instance.)  */
1439
1440 static int darwin_dwarf_label_counter;
1441
1442 void
1443 darwin_asm_output_dwarf_delta (FILE *file, int size,
1444                                const char *lab1, const char *lab2)
1445 {
1446   int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1447                      && lab2[0] == '*' && lab2[1] == 'L');
1448   const char *directive = (size == 8 ? ".quad" : ".long");
1449
1450   if (islocaldiff)
1451     fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1452   else
1453     fprintf (file, "\t%s\t", directive);
1454   assemble_name_raw (file, lab1);
1455   fprintf (file, "-");
1456   assemble_name_raw (file, lab2);
1457   if (islocaldiff)
1458     fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1459 }
1460
1461 void
1462 darwin_file_end (void)
1463 {
1464   machopic_finish (asm_out_file);
1465   if (strcmp (lang_hooks.name, "GNU C++") == 0)
1466     {
1467       switch_to_section (darwin_sections[constructor_section]);
1468       switch_to_section (darwin_sections[destructor_section]);
1469       ASM_OUTPUT_ALIGN (asm_out_file, 1);
1470     }
1471   fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1472 }
1473
1474 /* Cross-module name binding.  Darwin does not support overriding
1475    functions at dynamic-link time.  */
1476
1477 bool
1478 darwin_binds_local_p (tree decl)
1479 {
1480   return default_binds_local_p_1 (decl, 0);
1481 }
1482
1483 #include "gt-darwin.h"