OSDN Git Service

* config/avr/avr.h (PREFERRED_RELOAD_CLASS): Remove.
[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, 2008, 2009, 2010
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 "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "tree.h"
37 #include "expr.h"
38 #include "reload.h"
39 #include "function.h"
40 #include "ggc.h"
41 #include "langhooks.h"
42 #include "target.h"
43 #include "tm_p.h"
44 #include "diagnostic-core.h"
45 #include "toplev.h"
46 #include "hashtab.h"
47 #include "df.h"
48 #include "debug.h"
49 #include "obstack.h"
50 #include "lto-streamer.h"
51
52 /* Darwin supports a feature called fix-and-continue, which is used
53    for rapid turn around debugging.  When code is compiled with the
54    -mfix-and-continue flag, two changes are made to the generated code
55    that allow the system to do things that it would normally not be
56    able to do easily.  These changes allow gdb to load in
57    recompilation of a translation unit that has been changed into a
58    running program and replace existing functions and methods of that
59    translation unit with versions of those functions and methods
60    from the newly compiled translation unit.  The new functions access
61    the existing static symbols from the old translation unit, if the
62    symbol existed in the unit to be replaced, and from the new
63    translation unit, otherwise.
64
65    The changes are to insert 5 nops at the beginning of all functions
66    and to use indirection to get at static symbols.  The 5 nops
67    are required by consumers of the generated code.  Currently, gdb
68    uses this to patch in a jump to the overriding function, this
69    allows all uses of the old name to forward to the replacement,
70    including existing function pointers and virtual methods.  See
71    rs6000_emit_prologue for the code that handles the nop insertions.
72
73    The added indirection allows gdb to redirect accesses to static
74    symbols from the newly loaded translation unit to the existing
75    symbol, if any.  @code{static} symbols are special and are handled by
76    setting the second word in the .non_lazy_symbol_pointer data
77    structure to symbol.  See indirect_data for the code that handles
78    the extra indirection, and machopic_output_indirection and its use
79    of MACHO_SYMBOL_STATIC for the code that handles @code{static}
80    symbol indirection.  */
81
82 /* For darwin >= 9  (OSX 10.5) the linker is capable of making the necessary
83    branch islands and we no longer need to emit darwin stubs.
84    However, if we are generating code for earlier systems (or for use in the 
85    kernel) the stubs might still be required, and this will be set true.  */
86 int darwin_emit_branch_islands = false;
87
88 /* Section names.  */
89 section * darwin_sections[NUM_DARWIN_SECTIONS];
90
91 /* True if we're setting __attribute__ ((ms_struct)).  */
92 int darwin_ms_struct = false;
93
94 /* A get_unnamed_section callback used to switch to an ObjC section.
95    DIRECTIVE is as for output_section_asm_op.  */
96
97 static void
98 output_objc_section_asm_op (const void *directive)
99 {
100   static bool been_here = false;
101
102   /* The NeXT ObjC Runtime requires these sections to be present and in 
103      order in the object.  The code below implements this by emitting 
104      a section header for each ObjC section the first time that an ObjC
105      section is requested.  */
106   if (! been_here)
107     {
108       section *saved_in_section = in_section;
109       static const enum darwin_section_enum tomark[] =
110         {
111           /* written, cold -> hot */
112           objc_cat_cls_meth_section,
113           objc_cat_inst_meth_section,
114           objc_string_object_section,
115           objc_constant_string_object_section,
116           objc_selector_refs_section,
117           objc_selector_fixup_section,
118           objc_cls_refs_section,
119           objc_class_section,
120           objc_meta_class_section,
121           /* shared, hot -> cold */
122           objc_cls_meth_section,
123           objc_inst_meth_section,
124           objc_protocol_section,
125           objc_class_names_section,
126           objc_meth_var_types_section,
127           objc_meth_var_names_section,
128           objc_category_section,
129           objc_class_vars_section,
130           objc_instance_vars_section,
131           objc_module_info_section,
132           objc_symbols_section
133         };
134       size_t i;
135
136       been_here = true;
137       for (i = 0; i < ARRAY_SIZE (tomark); i++)
138         switch_to_section (darwin_sections[tomark[i]]);
139       switch_to_section (saved_in_section);
140     }
141   output_section_asm_op (directive);
142 }
143
144 /* Implement TARGET_ASM_INIT_SECTIONS.  */
145
146 void
147 darwin_init_sections (void)
148 {
149 #define DEF_SECTION(NAME, FLAGS, DIRECTIVE, OBJC)               \
150   darwin_sections[NAME] =                                       \
151     get_unnamed_section (FLAGS, (OBJC                           \
152                                  ? output_objc_section_asm_op   \
153                                  : output_section_asm_op),      \
154                          "\t" DIRECTIVE);
155 #include "config/darwin-sections.def"
156 #undef DEF_SECTION
157
158   readonly_data_section = darwin_sections[const_section];
159   exception_section = darwin_sections[darwin_exception_section];
160   eh_frame_section = darwin_sections[darwin_eh_frame_section];
161 }
162
163 int
164 name_needs_quotes (const char *name)
165 {
166   int c;
167   while ((c = *name++) != '\0')
168     if (! ISIDNUM (c) 
169           && c != '.' && c != '$' && c != '_' )
170       return 1;
171   return 0;
172 }
173
174 /* Return true if SYM_REF can be used without an indirection.  */
175 static int
176 machopic_symbol_defined_p (rtx sym_ref)
177 {
178   if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
179     return true;
180
181   /* If a symbol references local and is not an extern to this
182      file, then the symbol might be able to declared as defined.  */
183   if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
184     {
185       /* If the symbol references a variable and the variable is a
186          common symbol, then this symbol is not defined.  */
187       if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_VARIABLE)
188         {
189           tree decl = SYMBOL_REF_DECL (sym_ref);
190           if (!decl)
191             return true;
192           if (DECL_COMMON (decl))
193             return false;
194         }
195       return true;
196     }
197   return false;
198 }
199
200 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
201    reference, which will not be changed.  */
202
203 enum machopic_addr_class
204 machopic_classify_symbol (rtx sym_ref)
205 {
206   bool function_p;
207
208   function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
209   if (machopic_symbol_defined_p (sym_ref))
210     return (function_p
211             ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
212   else
213     return (function_p
214             ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
215 }
216
217 #ifndef TARGET_FIX_AND_CONTINUE
218 #define TARGET_FIX_AND_CONTINUE 0
219 #endif
220
221 /* Indicate when fix-and-continue style code generation is being used
222    and when a reference to data should be indirected so that it can be
223    rebound in a new translation unit to reference the original instance
224    of that data.  Symbol names that are for code generation local to
225    the translation unit are bound to the new translation unit;
226    currently this means symbols that begin with L or _OBJC_;
227    otherwise, we indicate that an indirect reference should be made to
228    permit the runtime to rebind new instances of the translation unit
229    to the original instance of the data.  */
230
231 static int
232 indirect_data (rtx sym_ref)
233 {
234   int lprefix;
235   const char *name;
236
237   /* If we aren't generating fix-and-continue code, don't do anything
238      special.  */
239   if (TARGET_FIX_AND_CONTINUE == 0)
240     return 0;
241
242   /* Otherwise, all symbol except symbols that begin with L or _OBJC_
243      are indirected.  Symbols that begin with L and _OBJC_ are always
244      bound to the current translation unit as they are used for
245      generated local data of the translation unit.  */
246
247   name = XSTR (sym_ref, 0);
248
249   lprefix = (((name[0] == '*' || name[0] == '&')
250               && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
251              || (strncmp (name, "_OBJC_", 6) == 0));
252
253   return ! lprefix;
254 }
255
256
257 static int
258 machopic_data_defined_p (rtx sym_ref)
259 {
260   if (indirect_data (sym_ref))
261     return 0;
262
263   switch (machopic_classify_symbol (sym_ref))
264     {
265     case MACHOPIC_DEFINED_DATA:
266     case MACHOPIC_DEFINED_FUNCTION:
267       return 1;
268     default:
269       return 0;
270     }
271 }
272
273 void
274 machopic_define_symbol (rtx mem)
275 {
276   rtx sym_ref;
277
278   gcc_assert (GET_CODE (mem) == MEM);
279   sym_ref = XEXP (mem, 0);
280   SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
281 }
282
283 /* Return either ORIG or:
284
285      (const:P (unspec:P [ORIG] UNSPEC_MACHOPIC_OFFSET))
286
287    depending on MACHO_DYNAMIC_NO_PIC_P.  */
288 rtx
289 machopic_gen_offset (rtx orig)
290 {
291   if (MACHO_DYNAMIC_NO_PIC_P)
292     return orig;
293   else
294     {
295       /* Play games to avoid marking the function as needing pic if we
296          are being called as part of the cost-estimation process.  */
297       if (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl)
298         crtl->uses_pic_offset_table = 1;
299       orig = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
300                              UNSPEC_MACHOPIC_OFFSET);
301       return gen_rtx_CONST (Pmode, orig);
302     }
303 }
304
305 static GTY(()) const char * function_base_func_name;
306 static GTY(()) int current_pic_label_num;
307
308 void
309 machopic_output_function_base_name (FILE *file)
310 {
311   const char *current_name;
312
313   /* If dynamic-no-pic is on, we should not get here.  */
314   gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
315   current_name =
316     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
317   if (function_base_func_name != current_name)
318     {
319       ++current_pic_label_num;
320       function_base_func_name = current_name;
321     }
322   fprintf (file, "L%011d$pb", current_pic_label_num);
323 }
324
325 /* The suffix attached to non-lazy pointer symbols.  */
326 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
327 /* The suffix attached to stub symbols.  */
328 #define STUB_SUFFIX "$stub"
329
330 typedef struct GTY (()) machopic_indirection
331 {
332   /* The SYMBOL_REF for the entity referenced.  */
333   rtx symbol;
334   /* The name of the stub or non-lazy pointer.  */
335   const char * ptr_name;
336   /* True iff this entry is for a stub (as opposed to a non-lazy
337      pointer).  */
338   bool stub_p;
339   /* True iff this stub or pointer pointer has been referenced.  */
340   bool used;
341 } machopic_indirection;
342
343 /* A table mapping stub names and non-lazy pointer names to
344    SYMBOL_REFs for the stubbed-to and pointed-to entities.  */
345
346 static GTY ((param_is (struct machopic_indirection))) htab_t
347   machopic_indirections;
348
349 /* Return a hash value for a SLOT in the indirections hash table.  */
350
351 static hashval_t
352 machopic_indirection_hash (const void *slot)
353 {
354   const machopic_indirection *p = (const machopic_indirection *) slot;
355   return htab_hash_string (p->ptr_name);
356 }
357
358 /* Returns true if the KEY is the same as that associated with
359    SLOT.  */
360
361 static int
362 machopic_indirection_eq (const void *slot, const void *key)
363 {
364   return strcmp (((const machopic_indirection *) slot)->ptr_name,
365                  (const char *) key) == 0;
366 }
367
368 /* Return the name of the non-lazy pointer (if STUB_P is false) or
369    stub (if STUB_B is true) corresponding to the given name.  */
370
371 const char *
372 machopic_indirection_name (rtx sym_ref, bool stub_p)
373 {
374   char *buffer;
375   const char *name = XSTR (sym_ref, 0);
376   size_t namelen = strlen (name);
377   machopic_indirection *p;
378   void ** slot;
379   bool needs_quotes;
380   const char *suffix;
381   const char *prefix = user_label_prefix;
382   const char *quote = "";
383   tree id;
384
385   id = maybe_get_identifier (name);
386   if (id)
387     {
388       tree id_orig = id;
389
390       while (IDENTIFIER_TRANSPARENT_ALIAS (id))
391         id = TREE_CHAIN (id);
392       if (id != id_orig)
393         {
394           name = IDENTIFIER_POINTER (id);
395           namelen = strlen (name);
396         }
397     }
398
399   if (name[0] == '*')
400     {
401       prefix = "";
402       ++name;
403       --namelen;
404     }
405
406   needs_quotes = name_needs_quotes (name);
407   if (needs_quotes)
408     {
409       quote = "\"";
410     }
411
412   if (stub_p)
413     suffix = STUB_SUFFIX;
414   else
415     suffix = NON_LAZY_POINTER_SUFFIX;
416
417   buffer = XALLOCAVEC (char, strlen ("&L")
418                    + strlen (prefix)
419                    + namelen
420                    + strlen (suffix)
421                    + 2 * strlen (quote)
422                    + 1 /* '\0' */);
423
424   /* Construct the name of the non-lazy pointer or stub.  */
425   sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
426
427   if (!machopic_indirections)
428     machopic_indirections = htab_create_ggc (37,
429                                              machopic_indirection_hash,
430                                              machopic_indirection_eq,
431                                              /*htab_del=*/NULL);
432
433   slot = htab_find_slot_with_hash (machopic_indirections, buffer,
434                                    htab_hash_string (buffer), INSERT);
435   if (*slot)
436     {
437       p = (machopic_indirection *) *slot;
438     }
439   else
440     {
441       p = ggc_alloc_machopic_indirection ();
442       p->symbol = sym_ref;
443       p->ptr_name = xstrdup (buffer);
444       p->stub_p = stub_p;
445       p->used = false;
446       *slot = p;
447     }
448
449   return p->ptr_name;
450 }
451
452 /* Return the name of the stub for the mcount function.  */
453
454 const char*
455 machopic_mcount_stub_name (void)
456 {
457   rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
458   return machopic_indirection_name (symbol, /*stub_p=*/true);
459 }
460
461 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
462    or non-lazy pointer as used -- and mark the object to which the
463    pointer/stub refers as used as well, since the pointer/stub will
464    emit a reference to it.  */
465
466 void
467 machopic_validate_stub_or_non_lazy_ptr (const char *name)
468 {
469   machopic_indirection *p;
470
471   p = ((machopic_indirection *)
472        (htab_find_with_hash (machopic_indirections, name,
473                              htab_hash_string (name))));
474   if (p && ! p->used)
475     {
476       const char *real_name;
477       tree id;
478
479       p->used = true;
480
481       /* Do what output_addr_const will do when we actually call it.  */
482       if (SYMBOL_REF_DECL (p->symbol))
483         mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
484
485       real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
486
487       id = maybe_get_identifier (real_name);
488       if (id)
489         mark_referenced (id);
490     }
491 }
492
493 /* Transform ORIG, which may be any data source, to the corresponding
494    source using indirections.  */
495
496 rtx
497 machopic_indirect_data_reference (rtx orig, rtx reg)
498 {
499   rtx ptr_ref = orig;
500
501   if (! MACHOPIC_INDIRECT)
502     return orig;
503
504   if (GET_CODE (orig) == SYMBOL_REF)
505     {
506       int defined = machopic_data_defined_p (orig);
507
508       if (defined && MACHO_DYNAMIC_NO_PIC_P)
509         {
510 #if defined (TARGET_TOC)
511           /* Create a new register for CSE opportunities.  */
512           rtx hi_reg = (!can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode));
513           emit_insn (gen_macho_high (hi_reg, orig));
514           emit_insn (gen_macho_low (reg, hi_reg, orig));
515 #else
516            /* some other cpu -- writeme!  */
517            gcc_unreachable ();
518 #endif
519            return reg;
520         }
521       else if (defined)
522         {
523 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
524           rtx offset = machopic_gen_offset (orig);
525 #endif
526
527 #if defined (TARGET_TOC) /* i.e., PowerPC */
528           rtx hi_sum_reg = (!can_create_pseudo_p ()
529                             ? reg
530                             : gen_reg_rtx (Pmode));
531
532           gcc_assert (reg);
533
534           emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
535                               gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
536                                        gen_rtx_HIGH (Pmode, offset))));
537           emit_insn (gen_rtx_SET (Pmode, reg,
538                                   gen_rtx_LO_SUM (Pmode, hi_sum_reg,
539                                                   copy_rtx (offset))));
540
541           orig = reg;
542 #else
543 #if defined (HAVE_lo_sum)
544           gcc_assert (reg);
545
546           emit_insn (gen_rtx_SET (VOIDmode, reg,
547                                   gen_rtx_HIGH (Pmode, offset)));
548           emit_insn (gen_rtx_SET (VOIDmode, reg,
549                                   gen_rtx_LO_SUM (Pmode, reg,
550                                                   copy_rtx (offset))));
551           emit_use (pic_offset_table_rtx);
552
553           orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
554 #endif
555 #endif
556           return orig;
557         }
558
559       ptr_ref = (gen_rtx_SYMBOL_REF
560                  (Pmode,
561                   machopic_indirection_name (orig, /*stub_p=*/false)));
562
563       SYMBOL_REF_DATA (ptr_ref) = SYMBOL_REF_DATA (orig);
564
565       ptr_ref = gen_const_mem (Pmode, ptr_ref);
566       machopic_define_symbol (ptr_ref);
567
568       return ptr_ref;
569     }
570   else if (GET_CODE (orig) == CONST)
571     {
572       rtx base, result;
573
574       /* legitimize both operands of the PLUS */
575       if (GET_CODE (XEXP (orig, 0)) == PLUS)
576         {
577           base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
578                                                    reg);
579           orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
580                                                    (base == reg ? 0 : reg));
581         }
582       else
583         return orig;
584
585       if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
586         result = plus_constant (base, INTVAL (orig));
587       else
588         result = gen_rtx_PLUS (Pmode, base, orig);
589
590       if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
591         {
592           if (reg)
593             {
594               emit_move_insn (reg, result);
595               result = reg;
596             }
597           else
598             {
599               result = force_reg (GET_MODE (result), result);
600             }
601         }
602
603       return result;
604
605     }
606   else if (GET_CODE (orig) == MEM)
607     XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
608   /* When the target is i386, this code prevents crashes due to the
609      compiler's ignorance on how to move the PIC base register to
610      other registers.  (The reload phase sometimes introduces such
611      insns.)  */
612   else if (GET_CODE (orig) == PLUS
613            && GET_CODE (XEXP (orig, 0)) == REG
614            && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
615 #ifdef I386
616            /* Prevent the same register from being erroneously used
617               as both the base and index registers.  */
618            && GET_CODE (XEXP (orig, 1)) == CONST
619 #endif
620            && reg)
621     {
622       emit_move_insn (reg, XEXP (orig, 0));
623       XEXP (ptr_ref, 0) = reg;
624     }
625   return ptr_ref;
626 }
627
628 /* Transform TARGET (a MEM), which is a function call target, to the
629    corresponding symbol_stub if necessary.  Return a new MEM.  */
630
631 rtx
632 machopic_indirect_call_target (rtx target)
633 {
634   if (! darwin_emit_branch_islands)
635     return target;
636
637   if (GET_CODE (target) != MEM)
638     return target;
639
640   if (MACHOPIC_INDIRECT
641       && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
642       && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
643            & MACHO_SYMBOL_FLAG_DEFINED))
644     {
645       rtx sym_ref = XEXP (target, 0);
646       const char *stub_name = machopic_indirection_name (sym_ref,
647                                                          /*stub_p=*/true);
648       enum machine_mode mode = GET_MODE (sym_ref);
649
650       XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
651       SYMBOL_REF_DATA (XEXP (target, 0)) = SYMBOL_REF_DATA (sym_ref);
652       MEM_READONLY_P (target) = 1;
653       MEM_NOTRAP_P (target) = 1;
654     }
655
656   return target;
657 }
658
659 rtx
660 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
661 {
662   rtx pic_ref = orig;
663
664   if (! MACHOPIC_INDIRECT)
665     return orig;
666
667   /* First handle a simple SYMBOL_REF or LABEL_REF */
668   if (GET_CODE (orig) == LABEL_REF
669       || (GET_CODE (orig) == SYMBOL_REF
670           ))
671     {
672       /* addr(foo) = &func+(foo-func) */
673       orig = machopic_indirect_data_reference (orig, reg);
674
675       if (GET_CODE (orig) == PLUS
676           && GET_CODE (XEXP (orig, 0)) == REG)
677         {
678           if (reg == 0)
679             return force_reg (mode, orig);
680
681           emit_move_insn (reg, orig);
682           return reg;
683         }
684
685       if (GET_CODE (orig) == MEM)
686         {
687           if (reg == 0)
688             {
689               gcc_assert (!reload_in_progress);
690               reg = gen_reg_rtx (Pmode);
691             }
692
693 #ifdef HAVE_lo_sum
694           if (MACHO_DYNAMIC_NO_PIC_P
695               && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
696                   || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
697             {
698 #if defined (TARGET_TOC)        /* ppc  */
699               rtx temp_reg = (!can_create_pseudo_p ()
700                               ? reg :
701                               gen_reg_rtx (Pmode));
702               rtx asym = XEXP (orig, 0);
703               rtx mem;
704
705               emit_insn (gen_macho_high (temp_reg, asym));
706               mem = gen_const_mem (GET_MODE (orig),
707                                    gen_rtx_LO_SUM (Pmode, temp_reg,
708                                                    copy_rtx (asym)));
709               emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
710 #else
711               /* Some other CPU -- WriteMe! but right now there are no other
712                  platforms that can use dynamic-no-pic  */
713               gcc_unreachable ();
714 #endif
715               pic_ref = reg;
716             }
717           else
718           if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
719               || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
720             {
721               rtx offset = machopic_gen_offset (XEXP (orig, 0));
722 #if defined (TARGET_TOC) /* i.e., PowerPC */
723               /* Generating a new reg may expose opportunities for
724                  common subexpression elimination.  */
725               rtx hi_sum_reg = (!can_create_pseudo_p ()
726                                 ? reg
727                                 : gen_reg_rtx (Pmode));
728               rtx mem;
729               rtx insn;
730               rtx sum;
731
732               sum = gen_rtx_HIGH (Pmode, offset);
733               if (! MACHO_DYNAMIC_NO_PIC_P)
734                 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
735
736               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
737
738               mem = gen_const_mem (GET_MODE (orig),
739                                   gen_rtx_LO_SUM (Pmode,
740                                                   hi_sum_reg,
741                                                   copy_rtx (offset)));
742               insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
743               set_unique_reg_note (insn, REG_EQUAL, pic_ref);
744
745               pic_ref = reg;
746 #else
747               emit_use (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
748
749               emit_insn (gen_rtx_SET (VOIDmode, reg,
750                                       gen_rtx_HIGH (Pmode,
751                                                     gen_rtx_CONST (Pmode,
752                                                                    offset))));
753               emit_insn (gen_rtx_SET (VOIDmode, reg,
754                                   gen_rtx_LO_SUM (Pmode, reg,
755                                            gen_rtx_CONST (Pmode,
756                                                           copy_rtx (offset)))));
757               pic_ref = gen_rtx_PLUS (Pmode,
758                                       pic_offset_table_rtx, reg);
759 #endif
760             }
761           else
762 #endif  /* HAVE_lo_sum */
763             {
764               rtx pic = pic_offset_table_rtx;
765               if (GET_CODE (pic) != REG)
766                 {
767                   emit_move_insn (reg, pic);
768                   pic = reg;
769                 }
770 #if 0
771               emit_use (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
772 #endif
773
774               if (reload_in_progress)
775                 df_set_regs_ever_live (REGNO (pic), true);
776               pic_ref = gen_rtx_PLUS (Pmode, pic,
777                                       machopic_gen_offset (XEXP (orig, 0)));
778             }
779
780 #if !defined (TARGET_TOC)
781           emit_move_insn (reg, pic_ref);
782           pic_ref = gen_const_mem (GET_MODE (orig), reg);
783 #endif
784         }
785       else
786         {
787
788 #ifdef HAVE_lo_sum
789           if (GET_CODE (orig) == SYMBOL_REF
790               || GET_CODE (orig) == LABEL_REF)
791             {
792               rtx offset = machopic_gen_offset (orig);
793 #if defined (TARGET_TOC) /* i.e., PowerPC */
794               rtx hi_sum_reg;
795
796               if (reg == 0)
797                 {
798                   gcc_assert (!reload_in_progress);
799                   reg = gen_reg_rtx (Pmode);
800                 }
801
802               hi_sum_reg = reg;
803
804               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
805                                       (MACHO_DYNAMIC_NO_PIC_P)
806                                       ? gen_rtx_HIGH (Pmode, offset)
807                                       : gen_rtx_PLUS (Pmode,
808                                                       pic_offset_table_rtx,
809                                                       gen_rtx_HIGH (Pmode,
810                                                                     offset))));
811               emit_insn (gen_rtx_SET (VOIDmode, reg,
812                                       gen_rtx_LO_SUM (Pmode,
813                                                       hi_sum_reg,
814                                                       copy_rtx (offset))));
815               pic_ref = reg;
816 #else
817               emit_insn (gen_rtx_SET (VOIDmode, reg,
818                                       gen_rtx_HIGH (Pmode, offset)));
819               emit_insn (gen_rtx_SET (VOIDmode, reg,
820                                       gen_rtx_LO_SUM (Pmode, reg,
821                                                       copy_rtx (offset))));
822               pic_ref = gen_rtx_PLUS (Pmode,
823                                       pic_offset_table_rtx, reg);
824 #endif
825             }
826           else
827 #endif  /*  HAVE_lo_sum  */
828             {
829               if (REG_P (orig)
830                   || GET_CODE (orig) == SUBREG)
831                 {
832                   return orig;
833                 }
834               else
835                 {
836                   rtx pic = pic_offset_table_rtx;
837                   if (GET_CODE (pic) != REG)
838                     {
839                       emit_move_insn (reg, pic);
840                       pic = reg;
841                     }
842 #if 0
843                   emit_use (pic_offset_table_rtx);
844 #endif
845                   if (reload_in_progress)
846                     df_set_regs_ever_live (REGNO (pic), true);
847                   pic_ref = gen_rtx_PLUS (Pmode,
848                                           pic,
849                                           machopic_gen_offset (orig));
850                 }
851             }
852         }
853
854       if (GET_CODE (pic_ref) != REG)
855         {
856           if (reg != 0)
857             {
858               emit_move_insn (reg, pic_ref);
859               return reg;
860             }
861           else
862             {
863               return force_reg (mode, pic_ref);
864             }
865         }
866       else
867         {
868           return pic_ref;
869         }
870     }
871
872   else if (GET_CODE (orig) == SYMBOL_REF)
873     return orig;
874
875   else if (GET_CODE (orig) == PLUS
876            && (GET_CODE (XEXP (orig, 0)) == MEM
877                || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
878                || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
879            && XEXP (orig, 0) != pic_offset_table_rtx
880            && GET_CODE (XEXP (orig, 1)) != REG)
881
882     {
883       rtx base;
884       int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
885
886       base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
887       orig = machopic_legitimize_pic_address (XEXP (orig, 1),
888                                               Pmode, (base == reg ? 0 : reg));
889       if (GET_CODE (orig) == CONST_INT)
890         {
891           pic_ref = plus_constant (base, INTVAL (orig));
892           is_complex = 1;
893         }
894       else
895         pic_ref = gen_rtx_PLUS (Pmode, base, orig);
896
897       if (reg && is_complex)
898         {
899           emit_move_insn (reg, pic_ref);
900           pic_ref = reg;
901         }
902       /* Likewise, should we set special REG_NOTEs here?  */
903     }
904
905   else if (GET_CODE (orig) == CONST)
906     {
907       return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
908     }
909
910   else if (GET_CODE (orig) == MEM
911            && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
912     {
913       rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
914       addr = replace_equiv_address (orig, addr);
915       emit_move_insn (reg, addr);
916       pic_ref = reg;
917     }
918
919   return pic_ref;
920 }
921
922 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
923    DATA is the FILE* for assembly output.  Called from
924    htab_traverse.  */
925
926 static int
927 machopic_output_indirection (void **slot, void *data)
928 {
929   machopic_indirection *p = *((machopic_indirection **) slot);
930   FILE *asm_out_file = (FILE *) data;
931   rtx symbol;
932   const char *sym_name;
933   const char *ptr_name;
934
935   if (!p->used)
936     return 1;
937
938   symbol = p->symbol;
939   sym_name = XSTR (symbol, 0);
940   ptr_name = p->ptr_name;
941
942   if (p->stub_p)
943     {
944       char *sym;
945       char *stub;
946       tree id;
947
948       id = maybe_get_identifier (sym_name);
949       if (id)
950         {
951           tree id_orig = id;
952
953           while (IDENTIFIER_TRANSPARENT_ALIAS (id))
954             id = TREE_CHAIN (id);
955           if (id != id_orig)
956             sym_name = IDENTIFIER_POINTER (id);
957         }
958
959       sym = XALLOCAVEC (char, strlen (sym_name) + 2);
960       if (sym_name[0] == '*' || sym_name[0] == '&')
961         strcpy (sym, sym_name + 1);
962       else if (sym_name[0] == '-' || sym_name[0] == '+')
963         strcpy (sym, sym_name);
964       else
965         sprintf (sym, "%s%s", user_label_prefix, sym_name);
966
967       stub = XALLOCAVEC (char, strlen (ptr_name) + 2);
968       if (ptr_name[0] == '*' || ptr_name[0] == '&')
969         strcpy (stub, ptr_name + 1);
970       else
971         sprintf (stub, "%s%s", user_label_prefix, ptr_name);
972
973       machopic_output_stub (asm_out_file, sym, stub);
974     }
975   else if (! indirect_data (symbol)
976            && (machopic_symbol_defined_p (symbol)
977                || SYMBOL_REF_LOCAL_P (symbol)))
978     {
979       switch_to_section (data_section);
980       assemble_align (GET_MODE_ALIGNMENT (Pmode));
981       assemble_label (asm_out_file, ptr_name);
982       assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
983                         GET_MODE_SIZE (Pmode),
984                         GET_MODE_ALIGNMENT (Pmode), 1);
985     }
986   else
987     {
988       rtx init = const0_rtx;
989
990       switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
991
992       /* Mach-O symbols are passed around in code through indirect
993          references and the original symbol_ref hasn't passed through
994          the generic handling and reference-catching in
995          output_operand, so we need to manually mark weak references
996          as such.  */
997       if (SYMBOL_REF_WEAK (symbol))
998         {
999           tree decl = SYMBOL_REF_DECL (symbol);
1000           gcc_assert (DECL_P (decl));
1001
1002           if (decl != NULL_TREE
1003               && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
1004               /* Handle only actual external-only definitions, not
1005                  e.g. extern inline code or variables for which
1006                  storage has been allocated.  */
1007               && !TREE_STATIC (decl))
1008             {
1009               fputs ("\t.weak_reference ", asm_out_file);
1010               assemble_name (asm_out_file, sym_name);
1011               fputc ('\n', asm_out_file);
1012             }
1013         }
1014
1015       assemble_name (asm_out_file, ptr_name);
1016       fprintf (asm_out_file, ":\n");
1017
1018       fprintf (asm_out_file, "\t.indirect_symbol ");
1019       assemble_name (asm_out_file, sym_name);
1020       fprintf (asm_out_file, "\n");
1021
1022       /* Variables that are marked with MACHO_SYMBOL_STATIC need to
1023          have their symbol name instead of 0 in the second entry of
1024          the non-lazy symbol pointer data structure when they are
1025          defined.  This allows the runtime to rebind newer instances
1026          of the translation unit with the original instance of the
1027          symbol.  */
1028
1029       if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
1030           && machopic_symbol_defined_p (symbol))
1031         init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
1032
1033       assemble_integer (init, GET_MODE_SIZE (Pmode),
1034                         GET_MODE_ALIGNMENT (Pmode), 1);
1035     }
1036
1037   return 1;
1038 }
1039
1040 void
1041 machopic_finish (FILE *asm_out_file)
1042 {
1043   if (machopic_indirections)
1044     htab_traverse_noresize (machopic_indirections,
1045                             machopic_output_indirection,
1046                             asm_out_file);
1047 }
1048
1049 int
1050 machopic_operand_p (rtx op)
1051 {
1052   if (MACHOPIC_JUST_INDIRECT)
1053     return (GET_CODE (op) == SYMBOL_REF
1054             && machopic_symbol_defined_p (op));
1055   else
1056     return (GET_CODE (op) == CONST
1057             && GET_CODE (XEXP (op, 0)) == UNSPEC
1058             && XINT (XEXP (op, 0), 1) == UNSPEC_MACHOPIC_OFFSET);
1059 }
1060
1061 /* This function records whether a given name corresponds to a defined
1062    or undefined function or variable, for machopic_classify_ident to
1063    use later.  */
1064
1065 void
1066 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
1067 {
1068   rtx sym_ref;
1069
1070   /* Do the standard encoding things first.  */
1071   default_encode_section_info (decl, rtl, first);
1072
1073   if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
1074     return;
1075
1076   sym_ref = XEXP (rtl, 0);
1077   if (TREE_CODE (decl) == VAR_DECL)
1078     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
1079
1080   if (!DECL_EXTERNAL (decl)
1081       && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
1082       && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1083       && ((TREE_STATIC (decl)
1084            && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1085           || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
1086               && DECL_INITIAL (decl) != error_mark_node)))
1087     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
1088
1089   if (! TREE_PUBLIC (decl))
1090     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
1091 }
1092
1093 void
1094 darwin_mark_decl_preserved (const char *name)
1095 {
1096   fprintf (asm_out_file, "\t.no_dead_strip ");
1097   assemble_name (asm_out_file, name);
1098   fputc ('\n', asm_out_file);
1099 }
1100
1101 static section *
1102 darwin_text_section (int reloc, int weak)
1103 {
1104   if (reloc)
1105     return (weak
1106             ? darwin_sections[text_unlikely_coal_section]
1107             : unlikely_text_section ());
1108   else
1109     return (weak
1110             ? darwin_sections[text_coal_section]
1111             : text_section);
1112 }
1113
1114 static section *
1115 darwin_rodata_section (int weak)
1116 {
1117   return (weak
1118           ? darwin_sections[const_coal_section]
1119           : darwin_sections[const_section]);
1120 }
1121
1122 static section *
1123 darwin_mergeable_string_section (tree exp,
1124                                  unsigned HOST_WIDE_INT align)
1125 {
1126   if (flag_merge_constants
1127       && TREE_CODE (exp) == STRING_CST
1128       && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
1129       && align <= 256
1130       && (int_size_in_bytes (TREE_TYPE (exp))
1131           == TREE_STRING_LENGTH (exp))
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_import",
1195                                      DECL_ATTRIBUTES (decl)));
1196   section *base_section;
1197
1198   switch (categorize_decl_for_section (decl, reloc))
1199     {
1200     case SECCAT_TEXT:
1201       base_section = darwin_text_section (reloc, weak);
1202       break;
1203
1204     case SECCAT_RODATA:
1205     case SECCAT_SRODATA:
1206       base_section = darwin_rodata_section (weak);
1207       break;
1208
1209     case SECCAT_RODATA_MERGE_STR:
1210       base_section = darwin_mergeable_string_section (decl, align);
1211       break;
1212
1213     case SECCAT_RODATA_MERGE_STR_INIT:
1214       base_section = darwin_mergeable_string_section (DECL_INITIAL (decl), align);
1215       break;
1216
1217     case SECCAT_RODATA_MERGE_CONST:
1218       base_section =  darwin_mergeable_constant_section (decl, align);
1219       break;
1220
1221     case SECCAT_DATA:
1222     case SECCAT_DATA_REL:
1223     case SECCAT_DATA_REL_LOCAL:
1224     case SECCAT_DATA_REL_RO:
1225     case SECCAT_DATA_REL_RO_LOCAL:
1226     case SECCAT_SDATA:
1227     case SECCAT_TDATA:
1228     case SECCAT_BSS:
1229     case SECCAT_SBSS:
1230     case SECCAT_TBSS:
1231       if (TREE_READONLY (decl) || TREE_CONSTANT (decl))
1232         base_section = weak ? darwin_sections[const_data_coal_section]
1233                             : darwin_sections[const_data_section];
1234       else
1235         base_section = weak ? darwin_sections[data_coal_section] : data_section;
1236       break;
1237
1238     default:
1239       gcc_unreachable ();
1240     }
1241
1242   /* Darwin weird special cases.  */
1243   if (TREE_CODE (decl) == CONSTRUCTOR
1244       && TREE_TYPE (decl)
1245       && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
1246       && TYPE_NAME (TREE_TYPE (decl)))
1247     {
1248       tree name = TYPE_NAME (TREE_TYPE (decl));
1249       if (TREE_CODE (name) == TYPE_DECL)
1250         name = DECL_NAME (name);
1251
1252       if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1253         {
1254           if (flag_next_runtime)
1255             return darwin_sections[objc_constant_string_object_section];
1256           else
1257             return darwin_sections[objc_string_object_section];
1258         }
1259       else
1260         return base_section;
1261     }
1262   else if (TREE_CODE (decl) == VAR_DECL
1263            && DECL_NAME (decl)
1264            && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE
1265            && IDENTIFIER_POINTER (DECL_NAME (decl))
1266            && !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "_OBJC_", 6))
1267     {
1268       const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
1269
1270       if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1271         return darwin_sections[objc_cls_meth_section];
1272       else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1273         return darwin_sections[objc_inst_meth_section];
1274       else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1275         return darwin_sections[objc_cat_cls_meth_section];
1276       else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1277         return darwin_sections[objc_cat_inst_meth_section];
1278       else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1279         return darwin_sections[objc_class_vars_section];
1280       else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1281         return darwin_sections[objc_instance_vars_section];
1282       else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1283         return darwin_sections[objc_cat_cls_meth_section];
1284       else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1285         return darwin_sections[objc_class_names_section];
1286       else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1287         return darwin_sections[objc_meth_var_names_section];
1288       else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1289         return darwin_sections[objc_meth_var_types_section];
1290       else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1291         return darwin_sections[objc_cls_refs_section];
1292       else if (!strncmp (name, "_OBJC_CLASS_", 12))
1293         return darwin_sections[objc_class_section];
1294       else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1295         return darwin_sections[objc_meta_class_section];
1296       else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1297         return darwin_sections[objc_category_section];
1298       else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1299         return darwin_sections[objc_selector_refs_section];
1300       else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1301         return darwin_sections[objc_selector_fixup_section];
1302       else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1303         return darwin_sections[objc_symbols_section];
1304       else if (!strncmp (name, "_OBJC_MODULES", 13))
1305         return darwin_sections[objc_module_info_section];
1306       else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1307         return darwin_sections[objc_image_info_section];
1308       else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1309         return darwin_sections[objc_cat_inst_meth_section];
1310       else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1311         return darwin_sections[objc_cat_cls_meth_section];
1312       else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1313         return darwin_sections[objc_cat_cls_meth_section];
1314       else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1315         return darwin_sections[objc_protocol_section];
1316       else
1317         return base_section;
1318     }
1319
1320   return base_section;
1321 }
1322
1323 /* This can be called with address expressions as "rtx".
1324    They must go in "const".  */
1325
1326 section *
1327 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1328                              unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1329 {
1330   if (GET_MODE_SIZE (mode) == 8
1331       && (GET_CODE (x) == CONST_INT
1332           || GET_CODE (x) == CONST_DOUBLE))
1333     return darwin_sections[literal8_section];
1334   else if (GET_MODE_SIZE (mode) == 4
1335            && (GET_CODE (x) == CONST_INT
1336                || GET_CODE (x) == CONST_DOUBLE))
1337     return darwin_sections[literal4_section];
1338   else if (HAVE_GAS_LITERAL16
1339            && TARGET_64BIT
1340            && GET_MODE_SIZE (mode) == 16
1341            && (GET_CODE (x) == CONST_INT
1342                || GET_CODE (x) == CONST_DOUBLE
1343                || GET_CODE (x) == CONST_VECTOR))
1344     return darwin_sections[literal16_section];
1345   else if (MACHOPIC_INDIRECT
1346            && (GET_CODE (x) == SYMBOL_REF
1347                || GET_CODE (x) == CONST
1348                || GET_CODE (x) == LABEL_REF))
1349     return darwin_sections[const_data_section];
1350   else
1351     return darwin_sections[const_section];
1352 }
1353
1354 void
1355 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1356 {
1357   if (MACHOPIC_INDIRECT)
1358     switch_to_section (darwin_sections[mod_init_section]);
1359   else
1360     switch_to_section (darwin_sections[constructor_section]);
1361   assemble_align (POINTER_SIZE);
1362   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1363
1364   if (! MACHOPIC_INDIRECT)
1365     fprintf (asm_out_file, ".reference .constructors_used\n");
1366 }
1367
1368 void
1369 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1370 {
1371   if (MACHOPIC_INDIRECT)
1372     switch_to_section (darwin_sections[mod_term_section]);
1373   else
1374     switch_to_section (darwin_sections[destructor_section]);
1375   assemble_align (POINTER_SIZE);
1376   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1377
1378   if (! MACHOPIC_INDIRECT)
1379     fprintf (asm_out_file, ".reference .destructors_used\n");
1380 }
1381
1382 void
1383 darwin_globalize_label (FILE *stream, const char *name)
1384 {
1385   if (!!strncmp (name, "_OBJC_", 6))
1386     default_globalize_label (stream, name);
1387 }
1388
1389 /* This routine returns non-zero if 'name' starts with the special objective-c 
1390    anonymous file-scope static name.  It accommodates c++'s mangling of such 
1391    symbols (in this case the symbols will have form _ZL{d}*_OBJC_* d=digit).  */
1392    
1393 int 
1394 darwin_label_is_anonymous_local_objc_name (const char *name)
1395 {
1396   const unsigned char *p = (const unsigned char *) name;
1397   if (*p != '_')
1398     return 0;
1399   if (p[1] == 'Z' && p[2] == 'L')
1400   {
1401     p += 3;
1402     while (*p >= '0' && *p <= '9')
1403       p++;
1404   }
1405   return (!strncmp ((const char *)p, "_OBJC_", 6));
1406 }
1407
1408 /* LTO support for Mach-O.  */
1409
1410 /* Section names for LTO sections.  */
1411 static unsigned int lto_section_names_offset = 0;
1412
1413 /* This is the obstack which we use to allocate the many strings.  */
1414 static struct obstack lto_section_names_obstack;
1415
1416 /* Segment name for LTO sections.  */
1417 #define LTO_SEGMENT_NAME "__GNU_LTO"
1418
1419 /* Section name for LTO section names section.  */
1420 #define LTO_NAMES_SECTION "__section_names"
1421
1422 /* File to temporarily store LTO data.  This is appended to asm_out_file
1423    in darwin_end_file.  */
1424 static FILE *lto_asm_out_file, *saved_asm_out_file;
1425 static char *lto_asm_out_name;
1426
1427 /* Prepare asm_out_file for LTO output.  For darwin, this means hiding
1428    asm_out_file and switching to an alternative output file.  */
1429 void
1430 darwin_asm_lto_start (void)
1431 {
1432   gcc_assert (! saved_asm_out_file);
1433   saved_asm_out_file = asm_out_file;
1434   if (! lto_asm_out_name)
1435     lto_asm_out_name = make_temp_file (".lto.s");
1436   lto_asm_out_file = fopen (lto_asm_out_name, "a");
1437   if (lto_asm_out_file == NULL)
1438     fatal_error ("failed to open temporary file %s for LTO output",
1439                  lto_asm_out_name);
1440   asm_out_file = lto_asm_out_file;
1441 }
1442
1443 /* Restore asm_out_file.  */
1444 void
1445 darwin_asm_lto_end (void)
1446 {
1447   gcc_assert (saved_asm_out_file);
1448   fclose (lto_asm_out_file);
1449   asm_out_file = saved_asm_out_file;
1450   saved_asm_out_file = NULL;
1451 }
1452
1453 void
1454 darwin_asm_named_section (const char *name,
1455                           unsigned int flags,
1456                           tree decl ATTRIBUTE_UNUSED)
1457 {
1458   /* LTO sections go in a special segment __GNU_LTO.  We want to replace the
1459      section name with something we can use to represent arbitrary-length
1460      names (section names in Mach-O are at most 16 characters long).  */
1461   if (strncmp (name, LTO_SECTION_NAME_PREFIX,
1462                strlen (LTO_SECTION_NAME_PREFIX)) == 0)
1463     {
1464       /* We expect certain flags to be set...  */
1465       gcc_assert ((flags & (SECTION_DEBUG | SECTION_NAMED))
1466                   == (SECTION_DEBUG | SECTION_NAMED));
1467
1468       /* Add the section name to the things to output when we end the
1469          current assembler output file.
1470          This is all not very efficient, but that doesn't matter -- this
1471          shouldn't be a hot path in the compiler...  */
1472       obstack_1grow (&lto_section_names_obstack, '\t');
1473       obstack_grow (&lto_section_names_obstack, ".ascii ", 7);
1474       obstack_1grow (&lto_section_names_obstack, '"');
1475       obstack_grow (&lto_section_names_obstack, name, strlen (name));
1476       obstack_grow (&lto_section_names_obstack, "\\0\"\n", 4);
1477
1478       /* Output the dummy section name.  */
1479       fprintf (asm_out_file, "\t# %s\n", name);
1480       fprintf (asm_out_file, "\t.section %s,__%08X,regular,debug\n",
1481                LTO_SEGMENT_NAME, lto_section_names_offset);
1482
1483       /* Update the offset for the next section name.  Make sure we stay
1484          within reasonable length.  */  
1485       lto_section_names_offset += strlen (name) + 1;
1486       gcc_assert (lto_section_names_offset > 0
1487                   && lto_section_names_offset < ((unsigned) 1 << 31));
1488     }
1489   else
1490     fprintf (asm_out_file, "\t.section %s\n", name);
1491 }
1492
1493 void
1494 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1495 {
1496   /* Darwin does not use unique sections.  */
1497 }
1498
1499 /* Handle __attribute__ ((apple_kext_compatibility)).
1500    This only applies to darwin kexts for 2.95 compatibility -- it shrinks the
1501    vtable for classes with this attribute (and their descendants) by not
1502    outputting the new 3.0 nondeleting destructor.  This means that such
1503    objects CANNOT be allocated on the stack or as globals UNLESS they have
1504    a completely empty `operator delete'.
1505    Luckily, this fits in with the Darwin kext model.
1506
1507    This attribute also disables gcc3's potential overlaying of derived
1508    class data members on the padding at the end of the base class.  */
1509
1510 tree
1511 darwin_handle_kext_attribute (tree *node, tree name,
1512                               tree args ATTRIBUTE_UNUSED,
1513                               int flags ATTRIBUTE_UNUSED,
1514                               bool *no_add_attrs)
1515 {
1516   /* APPLE KEXT stuff -- only applies with pure static C++ code.  */
1517   if (! TARGET_KEXTABI)
1518     {
1519       warning (0, "%qE 2.95 vtable-compatibility attribute applies "
1520                "only when compiling a kext", name);
1521
1522       *no_add_attrs = true;
1523     }
1524   else if (TREE_CODE (*node) != RECORD_TYPE)
1525     {
1526       warning (0, "%qE 2.95 vtable-compatibility attribute applies "
1527                "only to C++ classes", name);
1528
1529       *no_add_attrs = true;
1530     }
1531
1532   return NULL_TREE;
1533 }
1534
1535 /* Handle a "weak_import" attribute; arguments as in
1536    struct attribute_spec.handler.  */
1537
1538 tree
1539 darwin_handle_weak_import_attribute (tree *node, tree name,
1540                                      tree ARG_UNUSED (args),
1541                                      int ARG_UNUSED (flags),
1542                                      bool * no_add_attrs)
1543 {
1544   if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1545     {
1546       warning (OPT_Wattributes, "%qE attribute ignored",
1547                name);
1548       *no_add_attrs = true;
1549     }
1550   else
1551     declare_weak (*node);
1552
1553   return NULL_TREE;
1554 }
1555
1556 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1557    The third parameter is nonzero if this is for exception handling.
1558    The fourth parameter is nonzero if this is just a placeholder for an
1559    FDE that we are omitting. */
1560
1561 void
1562 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1563 {
1564   char *lab;
1565
1566   if (! for_eh)
1567     return;
1568
1569   lab = concat (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), ".eh", NULL);
1570
1571   if (TREE_PUBLIC (decl))
1572     {
1573       targetm.asm_out.globalize_label (file, lab);
1574       if (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN)
1575         {
1576           fputs ("\t.private_extern ", file);
1577           assemble_name (file, lab);
1578           fputc ('\n', file);
1579         }
1580     }
1581
1582   if (DECL_WEAK (decl))
1583     {
1584       fputs ("\t.weak_definition ", file);
1585       assemble_name (file, lab);
1586       fputc ('\n', file);
1587     }
1588
1589   assemble_name (file, lab);
1590   if (empty)
1591     {
1592       fputs (" = 0\n", file);
1593
1594       /* Mark the absolute .eh and .eh1 style labels as needed to
1595          ensure that we don't dead code strip them and keep such
1596          labels from another instantiation point until we can fix this
1597          properly with group comdat support.  */
1598       darwin_mark_decl_preserved (lab);
1599     }
1600   else
1601     fputs (":\n", file);
1602
1603   free (lab);
1604 }
1605
1606 static GTY(()) unsigned long except_table_label_num;
1607
1608 void
1609 darwin_emit_except_table_label (FILE *file)
1610 {
1611   char section_start_label[30];
1612
1613   ASM_GENERATE_INTERNAL_LABEL (section_start_label, "GCC_except_table",
1614                                except_table_label_num++);
1615   ASM_OUTPUT_LABEL (file, section_start_label);
1616 }
1617 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */
1618
1619 void
1620 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1621 {
1622   const char *nlp_name;
1623
1624   gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1625
1626   nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1627   fputs ("\t.long\t", file);
1628   ASM_OUTPUT_LABELREF (file, nlp_name);
1629   fputs ("-.", file);
1630 }
1631
1632 /* The implementation of ASM_DECLARE_CONSTANT_NAME.  */
1633
1634 void
1635 darwin_asm_declare_constant_name (FILE *file, const char *name,
1636                                   const_tree exp ATTRIBUTE_UNUSED,
1637                                   HOST_WIDE_INT size)
1638 {
1639   assemble_label (file, name);
1640
1641   /* Darwin doesn't support zero-size objects, so give them a byte.  */
1642   if ((size) == 0)
1643     assemble_zeros (1);
1644 }
1645
1646 /* Emit an assembler directive to set visibility for a symbol.  The
1647    only supported visibilities are VISIBILITY_DEFAULT and
1648    VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1649    extern".  There is no MACH-O equivalent of ELF's
1650    VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1651
1652 void
1653 darwin_assemble_visibility (tree decl, int vis)
1654 {
1655   if (vis == VISIBILITY_DEFAULT)
1656     ;
1657   else if (vis == VISIBILITY_HIDDEN)
1658     {
1659       fputs ("\t.private_extern ", asm_out_file);
1660       assemble_name (asm_out_file,
1661                      (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1662       fputs ("\n", asm_out_file);
1663     }
1664   else
1665     warning (OPT_Wattributes, "internal and protected visibility attributes "
1666              "not supported in this configuration; ignored");
1667 }
1668
1669 /* Output a difference of two labels that will be an assembly time
1670    constant if the two labels are local.  (.long lab1-lab2 will be
1671    very different if lab1 is at the boundary between two sections; it
1672    will be relocated according to the second section, not the first,
1673    so one ends up with a difference between labels in different
1674    sections, which is bad in the dwarf2 eh context for instance.)  */
1675
1676 static int darwin_dwarf_label_counter;
1677
1678 void
1679 darwin_asm_output_dwarf_delta (FILE *file, int size,
1680                                const char *lab1, const char *lab2)
1681 {
1682   int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1683                      && lab2[0] == '*' && lab2[1] == 'L');
1684   const char *directive = (size == 8 ? ".quad" : ".long");
1685
1686   if (islocaldiff)
1687     fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1688   else
1689     fprintf (file, "\t%s\t", directive);
1690   assemble_name_raw (file, lab1);
1691   fprintf (file, "-");
1692   assemble_name_raw (file, lab2);
1693   if (islocaldiff)
1694     fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1695 }
1696
1697 /* Output labels for the start of the DWARF sections if necessary.
1698    Initialize the stuff we need for LTO long section names support.  */
1699 void
1700 darwin_file_start (void)
1701 {
1702   if (write_symbols == DWARF2_DEBUG)
1703     {
1704       static const char * const debugnames[] =
1705         {
1706           DEBUG_FRAME_SECTION,
1707           DEBUG_INFO_SECTION,
1708           DEBUG_ABBREV_SECTION,
1709           DEBUG_ARANGES_SECTION,
1710           DEBUG_MACINFO_SECTION,
1711           DEBUG_LINE_SECTION,
1712           DEBUG_LOC_SECTION,
1713           DEBUG_PUBNAMES_SECTION,
1714           DEBUG_PUBTYPES_SECTION,
1715           DEBUG_STR_SECTION,
1716           DEBUG_RANGES_SECTION
1717         };
1718       size_t i;
1719
1720       for (i = 0; i < ARRAY_SIZE (debugnames); i++)
1721         {
1722           int namelen;
1723
1724           switch_to_section (get_section (debugnames[i], SECTION_DEBUG, NULL));
1725
1726           gcc_assert (strncmp (debugnames[i], "__DWARF,", 8) == 0);
1727           gcc_assert (strchr (debugnames[i] + 8, ','));
1728
1729           namelen = strchr (debugnames[i] + 8, ',') - (debugnames[i] + 8);
1730           fprintf (asm_out_file, "Lsection%.*s:\n", namelen, debugnames[i] + 8);
1731         }
1732     }
1733
1734   /* We fill this obstack with the complete section text for the lto section
1735      names to write in darwin_file_end.  */
1736   obstack_init (&lto_section_names_obstack);
1737   lto_section_names_offset = 0;
1738 }
1739
1740 /* Output an offset in a DWARF section on Darwin.  On Darwin, DWARF section
1741    offsets are not represented using relocs in .o files; either the
1742    section never leaves the .o file, or the linker or other tool is
1743    responsible for parsing the DWARF and updating the offsets.  */
1744
1745 void
1746 darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
1747                                 section *base)
1748 {
1749   char sname[64];
1750   int namelen;
1751
1752   gcc_assert (base->common.flags & SECTION_NAMED);
1753   gcc_assert (strncmp (base->named.name, "__DWARF,", 8) == 0);
1754   gcc_assert (strchr (base->named.name + 8, ','));
1755
1756   namelen = strchr (base->named.name + 8, ',') - (base->named.name + 8);
1757   sprintf (sname, "*Lsection%.*s", namelen, base->named.name + 8);
1758   darwin_asm_output_dwarf_delta (file, size, lab, sname);
1759 }
1760
1761 void
1762 darwin_file_end (void)
1763 {
1764   const char *lto_section_names;
1765
1766   machopic_finish (asm_out_file);
1767   if (strcmp (lang_hooks.name, "GNU C++") == 0)
1768     {
1769       switch_to_section (darwin_sections[constructor_section]);
1770       switch_to_section (darwin_sections[destructor_section]);
1771       ASM_OUTPUT_ALIGN (asm_out_file, 1);
1772     }
1773
1774   /* If there was LTO assembler output, append it to asm_out_file.  */
1775   if (lto_asm_out_name)
1776     {
1777       int n;
1778       char *buf, *lto_asm_txt;
1779
1780       /* Shouldn't be here if we failed to switch back.  */
1781       gcc_assert (! saved_asm_out_file);
1782
1783       lto_asm_out_file = fopen (lto_asm_out_name, "r");
1784       if (lto_asm_out_file == NULL)
1785         fatal_error ("failed to open temporary file %s with LTO output",
1786                      lto_asm_out_name);
1787       fseek (lto_asm_out_file, 0, SEEK_END);
1788       n = ftell (lto_asm_out_file);
1789       if (n > 0)
1790         {
1791           fseek (lto_asm_out_file, 0, SEEK_SET);
1792           lto_asm_txt = buf = (char *) xmalloc (n + 1);
1793           while (fgets (lto_asm_txt, n, lto_asm_out_file))
1794             fputs (lto_asm_txt, asm_out_file);
1795         }
1796
1797       /* Remove the temporary file.  */
1798       fclose (lto_asm_out_file);
1799       unlink_if_ordinary (lto_asm_out_name);
1800       free (lto_asm_out_name);
1801     }
1802
1803   /* Finish the LTO section names obstack.  Don't output anything if
1804      there are no recorded section names.  */
1805   obstack_1grow (&lto_section_names_obstack, '\0');
1806   lto_section_names = XOBFINISH (&lto_section_names_obstack, const char *);
1807   if (strlen (lto_section_names) > 0)
1808     {
1809       fprintf (asm_out_file,
1810                "\t.section %s,%s,regular,debug\n",
1811                LTO_SEGMENT_NAME, LTO_NAMES_SECTION);
1812       fprintf (asm_out_file,
1813                "\t# Section names in %s are offsets into this table\n",
1814                LTO_SEGMENT_NAME);
1815       fprintf (asm_out_file, "%s\n", lto_section_names);
1816     }
1817   obstack_free (&lto_section_names_obstack, NULL);
1818
1819   fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1820 }
1821
1822 /* TODO: Add a language hook for identifying if a decl is a vtable.  */
1823 #define DARWIN_VTABLE_P(DECL) 0
1824
1825 /* Cross-module name binding.  Darwin does not support overriding
1826    functions at dynamic-link time, except for vtables in kexts.  */
1827
1828 bool
1829 darwin_binds_local_p (const_tree decl)
1830 {
1831   return default_binds_local_p_1 (decl,
1832                                   TARGET_KEXTABI && DARWIN_VTABLE_P (decl));
1833 }
1834
1835 #if 0
1836 /* See TARGET_ASM_OUTPUT_ANCHOR for why we can't do this yet.  */
1837 /* The Darwin's implementation of TARGET_ASM_OUTPUT_ANCHOR.  Define the
1838    anchor relative to ".", the current section position.  We cannot use
1839    the default one because ASM_OUTPUT_DEF is wrong for Darwin.  */
1840
1841 void
1842 darwin_asm_output_anchor (rtx symbol)
1843 {
1844   fprintf (asm_out_file, "\t.set\t");
1845   assemble_name (asm_out_file, XSTR (symbol, 0));
1846   fprintf (asm_out_file, ", . + " HOST_WIDE_INT_PRINT_DEC "\n",
1847            SYMBOL_REF_BLOCK_OFFSET (symbol));
1848 }
1849 #endif
1850
1851 /* Set the darwin specific attributes on TYPE.  */
1852 void
1853 darwin_set_default_type_attributes (tree type)
1854 {
1855   if (darwin_ms_struct
1856       && TREE_CODE (type) == RECORD_TYPE)
1857     TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("ms_struct"),
1858                                         NULL_TREE,
1859                                         TYPE_ATTRIBUTES (type));
1860 }
1861
1862 /* True, iff we're generating code for loadable kernel extensions.  */
1863
1864 bool
1865 darwin_kextabi_p (void) {
1866   return flag_apple_kext;
1867 }
1868
1869 void
1870 darwin_override_options (void)
1871 {
1872   /* Don't emit DWARF3/4 unless specifically selected.  This is a 
1873      workaround for tool bugs.  */
1874   if (dwarf_strict < 0) 
1875     dwarf_strict = 1;
1876
1877   /* Disable -freorder-blocks-and-partition for darwin_emit_unwind_label.  */
1878   if (flag_reorder_blocks_and_partition 
1879       && (targetm.asm_out.emit_unwind_label == darwin_emit_unwind_label))
1880     {
1881       inform (input_location,
1882               "-freorder-blocks-and-partition does not work with exceptions "
1883               "on this architecture");
1884       flag_reorder_blocks_and_partition = 0;
1885       flag_reorder_blocks = 1;
1886     }
1887
1888   if (flag_mkernel || flag_apple_kext)
1889     {
1890       /* -mkernel implies -fapple-kext for C++ */
1891       if (strcmp (lang_hooks.name, "GNU C++") == 0)
1892         flag_apple_kext = 1;
1893
1894       flag_no_common = 1;
1895
1896       /* No EH in kexts.  */
1897       flag_exceptions = 0;
1898       /* No -fnon-call-exceptions data in kexts.  */
1899       flag_non_call_exceptions = 0;
1900       /* We still need to emit branch islands for kernel context.  */
1901       darwin_emit_branch_islands = true;
1902     }
1903   if (flag_var_tracking
1904       && strverscmp (darwin_macosx_version_min, "10.5") >= 0
1905       && debug_info_level >= DINFO_LEVEL_NORMAL
1906       && debug_hooks->var_location != do_nothing_debug_hooks.var_location)
1907     flag_var_tracking_uninit = 1;
1908
1909   /* It is assumed that branch island stubs are needed for earlier systems.  */
1910   if (darwin_macosx_version_min
1911       && strverscmp (darwin_macosx_version_min, "10.5") < 0)
1912     darwin_emit_branch_islands = true;
1913 }
1914
1915 /* Add $LDBL128 suffix to long double builtins.  */
1916
1917 static void
1918 darwin_patch_builtin (int fncode)
1919 {
1920   tree fn = built_in_decls[fncode];
1921   tree sym;
1922   char *newname;
1923
1924   if (!fn)
1925     return;
1926
1927   sym = DECL_ASSEMBLER_NAME (fn);
1928   newname = ACONCAT (("_", IDENTIFIER_POINTER (sym), "$LDBL128", NULL));
1929
1930   set_user_assembler_name (fn, newname);
1931
1932   fn = implicit_built_in_decls[fncode];
1933   if (fn)
1934     set_user_assembler_name (fn, newname);
1935 }
1936
1937 void
1938 darwin_patch_builtins (void)
1939 {
1940   if (LONG_DOUBLE_TYPE_SIZE != 128)
1941     return;
1942
1943 #define PATCH_BUILTIN(fncode) darwin_patch_builtin (fncode);
1944 #define PATCH_BUILTIN_NO64(fncode)              \
1945   if (!TARGET_64BIT)                            \
1946     darwin_patch_builtin (fncode);
1947 #define PATCH_BUILTIN_VARIADIC(fncode)                            \
1948   if (!TARGET_64BIT                                               \
1949       && (strverscmp (darwin_macosx_version_min, "10.3.9") >= 0)) \
1950     darwin_patch_builtin (fncode);
1951 #include "darwin-ppc-ldouble-patch.def"
1952 #undef PATCH_BUILTIN
1953 #undef PATCH_BUILTIN_NO64
1954 #undef PATCH_BUILTIN_VARIADIC
1955 }
1956
1957
1958 #include "gt-darwin.h"