OSDN Git Service

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