OSDN Git Service

* config/alpha/alpha.c (alpha_mangle_type, decl_has_samegp,
[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, 2006, 2007
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 3, 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 COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-flags.h"
34 #include "output.h"
35 #include "insn-attr.h"
36 #include "flags.h"
37 #include "tree.h"
38 #include "expr.h"
39 #include "reload.h"
40 #include "function.h"
41 #include "ggc.h"
42 #include "langhooks.h"
43 #include "target.h"
44 #include "tm_p.h"
45 #include "toplev.h"
46 #include "hashtab.h"
47 #include "df.h"
48 #include "debug.h"
49
50 /* Darwin supports a feature called fix-and-continue, which is used
51    for rapid turn around debugging.  When code is compiled with the
52    -mfix-and-continue flag, two changes are made to the generated code
53    that allow the system to do things that it would normally not be
54    able to do easily.  These changes allow gdb to load in
55    recompilation of a translation unit that has been changed into a
56    running program and replace existing functions and methods of that
57    translation unit with versions of those functions and methods
58    from the newly compiled translation unit.  The new functions access
59    the existing static symbols from the old translation unit, if the
60    symbol existed in the unit to be replaced, and from the new
61    translation unit, otherwise.
62
63    The changes are to insert 5 nops at the beginning of all functions
64    and to use indirection to get at static symbols.  The 5 nops
65    are required by consumers of the generated code.  Currently, gdb
66    uses this to patch in a jump to the overriding function, this
67    allows all uses of the old name to forward to the replacement,
68    including existing function pointers and virtual methods.  See
69    rs6000_emit_prologue for the code that handles the nop insertions.
70
71    The added indirection allows gdb to redirect accesses to static
72    symbols from the newly loaded translation unit to the existing
73    symbol, if any.  @code{static} symbols are special and are handled by
74    setting the second word in the .non_lazy_symbol_pointer data
75    structure to symbol.  See indirect_data for the code that handles
76    the extra indirection, and machopic_output_indirection and its use
77    of MACHO_SYMBOL_STATIC for the code that handles @code{static}
78    symbol indirection.  */
79
80 /* Section names.  */
81 section * darwin_sections[NUM_DARWIN_SECTIONS];
82
83 /* True if we're setting __attribute__ ((ms_struct)).  */
84 int darwin_ms_struct = false;
85
86 /* A get_unnamed_section callback used to switch to an ObjC section.
87    DIRECTIVE is as for output_section_asm_op.  */
88
89 static void
90 output_objc_section_asm_op (const void *directive)
91 {
92   static bool been_here = false;
93
94   if (! been_here)
95     {
96       static const enum darwin_section_enum tomark[] =
97         {
98           /* written, cold -> hot */
99           objc_cat_cls_meth_section,
100           objc_cat_inst_meth_section,
101           objc_string_object_section,
102           objc_constant_string_object_section,
103           objc_selector_refs_section,
104           objc_selector_fixup_section,
105           objc_cls_refs_section,
106           objc_class_section,
107           objc_meta_class_section,
108           /* shared, hot -> cold */
109           objc_cls_meth_section,
110           objc_inst_meth_section,
111           objc_protocol_section,
112           objc_class_names_section,
113           objc_meth_var_types_section,
114           objc_meth_var_names_section,
115           objc_category_section,
116           objc_class_vars_section,
117           objc_instance_vars_section,
118           objc_module_info_section,
119           objc_symbols_section
120         };
121       size_t i;
122
123       been_here = true;
124       for (i = 0; i < ARRAY_SIZE (tomark); i++)
125         switch_to_section (darwin_sections[tomark[i]]);
126     }
127   output_section_asm_op (directive);
128 }
129
130 /* Implement TARGET_ASM_INIT_SECTIONS.  */
131
132 void
133 darwin_init_sections (void)
134 {
135 #define DEF_SECTION(NAME, FLAGS, DIRECTIVE, OBJC)               \
136   darwin_sections[NAME] =                                       \
137     get_unnamed_section (FLAGS, (OBJC                           \
138                                  ? output_objc_section_asm_op   \
139                                  : output_section_asm_op),      \
140                          "\t" DIRECTIVE);
141 #include "config/darwin-sections.def"
142 #undef DEF_SECTION
143
144   readonly_data_section = darwin_sections[const_section];
145   exception_section = darwin_sections[darwin_exception_section];
146   eh_frame_section = darwin_sections[darwin_eh_frame_section];
147 }
148
149 int
150 name_needs_quotes (const char *name)
151 {
152   int c;
153   while ((c = *name++) != '\0')
154     if (! ISIDNUM (c) && c != '.' && c != '$')
155       return 1;
156   return 0;
157 }
158
159 /* Return true if SYM_REF can be used without an indirection.  */
160 static int
161 machopic_symbol_defined_p (rtx sym_ref)
162 {
163   if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
164     return true;
165
166   /* If a symbol references local and is not an extern to this
167      file, then the symbol might be able to declared as defined.  */
168   if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
169     {
170       /* If the symbol references a variable and the variable is a
171          common symbol, then this symbol is not defined.  */
172       if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_VARIABLE)
173         {
174           tree decl = SYMBOL_REF_DECL (sym_ref);
175           if (!decl)
176             return true;
177           if (DECL_COMMON (decl))
178             return false;
179         }
180       return true;
181     }
182   return false;
183 }
184
185 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
186    reference, which will not be changed.  */
187
188 enum machopic_addr_class
189 machopic_classify_symbol (rtx sym_ref)
190 {
191   int flags;
192   bool function_p;
193
194   flags = SYMBOL_REF_FLAGS (sym_ref);
195   function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
196   if (machopic_symbol_defined_p (sym_ref))
197     return (function_p
198             ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
199   else
200     return (function_p
201             ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
202 }
203
204 #ifndef TARGET_FIX_AND_CONTINUE
205 #define TARGET_FIX_AND_CONTINUE 0
206 #endif
207
208 /* Indicate when fix-and-continue style code generation is being used
209    and when a reference to data should be indirected so that it can be
210    rebound in a new translation unit to reference the original instance
211    of that data.  Symbol names that are for code generation local to
212    the translation unit are bound to the new translation unit;
213    currently this means symbols that begin with L or _OBJC_;
214    otherwise, we indicate that an indirect reference should be made to
215    permit the runtime to rebind new instances of the translation unit
216    to the original instance of the data.  */
217
218 static int
219 indirect_data (rtx sym_ref)
220 {
221   int lprefix;
222   const char *name;
223
224   /* If we aren't generating fix-and-continue code, don't do anything
225      special.  */
226   if (TARGET_FIX_AND_CONTINUE == 0)
227     return 0;
228
229   /* Otherwise, all symbol except symbols that begin with L or _OBJC_
230      are indirected.  Symbols that begin with L and _OBJC_ are always
231      bound to the current translation unit as they are used for
232      generated local data of the translation unit.  */
233
234   name = XSTR (sym_ref, 0);
235
236   lprefix = (((name[0] == '*' || name[0] == '&')
237               && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
238              || (strncmp (name, "_OBJC_", 6) == 0));
239
240   return ! lprefix;
241 }
242
243
244 static int
245 machopic_data_defined_p (rtx sym_ref)
246 {
247   if (indirect_data (sym_ref))
248     return 0;
249
250   switch (machopic_classify_symbol (sym_ref))
251     {
252     case MACHOPIC_DEFINED_DATA:
253     case MACHOPIC_DEFINED_FUNCTION:
254       return 1;
255     default:
256       return 0;
257     }
258 }
259
260 void
261 machopic_define_symbol (rtx mem)
262 {
263   rtx sym_ref;
264
265   gcc_assert (GET_CODE (mem) == MEM);
266   sym_ref = XEXP (mem, 0);
267   SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
268 }
269
270 static GTY(()) const char * function_base;
271
272 const char *
273 machopic_function_base_name (void)
274 {
275   /* if dynamic-no-pic is on, we should not get here */
276   gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
277
278   if (function_base == NULL)
279     function_base = 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 = (!can_create_pseudo_p () ? 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 = (!can_create_pseudo_p ()
536                             ? reg
537                             : gen_reg_rtx (Pmode));
538
539           gcc_assert (reg);
540
541           emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
542                               gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
543                                        gen_rtx_HIGH (Pmode, offset))));
544           emit_insn (gen_rtx_SET (Pmode, reg,
545                                   gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
546
547           orig = reg;
548 #else
549 #if defined (HAVE_lo_sum)
550           gcc_assert (reg);
551
552           emit_insn (gen_rtx_SET (VOIDmode, reg,
553                                   gen_rtx_HIGH (Pmode, offset)));
554           emit_insn (gen_rtx_SET (VOIDmode, reg,
555                                   gen_rtx_LO_SUM (Pmode, reg, offset)));
556           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
557
558           orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
559 #endif
560 #endif
561           return orig;
562         }
563
564       ptr_ref = (gen_rtx_SYMBOL_REF
565                  (Pmode,
566                   machopic_indirection_name (orig, /*stub_p=*/false)));
567
568       SYMBOL_REF_DATA (ptr_ref) = SYMBOL_REF_DATA (orig);
569
570       ptr_ref = gen_const_mem (Pmode, ptr_ref);
571       machopic_define_symbol (ptr_ref);
572
573       return ptr_ref;
574     }
575   else if (GET_CODE (orig) == CONST)
576     {
577       rtx base, result;
578
579       /* legitimize both operands of the PLUS */
580       if (GET_CODE (XEXP (orig, 0)) == PLUS)
581         {
582           base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
583                                                    reg);
584           orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
585                                                    (base == reg ? 0 : reg));
586         }
587       else
588         return orig;
589
590       if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
591         result = plus_constant (base, INTVAL (orig));
592       else
593         result = gen_rtx_PLUS (Pmode, base, orig);
594
595       if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
596         {
597           if (reg)
598             {
599               emit_move_insn (reg, result);
600               result = reg;
601             }
602           else
603             {
604               result = force_reg (GET_MODE (result), result);
605             }
606         }
607
608       return result;
609
610     }
611   else if (GET_CODE (orig) == MEM)
612     XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
613   /* When the target is i386, this code prevents crashes due to the
614      compiler's ignorance on how to move the PIC base register to
615      other registers.  (The reload phase sometimes introduces such
616      insns.)  */
617   else if (GET_CODE (orig) == PLUS
618            && GET_CODE (XEXP (orig, 0)) == REG
619            && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
620 #ifdef I386
621            /* Prevent the same register from being erroneously used
622               as both the base and index registers.  */
623            && GET_CODE (XEXP (orig, 1)) == CONST
624 #endif
625            && reg)
626     {
627       emit_move_insn (reg, XEXP (orig, 0));
628       XEXP (ptr_ref, 0) = reg;
629     }
630   return ptr_ref;
631 }
632
633 /* Transform TARGET (a MEM), which is a function call target, to the
634    corresponding symbol_stub if necessary.  Return a new MEM.  */
635
636 rtx
637 machopic_indirect_call_target (rtx target)
638 {
639   if (GET_CODE (target) != MEM)
640     return target;
641
642   if (MACHOPIC_INDIRECT
643       && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
644       && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
645            & MACHO_SYMBOL_FLAG_DEFINED))
646     {
647       rtx sym_ref = XEXP (target, 0);
648       const char *stub_name = machopic_indirection_name (sym_ref,
649                                                          /*stub_p=*/true);
650       enum machine_mode mode = GET_MODE (sym_ref);
651
652       XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
653       SYMBOL_REF_DATA (XEXP (target, 0)) = SYMBOL_REF_DATA (sym_ref);
654       MEM_READONLY_P (target) = 1;
655       MEM_NOTRAP_P (target) = 1;
656     }
657
658   return target;
659 }
660
661 rtx
662 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
663 {
664   rtx pic_ref = orig;
665
666   if (! MACHOPIC_INDIRECT)
667     return orig;
668
669   /* First handle a simple SYMBOL_REF or LABEL_REF */
670   if (GET_CODE (orig) == LABEL_REF
671       || (GET_CODE (orig) == SYMBOL_REF
672           ))
673     {
674       /* addr(foo) = &func+(foo-func) */
675       rtx pic_base;
676
677       orig = machopic_indirect_data_reference (orig, reg);
678
679       if (GET_CODE (orig) == PLUS
680           && GET_CODE (XEXP (orig, 0)) == REG)
681         {
682           if (reg == 0)
683             return force_reg (mode, orig);
684
685           emit_move_insn (reg, orig);
686           return reg;
687         }
688
689       /* if dynamic-no-pic we don't have a pic base  */
690       if (MACHO_DYNAMIC_NO_PIC_P)
691         pic_base = NULL;
692       else
693         pic_base = machopic_function_base_sym ();
694
695       if (GET_CODE (orig) == MEM)
696         {
697           if (reg == 0)
698             {
699               gcc_assert (!reload_in_progress);
700               reg = gen_reg_rtx (Pmode);
701             }
702
703 #ifdef HAVE_lo_sum
704           if (MACHO_DYNAMIC_NO_PIC_P
705               && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
706                   || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
707             {
708 #if defined (TARGET_TOC)        /* ppc  */
709               rtx temp_reg = (!can_create_pseudo_p ()
710                               ? reg :
711                               gen_reg_rtx (Pmode));
712               rtx asym = XEXP (orig, 0);
713               rtx mem;
714
715               emit_insn (gen_macho_high (temp_reg, asym));
716               mem = gen_const_mem (GET_MODE (orig),
717                                    gen_rtx_LO_SUM (Pmode, temp_reg, asym));
718               emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
719 #else
720               /* Some other CPU -- WriteMe! but right now there are no other
721                  platforms that can use dynamic-no-pic  */
722               gcc_unreachable ();
723 #endif
724               pic_ref = reg;
725             }
726           else
727           if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
728               || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
729             {
730               rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
731 #if defined (TARGET_TOC) /* i.e., PowerPC */
732               /* Generating a new reg may expose opportunities for
733                  common subexpression elimination.  */
734               rtx hi_sum_reg = (!can_create_pseudo_p ()
735                                 ? reg
736                                 : gen_reg_rtx (Pmode));
737               rtx mem;
738               rtx insn;
739               rtx sum;
740
741               sum = gen_rtx_HIGH (Pmode, offset);
742               if (! MACHO_DYNAMIC_NO_PIC_P)
743                 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
744
745               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
746
747               mem = gen_const_mem (GET_MODE (orig),
748                                   gen_rtx_LO_SUM (Pmode,
749                                                   hi_sum_reg, offset));
750               insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
751               set_unique_reg_note (insn, REG_EQUAL, pic_ref);
752
753               pic_ref = reg;
754 #else
755               emit_insn (gen_rtx_USE (VOIDmode,
756                                       gen_rtx_REG (Pmode,
757                                                    PIC_OFFSET_TABLE_REGNUM)));
758
759               emit_insn (gen_rtx_SET (VOIDmode, reg,
760                                       gen_rtx_HIGH (Pmode,
761                                                     gen_rtx_CONST (Pmode,
762                                                                    offset))));
763               emit_insn (gen_rtx_SET (VOIDmode, reg,
764                                   gen_rtx_LO_SUM (Pmode, reg,
765                                            gen_rtx_CONST (Pmode, offset))));
766               pic_ref = gen_rtx_PLUS (Pmode,
767                                       pic_offset_table_rtx, reg);
768 #endif
769             }
770           else
771 #endif  /* HAVE_lo_sum */
772             {
773               rtx pic = pic_offset_table_rtx;
774               if (GET_CODE (pic) != REG)
775                 {
776                   emit_move_insn (reg, pic);
777                   pic = reg;
778                 }
779 #if 0
780               emit_insn (gen_rtx_USE (VOIDmode,
781                                       gen_rtx_REG (Pmode,
782                                                    PIC_OFFSET_TABLE_REGNUM)));
783 #endif
784
785               if (reload_in_progress)
786                 df_set_regs_ever_live (REGNO (pic), true);
787               pic_ref = gen_rtx_PLUS (Pmode, pic,
788                                       gen_pic_offset (XEXP (orig, 0),
789                                                       pic_base));
790             }
791
792 #if !defined (TARGET_TOC)
793           emit_move_insn (reg, pic_ref);
794           pic_ref = gen_const_mem (GET_MODE (orig), reg);
795 #endif
796         }
797       else
798         {
799
800 #ifdef HAVE_lo_sum
801           if (GET_CODE (orig) == SYMBOL_REF
802               || GET_CODE (orig) == LABEL_REF)
803             {
804               rtx offset = gen_pic_offset (orig, pic_base);
805 #if defined (TARGET_TOC) /* i.e., PowerPC */
806               rtx hi_sum_reg;
807
808               if (reg == 0)
809                 {
810                   gcc_assert (!reload_in_progress);
811                   reg = gen_reg_rtx (Pmode);
812                 }
813
814               hi_sum_reg = reg;
815
816               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
817                                       (MACHO_DYNAMIC_NO_PIC_P)
818                                       ? gen_rtx_HIGH (Pmode, offset)
819                                       : gen_rtx_PLUS (Pmode,
820                                                       pic_offset_table_rtx,
821                                                       gen_rtx_HIGH (Pmode,
822                                                                     offset))));
823               emit_insn (gen_rtx_SET (VOIDmode, reg,
824                                       gen_rtx_LO_SUM (Pmode,
825                                                       hi_sum_reg, offset)));
826               pic_ref = reg;
827 #else
828               emit_insn (gen_rtx_SET (VOIDmode, reg,
829                                       gen_rtx_HIGH (Pmode, offset)));
830               emit_insn (gen_rtx_SET (VOIDmode, reg,
831                                       gen_rtx_LO_SUM (Pmode, reg, offset)));
832               pic_ref = gen_rtx_PLUS (Pmode,
833                                       pic_offset_table_rtx, reg);
834 #endif
835             }
836           else
837 #endif  /*  HAVE_lo_sum  */
838             {
839               if (REG_P (orig)
840                   || GET_CODE (orig) == SUBREG)
841                 {
842                   return orig;
843                 }
844               else
845                 {
846                   rtx pic = pic_offset_table_rtx;
847                   if (GET_CODE (pic) != REG)
848                     {
849                       emit_move_insn (reg, pic);
850                       pic = reg;
851                     }
852 #if 0
853                   emit_insn (gen_rtx_USE (VOIDmode,
854                                           pic_offset_table_rtx));
855 #endif
856                   if (reload_in_progress)
857                     df_set_regs_ever_live (REGNO (pic), true);
858                   pic_ref = gen_rtx_PLUS (Pmode,
859                                           pic,
860                                           gen_pic_offset (orig, pic_base));
861                 }
862             }
863         }
864
865       if (GET_CODE (pic_ref) != REG)
866         {
867           if (reg != 0)
868             {
869               emit_move_insn (reg, pic_ref);
870               return reg;
871             }
872           else
873             {
874               return force_reg (mode, pic_ref);
875             }
876         }
877       else
878         {
879           return pic_ref;
880         }
881     }
882
883   else if (GET_CODE (orig) == SYMBOL_REF)
884     return orig;
885
886   else if (GET_CODE (orig) == PLUS
887            && (GET_CODE (XEXP (orig, 0)) == MEM
888                || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
889                || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
890            && XEXP (orig, 0) != pic_offset_table_rtx
891            && GET_CODE (XEXP (orig, 1)) != REG)
892
893     {
894       rtx base;
895       int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
896
897       base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
898       orig = machopic_legitimize_pic_address (XEXP (orig, 1),
899                                               Pmode, (base == reg ? 0 : reg));
900       if (GET_CODE (orig) == CONST_INT)
901         {
902           pic_ref = plus_constant (base, INTVAL (orig));
903           is_complex = 1;
904         }
905       else
906         pic_ref = gen_rtx_PLUS (Pmode, base, orig);
907
908       if (reg && is_complex)
909         {
910           emit_move_insn (reg, pic_ref);
911           pic_ref = reg;
912         }
913       /* Likewise, should we set special REG_NOTEs here?  */
914     }
915
916   else if (GET_CODE (orig) == CONST)
917     {
918       return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
919     }
920
921   else if (GET_CODE (orig) == MEM
922            && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
923     {
924       rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
925       addr = replace_equiv_address (orig, addr);
926       emit_move_insn (reg, addr);
927       pic_ref = reg;
928     }
929
930   return pic_ref;
931 }
932
933 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
934    DATA is the FILE* for assembly output.  Called from
935    htab_traverse.  */
936
937 static int
938 machopic_output_indirection (void **slot, void *data)
939 {
940   machopic_indirection *p = *((machopic_indirection **) slot);
941   FILE *asm_out_file = (FILE *) data;
942   rtx symbol;
943   const char *sym_name;
944   const char *ptr_name;
945
946   if (!p->used)
947     return 1;
948
949   symbol = p->symbol;
950   sym_name = XSTR (symbol, 0);
951   ptr_name = p->ptr_name;
952
953   if (p->stub_p)
954     {
955       char *sym;
956       char *stub;
957       tree id;
958
959       id = maybe_get_identifier (sym_name);
960       if (id)
961         {
962           tree id_orig = id;
963
964           while (IDENTIFIER_TRANSPARENT_ALIAS (id))
965             id = TREE_CHAIN (id);
966           if (id != id_orig)
967             sym_name = IDENTIFIER_POINTER (id);
968         }
969
970       sym = alloca (strlen (sym_name) + 2);
971       if (sym_name[0] == '*' || sym_name[0] == '&')
972         strcpy (sym, sym_name + 1);
973       else if (sym_name[0] == '-' || sym_name[0] == '+')
974         strcpy (sym, sym_name);
975       else
976         sprintf (sym, "%s%s", user_label_prefix, sym_name);
977
978       stub = alloca (strlen (ptr_name) + 2);
979       if (ptr_name[0] == '*' || ptr_name[0] == '&')
980         strcpy (stub, ptr_name + 1);
981       else
982         sprintf (stub, "%s%s", user_label_prefix, ptr_name);
983
984       machopic_output_stub (asm_out_file, sym, stub);
985     }
986   else if (! indirect_data (symbol)
987            && (machopic_symbol_defined_p (symbol)
988                || SYMBOL_REF_LOCAL_P (symbol)))
989     {
990       switch_to_section (data_section);
991       assemble_align (GET_MODE_ALIGNMENT (Pmode));
992       assemble_label (ptr_name);
993       assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
994                         GET_MODE_SIZE (Pmode),
995                         GET_MODE_ALIGNMENT (Pmode), 1);
996     }
997   else
998     {
999       rtx init = const0_rtx;
1000
1001       switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
1002       assemble_name (asm_out_file, ptr_name);
1003       fprintf (asm_out_file, ":\n");
1004
1005       fprintf (asm_out_file, "\t.indirect_symbol ");
1006       assemble_name (asm_out_file, sym_name);
1007       fprintf (asm_out_file, "\n");
1008
1009       /* Variables that are marked with MACHO_SYMBOL_STATIC need to
1010          have their symbol name instead of 0 in the second entry of
1011          the non-lazy symbol pointer data structure when they are
1012          defined.  This allows the runtime to rebind newer instances
1013          of the translation unit with the original instance of the
1014          symbol.  */
1015
1016       if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
1017           && machopic_symbol_defined_p (symbol))
1018         init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
1019
1020       assemble_integer (init, GET_MODE_SIZE (Pmode),
1021                         GET_MODE_ALIGNMENT (Pmode), 1);
1022     }
1023
1024   return 1;
1025 }
1026
1027 void
1028 machopic_finish (FILE *asm_out_file)
1029 {
1030   if (machopic_indirections)
1031     htab_traverse_noresize (machopic_indirections,
1032                             machopic_output_indirection,
1033                             asm_out_file);
1034 }
1035
1036 int
1037 machopic_operand_p (rtx op)
1038 {
1039   if (MACHOPIC_JUST_INDIRECT)
1040     {
1041       while (GET_CODE (op) == CONST)
1042         op = XEXP (op, 0);
1043
1044       if (GET_CODE (op) == SYMBOL_REF)
1045         return machopic_symbol_defined_p (op);
1046       else
1047         return 0;
1048     }
1049
1050   while (GET_CODE (op) == CONST)
1051     op = XEXP (op, 0);
1052
1053   if (GET_CODE (op) == MINUS
1054       && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1055       && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
1056       && machopic_symbol_defined_p (XEXP (op, 0))
1057       && machopic_symbol_defined_p (XEXP (op, 1)))
1058       return 1;
1059
1060   return 0;
1061 }
1062
1063 /* This function records whether a given name corresponds to a defined
1064    or undefined function or variable, for machopic_classify_ident to
1065    use later.  */
1066
1067 void
1068 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
1069 {
1070   rtx sym_ref;
1071
1072   /* Do the standard encoding things first.  */
1073   default_encode_section_info (decl, rtl, first);
1074
1075   if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
1076     return;
1077
1078   sym_ref = XEXP (rtl, 0);
1079   if (TREE_CODE (decl) == VAR_DECL)
1080     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
1081
1082   if (!DECL_EXTERNAL (decl)
1083       && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
1084       && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1085       && ((TREE_STATIC (decl)
1086            && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1087           || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
1088               && DECL_INITIAL (decl) != error_mark_node)))
1089     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
1090
1091   if (! TREE_PUBLIC (decl))
1092     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
1093 }
1094
1095 void
1096 darwin_mark_decl_preserved (const char *name)
1097 {
1098   fprintf (asm_out_file, ".no_dead_strip ");
1099   assemble_name (asm_out_file, name);
1100   fputc ('\n', asm_out_file);
1101 }
1102
1103 static section *
1104 darwin_text_section (int reloc, int weak)
1105 {
1106   if (reloc)
1107     return (weak
1108             ? darwin_sections[text_unlikely_coal_section]
1109             : unlikely_text_section ());
1110   else
1111     return (weak
1112             ? darwin_sections[text_coal_section]
1113             : text_section);
1114 }
1115
1116 static section *
1117 darwin_rodata_section (int weak)
1118 {
1119   return (weak
1120           ? darwin_sections[const_coal_section]
1121           : darwin_sections[const_section]);
1122 }
1123
1124 static section *
1125 darwin_mergeable_string_section (tree exp,
1126                                  unsigned HOST_WIDE_INT align)
1127 {
1128   if (flag_merge_constants
1129       && TREE_CODE (exp) == STRING_CST
1130       && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
1131       && align <= 256
1132       && ((size_t) TREE_STRING_LENGTH (exp)
1133           == strlen (TREE_STRING_POINTER (exp)) + 1))
1134     return darwin_sections[cstring_section];
1135
1136   return readonly_data_section;
1137 }
1138
1139 #ifndef HAVE_GAS_LITERAL16
1140 #define HAVE_GAS_LITERAL16 0
1141 #endif
1142
1143 static section *
1144 darwin_mergeable_constant_section (tree exp,
1145                                    unsigned HOST_WIDE_INT align)
1146 {
1147   enum machine_mode mode = DECL_MODE (exp);
1148   unsigned int modesize = GET_MODE_BITSIZE (mode);
1149
1150   if (flag_merge_constants
1151       && mode != VOIDmode
1152       && mode != BLKmode
1153       && modesize <= align
1154       && align >= 8
1155       && align <= 256
1156       && (align & (align -1)) == 0)
1157     {
1158       tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1159
1160       if (TREE_CODE (size) == INTEGER_CST
1161           && TREE_INT_CST_LOW (size) == 4
1162           && TREE_INT_CST_HIGH (size) == 0)
1163         return darwin_sections[literal4_section];
1164       else if (TREE_CODE (size) == INTEGER_CST
1165                && TREE_INT_CST_LOW (size) == 8
1166                && TREE_INT_CST_HIGH (size) == 0)
1167         return darwin_sections[literal8_section];
1168       else if (HAVE_GAS_LITERAL16
1169                && TARGET_64BIT
1170                && TREE_CODE (size) == INTEGER_CST
1171                && TREE_INT_CST_LOW (size) == 16
1172                && TREE_INT_CST_HIGH (size) == 0)
1173         return darwin_sections[literal16_section];
1174       else
1175         return readonly_data_section;
1176     }
1177
1178   return readonly_data_section;
1179 }
1180
1181 int
1182 machopic_reloc_rw_mask (void)
1183 {
1184   return MACHOPIC_INDIRECT ? 3 : 0;
1185 }
1186
1187 section *
1188 machopic_select_section (tree decl,
1189                          int reloc,
1190                          unsigned HOST_WIDE_INT align)
1191 {
1192   bool weak = (DECL_P (decl)
1193                && DECL_WEAK (decl)
1194                && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
1195                    || ! lookup_attribute ("weak_import",
1196                                           DECL_ATTRIBUTES (decl))));
1197   section *base_section;
1198
1199   switch (categorize_decl_for_section (decl, reloc))
1200     {
1201     case SECCAT_TEXT:
1202       base_section = darwin_text_section (reloc, weak);
1203       break;
1204
1205     case SECCAT_RODATA:
1206     case SECCAT_SRODATA:
1207       base_section = darwin_rodata_section (weak);
1208       break;
1209
1210     case SECCAT_RODATA_MERGE_STR:
1211       base_section = darwin_mergeable_string_section (decl, align);
1212       break;
1213
1214     case SECCAT_RODATA_MERGE_STR_INIT:
1215       base_section = darwin_mergeable_string_section (DECL_INITIAL (decl), align);
1216       break;
1217
1218     case SECCAT_RODATA_MERGE_CONST:
1219       base_section =  darwin_mergeable_constant_section (decl, align);
1220       break;
1221
1222     case SECCAT_DATA:
1223     case SECCAT_DATA_REL:
1224     case SECCAT_DATA_REL_LOCAL:
1225     case SECCAT_DATA_REL_RO:
1226     case SECCAT_DATA_REL_RO_LOCAL:
1227     case SECCAT_SDATA:
1228     case SECCAT_TDATA:
1229     case SECCAT_BSS:
1230     case SECCAT_SBSS:
1231     case SECCAT_TBSS:
1232       if (TREE_READONLY (decl) || TREE_CONSTANT (decl))
1233         base_section = weak ? darwin_sections[const_data_coal_section]
1234                             : darwin_sections[const_data_section];
1235       else
1236         base_section = weak ? darwin_sections[data_coal_section] : data_section;
1237       break;
1238
1239     default:
1240       gcc_unreachable ();
1241     }
1242
1243   /* Darwin weird special cases.  */
1244   if (TREE_CODE (decl) == CONSTRUCTOR
1245       && TREE_TYPE (decl)
1246       && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
1247       && TYPE_NAME (TREE_TYPE (decl)))
1248     {
1249       tree name = TYPE_NAME (TREE_TYPE (decl));
1250       if (TREE_CODE (name) == TYPE_DECL)
1251         name = DECL_NAME (name);
1252
1253       if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1254         {
1255           if (flag_next_runtime)
1256             return darwin_sections[objc_constant_string_object_section];
1257           else
1258             return darwin_sections[objc_string_object_section];
1259         }
1260       else
1261         return base_section;
1262     }
1263   else if (TREE_CODE (decl) == VAR_DECL
1264            && DECL_NAME (decl)
1265            && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE
1266            && IDENTIFIER_POINTER (DECL_NAME (decl))
1267            && !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "_OBJC_", 6))
1268     {
1269       const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
1270
1271       if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1272         return darwin_sections[objc_cls_meth_section];
1273       else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1274         return darwin_sections[objc_inst_meth_section];
1275       else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1276         return darwin_sections[objc_cat_cls_meth_section];
1277       else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1278         return darwin_sections[objc_cat_inst_meth_section];
1279       else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1280         return darwin_sections[objc_class_vars_section];
1281       else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1282         return darwin_sections[objc_instance_vars_section];
1283       else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1284         return darwin_sections[objc_cat_cls_meth_section];
1285       else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1286         return darwin_sections[objc_class_names_section];
1287       else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1288         return darwin_sections[objc_meth_var_names_section];
1289       else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1290         return darwin_sections[objc_meth_var_types_section];
1291       else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1292         return darwin_sections[objc_cls_refs_section];
1293       else if (!strncmp (name, "_OBJC_CLASS_", 12))
1294         return darwin_sections[objc_class_section];
1295       else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1296         return darwin_sections[objc_meta_class_section];
1297       else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1298         return darwin_sections[objc_category_section];
1299       else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1300         return darwin_sections[objc_selector_refs_section];
1301       else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1302         return darwin_sections[objc_selector_fixup_section];
1303       else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1304         return darwin_sections[objc_symbols_section];
1305       else if (!strncmp (name, "_OBJC_MODULES", 13))
1306         return darwin_sections[objc_module_info_section];
1307       else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1308         return darwin_sections[objc_image_info_section];
1309       else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1310         return darwin_sections[objc_cat_inst_meth_section];
1311       else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1312         return darwin_sections[objc_cat_cls_meth_section];
1313       else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1314         return darwin_sections[objc_cat_cls_meth_section];
1315       else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1316         return darwin_sections[objc_protocol_section];
1317       else
1318         return base_section;
1319     }
1320
1321   return base_section;
1322 }
1323
1324 /* This can be called with address expressions as "rtx".
1325    They must go in "const".  */
1326
1327 section *
1328 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1329                              unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1330 {
1331   if (GET_MODE_SIZE (mode) == 8
1332       && (GET_CODE (x) == CONST_INT
1333           || GET_CODE (x) == CONST_DOUBLE))
1334     return darwin_sections[literal8_section];
1335   else if (GET_MODE_SIZE (mode) == 4
1336            && (GET_CODE (x) == CONST_INT
1337                || GET_CODE (x) == CONST_DOUBLE))
1338     return darwin_sections[literal4_section];
1339   else if (HAVE_GAS_LITERAL16
1340            && TARGET_64BIT
1341            && GET_MODE_SIZE (mode) == 16
1342            && (GET_CODE (x) == CONST_INT
1343                || GET_CODE (x) == CONST_DOUBLE
1344                || GET_CODE (x) == CONST_VECTOR))
1345     return darwin_sections[literal16_section];
1346   else if (MACHOPIC_INDIRECT
1347            && (GET_CODE (x) == SYMBOL_REF
1348                || GET_CODE (x) == CONST
1349                || GET_CODE (x) == LABEL_REF))
1350     return darwin_sections[const_data_section];
1351   else
1352     return darwin_sections[const_section];
1353 }
1354
1355 void
1356 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1357 {
1358   if (MACHOPIC_INDIRECT)
1359     switch_to_section (darwin_sections[mod_init_section]);
1360   else
1361     switch_to_section (darwin_sections[constructor_section]);
1362   assemble_align (POINTER_SIZE);
1363   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1364
1365   if (! MACHOPIC_INDIRECT)
1366     fprintf (asm_out_file, ".reference .constructors_used\n");
1367 }
1368
1369 void
1370 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1371 {
1372   if (MACHOPIC_INDIRECT)
1373     switch_to_section (darwin_sections[mod_term_section]);
1374   else
1375     switch_to_section (darwin_sections[destructor_section]);
1376   assemble_align (POINTER_SIZE);
1377   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1378
1379   if (! MACHOPIC_INDIRECT)
1380     fprintf (asm_out_file, ".reference .destructors_used\n");
1381 }
1382
1383 void
1384 darwin_globalize_label (FILE *stream, const char *name)
1385 {
1386   if (!!strncmp (name, "_OBJC_", 6))
1387     default_globalize_label (stream, name);
1388 }
1389
1390 void
1391 darwin_asm_named_section (const char *name,
1392                           unsigned int flags ATTRIBUTE_UNUSED,
1393                           tree decl ATTRIBUTE_UNUSED)
1394 {
1395   fprintf (asm_out_file, "\t.section %s\n", name);
1396 }
1397
1398 void
1399 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1400 {
1401   /* Darwin does not use unique sections.  */
1402 }
1403
1404 /* Handle __attribute__ ((apple_kext_compatibility)).
1405    This only applies to darwin kexts for 2.95 compatibility -- it shrinks the
1406    vtable for classes with this attribute (and their descendants) by not
1407    outputting the new 3.0 nondeleting destructor.  This means that such
1408    objects CANNOT be allocated on the stack or as globals UNLESS they have
1409    a completely empty `operator delete'.
1410    Luckily, this fits in with the Darwin kext model.
1411
1412    This attribute also disables gcc3's potential overlaying of derived
1413    class data members on the padding at the end of the base class.  */
1414
1415 tree
1416 darwin_handle_kext_attribute (tree *node, tree name,
1417                               tree args ATTRIBUTE_UNUSED,
1418                               int flags ATTRIBUTE_UNUSED,
1419                               bool *no_add_attrs)
1420 {
1421   /* APPLE KEXT stuff -- only applies with pure static C++ code.  */
1422   if (! TARGET_KEXTABI)
1423     {
1424       warning (0, "%<%s%> 2.95 vtable-compatibility attribute applies "
1425                "only when compiling a kext", IDENTIFIER_POINTER (name));
1426
1427       *no_add_attrs = true;
1428     }
1429   else if (TREE_CODE (*node) != RECORD_TYPE)
1430     {
1431       warning (0, "%<%s%> 2.95 vtable-compatibility attribute applies "
1432                "only to C++ classes", IDENTIFIER_POINTER (name));
1433
1434       *no_add_attrs = true;
1435     }
1436
1437   return NULL_TREE;
1438 }
1439
1440 /* Handle a "weak_import" attribute; arguments as in
1441    struct attribute_spec.handler.  */
1442
1443 tree
1444 darwin_handle_weak_import_attribute (tree *node, tree name,
1445                                      tree ARG_UNUSED (args),
1446                                      int ARG_UNUSED (flags),
1447                                      bool * no_add_attrs)
1448 {
1449   if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1450     {
1451       warning (OPT_Wattributes, "%qs attribute ignored",
1452                IDENTIFIER_POINTER (name));
1453       *no_add_attrs = true;
1454     }
1455   else
1456     declare_weak (*node);
1457
1458   return NULL_TREE;
1459 }
1460
1461 static void
1462 no_dead_strip (FILE *file, const char *lab)
1463 {
1464   fprintf (file, ".no_dead_strip %s\n", lab);
1465 }
1466
1467 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1468    The third parameter is nonzero if this is for exception handling.
1469    The fourth parameter is nonzero if this is just a placeholder for an
1470    FDE that we are omitting. */
1471
1472 void
1473 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1474 {
1475   const char *base;
1476   char *lab;
1477   bool need_quotes;
1478
1479   if (DECL_ASSEMBLER_NAME_SET_P (decl))
1480     base = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
1481   else
1482     base = IDENTIFIER_POINTER (DECL_NAME (decl));
1483
1484   base = targetm.strip_name_encoding (base);
1485   need_quotes = name_needs_quotes (base);
1486
1487   if (! for_eh)
1488     return;
1489
1490   lab = concat (need_quotes ? "\"" : "", user_label_prefix, base, ".eh",
1491                 need_quotes ? "\"" : "", NULL);
1492
1493   if (TREE_PUBLIC (decl))
1494     fprintf (file, "\t%s %s\n",
1495              (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1496               ? ".globl"
1497               : ".private_extern"),
1498              lab);
1499
1500   if (DECL_WEAK (decl))
1501     fprintf (file, "\t.weak_definition %s\n", lab);
1502
1503   if (empty)
1504     {
1505       fprintf (file, "%s = 0\n", lab);
1506
1507       /* Mark the absolute .eh and .eh1 style labels as needed to
1508          ensure that we don't dead code strip them and keep such
1509          labels from another instantiation point until we can fix this
1510          properly with group comdat support.  */
1511       no_dead_strip (file, lab);
1512     }
1513   else
1514     fprintf (file, "%s:\n", lab);
1515
1516   free (lab);
1517 }
1518
1519 static GTY(()) unsigned long except_table_label_num;
1520
1521 void
1522 darwin_emit_except_table_label (FILE *file)
1523 {
1524   char section_start_label[30];
1525
1526   ASM_GENERATE_INTERNAL_LABEL (section_start_label, "GCC_except_table",
1527                                except_table_label_num++);
1528   ASM_OUTPUT_LABEL (file, section_start_label);
1529 }
1530 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */
1531
1532 void
1533 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1534 {
1535   const char *nlp_name;
1536
1537   gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1538
1539   nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1540   fputs ("\t.long\t", file);
1541   ASM_OUTPUT_LABELREF (file, nlp_name);
1542   fputs ("-.", file);
1543 }
1544
1545 /* Emit an assembler directive to set visibility for a symbol.  The
1546    only supported visibilities are VISIBILITY_DEFAULT and
1547    VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1548    extern".  There is no MACH-O equivalent of ELF's
1549    VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1550
1551 void
1552 darwin_assemble_visibility (tree decl, int vis)
1553 {
1554   if (vis == VISIBILITY_DEFAULT)
1555     ;
1556   else if (vis == VISIBILITY_HIDDEN)
1557     {
1558       fputs ("\t.private_extern ", asm_out_file);
1559       assemble_name (asm_out_file,
1560                      (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1561       fputs ("\n", asm_out_file);
1562     }
1563   else
1564     warning (OPT_Wattributes, "internal and protected visibility attributes "
1565              "not supported in this configuration; ignored");
1566 }
1567
1568 /* Output a difference of two labels that will be an assembly time
1569    constant if the two labels are local.  (.long lab1-lab2 will be
1570    very different if lab1 is at the boundary between two sections; it
1571    will be relocated according to the second section, not the first,
1572    so one ends up with a difference between labels in different
1573    sections, which is bad in the dwarf2 eh context for instance.)  */
1574
1575 static int darwin_dwarf_label_counter;
1576
1577 void
1578 darwin_asm_output_dwarf_delta (FILE *file, int size,
1579                                const char *lab1, const char *lab2)
1580 {
1581   int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1582                      && lab2[0] == '*' && lab2[1] == 'L');
1583   const char *directive = (size == 8 ? ".quad" : ".long");
1584
1585   if (islocaldiff)
1586     fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1587   else
1588     fprintf (file, "\t%s\t", directive);
1589   assemble_name_raw (file, lab1);
1590   fprintf (file, "-");
1591   assemble_name_raw (file, lab2);
1592   if (islocaldiff)
1593     fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1594 }
1595
1596 /* Output labels for the start of the DWARF sections if necessary.  */
1597 void
1598 darwin_file_start (void)
1599 {
1600   if (write_symbols == DWARF2_DEBUG)
1601     {
1602       static const char * const debugnames[] =
1603         {
1604           DEBUG_FRAME_SECTION,
1605           DEBUG_INFO_SECTION,
1606           DEBUG_ABBREV_SECTION,
1607           DEBUG_ARANGES_SECTION,
1608           DEBUG_MACINFO_SECTION,
1609           DEBUG_LINE_SECTION,
1610           DEBUG_LOC_SECTION,
1611           DEBUG_PUBNAMES_SECTION,
1612           DEBUG_PUBTYPES_SECTION,
1613           DEBUG_STR_SECTION,
1614           DEBUG_RANGES_SECTION
1615         };
1616       size_t i;
1617
1618       for (i = 0; i < ARRAY_SIZE (debugnames); i++)
1619         {
1620           int namelen;
1621
1622           switch_to_section (get_section (debugnames[i], SECTION_DEBUG, NULL));
1623
1624           gcc_assert (strncmp (debugnames[i], "__DWARF,", 8) == 0);
1625           gcc_assert (strchr (debugnames[i] + 8, ','));
1626
1627           namelen = strchr (debugnames[i] + 8, ',') - (debugnames[i] + 8);
1628           fprintf (asm_out_file, "Lsection%.*s:\n", namelen, debugnames[i] + 8);
1629         }
1630     }
1631 }
1632
1633 /* Output an offset in a DWARF section on Darwin.  On Darwin, DWARF section
1634    offsets are not represented using relocs in .o files; either the
1635    section never leaves the .o file, or the linker or other tool is
1636    responsible for parsing the DWARF and updating the offsets.  */
1637
1638 void
1639 darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
1640                                 section *base)
1641 {
1642   char sname[64];
1643   int namelen;
1644
1645   gcc_assert (base->common.flags & SECTION_NAMED);
1646   gcc_assert (strncmp (base->named.name, "__DWARF,", 8) == 0);
1647   gcc_assert (strchr (base->named.name + 8, ','));
1648
1649   namelen = strchr (base->named.name + 8, ',') - (base->named.name + 8);
1650   sprintf (sname, "*Lsection%.*s", namelen, base->named.name + 8);
1651   darwin_asm_output_dwarf_delta (file, size, lab, sname);
1652 }
1653
1654 void
1655 darwin_file_end (void)
1656 {
1657   machopic_finish (asm_out_file);
1658   if (strcmp (lang_hooks.name, "GNU C++") == 0)
1659     {
1660       switch_to_section (darwin_sections[constructor_section]);
1661       switch_to_section (darwin_sections[destructor_section]);
1662       ASM_OUTPUT_ALIGN (asm_out_file, 1);
1663     }
1664   fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1665 }
1666
1667 /* TODO: Add a language hook for identifying if a decl is a vtable.  */
1668 #define DARWIN_VTABLE_P(DECL) 0
1669
1670 /* Cross-module name binding.  Darwin does not support overriding
1671    functions at dynamic-link time, except for vtables in kexts.  */
1672
1673 bool
1674 darwin_binds_local_p (const_tree decl)
1675 {
1676   return default_binds_local_p_1 (decl,
1677                                   TARGET_KEXTABI && DARWIN_VTABLE_P (decl));
1678 }
1679
1680 #if 0
1681 /* See TARGET_ASM_OUTPUT_ANCHOR for why we can't do this yet.  */
1682 /* The Darwin's implementation of TARGET_ASM_OUTPUT_ANCHOR.  Define the
1683    anchor relative to ".", the current section position.  We cannot use
1684    the default one because ASM_OUTPUT_DEF is wrong for Darwin.  */
1685
1686 void
1687 darwin_asm_output_anchor (rtx symbol)
1688 {
1689   fprintf (asm_out_file, "\t.set\t");
1690   assemble_name (asm_out_file, XSTR (symbol, 0));
1691   fprintf (asm_out_file, ", . + " HOST_WIDE_INT_PRINT_DEC "\n",
1692            SYMBOL_REF_BLOCK_OFFSET (symbol));
1693 }
1694 #endif
1695
1696 /* Set the darwin specific attributes on TYPE.  */
1697 void
1698 darwin_set_default_type_attributes (tree type)
1699 {
1700   if (darwin_ms_struct
1701       && TREE_CODE (type) == RECORD_TYPE)
1702     TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("ms_struct"),
1703                                         NULL_TREE,
1704                                         TYPE_ATTRIBUTES (type));
1705 }
1706
1707 /* True, iff we're generating code for loadable kernel extensions.  */
1708
1709 bool
1710 darwin_kextabi_p (void) {
1711   return flag_apple_kext;
1712 }
1713
1714 void
1715 darwin_override_options (void)
1716 {
1717   if (flag_mkernel || flag_apple_kext)
1718     {
1719       /* -mkernel implies -fapple-kext for C++ */
1720       if (strcmp (lang_hooks.name, "GNU C++") == 0)
1721         flag_apple_kext = 1;
1722
1723       flag_no_common = 1;
1724
1725       /* No EH in kexts.  */
1726       flag_exceptions = 0;
1727       /* No -fnon-call-exceptions data in kexts.  */
1728       flag_non_call_exceptions = 0;
1729     }
1730   if (flag_var_tracking
1731       && strverscmp (darwin_macosx_version_min, "10.5") >= 0
1732       && debug_info_level >= DINFO_LEVEL_NORMAL
1733       && debug_hooks->var_location != do_nothing_debug_hooks.var_location)
1734     flag_var_tracking_uninit = 1;
1735 }
1736
1737 #include "gt-darwin.h"