OSDN Git Service

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