OSDN Git Service

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