OSDN Git Service

* config/arm/arm.c (all_fpus): Fix comment typo.
[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               pic_ref = gen_rtx_PLUS (Pmode, pic,
777                                       gen_pic_offset (XEXP (orig, 0),
778                                                       pic_base));
779             }
780
781 #if !defined (TARGET_TOC)
782           emit_move_insn (reg, pic_ref);
783           pic_ref = gen_const_mem (GET_MODE (orig), reg);
784 #endif
785         }
786       else
787         {
788
789 #ifdef HAVE_lo_sum
790           if (GET_CODE (orig) == SYMBOL_REF
791               || GET_CODE (orig) == LABEL_REF)
792             {
793               rtx offset = gen_pic_offset (orig, pic_base);
794 #if defined (TARGET_TOC) /* i.e., PowerPC */
795               rtx hi_sum_reg;
796
797               if (reg == 0)
798                 {
799                   gcc_assert (!reload_in_progress);
800                   reg = gen_reg_rtx (Pmode);
801                 }
802
803               hi_sum_reg = reg;
804
805               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
806                                       (MACHO_DYNAMIC_NO_PIC_P)
807                                       ? gen_rtx_HIGH (Pmode, offset)
808                                       : gen_rtx_PLUS (Pmode,
809                                                       pic_offset_table_rtx,
810                                                       gen_rtx_HIGH (Pmode, 
811                                                                     offset))));
812               emit_insn (gen_rtx_SET (VOIDmode, reg,
813                                       gen_rtx_LO_SUM (Pmode,
814                                                       hi_sum_reg, offset)));
815               pic_ref = reg;
816 #else
817               emit_insn (gen_rtx_SET (VOIDmode, reg,
818                                       gen_rtx_HIGH (Pmode, offset)));
819               emit_insn (gen_rtx_SET (VOIDmode, reg,
820                                       gen_rtx_LO_SUM (Pmode, reg, offset)));
821               pic_ref = gen_rtx_PLUS (Pmode,
822                                       pic_offset_table_rtx, reg);
823 #endif
824             }
825           else
826 #endif  /*  HAVE_lo_sum  */
827             {
828               if (REG_P (orig)
829                   || GET_CODE (orig) == SUBREG)
830                 {
831                   return orig;
832                 }
833               else
834                 {
835                   rtx pic = pic_offset_table_rtx;
836                   if (GET_CODE (pic) != REG)
837                     {
838                       emit_move_insn (reg, pic);
839                       pic = reg;
840                     }
841 #if 0
842                   emit_insn (gen_rtx_USE (VOIDmode,
843                                           pic_offset_table_rtx));
844 #endif
845                   pic_ref = gen_rtx_PLUS (Pmode,
846                                           pic,
847                                           gen_pic_offset (orig, pic_base));
848                 }
849             }
850         }
851
852       if (GET_CODE (pic_ref) != REG)
853         {
854           if (reg != 0)
855             {
856               emit_move_insn (reg, pic_ref);
857               return reg;
858             }
859           else
860             {
861               return force_reg (mode, pic_ref);
862             }
863         }
864       else
865         {
866           return pic_ref;
867         }
868     }
869
870   else if (GET_CODE (orig) == SYMBOL_REF)
871     return orig;
872
873   else if (GET_CODE (orig) == PLUS
874            && (GET_CODE (XEXP (orig, 0)) == MEM
875                || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
876                || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
877            && XEXP (orig, 0) != pic_offset_table_rtx
878            && GET_CODE (XEXP (orig, 1)) != REG)
879
880     {
881       rtx base;
882       int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
883
884       base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
885       orig = machopic_legitimize_pic_address (XEXP (orig, 1),
886                                               Pmode, (base == reg ? 0 : reg));
887       if (GET_CODE (orig) == CONST_INT)
888         {
889           pic_ref = plus_constant (base, INTVAL (orig));
890           is_complex = 1;
891         }
892       else
893         pic_ref = gen_rtx_PLUS (Pmode, base, orig);
894
895       if (reg && is_complex)
896         {
897           emit_move_insn (reg, pic_ref);
898           pic_ref = reg;
899         }
900       /* Likewise, should we set special REG_NOTEs here?  */
901     }
902
903   else if (GET_CODE (orig) == CONST)
904     {
905       return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
906     }
907
908   else if (GET_CODE (orig) == MEM
909            && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
910     {
911       rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
912       addr = replace_equiv_address (orig, addr);
913       emit_move_insn (reg, addr);
914       pic_ref = reg;
915     }
916
917   return pic_ref;
918 }
919
920 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
921    DATA is the FILE* for assembly output.  Called from
922    htab_traverse.  */
923
924 static int
925 machopic_output_indirection (void **slot, void *data)
926 {
927   machopic_indirection *p = *((machopic_indirection **) slot);
928   FILE *asm_out_file = (FILE *) data;
929   rtx symbol;
930   const char *sym_name;
931   const char *ptr_name;
932   
933   if (!p->used)
934     return 1;
935
936   symbol = p->symbol;
937   sym_name = XSTR (symbol, 0);
938   ptr_name = p->ptr_name;
939   
940   if (p->stub_p)
941     {
942       char *sym;
943       char *stub;
944       tree id;
945
946       id = maybe_get_identifier (sym_name);
947       if (id)
948         {
949           tree id_orig = id;
950
951           while (IDENTIFIER_TRANSPARENT_ALIAS (id))
952             id = TREE_CHAIN (id);
953           if (id != id_orig)
954             sym_name = IDENTIFIER_POINTER (id);
955         }
956
957       sym = alloca (strlen (sym_name) + 2);
958       if (sym_name[0] == '*' || sym_name[0] == '&')
959         strcpy (sym, sym_name + 1);
960       else if (sym_name[0] == '-' || sym_name[0] == '+')
961         strcpy (sym, sym_name);
962       else
963         sprintf (sym, "%s%s", user_label_prefix, sym_name);
964
965       stub = alloca (strlen (ptr_name) + 2);
966       if (ptr_name[0] == '*' || ptr_name[0] == '&')
967         strcpy (stub, ptr_name + 1);
968       else
969         sprintf (stub, "%s%s", user_label_prefix, ptr_name);
970
971       machopic_output_stub (asm_out_file, sym, stub);
972     }
973   else if (! indirect_data (symbol)
974            && (machopic_symbol_defined_p (symbol)
975                || SYMBOL_REF_LOCAL_P (symbol)))
976     {
977       switch_to_section (data_section);
978       assemble_align (GET_MODE_ALIGNMENT (Pmode));
979       assemble_label (ptr_name);
980       assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
981                         GET_MODE_SIZE (Pmode),
982                         GET_MODE_ALIGNMENT (Pmode), 1);
983     }
984   else
985     {
986       rtx init = const0_rtx;
987
988       switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
989       assemble_name (asm_out_file, ptr_name);
990       fprintf (asm_out_file, ":\n");
991       
992       fprintf (asm_out_file, "\t.indirect_symbol ");
993       assemble_name (asm_out_file, sym_name);
994       fprintf (asm_out_file, "\n");
995       
996       /* Variables that are marked with MACHO_SYMBOL_STATIC need to
997          have their symbol name instead of 0 in the second entry of
998          the non-lazy symbol pointer data structure when they are
999          defined.  This allows the runtime to rebind newer instances
1000          of the translation unit with the original instance of the
1001          symbol.  */
1002
1003       if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
1004           && machopic_symbol_defined_p (symbol))
1005         init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
1006
1007       assemble_integer (init, GET_MODE_SIZE (Pmode),
1008                         GET_MODE_ALIGNMENT (Pmode), 1);
1009     }
1010   
1011   return 1;
1012 }
1013
1014 void
1015 machopic_finish (FILE *asm_out_file)
1016 {
1017   if (machopic_indirections)
1018     htab_traverse_noresize (machopic_indirections,
1019                             machopic_output_indirection,
1020                             asm_out_file);
1021 }
1022
1023 int
1024 machopic_operand_p (rtx op)
1025 {
1026   if (MACHOPIC_JUST_INDIRECT)
1027     {
1028       while (GET_CODE (op) == CONST)
1029         op = XEXP (op, 0);
1030
1031       if (GET_CODE (op) == SYMBOL_REF)
1032         return machopic_symbol_defined_p (op);
1033       else
1034         return 0;
1035     }
1036
1037   while (GET_CODE (op) == CONST)
1038     op = XEXP (op, 0);
1039
1040   if (GET_CODE (op) == MINUS
1041       && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1042       && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
1043       && machopic_symbol_defined_p (XEXP (op, 0))
1044       && machopic_symbol_defined_p (XEXP (op, 1)))
1045       return 1;
1046
1047   return 0;
1048 }
1049
1050 /* This function records whether a given name corresponds to a defined
1051    or undefined function or variable, for machopic_classify_ident to
1052    use later.  */
1053
1054 void
1055 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
1056 {
1057   rtx sym_ref;
1058
1059   /* Do the standard encoding things first.  */
1060   default_encode_section_info (decl, rtl, first);
1061
1062   if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
1063     return;
1064
1065   sym_ref = XEXP (rtl, 0);
1066   if (TREE_CODE (decl) == VAR_DECL)
1067     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
1068
1069   if (!DECL_EXTERNAL (decl)
1070       && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
1071       && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1072       && ((TREE_STATIC (decl)
1073            && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1074           || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
1075               && DECL_INITIAL (decl) != error_mark_node)))
1076     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
1077
1078   if (! TREE_PUBLIC (decl))
1079     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
1080 }
1081
1082 void
1083 darwin_mark_decl_preserved (const char *name)
1084 {
1085   fprintf (asm_out_file, ".no_dead_strip ");
1086   assemble_name (asm_out_file, name);
1087   fputc ('\n', asm_out_file);
1088 }
1089
1090 section *
1091 machopic_select_section (tree exp, int reloc,
1092                          unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1093 {
1094   section *base_section;
1095   bool weak_p = (DECL_P (exp) && DECL_WEAK (exp)
1096                  && (lookup_attribute ("weak", DECL_ATTRIBUTES (exp))
1097                      || ! lookup_attribute ("weak_import",
1098                                             DECL_ATTRIBUTES (exp))));
1099
1100   if (TREE_CODE (exp) == FUNCTION_DECL)
1101     {
1102       if (reloc == 1)
1103         base_section = (weak_p
1104                         ? darwin_sections[text_unlikely_coal_section]
1105                         : unlikely_text_section ());
1106       else
1107         base_section = weak_p ? darwin_sections[text_coal_section] : text_section;
1108     }
1109   else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1110     base_section = weak_p ? darwin_sections[const_coal_section] : darwin_sections[const_section];
1111   else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1112     base_section = weak_p ? darwin_sections[const_data_coal_section] : darwin_sections[const_data_section];
1113   else
1114     base_section = weak_p ? darwin_sections[data_coal_section] : data_section;
1115
1116   if (TREE_CODE (exp) == STRING_CST
1117       && ((size_t) TREE_STRING_LENGTH (exp)
1118           == strlen (TREE_STRING_POINTER (exp)) + 1))
1119     return darwin_sections[cstring_section];
1120   else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1121            && flag_merge_constants)
1122     {
1123       tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1124
1125       if (TREE_CODE (size) == INTEGER_CST &&
1126           TREE_INT_CST_LOW (size) == 4 &&
1127           TREE_INT_CST_HIGH (size) == 0)
1128         return darwin_sections[literal4_section];
1129       else if (TREE_CODE (size) == INTEGER_CST &&
1130                TREE_INT_CST_LOW (size) == 8 &&
1131                TREE_INT_CST_HIGH (size) == 0)
1132         return darwin_sections[literal8_section];
1133       else
1134         return base_section;
1135     }
1136   else if (TREE_CODE (exp) == CONSTRUCTOR
1137            && TREE_TYPE (exp)
1138            && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1139            && TYPE_NAME (TREE_TYPE (exp)))
1140     {
1141       tree name = TYPE_NAME (TREE_TYPE (exp));
1142       if (TREE_CODE (name) == TYPE_DECL)
1143         name = DECL_NAME (name);
1144
1145       if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1146         {
1147           if (flag_next_runtime)
1148             return darwin_sections[objc_constant_string_object_section];
1149           else
1150             return darwin_sections[objc_string_object_section];
1151         }
1152       else
1153         return base_section;
1154     }
1155   else if (TREE_CODE (exp) == VAR_DECL &&
1156            DECL_NAME (exp) &&
1157            TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1158            IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1159            !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1160     {
1161       const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1162
1163       if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1164         return darwin_sections[objc_cls_meth_section];
1165       else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1166         return darwin_sections[objc_inst_meth_section];
1167       else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1168         return darwin_sections[objc_cat_cls_meth_section];
1169       else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1170         return darwin_sections[objc_cat_inst_meth_section];
1171       else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1172         return darwin_sections[objc_class_vars_section];
1173       else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1174         return darwin_sections[objc_instance_vars_section];
1175       else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1176         return darwin_sections[objc_cat_cls_meth_section];
1177       else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1178         return darwin_sections[objc_class_names_section];
1179       else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1180         return darwin_sections[objc_meth_var_names_section];
1181       else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1182         return darwin_sections[objc_meth_var_types_section];
1183       else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1184         return darwin_sections[objc_cls_refs_section];
1185       else if (!strncmp (name, "_OBJC_CLASS_", 12))
1186         return darwin_sections[objc_class_section];
1187       else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1188         return darwin_sections[objc_meta_class_section];
1189       else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1190         return darwin_sections[objc_category_section];
1191       else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1192         return darwin_sections[objc_selector_refs_section];
1193       else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1194         return darwin_sections[objc_selector_fixup_section];
1195       else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1196         return darwin_sections[objc_symbols_section];
1197       else if (!strncmp (name, "_OBJC_MODULES", 13))
1198         return darwin_sections[objc_module_info_section];
1199       else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1200         return darwin_sections[objc_image_info_section];
1201       else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1202         return darwin_sections[objc_cat_inst_meth_section];
1203       else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1204         return darwin_sections[objc_cat_cls_meth_section];
1205       else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1206         return darwin_sections[objc_cat_cls_meth_section];
1207       else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1208         return darwin_sections[objc_protocol_section];
1209       else
1210         return base_section;
1211     }
1212   else
1213     return base_section;
1214 }
1215
1216 /* This can be called with address expressions as "rtx".
1217    They must go in "const".  */
1218
1219 section *
1220 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1221                              unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1222 {
1223   if (GET_MODE_SIZE (mode) == 8
1224       && (GET_CODE (x) == CONST_INT
1225           || GET_CODE (x) == CONST_DOUBLE))
1226     return darwin_sections[literal8_section];
1227   else if (GET_MODE_SIZE (mode) == 4
1228            && (GET_CODE (x) == CONST_INT
1229                || GET_CODE (x) == CONST_DOUBLE))
1230     return darwin_sections[literal4_section];
1231   else if (MACHOPIC_INDIRECT
1232            && (GET_CODE (x) == SYMBOL_REF
1233                || GET_CODE (x) == CONST
1234                || GET_CODE (x) == LABEL_REF))
1235     return darwin_sections[const_data_section];
1236   else
1237     return darwin_sections[const_section];
1238 }
1239
1240 void
1241 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1242 {
1243   if (MACHOPIC_INDIRECT)
1244     switch_to_section (darwin_sections[mod_init_section]);
1245   else
1246     switch_to_section (darwin_sections[constructor_section]);
1247   assemble_align (POINTER_SIZE);
1248   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1249
1250   if (! MACHOPIC_INDIRECT)
1251     fprintf (asm_out_file, ".reference .constructors_used\n");
1252 }
1253
1254 void
1255 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1256 {
1257   if (MACHOPIC_INDIRECT)
1258     switch_to_section (darwin_sections[mod_term_section]);
1259   else
1260     switch_to_section (darwin_sections[destructor_section]);
1261   assemble_align (POINTER_SIZE);
1262   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1263
1264   if (! MACHOPIC_INDIRECT)
1265     fprintf (asm_out_file, ".reference .destructors_used\n");
1266 }
1267
1268 void
1269 darwin_globalize_label (FILE *stream, const char *name)
1270 {
1271   if (!!strncmp (name, "_OBJC_", 6))
1272     default_globalize_label (stream, name);
1273 }
1274
1275 void
1276 darwin_asm_named_section (const char *name, 
1277                           unsigned int flags ATTRIBUTE_UNUSED,
1278                           tree decl ATTRIBUTE_UNUSED)
1279 {
1280   fprintf (asm_out_file, "\t.section %s\n", name);
1281 }
1282
1283 void 
1284 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1285 {
1286   /* Darwin does not use unique sections.  */
1287 }
1288
1289 /* Handle a "weak_import" attribute; arguments as in
1290    struct attribute_spec.handler.  */
1291
1292 tree
1293 darwin_handle_weak_import_attribute (tree *node, tree name,
1294                                      tree ARG_UNUSED (args),
1295                                      int ARG_UNUSED (flags),
1296                                      bool * no_add_attrs)
1297 {
1298   if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1299     {
1300       warning (OPT_Wattributes, "%qs attribute ignored",
1301                IDENTIFIER_POINTER (name));
1302       *no_add_attrs = true;
1303     }
1304   else
1305     declare_weak (*node);
1306
1307   return NULL_TREE;
1308 }
1309
1310 static void
1311 no_dead_strip (FILE *file, const char *lab)
1312 {
1313   fprintf (file, ".no_dead_strip %s\n", lab);
1314 }
1315
1316 /* Emit a label for an FDE, making it global and/or weak if appropriate. 
1317    The third parameter is nonzero if this is for exception handling.
1318    The fourth parameter is nonzero if this is just a placeholder for an
1319    FDE that we are omitting. */
1320
1321 void 
1322 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1323 {
1324   tree id = DECL_ASSEMBLER_NAME (decl)
1325     ? DECL_ASSEMBLER_NAME (decl)
1326     : DECL_NAME (decl);
1327
1328   const char *prefix = user_label_prefix;
1329
1330   const char *base = IDENTIFIER_POINTER (id);
1331   unsigned int base_len = IDENTIFIER_LENGTH (id);
1332
1333   const char *suffix = ".eh";
1334
1335   int need_quotes = name_needs_quotes (base);
1336   int quotes_len = need_quotes ? 2 : 0;
1337   char *lab;
1338
1339   if (! for_eh)
1340     suffix = ".eh1";
1341
1342   lab = xmalloc (strlen (prefix)
1343                  + base_len + strlen (suffix) + quotes_len + 1);
1344   lab[0] = '\0';
1345
1346   if (need_quotes)
1347     strcat(lab, "\"");
1348   strcat(lab, prefix);
1349   strcat(lab, base);
1350   strcat(lab, suffix);
1351   if (need_quotes)
1352     strcat(lab, "\"");
1353
1354   if (TREE_PUBLIC (decl))
1355     fprintf (file, "\t%s %s\n",
1356              (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1357               ? ".globl"
1358               : ".private_extern"),
1359              lab);
1360
1361   if (DECL_WEAK (decl))
1362     fprintf (file, "\t.weak_definition %s\n", lab);
1363
1364   if (empty)
1365     {
1366       fprintf (file, "%s = 0\n", lab);
1367
1368       /* Mark the absolute .eh and .eh1 style labels as needed to
1369          ensure that we don't dead code strip them and keep such
1370          labels from another instantiation point until we can fix this
1371          properly with group comdat support.  */
1372       no_dead_strip (file, lab);
1373     }
1374   else
1375     fprintf (file, "%s:\n", lab);
1376
1377   free (lab);
1378 }
1379
1380 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */ 
1381
1382 void
1383 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1384 {
1385   const char *nlp_name;
1386
1387   gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1388
1389   nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1390   fputs ("\t.long\t", file);
1391   ASM_OUTPUT_LABELREF (file, nlp_name);
1392   fputs ("-.", file);
1393 }
1394
1395 /* Emit an assembler directive to set visibility for a symbol.  The
1396    only supported visibilities are VISIBILITY_DEFAULT and
1397    VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1398    extern".  There is no MACH-O equivalent of ELF's
1399    VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1400
1401 void 
1402 darwin_assemble_visibility (tree decl, int vis)
1403 {
1404   if (vis == VISIBILITY_DEFAULT)
1405     ;
1406   else if (vis == VISIBILITY_HIDDEN)
1407     {
1408       fputs ("\t.private_extern ", asm_out_file);
1409       assemble_name (asm_out_file,
1410                      (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1411       fputs ("\n", asm_out_file);
1412     }
1413   else
1414     warning (OPT_Wattributes, "internal and protected visibility attributes "
1415              "not supported in this configuration; ignored");
1416 }
1417
1418 /* Output a difference of two labels that will be an assembly time
1419    constant if the two labels are local.  (.long lab1-lab2 will be
1420    very different if lab1 is at the boundary between two sections; it
1421    will be relocated according to the second section, not the first,
1422    so one ends up with a difference between labels in different
1423    sections, which is bad in the dwarf2 eh context for instance.)  */
1424
1425 static int darwin_dwarf_label_counter;
1426
1427 void
1428 darwin_asm_output_dwarf_delta (FILE *file, int size,
1429                                const char *lab1, const char *lab2)
1430 {
1431   int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1432                      && lab2[0] == '*' && lab2[1] == 'L');
1433   const char *directive = (size == 8 ? ".quad" : ".long");
1434
1435   if (islocaldiff)
1436     fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1437   else
1438     fprintf (file, "\t%s\t", directive);
1439   assemble_name_raw (file, lab1);
1440   fprintf (file, "-");
1441   assemble_name_raw (file, lab2);
1442   if (islocaldiff)
1443     fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1444 }
1445
1446 void
1447 darwin_file_end (void)
1448 {
1449   machopic_finish (asm_out_file);
1450   if (strcmp (lang_hooks.name, "GNU C++") == 0)
1451     {
1452       switch_to_section (darwin_sections[constructor_section]);
1453       switch_to_section (darwin_sections[destructor_section]);
1454       ASM_OUTPUT_ALIGN (asm_out_file, 1);
1455     }
1456   fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1457 }
1458
1459 /* Cross-module name binding.  Darwin does not support overriding
1460    functions at dynamic-link time.  */
1461
1462 bool
1463 darwin_binds_local_p (tree decl)
1464 {
1465   return default_binds_local_p_1 (decl, 0);
1466 }
1467
1468 #include "gt-darwin.h"