Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / gcc4 / gcc / config / darwin.c
blob98c7d30cd72c3061aa53e0191290d15c9205bfbf
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.
7 This file is part of GCC.
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.
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.
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. */
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"
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 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.
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.
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. */
80 int
81 name_needs_quotes (const char *name)
83 int c;
84 while ((c = *name++) != '\0')
85 if (! ISIDNUM (c) && c != '.' && c != '$')
86 return 1;
87 return 0;
90 /* Return true if SYM_REF can be used without an indirection. */
91 static int
92 machopic_symbol_defined_p (rtx sym_ref)
94 if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
95 return true;
97 /* If a symbol references local and is not an extern to this
98 file, then the symbol might be able to declared as defined. */
99 if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
101 /* If the symbol references a variable and the variable is a
102 common symbol, then this symbol is not defined. */
103 if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_VARIABLE)
105 tree decl = SYMBOL_REF_DECL (sym_ref);
106 if (!decl)
107 return true;
108 if (DECL_COMMON (decl))
109 return false;
111 return true;
113 return false;
116 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
117 reference, which will not be changed. */
119 enum machopic_addr_class
120 machopic_classify_symbol (rtx sym_ref)
122 int flags;
123 bool function_p;
125 flags = SYMBOL_REF_FLAGS (sym_ref);
126 function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
127 if (machopic_symbol_defined_p (sym_ref))
128 return (function_p
129 ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
130 else
131 return (function_p
132 ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
135 #ifndef TARGET_FIX_AND_CONTINUE
136 #define TARGET_FIX_AND_CONTINUE 0
137 #endif
139 /* Indicate when fix-and-continue style code generation is being used
140 and when a reference to data should be indirected so that it can be
141 rebound in a new translation unit to reference the original instance
142 of that data. Symbol names that are for code generation local to
143 the translation unit are bound to the new translation unit;
144 currently this means symbols that begin with L or _OBJC_;
145 otherwise, we indicate that an indirect reference should be made to
146 permit the runtime to rebind new instances of the translation unit
147 to the original instance of the data. */
149 static int
150 indirect_data (rtx sym_ref)
152 int lprefix;
153 const char *name;
155 /* If we aren't generating fix-and-continue code, don't do anything special. */
156 if (TARGET_FIX_AND_CONTINUE == 0)
157 return 0;
159 /* Otherwise, all symbol except symbols that begin with L or _OBJC_
160 are indirected. Symbols that begin with L and _OBJC_ are always
161 bound to the current translation unit as they are used for
162 generated local data of the translation unit. */
164 name = XSTR (sym_ref, 0);
166 lprefix = (((name[0] == '*' || name[0] == '&')
167 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
168 || (strncmp (name, "_OBJC_", 6) == 0));
170 return ! lprefix;
174 static int
175 machopic_data_defined_p (rtx sym_ref)
177 if (indirect_data (sym_ref))
178 return 0;
180 switch (machopic_classify_symbol (sym_ref))
182 case MACHOPIC_DEFINED_DATA:
183 case MACHOPIC_DEFINED_FUNCTION:
184 return 1;
185 default:
186 return 0;
190 void
191 machopic_define_symbol (rtx mem)
193 rtx sym_ref;
195 gcc_assert (GET_CODE (mem) == MEM);
196 sym_ref = XEXP (mem, 0);
197 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
200 static GTY(()) char * function_base;
202 const char *
203 machopic_function_base_name (void)
205 /* if dynamic-no-pic is on, we should not get here */
206 gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
208 if (function_base == NULL)
209 function_base =
210 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
212 current_function_uses_pic_offset_table = 1;
214 return function_base;
217 /* Return a SYMBOL_REF for the PIC function base. */
220 machopic_function_base_sym (void)
222 rtx sym_ref;
224 sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
225 SYMBOL_REF_FLAGS (sym_ref)
226 |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
227 return sym_ref;
230 /* Return either ORIG or (const:P (minus:P ORIG PIC_BASE)), depending
231 on whether pic_base is NULL or not. */
232 static inline rtx
233 gen_pic_offset (rtx orig, rtx pic_base)
235 if (!pic_base)
236 return orig;
237 else
238 return gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, pic_base));
241 static GTY(()) const char * function_base_func_name;
242 static GTY(()) int current_pic_label_num;
244 void
245 machopic_output_function_base_name (FILE *file)
247 const char *current_name;
249 /* If dynamic-no-pic is on, we should not get here. */
250 gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
251 current_name =
252 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
253 if (function_base_func_name != current_name)
255 ++current_pic_label_num;
256 function_base_func_name = current_name;
258 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
261 /* The suffix attached to non-lazy pointer symbols. */
262 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
263 /* The suffix attached to stub symbols. */
264 #define STUB_SUFFIX "$stub"
266 typedef struct machopic_indirection GTY (())
268 /* The SYMBOL_REF for the entity referenced. */
269 rtx symbol;
270 /* The name of the stub or non-lazy pointer. */
271 const char * ptr_name;
272 /* True iff this entry is for a stub (as opposed to a non-lazy
273 pointer). */
274 bool stub_p;
275 /* True iff this stub or pointer pointer has been referenced. */
276 bool used;
277 } machopic_indirection;
279 /* A table mapping stub names and non-lazy pointer names to
280 SYMBOL_REFs for the stubbed-to and pointed-to entities. */
282 static GTY ((param_is (struct machopic_indirection))) htab_t
283 machopic_indirections;
285 /* Return a hash value for a SLOT in the indirections hash table. */
287 static hashval_t
288 machopic_indirection_hash (const void *slot)
290 const machopic_indirection *p = (const machopic_indirection *) slot;
291 return htab_hash_string (p->ptr_name);
294 /* Returns true if the KEY is the same as that associated with
295 SLOT. */
297 static int
298 machopic_indirection_eq (const void *slot, const void *key)
300 return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0;
303 /* Return the name of the non-lazy pointer (if STUB_P is false) or
304 stub (if STUB_B is true) corresponding to the given name. */
306 const char *
307 machopic_indirection_name (rtx sym_ref, bool stub_p)
309 char *buffer;
310 const char *name = XSTR (sym_ref, 0);
311 size_t namelen = strlen (name);
312 machopic_indirection *p;
313 void ** slot;
314 bool saw_star = false;
315 bool needs_quotes;
316 const char *suffix;
317 const char *prefix = user_label_prefix;
318 const char *quote = "";
319 tree id;
321 id = maybe_get_identifier (name);
322 if (id)
324 tree id_orig = id;
326 while (IDENTIFIER_TRANSPARENT_ALIAS (id))
327 id = TREE_CHAIN (id);
328 if (id != id_orig)
330 name = IDENTIFIER_POINTER (id);
331 namelen = strlen (name);
335 if (name[0] == '*')
337 saw_star = true;
338 prefix = "";
339 ++name;
340 --namelen;
343 needs_quotes = name_needs_quotes (name);
344 if (needs_quotes)
346 quote = "\"";
349 if (stub_p)
350 suffix = STUB_SUFFIX;
351 else
352 suffix = NON_LAZY_POINTER_SUFFIX;
354 buffer = alloca (strlen ("&L")
355 + strlen (prefix)
356 + namelen
357 + strlen (suffix)
358 + 2 * strlen (quote)
359 + 1 /* '\0' */);
361 /* Construct the name of the non-lazy pointer or stub. */
362 sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
364 if (!machopic_indirections)
365 machopic_indirections = htab_create_ggc (37,
366 machopic_indirection_hash,
367 machopic_indirection_eq,
368 /*htab_del=*/NULL);
370 slot = htab_find_slot_with_hash (machopic_indirections, buffer,
371 htab_hash_string (buffer), INSERT);
372 if (*slot)
374 p = (machopic_indirection *) *slot;
376 else
378 p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
379 p->symbol = sym_ref;
380 p->ptr_name = xstrdup (buffer);
381 p->stub_p = stub_p;
382 p->used = false;
383 *slot = p;
386 return p->ptr_name;
389 /* Return the name of the stub for the mcount function. */
391 const char*
392 machopic_mcount_stub_name (void)
394 rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
395 return machopic_indirection_name (symbol, /*stub_p=*/true);
398 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
399 or non-lazy pointer as used -- and mark the object to which the
400 pointer/stub refers as used as well, since the pointer/stub will
401 emit a reference to it. */
403 void
404 machopic_validate_stub_or_non_lazy_ptr (const char *name)
406 machopic_indirection *p;
408 p = ((machopic_indirection *)
409 (htab_find_with_hash (machopic_indirections, name,
410 htab_hash_string (name))));
411 if (p && ! p->used)
413 const char *real_name;
414 tree id;
416 p->used = true;
418 /* Do what output_addr_const will do when we actually call it. */
419 if (SYMBOL_REF_DECL (p->symbol))
420 mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
422 real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
424 id = maybe_get_identifier (real_name);
425 if (id)
426 mark_referenced (id);
430 /* Transform ORIG, which may be any data source, to the corresponding
431 source using indirections. */
434 machopic_indirect_data_reference (rtx orig, rtx reg)
436 rtx ptr_ref = orig;
438 if (! MACHOPIC_INDIRECT)
439 return orig;
441 if (GET_CODE (orig) == SYMBOL_REF)
443 int defined = machopic_data_defined_p (orig);
445 if (defined && MACHO_DYNAMIC_NO_PIC_P)
447 #if defined (TARGET_TOC)
448 /* Create a new register for CSE opportunities. */
449 rtx hi_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
450 emit_insn (gen_macho_high (hi_reg, orig));
451 emit_insn (gen_macho_low (reg, hi_reg, orig));
452 #else
453 /* some other cpu -- writeme! */
454 gcc_unreachable ();
455 #endif
456 return reg;
458 else if (defined)
460 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
461 rtx pic_base = machopic_function_base_sym ();
462 rtx offset = gen_pic_offset (orig, pic_base);
463 #endif
465 #if defined (TARGET_TOC) /* i.e., PowerPC */
466 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
468 gcc_assert (reg);
470 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
471 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
472 gen_rtx_HIGH (Pmode, offset))));
473 emit_insn (gen_rtx_SET (Pmode, reg,
474 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
476 orig = reg;
477 #else
478 #if defined (HAVE_lo_sum)
479 gcc_assert (reg);
481 emit_insn (gen_rtx_SET (VOIDmode, reg,
482 gen_rtx_HIGH (Pmode, offset)));
483 emit_insn (gen_rtx_SET (VOIDmode, reg,
484 gen_rtx_LO_SUM (Pmode, reg, offset)));
485 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
487 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
488 #endif
489 #endif
490 return orig;
493 ptr_ref = (gen_rtx_SYMBOL_REF
494 (Pmode,
495 machopic_indirection_name (orig, /*stub_p=*/false)));
497 SYMBOL_REF_DECL (ptr_ref) = SYMBOL_REF_DECL (orig);
499 ptr_ref = gen_const_mem (Pmode, ptr_ref);
500 machopic_define_symbol (ptr_ref);
502 return ptr_ref;
504 else if (GET_CODE (orig) == CONST)
506 rtx base, result;
508 /* legitimize both operands of the PLUS */
509 if (GET_CODE (XEXP (orig, 0)) == PLUS)
511 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
512 reg);
513 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
514 (base == reg ? 0 : reg));
516 else
517 return orig;
519 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
520 result = plus_constant (base, INTVAL (orig));
521 else
522 result = gen_rtx_PLUS (Pmode, base, orig);
524 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
526 if (reg)
528 emit_move_insn (reg, result);
529 result = reg;
531 else
533 result = force_reg (GET_MODE (result), result);
537 return result;
540 else if (GET_CODE (orig) == MEM)
541 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
542 /* When the target is i386, this code prevents crashes due to the
543 compiler's ignorance on how to move the PIC base register to
544 other registers. (The reload phase sometimes introduces such
545 insns.) */
546 else if (GET_CODE (orig) == PLUS
547 && GET_CODE (XEXP (orig, 0)) == REG
548 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
549 #ifdef I386
550 /* Prevent the same register from being erroneously used
551 as both the base and index registers. */
552 && GET_CODE (XEXP (orig, 1)) == CONST
553 #endif
554 && reg)
556 emit_move_insn (reg, XEXP (orig, 0));
557 XEXP (ptr_ref, 0) = reg;
559 return ptr_ref;
562 /* Transform TARGET (a MEM), which is a function call target, to the
563 corresponding symbol_stub if necessary. Return a new MEM. */
566 machopic_indirect_call_target (rtx target)
568 if (GET_CODE (target) != MEM)
569 return target;
571 if (MACHOPIC_INDIRECT
572 && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
573 && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
574 & MACHO_SYMBOL_FLAG_DEFINED))
576 rtx sym_ref = XEXP (target, 0);
577 const char *stub_name = machopic_indirection_name (sym_ref,
578 /*stub_p=*/true);
579 enum machine_mode mode = GET_MODE (sym_ref);
580 tree decl = SYMBOL_REF_DECL (sym_ref);
582 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
583 SYMBOL_REF_DECL (XEXP (target, 0)) = decl;
584 MEM_READONLY_P (target) = 1;
585 MEM_NOTRAP_P (target) = 1;
588 return target;
592 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
594 rtx pic_ref = orig;
596 if (! MACHOPIC_INDIRECT)
597 return orig;
599 /* First handle a simple SYMBOL_REF or LABEL_REF */
600 if (GET_CODE (orig) == LABEL_REF
601 || (GET_CODE (orig) == SYMBOL_REF
604 /* addr(foo) = &func+(foo-func) */
605 rtx pic_base;
607 orig = machopic_indirect_data_reference (orig, reg);
609 if (GET_CODE (orig) == PLUS
610 && GET_CODE (XEXP (orig, 0)) == REG)
612 if (reg == 0)
613 return force_reg (mode, orig);
615 emit_move_insn (reg, orig);
616 return reg;
619 /* if dynamic-no-pic we don't have a pic base */
620 if (MACHO_DYNAMIC_NO_PIC_P)
621 pic_base = NULL;
622 else
623 pic_base = machopic_function_base_sym ();
625 if (GET_CODE (orig) == MEM)
627 if (reg == 0)
629 gcc_assert (!reload_in_progress);
630 reg = gen_reg_rtx (Pmode);
633 #ifdef HAVE_lo_sum
634 if (MACHO_DYNAMIC_NO_PIC_P
635 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
636 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
638 #if defined (TARGET_TOC) /* ppc */
639 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
640 rtx asym = XEXP (orig, 0);
641 rtx mem;
643 emit_insn (gen_macho_high (temp_reg, asym));
644 mem = gen_const_mem (GET_MODE (orig),
645 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
646 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
647 #else
648 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
649 gcc_unreachable ();
650 #endif
651 pic_ref = reg;
653 else
654 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
655 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
657 rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
658 #if defined (TARGET_TOC) /* i.e., PowerPC */
659 /* Generating a new reg may expose opportunities for
660 common subexpression elimination. */
661 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
662 rtx mem;
663 rtx insn;
664 rtx sum;
666 sum = gen_rtx_HIGH (Pmode, offset);
667 if (! MACHO_DYNAMIC_NO_PIC_P)
668 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
670 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
672 mem = gen_const_mem (GET_MODE (orig),
673 gen_rtx_LO_SUM (Pmode,
674 hi_sum_reg, offset));
675 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
676 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
677 REG_NOTES (insn));
679 pic_ref = reg;
680 #else
681 emit_insn (gen_rtx_USE (VOIDmode,
682 gen_rtx_REG (Pmode,
683 PIC_OFFSET_TABLE_REGNUM)));
685 emit_insn (gen_rtx_SET (VOIDmode, reg,
686 gen_rtx_HIGH (Pmode,
687 gen_rtx_CONST (Pmode,
688 offset))));
689 emit_insn (gen_rtx_SET (VOIDmode, reg,
690 gen_rtx_LO_SUM (Pmode, reg,
691 gen_rtx_CONST (Pmode, offset))));
692 pic_ref = gen_rtx_PLUS (Pmode,
693 pic_offset_table_rtx, reg);
694 #endif
696 else
697 #endif /* HAVE_lo_sum */
699 rtx pic = pic_offset_table_rtx;
700 if (GET_CODE (pic) != REG)
702 emit_move_insn (reg, pic);
703 pic = reg;
705 #if 0
706 emit_insn (gen_rtx_USE (VOIDmode,
707 gen_rtx_REG (Pmode,
708 PIC_OFFSET_TABLE_REGNUM)));
709 #endif
711 pic_ref = gen_rtx_PLUS (Pmode, pic,
712 gen_pic_offset (XEXP (orig, 0),
713 pic_base));
716 #if !defined (TARGET_TOC)
717 emit_move_insn (reg, pic_ref);
718 pic_ref = gen_const_mem (GET_MODE (orig), reg);
719 #endif
721 else
724 #ifdef HAVE_lo_sum
725 if (GET_CODE (orig) == SYMBOL_REF
726 || GET_CODE (orig) == LABEL_REF)
728 rtx offset = gen_pic_offset (orig, pic_base);
729 #if defined (TARGET_TOC) /* i.e., PowerPC */
730 rtx hi_sum_reg;
732 if (reg == 0)
734 gcc_assert (!reload_in_progress);
735 reg = gen_reg_rtx (Pmode);
738 hi_sum_reg = reg;
740 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
741 (MACHO_DYNAMIC_NO_PIC_P)
742 ? gen_rtx_HIGH (Pmode, offset)
743 : gen_rtx_PLUS (Pmode,
744 pic_offset_table_rtx,
745 gen_rtx_HIGH (Pmode,
746 offset))));
747 emit_insn (gen_rtx_SET (VOIDmode, reg,
748 gen_rtx_LO_SUM (Pmode,
749 hi_sum_reg, offset)));
750 pic_ref = reg;
751 #else
752 emit_insn (gen_rtx_SET (VOIDmode, reg,
753 gen_rtx_HIGH (Pmode, offset)));
754 emit_insn (gen_rtx_SET (VOIDmode, reg,
755 gen_rtx_LO_SUM (Pmode, reg, offset)));
756 pic_ref = gen_rtx_PLUS (Pmode,
757 pic_offset_table_rtx, reg);
758 #endif
760 else
761 #endif /* HAVE_lo_sum */
763 if (REG_P (orig)
764 || GET_CODE (orig) == SUBREG)
766 return orig;
768 else
770 rtx pic = pic_offset_table_rtx;
771 if (GET_CODE (pic) != REG)
773 emit_move_insn (reg, pic);
774 pic = reg;
776 #if 0
777 emit_insn (gen_rtx_USE (VOIDmode,
778 pic_offset_table_rtx));
779 #endif
780 pic_ref = gen_rtx_PLUS (Pmode,
781 pic,
782 gen_pic_offset (orig, pic_base));
787 if (GET_CODE (pic_ref) != REG)
789 if (reg != 0)
791 emit_move_insn (reg, pic_ref);
792 return reg;
794 else
796 return force_reg (mode, pic_ref);
799 else
801 return pic_ref;
805 else if (GET_CODE (orig) == SYMBOL_REF)
806 return orig;
808 else if (GET_CODE (orig) == PLUS
809 && (GET_CODE (XEXP (orig, 0)) == MEM
810 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
811 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
812 && XEXP (orig, 0) != pic_offset_table_rtx
813 && GET_CODE (XEXP (orig, 1)) != REG)
816 rtx base;
817 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
819 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
820 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
821 Pmode, (base == reg ? 0 : reg));
822 if (GET_CODE (orig) == CONST_INT)
824 pic_ref = plus_constant (base, INTVAL (orig));
825 is_complex = 1;
827 else
828 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
830 if (reg && is_complex)
832 emit_move_insn (reg, pic_ref);
833 pic_ref = reg;
835 /* Likewise, should we set special REG_NOTEs here? */
838 else if (GET_CODE (orig) == CONST)
840 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
843 else if (GET_CODE (orig) == MEM
844 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
846 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
847 addr = replace_equiv_address (orig, addr);
848 emit_move_insn (reg, addr);
849 pic_ref = reg;
852 return pic_ref;
855 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
856 DATA is the FILE* for assembly output. Called from
857 htab_traverse. */
859 static int
860 machopic_output_indirection (void **slot, void *data)
862 machopic_indirection *p = *((machopic_indirection **) slot);
863 FILE *asm_out_file = (FILE *) data;
864 rtx symbol;
865 const char *sym_name;
866 const char *ptr_name;
868 if (!p->used)
869 return 1;
871 symbol = p->symbol;
872 sym_name = XSTR (symbol, 0);
873 ptr_name = p->ptr_name;
875 if (p->stub_p)
877 char *sym;
878 char *stub;
879 tree id;
881 id = maybe_get_identifier (sym_name);
882 if (id)
884 tree id_orig = id;
886 while (IDENTIFIER_TRANSPARENT_ALIAS (id))
887 id = TREE_CHAIN (id);
888 if (id != id_orig)
889 sym_name = IDENTIFIER_POINTER (id);
892 sym = alloca (strlen (sym_name) + 2);
893 if (sym_name[0] == '*' || sym_name[0] == '&')
894 strcpy (sym, sym_name + 1);
895 else if (sym_name[0] == '-' || sym_name[0] == '+')
896 strcpy (sym, sym_name);
897 else
898 sprintf (sym, "%s%s", user_label_prefix, sym_name);
900 stub = alloca (strlen (ptr_name) + 2);
901 if (ptr_name[0] == '*' || ptr_name[0] == '&')
902 strcpy (stub, ptr_name + 1);
903 else
904 sprintf (stub, "%s%s", user_label_prefix, ptr_name);
906 machopic_output_stub (asm_out_file, sym, stub);
908 else if (! indirect_data (symbol)
909 && (machopic_symbol_defined_p (symbol)
910 || SYMBOL_REF_LOCAL_P (symbol)))
912 data_section ();
913 assemble_align (GET_MODE_ALIGNMENT (Pmode));
914 assemble_label (ptr_name);
915 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
916 GET_MODE_SIZE (Pmode),
917 GET_MODE_ALIGNMENT (Pmode), 1);
919 else
921 rtx init = const0_rtx;
923 machopic_nl_symbol_ptr_section ();
924 assemble_name (asm_out_file, ptr_name);
925 fprintf (asm_out_file, ":\n");
927 fprintf (asm_out_file, "\t.indirect_symbol ");
928 assemble_name (asm_out_file, sym_name);
929 fprintf (asm_out_file, "\n");
931 /* Variables that are marked with MACHO_SYMBOL_STATIC need to
932 have their symbol name instead of 0 in the second entry of
933 the non-lazy symbol pointer data structure when they are
934 defined. This allows the runtime to rebind newer instances
935 of the translation unit with the original instance of the
936 symbol. */
938 if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
939 && machopic_symbol_defined_p (symbol))
940 init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
942 assemble_integer (init, GET_MODE_SIZE (Pmode),
943 GET_MODE_ALIGNMENT (Pmode), 1);
946 return 1;
949 void
950 machopic_finish (FILE *asm_out_file)
952 if (machopic_indirections)
953 htab_traverse_noresize (machopic_indirections,
954 machopic_output_indirection,
955 asm_out_file);
959 machopic_operand_p (rtx op)
961 if (MACHOPIC_JUST_INDIRECT)
963 while (GET_CODE (op) == CONST)
964 op = XEXP (op, 0);
966 if (GET_CODE (op) == SYMBOL_REF)
967 return machopic_symbol_defined_p (op);
968 else
969 return 0;
972 while (GET_CODE (op) == CONST)
973 op = XEXP (op, 0);
975 if (GET_CODE (op) == MINUS
976 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
977 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
978 && machopic_symbol_defined_p (XEXP (op, 0))
979 && machopic_symbol_defined_p (XEXP (op, 1)))
980 return 1;
982 return 0;
985 /* This function records whether a given name corresponds to a defined
986 or undefined function or variable, for machopic_classify_ident to
987 use later. */
989 void
990 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
992 rtx sym_ref;
994 /* Do the standard encoding things first. */
995 default_encode_section_info (decl, rtl, first);
997 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
998 return;
1000 sym_ref = XEXP (rtl, 0);
1001 if (TREE_CODE (decl) == VAR_DECL)
1002 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
1004 if (!DECL_EXTERNAL (decl)
1005 && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
1006 && ((TREE_STATIC (decl)
1007 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1008 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
1009 && DECL_INITIAL (decl) != error_mark_node)))
1010 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
1012 if (! TREE_PUBLIC (decl))
1013 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
1016 void
1017 darwin_mark_decl_preserved (const char *name)
1019 fprintf (asm_out_file, ".no_dead_strip ");
1020 assemble_name (asm_out_file, name);
1021 fputc ('\n', asm_out_file);
1024 void
1025 machopic_select_section (tree exp, int reloc,
1026 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1028 void (*base_function)(void);
1029 bool weak_p = DECL_P (exp) && DECL_WEAK (exp);
1030 static void (* const base_funs[][2])(void) = {
1031 { text_section, text_coal_section },
1032 { unlikely_text_section, text_unlikely_coal_section },
1033 { readonly_data_section, const_coal_section },
1034 { const_data_section, const_data_coal_section },
1035 { data_section, data_coal_section }
1038 if (reloc == 0
1039 && (last_text_section == in_text_unlikely
1040 || last_text_section == in_text_unlikely_coal))
1041 reloc = 1;
1043 if (TREE_CODE (exp) == FUNCTION_DECL)
1044 base_function = base_funs[reloc][weak_p];
1045 else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1046 base_function = base_funs[2][weak_p];
1047 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1048 base_function = base_funs[3][weak_p];
1049 else
1050 base_function = base_funs[4][weak_p];
1052 if (TREE_CODE (exp) == STRING_CST
1053 && ((size_t) TREE_STRING_LENGTH (exp)
1054 == strlen (TREE_STRING_POINTER (exp)) + 1))
1055 cstring_section ();
1056 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1057 && flag_merge_constants)
1059 tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1061 if (TREE_CODE (size) == INTEGER_CST &&
1062 TREE_INT_CST_LOW (size) == 4 &&
1063 TREE_INT_CST_HIGH (size) == 0)
1064 literal4_section ();
1065 else if (TREE_CODE (size) == INTEGER_CST &&
1066 TREE_INT_CST_LOW (size) == 8 &&
1067 TREE_INT_CST_HIGH (size) == 0)
1068 literal8_section ();
1069 else
1070 base_function ();
1072 else if (TREE_CODE (exp) == CONSTRUCTOR
1073 && TREE_TYPE (exp)
1074 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1075 && TYPE_NAME (TREE_TYPE (exp)))
1077 tree name = TYPE_NAME (TREE_TYPE (exp));
1078 if (TREE_CODE (name) == TYPE_DECL)
1079 name = DECL_NAME (name);
1081 if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1083 if (flag_next_runtime)
1084 objc_constant_string_object_section ();
1085 else
1086 objc_string_object_section ();
1088 else
1089 base_function ();
1091 else if (TREE_CODE (exp) == VAR_DECL &&
1092 DECL_NAME (exp) &&
1093 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1094 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1095 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1097 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1099 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1100 objc_cls_meth_section ();
1101 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1102 objc_inst_meth_section ();
1103 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1104 objc_cat_cls_meth_section ();
1105 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1106 objc_cat_inst_meth_section ();
1107 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1108 objc_class_vars_section ();
1109 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1110 objc_instance_vars_section ();
1111 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1112 objc_cat_cls_meth_section ();
1113 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1114 objc_class_names_section ();
1115 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1116 objc_meth_var_names_section ();
1117 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1118 objc_meth_var_types_section ();
1119 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1120 objc_cls_refs_section ();
1121 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1122 objc_class_section ();
1123 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1124 objc_meta_class_section ();
1125 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1126 objc_category_section ();
1127 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1128 objc_selector_refs_section ();
1129 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1130 objc_selector_fixup_section ();
1131 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1132 objc_symbols_section ();
1133 else if (!strncmp (name, "_OBJC_MODULES", 13))
1134 objc_module_info_section ();
1135 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1136 objc_image_info_section ();
1137 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1138 objc_cat_inst_meth_section ();
1139 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1140 objc_cat_cls_meth_section ();
1141 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1142 objc_cat_cls_meth_section ();
1143 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1144 objc_protocol_section ();
1145 else
1146 base_function ();
1148 else
1149 base_function ();
1152 /* This can be called with address expressions as "rtx".
1153 They must go in "const". */
1155 void
1156 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1157 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1159 if (GET_MODE_SIZE (mode) == 8
1160 && (GET_CODE (x) == CONST_INT
1161 || GET_CODE (x) == CONST_DOUBLE))
1162 literal8_section ();
1163 else if (GET_MODE_SIZE (mode) == 4
1164 && (GET_CODE (x) == CONST_INT
1165 || GET_CODE (x) == CONST_DOUBLE))
1166 literal4_section ();
1167 else if (MACHOPIC_INDIRECT
1168 && (GET_CODE (x) == SYMBOL_REF
1169 || GET_CODE (x) == CONST
1170 || GET_CODE (x) == LABEL_REF))
1171 const_data_section ();
1172 else
1173 const_section ();
1176 void
1177 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1179 if (MACHOPIC_INDIRECT)
1180 mod_init_section ();
1181 else
1182 constructor_section ();
1183 assemble_align (POINTER_SIZE);
1184 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1186 if (! MACHOPIC_INDIRECT)
1187 fprintf (asm_out_file, ".reference .constructors_used\n");
1190 void
1191 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1193 if (MACHOPIC_INDIRECT)
1194 mod_term_section ();
1195 else
1196 destructor_section ();
1197 assemble_align (POINTER_SIZE);
1198 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1200 if (! MACHOPIC_INDIRECT)
1201 fprintf (asm_out_file, ".reference .destructors_used\n");
1204 void
1205 darwin_globalize_label (FILE *stream, const char *name)
1207 if (!!strncmp (name, "_OBJC_", 6))
1208 default_globalize_label (stream, name);
1211 void
1212 darwin_asm_named_section (const char *name,
1213 unsigned int flags ATTRIBUTE_UNUSED,
1214 tree decl ATTRIBUTE_UNUSED)
1216 fprintf (asm_out_file, "\t.section %s\n", name);
1219 void
1220 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1222 /* Darwin does not use unique sections. */
1225 /* Handle a "weak_import" attribute; arguments as in
1226 struct attribute_spec.handler. */
1228 tree
1229 darwin_handle_weak_import_attribute (tree *node, tree name,
1230 tree ARG_UNUSED (args),
1231 int ARG_UNUSED (flags),
1232 bool * no_add_attrs)
1234 if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1236 warning (OPT_Wattributes, "%qs attribute ignored",
1237 IDENTIFIER_POINTER (name));
1238 *no_add_attrs = true;
1240 else
1241 declare_weak (*node);
1243 return NULL_TREE;
1246 static void
1247 no_dead_strip (FILE *file, const char *lab)
1249 fprintf (file, ".no_dead_strip %s\n", lab);
1252 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1253 The third parameter is nonzero if this is for exception handling.
1254 The fourth parameter is nonzero if this is just a placeholder for an
1255 FDE that we are omitting. */
1257 void
1258 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1260 tree id = DECL_ASSEMBLER_NAME (decl)
1261 ? DECL_ASSEMBLER_NAME (decl)
1262 : DECL_NAME (decl);
1264 const char *prefix = user_label_prefix;
1266 const char *base = IDENTIFIER_POINTER (id);
1267 unsigned int base_len = IDENTIFIER_LENGTH (id);
1269 const char *suffix = ".eh";
1271 int need_quotes = name_needs_quotes (base);
1272 int quotes_len = need_quotes ? 2 : 0;
1273 char *lab;
1275 if (! for_eh)
1276 suffix = ".eh1";
1278 lab = xmalloc (strlen (prefix)
1279 + base_len + strlen (suffix) + quotes_len + 1);
1280 lab[0] = '\0';
1282 if (need_quotes)
1283 strcat(lab, "\"");
1284 strcat(lab, prefix);
1285 strcat(lab, base);
1286 strcat(lab, suffix);
1287 if (need_quotes)
1288 strcat(lab, "\"");
1290 if (TREE_PUBLIC (decl))
1291 fprintf (file, "\t%s %s\n",
1292 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1293 ? ".globl"
1294 : ".private_extern"),
1295 lab);
1297 if (DECL_WEAK (decl))
1298 fprintf (file, "\t.weak_definition %s\n", lab);
1300 if (empty)
1302 fprintf (file, "%s = 0\n", lab);
1304 /* Mark the absolute .eh and .eh1 style labels as needed to
1305 ensure that we don't dead code strip them and keep such
1306 labels from another instantiation point until we can fix this
1307 properly with group comdat support. */
1308 no_dead_strip (file, lab);
1310 else
1311 fprintf (file, "%s:\n", lab);
1313 free (lab);
1316 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1318 void
1319 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1321 const char *nlp_name;
1323 gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1325 nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1326 fputs ("\t.long\t", file);
1327 ASM_OUTPUT_LABELREF (file, nlp_name);
1328 fputs ("-.", file);
1331 /* Emit an assembler directive to set visibility for a symbol. The
1332 only supported visibilities are VISIBILITY_DEFAULT and
1333 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1334 extern". There is no MACH-O equivalent of ELF's
1335 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1337 void
1338 darwin_assemble_visibility (tree decl, int vis)
1340 if (vis == VISIBILITY_DEFAULT)
1342 else if (vis == VISIBILITY_HIDDEN)
1344 fputs ("\t.private_extern ", asm_out_file);
1345 assemble_name (asm_out_file,
1346 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1347 fputs ("\n", asm_out_file);
1349 else
1350 warning (OPT_Wattributes, "internal and protected visibility attributes "
1351 "not supported in this configuration; ignored");
1354 /* Output a difference of two labels that will be an assembly time
1355 constant if the two labels are local. (.long lab1-lab2 will be
1356 very different if lab1 is at the boundary between two sections; it
1357 will be relocated according to the second section, not the first,
1358 so one ends up with a difference between labels in different
1359 sections, which is bad in the dwarf2 eh context for instance.) */
1361 static int darwin_dwarf_label_counter;
1363 void
1364 darwin_asm_output_dwarf_delta (FILE *file, int size,
1365 const char *lab1, const char *lab2)
1367 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1368 && lab2[0] == '*' && lab2[1] == 'L');
1369 const char *directive = (size == 8 ? ".quad" : ".long");
1371 if (islocaldiff)
1372 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1373 else
1374 fprintf (file, "\t%s\t", directive);
1375 assemble_name_raw (file, lab1);
1376 fprintf (file, "-");
1377 assemble_name_raw (file, lab2);
1378 if (islocaldiff)
1379 fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1382 void
1383 darwin_file_end (void)
1385 machopic_finish (asm_out_file);
1386 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1388 constructor_section ();
1389 destructor_section ();
1390 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1392 fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1395 /* Cross-module name binding. Darwin does not support overriding
1396 functions at dynamic-link time. */
1398 bool
1399 darwin_binds_local_p (tree decl)
1401 return default_binds_local_p_1 (decl, 0);
1404 #include "gt-darwin.h"