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,
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)
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. */
26 #include "coretypes.h"
30 #include "hard-reg-set.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "insn-flags.h"
36 #include "insn-attr.h"
43 #include "langhooks.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. */
81 name_needs_quotes (const char *name)
84 while ((c = *name++) != '\0')
85 if (! ISIDNUM (c) && c != '.' && c != '$')
90 /* Return true if SYM_REF can be used without an indirection. */
92 machopic_symbol_defined_p (rtx sym_ref)
94 if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
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);
108 if (DECL_COMMON (decl))
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)
125 flags = SYMBOL_REF_FLAGS (sym_ref);
126 function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
127 if (machopic_symbol_defined_p (sym_ref))
129 ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
132 ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
135 #ifndef TARGET_FIX_AND_CONTINUE
136 #define TARGET_FIX_AND_CONTINUE 0
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. */
150 indirect_data (rtx sym_ref)
155 /* If we aren't generating fix-and-continue code, don't do anything special. */
156 if (TARGET_FIX_AND_CONTINUE == 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));
175 machopic_data_defined_p (rtx sym_ref)
177 if (indirect_data (sym_ref))
180 switch (machopic_classify_symbol (sym_ref))
182 case MACHOPIC_DEFINED_DATA:
183 case MACHOPIC_DEFINED_FUNCTION:
191 machopic_define_symbol (rtx mem)
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;
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)
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)
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);
230 /* Return either ORIG or (const:P (minus:P ORIG PIC_BASE)), depending
231 on whether pic_base is NULL or not. */
233 gen_pic_offset (rtx orig, rtx pic_base)
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;
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);
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. */
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
275 /* True iff this stub or pointer pointer has been referenced. */
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. */
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
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. */
307 machopic_indirection_name (rtx sym_ref, bool stub_p)
310 const char *name = XSTR (sym_ref, 0);
311 size_t namelen = strlen (name);
312 machopic_indirection *p;
314 bool saw_star = false;
317 const char *prefix = user_label_prefix;
318 const char *quote = "";
328 needs_quotes = name_needs_quotes (name);
335 suffix = STUB_SUFFIX;
337 suffix = NON_LAZY_POINTER_SUFFIX;
339 buffer = alloca (strlen ("&L")
346 /* Construct the name of the non-lazy pointer or stub. */
347 sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
349 if (!machopic_indirections)
350 machopic_indirections = htab_create_ggc (37,
351 machopic_indirection_hash,
352 machopic_indirection_eq,
355 slot = htab_find_slot_with_hash (machopic_indirections, buffer,
356 htab_hash_string (buffer), INSERT);
359 p = (machopic_indirection *) *slot;
363 p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
365 p->ptr_name = xstrdup (buffer);
374 /* Return the name of the stub for the mcount function. */
377 machopic_mcount_stub_name (void)
379 rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
380 return machopic_indirection_name (symbol, /*stub_p=*/true);
383 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
384 or non-lazy pointer as used -- and mark the object to which the
385 pointer/stub refers as used as well, since the pointer/stub will
386 emit a reference to it. */
389 machopic_validate_stub_or_non_lazy_ptr (const char *name)
391 machopic_indirection *p;
393 p = ((machopic_indirection *)
394 (htab_find_with_hash (machopic_indirections, name,
395 htab_hash_string (name))));
398 const char *real_name;
403 /* Do what output_addr_const will do when we actually call it. */
404 if (SYMBOL_REF_DECL (p->symbol))
405 mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
407 real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
409 id = maybe_get_identifier (real_name);
411 mark_referenced (id);
415 /* Transform ORIG, which may be any data source, to the corresponding
416 source using indirections. */
419 machopic_indirect_data_reference (rtx orig, rtx reg)
423 if (! MACHOPIC_INDIRECT)
426 if (GET_CODE (orig) == SYMBOL_REF)
428 int defined = machopic_data_defined_p (orig);
430 if (defined && MACHO_DYNAMIC_NO_PIC_P)
432 #if defined (TARGET_TOC)
433 /* Create a new register for CSE opportunities. */
434 rtx hi_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
435 emit_insn (gen_macho_high (hi_reg, orig));
436 emit_insn (gen_macho_low (reg, hi_reg, orig));
438 /* some other cpu -- writeme! */
445 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
446 rtx pic_base = machopic_function_base_sym ();
447 rtx offset = gen_pic_offset (orig, pic_base);
450 #if defined (TARGET_TOC) /* i.e., PowerPC */
451 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
455 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
456 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
457 gen_rtx_HIGH (Pmode, offset))));
458 emit_insn (gen_rtx_SET (Pmode, reg,
459 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
463 #if defined (HAVE_lo_sum)
466 emit_insn (gen_rtx_SET (VOIDmode, reg,
467 gen_rtx_HIGH (Pmode, offset)));
468 emit_insn (gen_rtx_SET (VOIDmode, reg,
469 gen_rtx_LO_SUM (Pmode, reg, offset)));
470 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
472 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
478 ptr_ref = (gen_rtx_SYMBOL_REF
480 machopic_indirection_name (orig, /*stub_p=*/false)));
482 SYMBOL_REF_DECL (ptr_ref) = SYMBOL_REF_DECL (orig);
484 ptr_ref = gen_const_mem (Pmode, ptr_ref);
485 machopic_define_symbol (ptr_ref);
489 else if (GET_CODE (orig) == CONST)
493 /* legitimize both operands of the PLUS */
494 if (GET_CODE (XEXP (orig, 0)) == PLUS)
496 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
498 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
499 (base == reg ? 0 : reg));
504 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
505 result = plus_constant (base, INTVAL (orig));
507 result = gen_rtx_PLUS (Pmode, base, orig);
509 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
513 emit_move_insn (reg, result);
518 result = force_reg (GET_MODE (result), result);
525 else if (GET_CODE (orig) == MEM)
526 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
527 /* When the target is i386, this code prevents crashes due to the
528 compiler's ignorance on how to move the PIC base register to
529 other registers. (The reload phase sometimes introduces such
531 else if (GET_CODE (orig) == PLUS
532 && GET_CODE (XEXP (orig, 0)) == REG
533 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
535 /* Prevent the same register from being erroneously used
536 as both the base and index registers. */
537 && GET_CODE (XEXP (orig, 1)) == CONST
541 emit_move_insn (reg, XEXP (orig, 0));
542 XEXP (ptr_ref, 0) = reg;
547 /* Transform TARGET (a MEM), which is a function call target, to the
548 corresponding symbol_stub if necessary. Return a new MEM. */
551 machopic_indirect_call_target (rtx target)
553 if (GET_CODE (target) != MEM)
556 if (MACHOPIC_INDIRECT
557 && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
558 && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
559 & MACHO_SYMBOL_FLAG_DEFINED))
561 rtx sym_ref = XEXP (target, 0);
562 const char *stub_name = machopic_indirection_name (sym_ref,
564 enum machine_mode mode = GET_MODE (sym_ref);
565 tree decl = SYMBOL_REF_DECL (sym_ref);
567 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
568 SYMBOL_REF_DECL (XEXP (target, 0)) = decl;
569 MEM_READONLY_P (target) = 1;
570 MEM_NOTRAP_P (target) = 1;
577 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
581 if (! MACHOPIC_INDIRECT)
584 /* First handle a simple SYMBOL_REF or LABEL_REF */
585 if (GET_CODE (orig) == LABEL_REF
586 || (GET_CODE (orig) == SYMBOL_REF
589 /* addr(foo) = &func+(foo-func) */
592 orig = machopic_indirect_data_reference (orig, reg);
594 if (GET_CODE (orig) == PLUS
595 && GET_CODE (XEXP (orig, 0)) == REG)
598 return force_reg (mode, orig);
600 emit_move_insn (reg, orig);
604 /* if dynamic-no-pic we don't have a pic base */
605 if (MACHO_DYNAMIC_NO_PIC_P)
608 pic_base = machopic_function_base_sym ();
610 if (GET_CODE (orig) == MEM)
614 gcc_assert (!reload_in_progress);
615 reg = gen_reg_rtx (Pmode);
619 if (MACHO_DYNAMIC_NO_PIC_P
620 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
621 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
623 #if defined (TARGET_TOC) /* ppc */
624 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
625 rtx asym = XEXP (orig, 0);
628 emit_insn (gen_macho_high (temp_reg, asym));
629 mem = gen_const_mem (GET_MODE (orig),
630 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
631 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
633 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
639 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
640 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
642 rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
643 #if defined (TARGET_TOC) /* i.e., PowerPC */
644 /* Generating a new reg may expose opportunities for
645 common subexpression elimination. */
646 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
651 sum = gen_rtx_HIGH (Pmode, offset);
652 if (! MACHO_DYNAMIC_NO_PIC_P)
653 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
655 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
657 mem = gen_const_mem (GET_MODE (orig),
658 gen_rtx_LO_SUM (Pmode,
659 hi_sum_reg, offset));
660 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
661 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
666 emit_insn (gen_rtx_USE (VOIDmode,
668 PIC_OFFSET_TABLE_REGNUM)));
670 emit_insn (gen_rtx_SET (VOIDmode, reg,
672 gen_rtx_CONST (Pmode,
674 emit_insn (gen_rtx_SET (VOIDmode, reg,
675 gen_rtx_LO_SUM (Pmode, reg,
676 gen_rtx_CONST (Pmode, offset))));
677 pic_ref = gen_rtx_PLUS (Pmode,
678 pic_offset_table_rtx, reg);
682 #endif /* HAVE_lo_sum */
684 rtx pic = pic_offset_table_rtx;
685 if (GET_CODE (pic) != REG)
687 emit_move_insn (reg, pic);
691 emit_insn (gen_rtx_USE (VOIDmode,
693 PIC_OFFSET_TABLE_REGNUM)));
696 pic_ref = gen_rtx_PLUS (Pmode, pic,
697 gen_pic_offset (XEXP (orig, 0),
701 #if !defined (TARGET_TOC)
702 emit_move_insn (reg, pic_ref);
703 pic_ref = gen_const_mem (GET_MODE (orig), reg);
710 if (GET_CODE (orig) == SYMBOL_REF
711 || GET_CODE (orig) == LABEL_REF)
713 rtx offset = gen_pic_offset (orig, pic_base);
714 #if defined (TARGET_TOC) /* i.e., PowerPC */
719 gcc_assert (!reload_in_progress);
720 reg = gen_reg_rtx (Pmode);
725 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
726 (MACHO_DYNAMIC_NO_PIC_P)
727 ? gen_rtx_HIGH (Pmode, offset)
728 : gen_rtx_PLUS (Pmode,
729 pic_offset_table_rtx,
732 emit_insn (gen_rtx_SET (VOIDmode, reg,
733 gen_rtx_LO_SUM (Pmode,
734 hi_sum_reg, offset)));
737 emit_insn (gen_rtx_SET (VOIDmode, reg,
738 gen_rtx_HIGH (Pmode, offset)));
739 emit_insn (gen_rtx_SET (VOIDmode, reg,
740 gen_rtx_LO_SUM (Pmode, reg, offset)));
741 pic_ref = gen_rtx_PLUS (Pmode,
742 pic_offset_table_rtx, reg);
746 #endif /* HAVE_lo_sum */
749 || GET_CODE (orig) == SUBREG)
755 rtx pic = pic_offset_table_rtx;
756 if (GET_CODE (pic) != REG)
758 emit_move_insn (reg, pic);
762 emit_insn (gen_rtx_USE (VOIDmode,
763 pic_offset_table_rtx));
765 pic_ref = gen_rtx_PLUS (Pmode,
767 gen_pic_offset (orig, pic_base));
772 if (GET_CODE (pic_ref) != REG)
776 emit_move_insn (reg, pic_ref);
781 return force_reg (mode, pic_ref);
790 else if (GET_CODE (orig) == SYMBOL_REF)
793 else if (GET_CODE (orig) == PLUS
794 && (GET_CODE (XEXP (orig, 0)) == MEM
795 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
796 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
797 && XEXP (orig, 0) != pic_offset_table_rtx
798 && GET_CODE (XEXP (orig, 1)) != REG)
802 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
804 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
805 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
806 Pmode, (base == reg ? 0 : reg));
807 if (GET_CODE (orig) == CONST_INT)
809 pic_ref = plus_constant (base, INTVAL (orig));
813 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
815 if (reg && is_complex)
817 emit_move_insn (reg, pic_ref);
820 /* Likewise, should we set special REG_NOTEs here? */
823 else if (GET_CODE (orig) == CONST)
825 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
828 else if (GET_CODE (orig) == MEM
829 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
831 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
832 addr = replace_equiv_address (orig, addr);
833 emit_move_insn (reg, addr);
840 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
841 DATA is the FILE* for assembly output. Called from
845 machopic_output_indirection (void **slot, void *data)
847 machopic_indirection *p = *((machopic_indirection **) slot);
848 FILE *asm_out_file = (FILE *) data;
850 const char *sym_name;
851 const char *ptr_name;
857 sym_name = XSTR (symbol, 0);
858 ptr_name = p->ptr_name;
865 sym = alloca (strlen (sym_name) + 2);
866 if (sym_name[0] == '*' || sym_name[0] == '&')
867 strcpy (sym, sym_name + 1);
868 else if (sym_name[0] == '-' || sym_name[0] == '+')
869 strcpy (sym, sym_name);
871 sprintf (sym, "%s%s", user_label_prefix, sym_name);
873 stub = alloca (strlen (ptr_name) + 2);
874 if (ptr_name[0] == '*' || ptr_name[0] == '&')
875 strcpy (stub, ptr_name + 1);
877 sprintf (stub, "%s%s", user_label_prefix, ptr_name);
879 machopic_output_stub (asm_out_file, sym, stub);
881 else if (! indirect_data (symbol)
882 && (machopic_symbol_defined_p (symbol)
883 || SYMBOL_REF_LOCAL_P (symbol)))
886 assemble_align (GET_MODE_ALIGNMENT (Pmode));
887 assemble_label (ptr_name);
888 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
889 GET_MODE_SIZE (Pmode),
890 GET_MODE_ALIGNMENT (Pmode), 1);
894 rtx init = const0_rtx;
896 machopic_nl_symbol_ptr_section ();
897 assemble_name (asm_out_file, ptr_name);
898 fprintf (asm_out_file, ":\n");
900 fprintf (asm_out_file, "\t.indirect_symbol ");
901 assemble_name (asm_out_file, sym_name);
902 fprintf (asm_out_file, "\n");
904 /* Variables that are marked with MACHO_SYMBOL_STATIC need to
905 have their symbol name instead of 0 in the second entry of
906 the non-lazy symbol pointer data structure when they are
907 defined. This allows the runtime to rebind newer instances
908 of the translation unit with the original instance of the
911 if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
912 && machopic_symbol_defined_p (symbol))
913 init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
915 assemble_integer (init, GET_MODE_SIZE (Pmode),
916 GET_MODE_ALIGNMENT (Pmode), 1);
923 machopic_finish (FILE *asm_out_file)
925 if (machopic_indirections)
926 htab_traverse_noresize (machopic_indirections,
927 machopic_output_indirection,
932 machopic_operand_p (rtx op)
934 if (MACHOPIC_JUST_INDIRECT)
936 while (GET_CODE (op) == CONST)
939 if (GET_CODE (op) == SYMBOL_REF)
940 return machopic_symbol_defined_p (op);
945 while (GET_CODE (op) == CONST)
948 if (GET_CODE (op) == MINUS
949 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
950 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
951 && machopic_symbol_defined_p (XEXP (op, 0))
952 && machopic_symbol_defined_p (XEXP (op, 1)))
958 /* This function records whether a given name corresponds to a defined
959 or undefined function or variable, for machopic_classify_ident to
963 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
967 /* Do the standard encoding things first. */
968 default_encode_section_info (decl, rtl, first);
970 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
973 sym_ref = XEXP (rtl, 0);
974 if (TREE_CODE (decl) == VAR_DECL)
975 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
977 if (!DECL_EXTERNAL (decl)
978 && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
979 && ((TREE_STATIC (decl)
980 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
981 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
982 && DECL_INITIAL (decl) != error_mark_node)))
983 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
985 if (! TREE_PUBLIC (decl))
986 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
990 darwin_mark_decl_preserved (const char *name)
992 fprintf (asm_out_file, ".no_dead_strip ");
993 assemble_name (asm_out_file, name);
994 fputc ('\n', asm_out_file);
998 machopic_select_section (tree exp, int reloc,
999 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1001 void (*base_function)(void);
1002 bool weak_p = DECL_P (exp) && DECL_WEAK (exp);
1003 static void (* const base_funs[][2])(void) = {
1004 { text_section, text_coal_section },
1005 { unlikely_text_section, text_unlikely_coal_section },
1006 { readonly_data_section, const_coal_section },
1007 { const_data_section, const_data_coal_section },
1008 { data_section, data_coal_section }
1012 && (last_text_section == in_text_unlikely
1013 || last_text_section == in_text_unlikely_coal))
1016 if (TREE_CODE (exp) == FUNCTION_DECL)
1017 base_function = base_funs[reloc][weak_p];
1018 else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1019 base_function = base_funs[2][weak_p];
1020 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1021 base_function = base_funs[3][weak_p];
1023 base_function = base_funs[4][weak_p];
1025 if (TREE_CODE (exp) == STRING_CST
1026 && ((size_t) TREE_STRING_LENGTH (exp)
1027 == strlen (TREE_STRING_POINTER (exp)) + 1))
1029 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1030 && flag_merge_constants)
1032 tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1034 if (TREE_CODE (size) == INTEGER_CST &&
1035 TREE_INT_CST_LOW (size) == 4 &&
1036 TREE_INT_CST_HIGH (size) == 0)
1037 literal4_section ();
1038 else if (TREE_CODE (size) == INTEGER_CST &&
1039 TREE_INT_CST_LOW (size) == 8 &&
1040 TREE_INT_CST_HIGH (size) == 0)
1041 literal8_section ();
1045 else if (TREE_CODE (exp) == CONSTRUCTOR
1047 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1048 && TYPE_NAME (TREE_TYPE (exp)))
1050 tree name = TYPE_NAME (TREE_TYPE (exp));
1051 if (TREE_CODE (name) == TYPE_DECL)
1052 name = DECL_NAME (name);
1054 if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1056 if (flag_next_runtime)
1057 objc_constant_string_object_section ();
1059 objc_string_object_section ();
1064 else if (TREE_CODE (exp) == VAR_DECL &&
1066 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1067 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1068 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1070 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1072 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1073 objc_cls_meth_section ();
1074 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1075 objc_inst_meth_section ();
1076 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1077 objc_cat_cls_meth_section ();
1078 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1079 objc_cat_inst_meth_section ();
1080 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1081 objc_class_vars_section ();
1082 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1083 objc_instance_vars_section ();
1084 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1085 objc_cat_cls_meth_section ();
1086 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1087 objc_class_names_section ();
1088 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1089 objc_meth_var_names_section ();
1090 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1091 objc_meth_var_types_section ();
1092 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1093 objc_cls_refs_section ();
1094 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1095 objc_class_section ();
1096 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1097 objc_meta_class_section ();
1098 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1099 objc_category_section ();
1100 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1101 objc_selector_refs_section ();
1102 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1103 objc_selector_fixup_section ();
1104 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1105 objc_symbols_section ();
1106 else if (!strncmp (name, "_OBJC_MODULES", 13))
1107 objc_module_info_section ();
1108 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1109 objc_image_info_section ();
1110 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1111 objc_cat_inst_meth_section ();
1112 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1113 objc_cat_cls_meth_section ();
1114 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1115 objc_cat_cls_meth_section ();
1116 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1117 objc_protocol_section ();
1125 /* This can be called with address expressions as "rtx".
1126 They must go in "const". */
1129 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1130 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1132 if (GET_MODE_SIZE (mode) == 8
1133 && (GET_CODE (x) == CONST_INT
1134 || GET_CODE (x) == CONST_DOUBLE))
1135 literal8_section ();
1136 else if (GET_MODE_SIZE (mode) == 4
1137 && (GET_CODE (x) == CONST_INT
1138 || GET_CODE (x) == CONST_DOUBLE))
1139 literal4_section ();
1140 else if (MACHOPIC_INDIRECT
1141 && (GET_CODE (x) == SYMBOL_REF
1142 || GET_CODE (x) == CONST
1143 || GET_CODE (x) == LABEL_REF))
1144 const_data_section ();
1150 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1152 if (MACHOPIC_INDIRECT)
1153 mod_init_section ();
1155 constructor_section ();
1156 assemble_align (POINTER_SIZE);
1157 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1159 if (! MACHOPIC_INDIRECT)
1160 fprintf (asm_out_file, ".reference .constructors_used\n");
1164 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1166 if (MACHOPIC_INDIRECT)
1167 mod_term_section ();
1169 destructor_section ();
1170 assemble_align (POINTER_SIZE);
1171 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1173 if (! MACHOPIC_INDIRECT)
1174 fprintf (asm_out_file, ".reference .destructors_used\n");
1178 darwin_globalize_label (FILE *stream, const char *name)
1180 if (!!strncmp (name, "_OBJC_", 6))
1181 default_globalize_label (stream, name);
1185 darwin_asm_named_section (const char *name,
1186 unsigned int flags ATTRIBUTE_UNUSED,
1187 tree decl ATTRIBUTE_UNUSED)
1189 fprintf (asm_out_file, "\t.section %s\n", name);
1193 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1195 /* Darwin does not use unique sections. */
1198 /* Handle a "weak_import" attribute; arguments as in
1199 struct attribute_spec.handler. */
1202 darwin_handle_weak_import_attribute (tree *node, tree name,
1203 tree ARG_UNUSED (args),
1204 int ARG_UNUSED (flags),
1205 bool * no_add_attrs)
1207 if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1209 warning (OPT_Wattributes, "%qs attribute ignored",
1210 IDENTIFIER_POINTER (name));
1211 *no_add_attrs = true;
1214 declare_weak (*node);
1220 no_dead_strip (FILE *file, const char *lab)
1222 fprintf (file, ".no_dead_strip %s\n", lab);
1225 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1226 The third parameter is nonzero if this is for exception handling.
1227 The fourth parameter is nonzero if this is just a placeholder for an
1228 FDE that we are omitting. */
1231 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1233 tree id = DECL_ASSEMBLER_NAME (decl)
1234 ? DECL_ASSEMBLER_NAME (decl)
1237 const char *prefix = user_label_prefix;
1239 const char *base = IDENTIFIER_POINTER (id);
1240 unsigned int base_len = IDENTIFIER_LENGTH (id);
1242 const char *suffix = ".eh";
1244 int need_quotes = name_needs_quotes (base);
1245 int quotes_len = need_quotes ? 2 : 0;
1251 lab = xmalloc (strlen (prefix)
1252 + base_len + strlen (suffix) + quotes_len + 1);
1257 strcat(lab, prefix);
1259 strcat(lab, suffix);
1263 if (TREE_PUBLIC (decl))
1264 fprintf (file, "\t%s %s\n",
1265 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1267 : ".private_extern"),
1270 if (DECL_WEAK (decl))
1271 fprintf (file, "\t.weak_definition %s\n", lab);
1275 fprintf (file, "%s = 0\n", lab);
1277 /* Mark the absolute .eh and .eh1 style labels as needed to
1278 ensure that we don't dead code strip them and keep such
1279 labels from another instantiation point until we can fix this
1280 properly with group comdat support. */
1281 no_dead_strip (file, lab);
1284 fprintf (file, "%s:\n", lab);
1289 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1292 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1294 const char *nlp_name;
1296 gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1298 nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1299 fputs ("\t.long\t", file);
1300 ASM_OUTPUT_LABELREF (file, nlp_name);
1304 /* Emit an assembler directive to set visibility for a symbol. The
1305 only supported visibilities are VISIBILITY_DEFAULT and
1306 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1307 extern". There is no MACH-O equivalent of ELF's
1308 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1311 darwin_assemble_visibility (tree decl, int vis)
1313 if (vis == VISIBILITY_DEFAULT)
1315 else if (vis == VISIBILITY_HIDDEN)
1317 fputs ("\t.private_extern ", asm_out_file);
1318 assemble_name (asm_out_file,
1319 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1320 fputs ("\n", asm_out_file);
1323 warning (OPT_Wattributes, "internal and protected visibility attributes "
1324 "not supported in this configuration; ignored");
1327 /* Output a difference of two labels that will be an assembly time
1328 constant if the two labels are local. (.long lab1-lab2 will be
1329 very different if lab1 is at the boundary between two sections; it
1330 will be relocated according to the second section, not the first,
1331 so one ends up with a difference between labels in different
1332 sections, which is bad in the dwarf2 eh context for instance.) */
1334 static int darwin_dwarf_label_counter;
1337 darwin_asm_output_dwarf_delta (FILE *file, int size,
1338 const char *lab1, const char *lab2)
1340 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1341 && lab2[0] == '*' && lab2[1] == 'L');
1342 const char *directive = (size == 8 ? ".quad" : ".long");
1345 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1347 fprintf (file, "\t%s\t", directive);
1348 assemble_name_raw (file, lab1);
1349 fprintf (file, "-");
1350 assemble_name_raw (file, lab2);
1352 fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1356 darwin_file_end (void)
1358 machopic_finish (asm_out_file);
1359 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1361 constructor_section ();
1362 destructor_section ();
1363 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1365 fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1368 /* Cross-module name binding. Darwin does not support overriding
1369 functions at dynamic-link time. */
1372 darwin_binds_local_p (tree decl)
1374 return default_binds_local_p_1 (decl, 0);
1377 #include "gt-darwin.h"