OSDN Git Service

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