OSDN Git Service

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