OSDN Git Service

2007-06-15 Andrew Pinski <andrew_pinski@playstation.sony.com>
[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 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 #include "df.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(()) 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 =
280       (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
281
282   current_function_uses_pic_offset_table = 1;
283
284   return function_base;
285 }
286
287 /* Return a SYMBOL_REF for the PIC function base.  */
288
289 rtx
290 machopic_function_base_sym (void)
291 {
292   rtx sym_ref;
293
294   sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
295   SYMBOL_REF_FLAGS (sym_ref)
296     |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
297   return sym_ref;
298 }
299
300 /* Return either ORIG or (const:P (minus:P ORIG PIC_BASE)), depending
301    on whether pic_base is NULL or not.  */
302 static inline rtx
303 gen_pic_offset (rtx orig, rtx pic_base)
304 {
305   if (!pic_base)
306     return orig;
307   else
308     return gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, pic_base));
309 }
310
311 static GTY(()) const char * function_base_func_name;
312 static GTY(()) int current_pic_label_num;
313
314 void
315 machopic_output_function_base_name (FILE *file)
316 {
317   const char *current_name;
318
319   /* If dynamic-no-pic is on, we should not get here.  */
320   gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
321   current_name =
322     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
323   if (function_base_func_name != current_name)
324     {
325       ++current_pic_label_num;
326       function_base_func_name = current_name;
327     }
328   fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
329 }
330
331 /* The suffix attached to non-lazy pointer symbols.  */
332 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
333 /* The suffix attached to stub symbols.  */
334 #define STUB_SUFFIX "$stub"
335
336 typedef struct machopic_indirection GTY (())
337 {
338   /* The SYMBOL_REF for the entity referenced.  */
339   rtx symbol;
340   /* The name of the stub or non-lazy pointer.  */
341   const char * ptr_name;
342   /* True iff this entry is for a stub (as opposed to a non-lazy
343      pointer).  */
344   bool stub_p;
345   /* True iff this stub or pointer pointer has been referenced.  */
346   bool used;
347 } machopic_indirection;
348
349 /* A table mapping stub names and non-lazy pointer names to
350    SYMBOL_REFs for the stubbed-to and pointed-to entities.  */
351
352 static GTY ((param_is (struct machopic_indirection))) htab_t
353   machopic_indirections;
354
355 /* Return a hash value for a SLOT in the indirections hash table.  */
356
357 static hashval_t
358 machopic_indirection_hash (const void *slot)
359 {
360   const machopic_indirection *p = (const machopic_indirection *) slot;
361   return htab_hash_string (p->ptr_name);
362 }
363
364 /* Returns true if the KEY is the same as that associated with
365    SLOT.  */
366
367 static int
368 machopic_indirection_eq (const void *slot, const void *key)
369 {
370   return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0;
371 }
372
373 /* Return the name of the non-lazy pointer (if STUB_P is false) or
374    stub (if STUB_B is true) corresponding to the given name.  */
375
376 const char *
377 machopic_indirection_name (rtx sym_ref, bool stub_p)
378 {
379   char *buffer;
380   const char *name = XSTR (sym_ref, 0);
381   size_t namelen = strlen (name);
382   machopic_indirection *p;
383   void ** slot;
384   bool saw_star = false;
385   bool needs_quotes;
386   const char *suffix;
387   const char *prefix = user_label_prefix;
388   const char *quote = "";
389   tree id;
390
391   id = maybe_get_identifier (name);
392   if (id)
393     {
394       tree id_orig = id;
395
396       while (IDENTIFIER_TRANSPARENT_ALIAS (id))
397         id = TREE_CHAIN (id);
398       if (id != id_orig)
399         {
400           name = IDENTIFIER_POINTER (id);
401           namelen = strlen (name);
402         }
403     }
404
405   if (name[0] == '*')
406     {
407       saw_star = true;
408       prefix = "";
409       ++name;
410       --namelen;
411     }
412
413   needs_quotes = name_needs_quotes (name);
414   if (needs_quotes)
415     {
416       quote = "\"";
417     }
418
419   if (stub_p)
420     suffix = STUB_SUFFIX;
421   else
422     suffix = NON_LAZY_POINTER_SUFFIX;
423
424   buffer = alloca (strlen ("&L")
425                    + strlen (prefix)
426                    + namelen
427                    + strlen (suffix)
428                    + 2 * strlen (quote)
429                    + 1 /* '\0' */);
430
431   /* Construct the name of the non-lazy pointer or stub.  */
432   sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
433
434   if (!machopic_indirections)
435     machopic_indirections = htab_create_ggc (37,
436                                              machopic_indirection_hash,
437                                              machopic_indirection_eq,
438                                              /*htab_del=*/NULL);
439
440   slot = htab_find_slot_with_hash (machopic_indirections, buffer,
441                                    htab_hash_string (buffer), INSERT);
442   if (*slot)
443     {
444       p = (machopic_indirection *) *slot;
445     }
446   else
447     {
448       p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
449       p->symbol = sym_ref;
450       p->ptr_name = xstrdup (buffer);
451       p->stub_p = stub_p;
452       p->used = false;
453       *slot = p;
454     }
455
456   return p->ptr_name;
457 }
458
459 /* Return the name of the stub for the mcount function.  */
460
461 const char*
462 machopic_mcount_stub_name (void)
463 {
464   rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
465   return machopic_indirection_name (symbol, /*stub_p=*/true);
466 }
467
468 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
469    or non-lazy pointer as used -- and mark the object to which the
470    pointer/stub refers as used as well, since the pointer/stub will
471    emit a reference to it.  */
472
473 void
474 machopic_validate_stub_or_non_lazy_ptr (const char *name)
475 {
476   machopic_indirection *p;
477
478   p = ((machopic_indirection *)
479        (htab_find_with_hash (machopic_indirections, name,
480                              htab_hash_string (name))));
481   if (p && ! p->used)
482     {
483       const char *real_name;
484       tree id;
485
486       p->used = true;
487
488       /* Do what output_addr_const will do when we actually call it.  */
489       if (SYMBOL_REF_DECL (p->symbol))
490         mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
491
492       real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
493
494       id = maybe_get_identifier (real_name);
495       if (id)
496         mark_referenced (id);
497     }
498 }
499
500 /* Transform ORIG, which may be any data source, to the corresponding
501    source using indirections.  */
502
503 rtx
504 machopic_indirect_data_reference (rtx orig, rtx reg)
505 {
506   rtx ptr_ref = orig;
507
508   if (! MACHOPIC_INDIRECT)
509     return orig;
510
511   if (GET_CODE (orig) == SYMBOL_REF)
512     {
513       int defined = machopic_data_defined_p (orig);
514
515       if (defined && MACHO_DYNAMIC_NO_PIC_P)
516         {
517 #if defined (TARGET_TOC)
518           /* Create a new register for CSE opportunities.  */
519           rtx hi_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
520           emit_insn (gen_macho_high (hi_reg, orig));
521           emit_insn (gen_macho_low (reg, hi_reg, orig));
522 #else
523            /* some other cpu -- writeme!  */
524            gcc_unreachable ();
525 #endif
526            return reg;
527         }
528       else if (defined)
529         {
530 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
531           rtx pic_base = machopic_function_base_sym ();
532           rtx offset = gen_pic_offset (orig, pic_base);
533 #endif
534
535 #if defined (TARGET_TOC) /* i.e., PowerPC */
536           rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
537
538           gcc_assert (reg);
539
540           emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
541                               gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
542                                        gen_rtx_HIGH (Pmode, offset))));
543           emit_insn (gen_rtx_SET (Pmode, reg,
544                                   gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
545
546           orig = reg;
547 #else
548 #if defined (HAVE_lo_sum)
549           gcc_assert (reg);
550
551           emit_insn (gen_rtx_SET (VOIDmode, reg,
552                                   gen_rtx_HIGH (Pmode, offset)));
553           emit_insn (gen_rtx_SET (VOIDmode, reg,
554                                   gen_rtx_LO_SUM (Pmode, reg, offset)));
555           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
556
557           orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
558 #endif
559 #endif
560           return orig;
561         }
562
563       ptr_ref = (gen_rtx_SYMBOL_REF
564                  (Pmode,
565                   machopic_indirection_name (orig, /*stub_p=*/false)));
566
567       SYMBOL_REF_DATA (ptr_ref) = SYMBOL_REF_DATA (orig);
568
569       ptr_ref = gen_const_mem (Pmode, ptr_ref);
570       machopic_define_symbol (ptr_ref);
571
572       return ptr_ref;
573     }
574   else if (GET_CODE (orig) == CONST)
575     {
576       rtx base, result;
577
578       /* legitimize both operands of the PLUS */
579       if (GET_CODE (XEXP (orig, 0)) == PLUS)
580         {
581           base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
582                                                    reg);
583           orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
584                                                    (base == reg ? 0 : reg));
585         }
586       else
587         return orig;
588
589       if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
590         result = plus_constant (base, INTVAL (orig));
591       else
592         result = gen_rtx_PLUS (Pmode, base, orig);
593
594       if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
595         {
596           if (reg)
597             {
598               emit_move_insn (reg, result);
599               result = reg;
600             }
601           else
602             {
603               result = force_reg (GET_MODE (result), result);
604             }
605         }
606
607       return result;
608
609     }
610   else if (GET_CODE (orig) == MEM)
611     XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
612   /* When the target is i386, this code prevents crashes due to the
613      compiler's ignorance on how to move the PIC base register to
614      other registers.  (The reload phase sometimes introduces such
615      insns.)  */
616   else if (GET_CODE (orig) == PLUS
617            && GET_CODE (XEXP (orig, 0)) == REG
618            && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
619 #ifdef I386
620            /* Prevent the same register from being erroneously used
621               as both the base and index registers.  */
622            && GET_CODE (XEXP (orig, 1)) == CONST
623 #endif
624            && reg)
625     {
626       emit_move_insn (reg, XEXP (orig, 0));
627       XEXP (ptr_ref, 0) = reg;
628     }
629   return ptr_ref;
630 }
631
632 /* Transform TARGET (a MEM), which is a function call target, to the
633    corresponding symbol_stub if necessary.  Return a new MEM.  */
634
635 rtx
636 machopic_indirect_call_target (rtx target)
637 {
638   if (GET_CODE (target) != MEM)
639     return target;
640
641   if (MACHOPIC_INDIRECT
642       && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
643       && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
644            & MACHO_SYMBOL_FLAG_DEFINED))
645     {
646       rtx sym_ref = XEXP (target, 0);
647       const char *stub_name = machopic_indirection_name (sym_ref,
648                                                          /*stub_p=*/true);
649       enum machine_mode mode = GET_MODE (sym_ref);
650
651       XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
652       SYMBOL_REF_DATA (XEXP (target, 0)) = SYMBOL_REF_DATA (sym_ref);
653       MEM_READONLY_P (target) = 1;
654       MEM_NOTRAP_P (target) = 1;
655     }
656
657   return target;
658 }
659
660 rtx
661 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
662 {
663   rtx pic_ref = orig;
664
665   if (! MACHOPIC_INDIRECT)
666     return orig;
667
668   /* First handle a simple SYMBOL_REF or LABEL_REF */
669   if (GET_CODE (orig) == LABEL_REF
670       || (GET_CODE (orig) == SYMBOL_REF
671           ))
672     {
673       /* addr(foo) = &func+(foo-func) */
674       rtx pic_base;
675
676       orig = machopic_indirect_data_reference (orig, reg);
677
678       if (GET_CODE (orig) == PLUS
679           && GET_CODE (XEXP (orig, 0)) == REG)
680         {
681           if (reg == 0)
682             return force_reg (mode, orig);
683
684           emit_move_insn (reg, orig);
685           return reg;
686         }
687
688       /* if dynamic-no-pic we don't have a pic base  */
689       if (MACHO_DYNAMIC_NO_PIC_P)
690         pic_base = NULL;
691       else
692         pic_base = machopic_function_base_sym ();
693
694       if (GET_CODE (orig) == MEM)
695         {
696           if (reg == 0)
697             {
698               gcc_assert (!reload_in_progress);
699               reg = gen_reg_rtx (Pmode);
700             }
701
702 #ifdef HAVE_lo_sum
703           if (MACHO_DYNAMIC_NO_PIC_P
704               && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
705                   || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
706             {
707 #if defined (TARGET_TOC)        /* ppc  */
708               rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
709               rtx asym = XEXP (orig, 0);
710               rtx mem;
711
712               emit_insn (gen_macho_high (temp_reg, asym));
713               mem = gen_const_mem (GET_MODE (orig),
714                                    gen_rtx_LO_SUM (Pmode, temp_reg, asym));
715               emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
716 #else
717               /* Some other CPU -- WriteMe! but right now there are no other
718                  platforms that can use dynamic-no-pic  */
719               gcc_unreachable ();
720 #endif
721               pic_ref = reg;
722             }
723           else
724           if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
725               || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
726             {
727               rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
728 #if defined (TARGET_TOC) /* i.e., PowerPC */
729               /* Generating a new reg may expose opportunities for
730                  common subexpression elimination.  */
731               rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
732               rtx mem;
733               rtx insn;
734               rtx sum;
735
736               sum = gen_rtx_HIGH (Pmode, offset);
737               if (! MACHO_DYNAMIC_NO_PIC_P)
738                 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
739
740               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
741
742               mem = gen_const_mem (GET_MODE (orig),
743                                   gen_rtx_LO_SUM (Pmode,
744                                                   hi_sum_reg, offset));
745               insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
746               set_unique_reg_note (insn, REG_EQUAL, pic_ref);
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                 df_set_regs_ever_live (REGNO (pic), true);
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                     df_set_regs_ever_live (REGNO (pic), true);
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 static section *
1099 darwin_text_section (int reloc, int weak)
1100 {
1101   if (reloc)
1102     return (weak
1103             ? darwin_sections[text_unlikely_coal_section]
1104             : unlikely_text_section ());
1105   else
1106     return (weak
1107             ? darwin_sections[text_coal_section]
1108             : text_section);
1109 }
1110
1111 static section *
1112 darwin_rodata_section (int weak)
1113 {
1114   return (weak
1115           ? darwin_sections[const_coal_section]
1116           : darwin_sections[const_section]);
1117 }
1118
1119 static section *
1120 darwin_mergeable_string_section (tree exp,
1121                                  unsigned HOST_WIDE_INT align)
1122 {
1123   if (flag_merge_constants
1124       && TREE_CODE (exp) == STRING_CST
1125       && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
1126       && align <= 256
1127       && ((size_t) TREE_STRING_LENGTH (exp)
1128           == strlen (TREE_STRING_POINTER (exp)) + 1))
1129     return darwin_sections[cstring_section];
1130
1131   return readonly_data_section;
1132 }
1133
1134 #ifndef HAVE_GAS_LITERAL16
1135 #define HAVE_GAS_LITERAL16 0
1136 #endif
1137
1138 static section *
1139 darwin_mergeable_constant_section (tree exp,
1140                                    unsigned HOST_WIDE_INT align)
1141 {
1142   enum machine_mode mode = DECL_MODE (exp);
1143   unsigned int modesize = GET_MODE_BITSIZE (mode);
1144
1145   if (flag_merge_constants
1146       && mode != VOIDmode
1147       && mode != BLKmode
1148       && modesize <= align
1149       && align >= 8
1150       && align <= 256
1151       && (align & (align -1)) == 0)
1152     {
1153       tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1154
1155       if (TREE_CODE (size) == INTEGER_CST
1156           && TREE_INT_CST_LOW (size) == 4
1157           && TREE_INT_CST_HIGH (size) == 0)
1158         return darwin_sections[literal4_section];
1159       else if (TREE_CODE (size) == INTEGER_CST
1160                && TREE_INT_CST_LOW (size) == 8
1161                && TREE_INT_CST_HIGH (size) == 0)
1162         return darwin_sections[literal8_section];
1163       else if (HAVE_GAS_LITERAL16
1164                && TARGET_64BIT
1165                && TREE_CODE (size) == INTEGER_CST
1166                && TREE_INT_CST_LOW (size) == 16
1167                && TREE_INT_CST_HIGH (size) == 0)
1168         return darwin_sections[literal16_section];
1169       else
1170         return readonly_data_section;
1171     }
1172
1173   return readonly_data_section;
1174 }
1175
1176 int
1177 machopic_reloc_rw_mask (void)
1178 {
1179   return MACHOPIC_INDIRECT ? 3 : 0;
1180 }
1181
1182 section *
1183 machopic_select_section (tree decl,
1184                          int reloc,
1185                          unsigned HOST_WIDE_INT align)
1186 {
1187   bool weak = (DECL_P (decl)
1188                && DECL_WEAK (decl)
1189                && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
1190                    || ! lookup_attribute ("weak_import",
1191                                           DECL_ATTRIBUTES (decl))));
1192   section *base_section;
1193
1194   switch (categorize_decl_for_section (decl, reloc))
1195     {
1196     case SECCAT_TEXT:
1197       base_section = darwin_text_section (reloc, weak);
1198       break;
1199
1200     case SECCAT_RODATA:
1201     case SECCAT_SRODATA:
1202       base_section = darwin_rodata_section (weak);
1203       break;
1204
1205     case SECCAT_RODATA_MERGE_STR:
1206       base_section = darwin_mergeable_string_section (decl, align);
1207       break;
1208
1209     case SECCAT_RODATA_MERGE_STR_INIT:
1210       base_section = darwin_mergeable_string_section (DECL_INITIAL (decl), align);
1211       break;
1212
1213     case SECCAT_RODATA_MERGE_CONST:
1214       base_section =  darwin_mergeable_constant_section (decl, align);
1215       break;
1216
1217     case SECCAT_DATA:
1218     case SECCAT_DATA_REL:
1219     case SECCAT_DATA_REL_LOCAL:
1220     case SECCAT_DATA_REL_RO:
1221     case SECCAT_DATA_REL_RO_LOCAL:
1222     case SECCAT_SDATA:
1223     case SECCAT_TDATA:
1224     case SECCAT_BSS:
1225     case SECCAT_SBSS:
1226     case SECCAT_TBSS:
1227       if (TREE_READONLY (decl) || TREE_CONSTANT (decl))
1228         base_section = weak ? darwin_sections[const_data_coal_section]
1229                             : darwin_sections[const_data_section];
1230       else
1231         base_section = weak ? darwin_sections[data_coal_section] : data_section;
1232       break;
1233
1234     default:
1235       gcc_unreachable ();
1236     }
1237
1238   /* Darwin weird special cases.  */
1239   if (TREE_CODE (decl) == CONSTRUCTOR
1240       && TREE_TYPE (decl)
1241       && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
1242       && TYPE_NAME (TREE_TYPE (decl)))
1243     {
1244       tree name = TYPE_NAME (TREE_TYPE (decl));
1245       if (TREE_CODE (name) == TYPE_DECL)
1246         name = DECL_NAME (name);
1247
1248       if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1249         {
1250           if (flag_next_runtime)
1251             return darwin_sections[objc_constant_string_object_section];
1252           else
1253             return darwin_sections[objc_string_object_section];
1254         }
1255       else
1256         return base_section;
1257     }
1258   else if (TREE_CODE (decl) == VAR_DECL
1259            && DECL_NAME (decl)
1260            && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE
1261            && IDENTIFIER_POINTER (DECL_NAME (decl))
1262            && !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "_OBJC_", 6))
1263     {
1264       const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
1265
1266       if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1267         return darwin_sections[objc_cls_meth_section];
1268       else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1269         return darwin_sections[objc_inst_meth_section];
1270       else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1271         return darwin_sections[objc_cat_cls_meth_section];
1272       else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1273         return darwin_sections[objc_cat_inst_meth_section];
1274       else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1275         return darwin_sections[objc_class_vars_section];
1276       else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1277         return darwin_sections[objc_instance_vars_section];
1278       else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1279         return darwin_sections[objc_cat_cls_meth_section];
1280       else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1281         return darwin_sections[objc_class_names_section];
1282       else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1283         return darwin_sections[objc_meth_var_names_section];
1284       else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1285         return darwin_sections[objc_meth_var_types_section];
1286       else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1287         return darwin_sections[objc_cls_refs_section];
1288       else if (!strncmp (name, "_OBJC_CLASS_", 12))
1289         return darwin_sections[objc_class_section];
1290       else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1291         return darwin_sections[objc_meta_class_section];
1292       else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1293         return darwin_sections[objc_category_section];
1294       else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1295         return darwin_sections[objc_selector_refs_section];
1296       else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1297         return darwin_sections[objc_selector_fixup_section];
1298       else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1299         return darwin_sections[objc_symbols_section];
1300       else if (!strncmp (name, "_OBJC_MODULES", 13))
1301         return darwin_sections[objc_module_info_section];
1302       else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1303         return darwin_sections[objc_image_info_section];
1304       else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1305         return darwin_sections[objc_cat_inst_meth_section];
1306       else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1307         return darwin_sections[objc_cat_cls_meth_section];
1308       else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1309         return darwin_sections[objc_cat_cls_meth_section];
1310       else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1311         return darwin_sections[objc_protocol_section];
1312       else
1313         return base_section;
1314     }
1315
1316   return base_section;
1317 }
1318
1319 /* This can be called with address expressions as "rtx".
1320    They must go in "const".  */
1321
1322 section *
1323 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1324                              unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1325 {
1326   if (GET_MODE_SIZE (mode) == 8
1327       && (GET_CODE (x) == CONST_INT
1328           || GET_CODE (x) == CONST_DOUBLE))
1329     return darwin_sections[literal8_section];
1330   else if (GET_MODE_SIZE (mode) == 4
1331            && (GET_CODE (x) == CONST_INT
1332                || GET_CODE (x) == CONST_DOUBLE))
1333     return darwin_sections[literal4_section];
1334   else if (HAVE_GAS_LITERAL16
1335            && TARGET_64BIT
1336            && GET_MODE_SIZE (mode) == 16
1337            && (GET_CODE (x) == CONST_INT
1338                || GET_CODE (x) == CONST_DOUBLE
1339                || GET_CODE (x) == CONST_VECTOR))
1340     return darwin_sections[literal16_section];
1341   else if (MACHOPIC_INDIRECT
1342            && (GET_CODE (x) == SYMBOL_REF
1343                || GET_CODE (x) == CONST
1344                || GET_CODE (x) == LABEL_REF))
1345     return darwin_sections[const_data_section];
1346   else
1347     return darwin_sections[const_section];
1348 }
1349
1350 void
1351 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1352 {
1353   if (MACHOPIC_INDIRECT)
1354     switch_to_section (darwin_sections[mod_init_section]);
1355   else
1356     switch_to_section (darwin_sections[constructor_section]);
1357   assemble_align (POINTER_SIZE);
1358   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1359
1360   if (! MACHOPIC_INDIRECT)
1361     fprintf (asm_out_file, ".reference .constructors_used\n");
1362 }
1363
1364 void
1365 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1366 {
1367   if (MACHOPIC_INDIRECT)
1368     switch_to_section (darwin_sections[mod_term_section]);
1369   else
1370     switch_to_section (darwin_sections[destructor_section]);
1371   assemble_align (POINTER_SIZE);
1372   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1373
1374   if (! MACHOPIC_INDIRECT)
1375     fprintf (asm_out_file, ".reference .destructors_used\n");
1376 }
1377
1378 void
1379 darwin_globalize_label (FILE *stream, const char *name)
1380 {
1381   if (!!strncmp (name, "_OBJC_", 6))
1382     default_globalize_label (stream, name);
1383 }
1384
1385 void
1386 darwin_asm_named_section (const char *name,
1387                           unsigned int flags ATTRIBUTE_UNUSED,
1388                           tree decl ATTRIBUTE_UNUSED)
1389 {
1390   fprintf (asm_out_file, "\t.section %s\n", name);
1391 }
1392
1393 void
1394 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1395 {
1396   /* Darwin does not use unique sections.  */
1397 }
1398
1399 /* Handle __attribute__ ((apple_kext_compatibility)).
1400    This only applies to darwin kexts for 2.95 compatibility -- it shrinks the
1401    vtable for classes with this attribute (and their descendants) by not
1402    outputting the new 3.0 nondeleting destructor.  This means that such
1403    objects CANNOT be allocated on the stack or as globals UNLESS they have
1404    a completely empty `operator delete'.
1405    Luckily, this fits in with the Darwin kext model.
1406
1407    This attribute also disables gcc3's potential overlaying of derived
1408    class data members on the padding at the end of the base class.  */
1409
1410 tree
1411 darwin_handle_kext_attribute (tree *node, tree name,
1412                               tree args ATTRIBUTE_UNUSED,
1413                               int flags ATTRIBUTE_UNUSED,
1414                               bool *no_add_attrs)
1415 {
1416   /* APPLE KEXT stuff -- only applies with pure static C++ code.  */
1417   if (! TARGET_KEXTABI)
1418     {
1419       warning (0, "%<%s%> 2.95 vtable-compatibility attribute applies "
1420                "only when compiling a kext", IDENTIFIER_POINTER (name));
1421
1422       *no_add_attrs = true;
1423     }
1424   else if (TREE_CODE (*node) != RECORD_TYPE)
1425     {
1426       warning (0, "%<%s%> 2.95 vtable-compatibility attribute applies "
1427                "only to C++ classes", IDENTIFIER_POINTER (name));
1428
1429       *no_add_attrs = true;
1430     }
1431
1432   return NULL_TREE;
1433 }
1434
1435 /* Handle a "weak_import" attribute; arguments as in
1436    struct attribute_spec.handler.  */
1437
1438 tree
1439 darwin_handle_weak_import_attribute (tree *node, tree name,
1440                                      tree ARG_UNUSED (args),
1441                                      int ARG_UNUSED (flags),
1442                                      bool * no_add_attrs)
1443 {
1444   if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1445     {
1446       warning (OPT_Wattributes, "%qs attribute ignored",
1447                IDENTIFIER_POINTER (name));
1448       *no_add_attrs = true;
1449     }
1450   else
1451     declare_weak (*node);
1452
1453   return NULL_TREE;
1454 }
1455
1456 static void
1457 no_dead_strip (FILE *file, const char *lab)
1458 {
1459   fprintf (file, ".no_dead_strip %s\n", lab);
1460 }
1461
1462 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1463    The third parameter is nonzero if this is for exception handling.
1464    The fourth parameter is nonzero if this is just a placeholder for an
1465    FDE that we are omitting. */
1466
1467 void
1468 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1469 {
1470   const char *base;
1471   char *lab;
1472   bool need_quotes;
1473
1474   if (DECL_ASSEMBLER_NAME_SET_P (decl))
1475     base = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
1476   else
1477     base = IDENTIFIER_POINTER (DECL_NAME (decl));
1478
1479   base = targetm.strip_name_encoding (base);
1480   need_quotes = name_needs_quotes (base);
1481
1482   if (! for_eh)
1483     return;
1484
1485   lab = concat (need_quotes ? "\"" : "", user_label_prefix, base, ".eh",
1486                 need_quotes ? "\"" : "", NULL);
1487
1488   if (TREE_PUBLIC (decl))
1489     fprintf (file, "\t%s %s\n",
1490              (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1491               ? ".globl"
1492               : ".private_extern"),
1493              lab);
1494
1495   if (DECL_WEAK (decl))
1496     fprintf (file, "\t.weak_definition %s\n", lab);
1497
1498   if (empty)
1499     {
1500       fprintf (file, "%s = 0\n", lab);
1501
1502       /* Mark the absolute .eh and .eh1 style labels as needed to
1503          ensure that we don't dead code strip them and keep such
1504          labels from another instantiation point until we can fix this
1505          properly with group comdat support.  */
1506       no_dead_strip (file, lab);
1507     }
1508   else
1509     fprintf (file, "%s:\n", lab);
1510
1511   free (lab);
1512 }
1513
1514 static GTY(()) unsigned long except_table_label_num;
1515
1516 void
1517 darwin_emit_except_table_label (FILE *file)
1518 {
1519   char section_start_label[30];
1520
1521   ASM_GENERATE_INTERNAL_LABEL (section_start_label, "GCC_except_table",
1522                                except_table_label_num++);
1523   ASM_OUTPUT_LABEL (file, section_start_label);
1524 }
1525 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */
1526
1527 void
1528 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1529 {
1530   const char *nlp_name;
1531
1532   gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1533
1534   nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1535   fputs ("\t.long\t", file);
1536   ASM_OUTPUT_LABELREF (file, nlp_name);
1537   fputs ("-.", file);
1538 }
1539
1540 /* Emit an assembler directive to set visibility for a symbol.  The
1541    only supported visibilities are VISIBILITY_DEFAULT and
1542    VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1543    extern".  There is no MACH-O equivalent of ELF's
1544    VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1545
1546 void
1547 darwin_assemble_visibility (tree decl, int vis)
1548 {
1549   if (vis == VISIBILITY_DEFAULT)
1550     ;
1551   else if (vis == VISIBILITY_HIDDEN)
1552     {
1553       fputs ("\t.private_extern ", asm_out_file);
1554       assemble_name (asm_out_file,
1555                      (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1556       fputs ("\n", asm_out_file);
1557     }
1558   else
1559     warning (OPT_Wattributes, "internal and protected visibility attributes "
1560              "not supported in this configuration; ignored");
1561 }
1562
1563 /* Output a difference of two labels that will be an assembly time
1564    constant if the two labels are local.  (.long lab1-lab2 will be
1565    very different if lab1 is at the boundary between two sections; it
1566    will be relocated according to the second section, not the first,
1567    so one ends up with a difference between labels in different
1568    sections, which is bad in the dwarf2 eh context for instance.)  */
1569
1570 static int darwin_dwarf_label_counter;
1571
1572 void
1573 darwin_asm_output_dwarf_delta (FILE *file, int size,
1574                                const char *lab1, const char *lab2)
1575 {
1576   int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1577                      && lab2[0] == '*' && lab2[1] == 'L');
1578   const char *directive = (size == 8 ? ".quad" : ".long");
1579
1580   if (islocaldiff)
1581     fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1582   else
1583     fprintf (file, "\t%s\t", directive);
1584   assemble_name_raw (file, lab1);
1585   fprintf (file, "-");
1586   assemble_name_raw (file, lab2);
1587   if (islocaldiff)
1588     fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1589 }
1590
1591 /* Output labels for the start of the DWARF sections if necessary.  */
1592 void
1593 darwin_file_start (void)
1594 {
1595   if (write_symbols == DWARF2_DEBUG)
1596     {
1597       static const char * const debugnames[] =
1598         {
1599           DEBUG_FRAME_SECTION,
1600           DEBUG_INFO_SECTION,
1601           DEBUG_ABBREV_SECTION,
1602           DEBUG_ARANGES_SECTION,
1603           DEBUG_MACINFO_SECTION,
1604           DEBUG_LINE_SECTION,
1605           DEBUG_LOC_SECTION,
1606           DEBUG_PUBNAMES_SECTION,
1607           DEBUG_PUBTYPES_SECTION,
1608           DEBUG_STR_SECTION,
1609           DEBUG_RANGES_SECTION
1610         };
1611       size_t i;
1612
1613       for (i = 0; i < ARRAY_SIZE (debugnames); i++)
1614         {
1615           int namelen;
1616
1617           switch_to_section (get_section (debugnames[i], SECTION_DEBUG, NULL));
1618
1619           gcc_assert (strncmp (debugnames[i], "__DWARF,", 8) == 0);
1620           gcc_assert (strchr (debugnames[i] + 8, ','));
1621
1622           namelen = strchr (debugnames[i] + 8, ',') - (debugnames[i] + 8);
1623           fprintf (asm_out_file, "Lsection%.*s:\n", namelen, debugnames[i] + 8);
1624         }
1625     }
1626 }
1627
1628 /* Output an offset in a DWARF section on Darwin.  On Darwin, DWARF section
1629    offsets are not represented using relocs in .o files; either the
1630    section never leaves the .o file, or the linker or other tool is
1631    responsible for parsing the DWARF and updating the offsets.  */
1632
1633 void
1634 darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
1635                                 section *base)
1636 {
1637   char sname[64];
1638   int namelen;
1639
1640   gcc_assert (base->common.flags & SECTION_NAMED);
1641   gcc_assert (strncmp (base->named.name, "__DWARF,", 8) == 0);
1642   gcc_assert (strchr (base->named.name + 8, ','));
1643
1644   namelen = strchr (base->named.name + 8, ',') - (base->named.name + 8);
1645   sprintf (sname, "*Lsection%.*s", namelen, base->named.name + 8);
1646   darwin_asm_output_dwarf_delta (file, size, lab, sname);
1647 }
1648
1649 void
1650 darwin_file_end (void)
1651 {
1652   machopic_finish (asm_out_file);
1653   if (strcmp (lang_hooks.name, "GNU C++") == 0)
1654     {
1655       switch_to_section (darwin_sections[constructor_section]);
1656       switch_to_section (darwin_sections[destructor_section]);
1657       ASM_OUTPUT_ALIGN (asm_out_file, 1);
1658     }
1659   fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1660 }
1661
1662 /* TODO: Add a language hook for identifying if a decl is a vtable.  */
1663 #define DARWIN_VTABLE_P(DECL) 0
1664
1665 /* Cross-module name binding.  Darwin does not support overriding
1666    functions at dynamic-link time, except for vtables in kexts.  */
1667
1668 bool
1669 darwin_binds_local_p (tree decl)
1670 {
1671   return default_binds_local_p_1 (decl,
1672                                   TARGET_KEXTABI && DARWIN_VTABLE_P (decl));
1673 }
1674
1675 #if 0
1676 /* See TARGET_ASM_OUTPUT_ANCHOR for why we can't do this yet.  */
1677 /* The Darwin's implementation of TARGET_ASM_OUTPUT_ANCHOR.  Define the
1678    anchor relative to ".", the current section position.  We cannot use
1679    the default one because ASM_OUTPUT_DEF is wrong for Darwin.  */
1680
1681 void
1682 darwin_asm_output_anchor (rtx symbol)
1683 {
1684   fprintf (asm_out_file, "\t.set\t");
1685   assemble_name (asm_out_file, XSTR (symbol, 0));
1686   fprintf (asm_out_file, ", . + " HOST_WIDE_INT_PRINT_DEC "\n",
1687            SYMBOL_REF_BLOCK_OFFSET (symbol));
1688 }
1689 #endif
1690
1691 /* Set the darwin specific attributes on TYPE.  */
1692 void
1693 darwin_set_default_type_attributes (tree type)
1694 {
1695   if (darwin_ms_struct
1696       && TREE_CODE (type) == RECORD_TYPE)
1697     TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("ms_struct"),
1698                                         NULL_TREE,
1699                                         TYPE_ATTRIBUTES (type));
1700 }
1701
1702 /* True, iff we're generating code for loadable kernel extensions.  */
1703
1704 bool
1705 darwin_kextabi_p (void) {
1706   return flag_apple_kext;
1707 }
1708
1709 void
1710 darwin_override_options (void)
1711 {
1712   if (flag_mkernel || flag_apple_kext)
1713     {
1714       /* -mkernel implies -fapple-kext for C++ */
1715       if (strcmp (lang_hooks.name, "GNU C++") == 0)
1716         flag_apple_kext = 1;
1717
1718       flag_no_common = 1;
1719
1720       /* No EH in kexts.  */
1721       flag_exceptions = 0;
1722       /* No -fnon-call-exceptions data in kexts.  */
1723       flag_non_call_exceptions = 0;
1724     }
1725 }
1726
1727 #include "gt-darwin.h"