OSDN Git Service

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