OSDN Git Service

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