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, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, 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 data from the old translation unit, if the data
59 existed in the unit to be replaced, and from the new translation
62 The changes are to insert 5 nops at the beginning of all functions
63 and to use indirection to get at static duration data. 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 duration data from the newly loaded translation unit to the
72 existing data, if any. @code{static} data is special and is
73 handled by setting the second word in the .non_lazy_symbol_pointer
74 data structure to the address of the data. See indirect_data for
75 the code that handles the extra indirection, and
76 machopic_output_indirection and its use of MACHO_SYMBOL_STATIC for
77 the code that handles @code{static} data 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)
194 if (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 if (MACHO_DYNAMIC_NO_PIC_P)
209 if (function_base == NULL)
211 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
213 current_function_uses_pic_offset_table = 1;
215 return function_base;
218 /* Return a SYMBOL_REF for the PIC function base. */
221 machopic_function_base_sym (void)
225 sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
226 SYMBOL_REF_FLAGS (sym_ref)
227 |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
231 static GTY(()) const char * function_base_func_name;
232 static GTY(()) int current_pic_label_num;
235 machopic_output_function_base_name (FILE *file)
237 const char *current_name;
239 /* If dynamic-no-pic is on, we should not get here. */
240 if (MACHO_DYNAMIC_NO_PIC_P)
243 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
244 if (function_base_func_name != current_name)
246 ++current_pic_label_num;
247 function_base_func_name = current_name;
249 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
252 /* The suffix attached to non-lazy pointer symbols. */
253 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
254 /* The suffix attached to stub symbols. */
255 #define STUB_SUFFIX "$stub"
257 typedef struct machopic_indirection GTY (())
259 /* The SYMBOL_REF for the entity referenced. */
261 /* The name of the stub or non-lazy pointer. */
262 const char * ptr_name;
263 /* True iff this entry is for a stub (as opposed to a non-lazy
266 /* True iff this stub or pointer pointer has been referenced. */
268 } machopic_indirection;
270 /* A table mapping stub names and non-lazy pointer names to
271 SYMBOL_REFs for the stubbed-to and pointed-to entities. */
273 static GTY ((param_is (struct machopic_indirection))) htab_t
274 machopic_indirections;
276 /* Return a hash value for a SLOT in the indirections hash table. */
279 machopic_indirection_hash (const void *slot)
281 const machopic_indirection *p = (const machopic_indirection *) slot;
282 return htab_hash_string (p->ptr_name);
285 /* Returns true if the KEY is the same as that associated with
289 machopic_indirection_eq (const void *slot, const void *key)
291 return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0;
294 /* Return the name of the non-lazy pointer (if STUB_P is false) or
295 stub (if STUB_B is true) corresponding to the given name. */
298 machopic_indirection_name (rtx sym_ref, bool stub_p)
301 const char *name = XSTR (sym_ref, 0);
302 size_t namelen = strlen (name);
303 machopic_indirection *p;
306 /* Construct the name of the non-lazy pointer or stub. */
309 int needs_quotes = name_needs_quotes (name);
310 buffer = alloca (strlen ("&L")
312 + strlen (STUB_SUFFIX)
313 + 2 /* possible quotes */
319 sprintf (buffer, "&\"L%s" STUB_SUFFIX "\"", name + 1);
321 sprintf (buffer, "&\"L%s%s" STUB_SUFFIX "\"", user_label_prefix,
324 else if (name[0] == '*')
325 sprintf (buffer, "&L%s" STUB_SUFFIX, name + 1);
327 sprintf (buffer, "&L%s%s" STUB_SUFFIX, user_label_prefix, name);
331 buffer = alloca (strlen ("&L")
332 + strlen (user_label_prefix)
334 + strlen (NON_LAZY_POINTER_SUFFIX)
337 sprintf (buffer, "&L%s" NON_LAZY_POINTER_SUFFIX, name + 1);
339 sprintf (buffer, "&L%s%s" NON_LAZY_POINTER_SUFFIX,
340 user_label_prefix, name);
343 if (!machopic_indirections)
344 machopic_indirections = htab_create_ggc (37,
345 machopic_indirection_hash,
346 machopic_indirection_eq,
349 slot = htab_find_slot_with_hash (machopic_indirections, buffer,
350 htab_hash_string (buffer), INSERT);
353 p = (machopic_indirection *) *slot;
357 p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
359 p->ptr_name = xstrdup (buffer);
368 /* Return the name of the stub for the mcount function. */
371 machopic_mcount_stub_name (void)
373 rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
374 return machopic_indirection_name (symbol, /*stub_p=*/true);
377 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
378 or non-lazy pointer as used -- and mark the object to which the
379 pointer/stub refers as used as well, since the pointer/stub will
380 emit a reference to it. */
383 machopic_validate_stub_or_non_lazy_ptr (const char *name)
385 machopic_indirection *p;
387 p = ((machopic_indirection *)
388 (htab_find_with_hash (machopic_indirections, name,
389 htab_hash_string (name))));
392 const char *real_name;
397 /* Do what output_addr_const will do when we actually call it. */
398 if (SYMBOL_REF_DECL (p->symbol))
399 mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
401 real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
403 id = maybe_get_identifier (real_name);
405 mark_referenced (id);
409 /* Transform ORIG, which may be any data source, to the corresponding
410 source using indirections. */
413 machopic_indirect_data_reference (rtx orig, rtx reg)
417 if (! MACHOPIC_INDIRECT)
420 if (GET_CODE (orig) == SYMBOL_REF)
422 int defined = machopic_data_defined_p (orig);
424 if (defined && MACHO_DYNAMIC_NO_PIC_P)
426 #if defined (TARGET_TOC)
427 emit_insn (gen_macho_high (reg, orig));
428 emit_insn (gen_macho_low (reg, reg, orig));
430 /* some other cpu -- writeme! */
437 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
438 rtx pic_base = machopic_function_base_sym ();
439 rtx offset = gen_rtx_CONST (Pmode,
440 gen_rtx_MINUS (Pmode, orig, pic_base));
443 #if defined (TARGET_TOC) /* i.e., PowerPC */
444 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
449 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
450 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
451 gen_rtx_HIGH (Pmode, offset))));
452 emit_insn (gen_rtx_SET (Pmode, reg,
453 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
457 #if defined (HAVE_lo_sum)
458 if (reg == 0) abort ();
460 emit_insn (gen_rtx_SET (VOIDmode, reg,
461 gen_rtx_HIGH (Pmode, offset)));
462 emit_insn (gen_rtx_SET (VOIDmode, reg,
463 gen_rtx_LO_SUM (Pmode, reg, offset)));
464 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
466 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
472 ptr_ref = (gen_rtx_SYMBOL_REF
474 machopic_indirection_name (orig, /*stub_p=*/false)));
476 SYMBOL_REF_DECL (ptr_ref) = SYMBOL_REF_DECL (orig);
478 ptr_ref = gen_const_mem (Pmode, ptr_ref);
479 machopic_define_symbol (ptr_ref);
483 else if (GET_CODE (orig) == CONST)
487 /* legitimize both operands of the PLUS */
488 if (GET_CODE (XEXP (orig, 0)) == PLUS)
490 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
492 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
493 (base == reg ? 0 : reg));
498 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
499 result = plus_constant (base, INTVAL (orig));
501 result = gen_rtx_PLUS (Pmode, base, orig);
503 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
507 emit_move_insn (reg, result);
512 result = force_reg (GET_MODE (result), result);
519 else if (GET_CODE (orig) == MEM)
520 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
521 /* When the target is i386, this code prevents crashes due to the
522 compiler's ignorance on how to move the PIC base register to
523 other registers. (The reload phase sometimes introduces such
525 else if (GET_CODE (orig) == PLUS
526 && GET_CODE (XEXP (orig, 0)) == REG
527 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
529 /* Prevent the same register from being erroneously used
530 as both the base and index registers. */
531 && GET_CODE (XEXP (orig, 1)) == CONST
535 emit_move_insn (reg, XEXP (orig, 0));
536 XEXP (ptr_ref, 0) = reg;
541 /* Transform TARGET (a MEM), which is a function call target, to the
542 corresponding symbol_stub if necessary. Return a new MEM. */
545 machopic_indirect_call_target (rtx target)
547 if (GET_CODE (target) != MEM)
550 if (MACHOPIC_INDIRECT
551 && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
552 && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
553 & MACHO_SYMBOL_FLAG_DEFINED))
555 rtx sym_ref = XEXP (target, 0);
556 const char *stub_name = machopic_indirection_name (sym_ref,
558 enum machine_mode mode = GET_MODE (sym_ref);
559 tree decl = SYMBOL_REF_DECL (sym_ref);
561 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
562 SYMBOL_REF_DECL (XEXP (target, 0)) = decl;
563 MEM_READONLY_P (target) = 1;
564 MEM_NOTRAP_P (target) = 1;
571 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
575 if (! MACHOPIC_INDIRECT)
578 /* First handle a simple SYMBOL_REF or LABEL_REF */
579 if (GET_CODE (orig) == LABEL_REF
580 || (GET_CODE (orig) == SYMBOL_REF
583 /* addr(foo) = &func+(foo-func) */
586 orig = machopic_indirect_data_reference (orig, reg);
588 if (GET_CODE (orig) == PLUS
589 && GET_CODE (XEXP (orig, 0)) == REG)
592 return force_reg (mode, orig);
594 emit_move_insn (reg, orig);
598 /* if dynamic-no-pic then use 0 as the pic base */
599 if (MACHO_DYNAMIC_NO_PIC_P)
600 pic_base = CONST0_RTX (Pmode);
602 pic_base = machopic_function_base_sym ();
604 if (GET_CODE (orig) == MEM)
608 if (reload_in_progress)
611 reg = gen_reg_rtx (Pmode);
615 if (MACHO_DYNAMIC_NO_PIC_P
616 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
617 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
619 #if defined (TARGET_TOC) /* ppc */
620 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
621 rtx asym = XEXP (orig, 0);
624 emit_insn (gen_macho_high (temp_reg, asym));
625 mem = gen_const_mem (GET_MODE (orig),
626 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
627 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
629 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
635 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
636 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
638 rtx offset = gen_rtx_CONST (Pmode,
639 gen_rtx_MINUS (Pmode,
642 #if defined (TARGET_TOC) /* i.e., PowerPC */
643 /* Generating a new reg may expose opportunities for
644 common subexpression elimination. */
645 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
650 sum = gen_rtx_HIGH (Pmode, offset);
651 if (! MACHO_DYNAMIC_NO_PIC_P)
652 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
654 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
656 mem = gen_const_mem (GET_MODE (orig),
657 gen_rtx_LO_SUM (Pmode,
658 hi_sum_reg, offset));
659 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
660 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
665 emit_insn (gen_rtx_USE (VOIDmode,
667 PIC_OFFSET_TABLE_REGNUM)));
669 emit_insn (gen_rtx_SET (VOIDmode, reg,
671 gen_rtx_CONST (Pmode,
673 emit_insn (gen_rtx_SET (VOIDmode, reg,
674 gen_rtx_LO_SUM (Pmode, reg,
675 gen_rtx_CONST (Pmode, offset))));
676 pic_ref = gen_rtx_PLUS (Pmode,
677 pic_offset_table_rtx, reg);
681 #endif /* HAVE_lo_sum */
683 rtx pic = pic_offset_table_rtx;
684 if (GET_CODE (pic) != REG)
686 emit_move_insn (reg, pic);
690 emit_insn (gen_rtx_USE (VOIDmode,
692 PIC_OFFSET_TABLE_REGNUM)));
695 pic_ref = gen_rtx_PLUS (Pmode,
697 gen_rtx_CONST (Pmode,
698 gen_rtx_MINUS (Pmode,
703 #if !defined (TARGET_TOC)
704 emit_move_insn (reg, pic_ref);
705 pic_ref = gen_const_mem (GET_MODE (orig), reg);
712 if (GET_CODE (orig) == SYMBOL_REF
713 || GET_CODE (orig) == LABEL_REF)
715 rtx offset = gen_rtx_CONST (Pmode,
716 gen_rtx_MINUS (Pmode,
718 #if defined (TARGET_TOC) /* i.e., PowerPC */
723 if (reload_in_progress)
726 reg = gen_reg_rtx (Pmode);
731 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
732 (MACHO_DYNAMIC_NO_PIC_P)
733 ? gen_rtx_HIGH (Pmode, offset)
734 : gen_rtx_PLUS (Pmode,
735 pic_offset_table_rtx,
738 emit_insn (gen_rtx_SET (VOIDmode, reg,
739 gen_rtx_LO_SUM (Pmode,
740 hi_sum_reg, offset)));
743 emit_insn (gen_rtx_SET (VOIDmode, reg,
744 gen_rtx_HIGH (Pmode, offset)));
745 emit_insn (gen_rtx_SET (VOIDmode, reg,
746 gen_rtx_LO_SUM (Pmode, reg, offset)));
747 pic_ref = gen_rtx_PLUS (Pmode,
748 pic_offset_table_rtx, reg);
752 #endif /* HAVE_lo_sum */
755 || GET_CODE (orig) == SUBREG)
761 rtx pic = pic_offset_table_rtx;
762 if (GET_CODE (pic) != REG)
764 emit_move_insn (reg, pic);
768 emit_insn (gen_rtx_USE (VOIDmode,
769 pic_offset_table_rtx));
771 pic_ref = gen_rtx_PLUS (Pmode,
773 gen_rtx_CONST (Pmode,
774 gen_rtx_MINUS (Pmode,
780 if (GET_CODE (pic_ref) != REG)
784 emit_move_insn (reg, pic_ref);
789 return force_reg (mode, pic_ref);
798 else if (GET_CODE (orig) == SYMBOL_REF)
801 else if (GET_CODE (orig) == PLUS
802 && (GET_CODE (XEXP (orig, 0)) == MEM
803 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
804 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
805 && XEXP (orig, 0) != pic_offset_table_rtx
806 && GET_CODE (XEXP (orig, 1)) != REG)
810 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
812 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
813 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
814 Pmode, (base == reg ? 0 : reg));
815 if (GET_CODE (orig) == CONST_INT)
817 pic_ref = plus_constant (base, INTVAL (orig));
821 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
823 if (reg && is_complex)
825 emit_move_insn (reg, pic_ref);
828 /* Likewise, should we set special REG_NOTEs here? */
831 else if (GET_CODE (orig) == CONST)
833 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
836 else if (GET_CODE (orig) == MEM
837 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
839 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
840 addr = replace_equiv_address (orig, addr);
841 emit_move_insn (reg, addr);
848 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
849 DATA is the FILE* for assembly output. Called from
853 machopic_output_indirection (void **slot, void *data)
855 machopic_indirection *p = *((machopic_indirection **) slot);
856 FILE *asm_out_file = (FILE *) data;
858 const char *sym_name;
859 const char *ptr_name;
865 sym_name = XSTR (symbol, 0);
866 ptr_name = p->ptr_name;
873 sym = alloca (strlen (sym_name) + 2);
874 if (sym_name[0] == '*' || sym_name[0] == '&')
875 strcpy (sym, sym_name + 1);
876 else if (sym_name[0] == '-' || sym_name[0] == '+')
877 strcpy (sym, sym_name);
879 sprintf (sym, "%s%s", user_label_prefix, sym_name);
881 stub = alloca (strlen (ptr_name) + 2);
882 if (ptr_name[0] == '*' || ptr_name[0] == '&')
883 strcpy (stub, ptr_name + 1);
885 sprintf (stub, "%s%s", user_label_prefix, ptr_name);
887 machopic_output_stub (asm_out_file, sym, stub);
889 else if (! indirect_data (symbol)
890 && (machopic_symbol_defined_p (symbol)
891 || SYMBOL_REF_LOCAL_P (symbol)))
894 assemble_align (GET_MODE_ALIGNMENT (Pmode));
895 assemble_label (ptr_name);
896 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
897 GET_MODE_SIZE (Pmode),
898 GET_MODE_ALIGNMENT (Pmode), 1);
902 rtx init = const0_rtx;
904 machopic_nl_symbol_ptr_section ();
905 assemble_name (asm_out_file, ptr_name);
906 fprintf (asm_out_file, ":\n");
908 fprintf (asm_out_file, "\t.indirect_symbol ");
909 assemble_name (asm_out_file, sym_name);
910 fprintf (asm_out_file, "\n");
912 /* Variables that are marked with MACHO_SYMBOL_STATIC need to
913 have their symbol name instead of 0 in the second entry of
914 the non-lazy symbol pointer data structure when they are
915 defined. This allows the runtime to rebind newer instances
916 of the translation unit with the original instance of the
919 if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
920 && machopic_symbol_defined_p (symbol))
921 init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
923 assemble_integer (init, GET_MODE_SIZE (Pmode),
924 GET_MODE_ALIGNMENT (Pmode), 1);
931 machopic_finish (FILE *asm_out_file)
933 if (machopic_indirections)
934 htab_traverse_noresize (machopic_indirections,
935 machopic_output_indirection,
940 machopic_operand_p (rtx op)
942 if (MACHOPIC_JUST_INDIRECT)
944 while (GET_CODE (op) == CONST)
947 if (GET_CODE (op) == SYMBOL_REF)
948 return machopic_symbol_defined_p (op);
953 while (GET_CODE (op) == CONST)
956 if (GET_CODE (op) == MINUS
957 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
958 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
959 && machopic_symbol_defined_p (XEXP (op, 0))
960 && machopic_symbol_defined_p (XEXP (op, 1)))
966 /* This function records whether a given name corresponds to a defined
967 or undefined function or variable, for machopic_classify_ident to
971 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
975 /* Do the standard encoding things first. */
976 default_encode_section_info (decl, rtl, first);
978 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
981 sym_ref = XEXP (rtl, 0);
982 if (TREE_CODE (decl) == VAR_DECL)
983 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
985 if (!DECL_EXTERNAL (decl)
986 && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
987 && ((TREE_STATIC (decl)
988 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
989 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
990 && DECL_INITIAL (decl) != error_mark_node)))
991 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
993 if (TREE_CODE (decl) == VAR_DECL
994 && indirect_data (sym_ref)
995 && ! TREE_PUBLIC (decl))
996 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
1000 darwin_mark_decl_preserved (const char *name)
1002 fprintf (asm_out_file, ".no_dead_strip ");
1003 assemble_name (asm_out_file, name);
1004 fputc ('\n', asm_out_file);
1008 machopic_select_section (tree exp, int reloc,
1009 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1011 void (*base_function)(void);
1012 bool weak_p = DECL_P (exp) && DECL_WEAK (exp);
1013 static void (* const base_funs[][2])(void) = {
1014 { text_section, text_coal_section },
1015 { unlikely_text_section, text_unlikely_coal_section },
1016 { readonly_data_section, const_coal_section },
1017 { const_data_section, const_data_coal_section },
1018 { data_section, data_coal_section }
1022 && (last_text_section == in_text_unlikely
1023 || last_text_section == in_text_unlikely_coal))
1026 if (TREE_CODE (exp) == FUNCTION_DECL)
1027 base_function = base_funs[reloc][weak_p];
1028 else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1029 base_function = base_funs[2][weak_p];
1030 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1031 base_function = base_funs[3][weak_p];
1033 base_function = base_funs[4][weak_p];
1035 if (TREE_CODE (exp) == STRING_CST
1036 && ((size_t) TREE_STRING_LENGTH (exp)
1037 == strlen (TREE_STRING_POINTER (exp)) + 1))
1039 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1040 && flag_merge_constants)
1042 tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1044 if (TREE_CODE (size) == INTEGER_CST &&
1045 TREE_INT_CST_LOW (size) == 4 &&
1046 TREE_INT_CST_HIGH (size) == 0)
1047 literal4_section ();
1048 else if (TREE_CODE (size) == INTEGER_CST &&
1049 TREE_INT_CST_LOW (size) == 8 &&
1050 TREE_INT_CST_HIGH (size) == 0)
1051 literal8_section ();
1055 else if (TREE_CODE (exp) == CONSTRUCTOR
1057 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1058 && TYPE_NAME (TREE_TYPE (exp)))
1060 tree name = TYPE_NAME (TREE_TYPE (exp));
1061 if (TREE_CODE (name) == TYPE_DECL)
1062 name = DECL_NAME (name);
1063 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1064 objc_constant_string_object_section ();
1065 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1066 objc_string_object_section ();
1070 else if (TREE_CODE (exp) == VAR_DECL &&
1072 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1073 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1074 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1076 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1078 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1079 objc_cls_meth_section ();
1080 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1081 objc_inst_meth_section ();
1082 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1083 objc_cat_cls_meth_section ();
1084 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1085 objc_cat_inst_meth_section ();
1086 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1087 objc_class_vars_section ();
1088 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1089 objc_instance_vars_section ();
1090 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1091 objc_cat_cls_meth_section ();
1092 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1093 objc_class_names_section ();
1094 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1095 objc_meth_var_names_section ();
1096 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1097 objc_meth_var_types_section ();
1098 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1099 objc_cls_refs_section ();
1100 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1101 objc_class_section ();
1102 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1103 objc_meta_class_section ();
1104 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1105 objc_category_section ();
1106 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1107 objc_selector_refs_section ();
1108 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1109 objc_selector_fixup_section ();
1110 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1111 objc_symbols_section ();
1112 else if (!strncmp (name, "_OBJC_MODULES", 13))
1113 objc_module_info_section ();
1114 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1115 objc_image_info_section ();
1116 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1117 objc_cat_inst_meth_section ();
1118 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1119 objc_cat_cls_meth_section ();
1120 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1121 objc_cat_cls_meth_section ();
1122 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1123 objc_protocol_section ();
1127 /* ::operator new and ::operator delete must be coalesced, even
1128 if not weak. There are 8 variants that we look for. */
1129 else if (TREE_CODE (exp) == FUNCTION_DECL
1130 && ! DECL_ONE_ONLY (exp))
1132 const char * name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (exp));
1133 if (name[0] == '_' && name[1] == 'Z'
1134 && ((name[2] == 'n' && (name[3] == 'a' || name[3] == 'w')
1136 || (name[2] == 'd' && (name[3] == 'a' || name[3] == 'l')
1137 && name[4] == 'P' && name[5] == 'v')))
1139 bool delete_p = name[2] == 'd';
1140 if (name[5 + delete_p] == 0
1141 || strcmp (name + 5 + delete_p, "KSt9nothrow_t") == 0)
1142 base_funs[reloc][1] ();
1153 /* This can be called with address expressions as "rtx".
1154 They must go in "const". */
1157 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1158 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1160 if (GET_MODE_SIZE (mode) == 8
1161 && (GET_CODE (x) == CONST_INT
1162 || GET_CODE (x) == CONST_DOUBLE))
1163 literal8_section ();
1164 else if (GET_MODE_SIZE (mode) == 4
1165 && (GET_CODE (x) == CONST_INT
1166 || GET_CODE (x) == CONST_DOUBLE))
1167 literal4_section ();
1168 else if (MACHOPIC_INDIRECT
1169 && (GET_CODE (x) == SYMBOL_REF
1170 || GET_CODE (x) == CONST
1171 || GET_CODE (x) == LABEL_REF))
1172 const_data_section ();
1178 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1180 if (MACHOPIC_INDIRECT)
1181 mod_init_section ();
1183 constructor_section ();
1184 assemble_align (POINTER_SIZE);
1185 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1187 if (! MACHOPIC_INDIRECT)
1188 fprintf (asm_out_file, ".reference .constructors_used\n");
1192 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1194 if (MACHOPIC_INDIRECT)
1195 mod_term_section ();
1197 destructor_section ();
1198 assemble_align (POINTER_SIZE);
1199 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1201 if (! MACHOPIC_INDIRECT)
1202 fprintf (asm_out_file, ".reference .destructors_used\n");
1206 darwin_globalize_label (FILE *stream, const char *name)
1208 if (!!strncmp (name, "_OBJC_", 6))
1209 default_globalize_label (stream, name);
1213 darwin_asm_named_section (const char *name,
1214 unsigned int flags ATTRIBUTE_UNUSED,
1215 tree decl ATTRIBUTE_UNUSED)
1217 fprintf (asm_out_file, "\t.section %s\n", name);
1221 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1223 /* Darwin does not use unique sections. */
1226 /* Handle a "weak_import" attribute; arguments as in
1227 struct attribute_spec.handler. */
1230 darwin_handle_weak_import_attribute (tree *node, tree name,
1231 tree ARG_UNUSED (args),
1232 int ARG_UNUSED (flags),
1233 bool * no_add_attrs)
1235 if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1237 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
1238 *no_add_attrs = true;
1241 declare_weak (*node);
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. */
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)
1264 const char *prefix = "_";
1265 const int prefix_len = 1;
1267 const char *base = IDENTIFIER_POINTER (id);
1268 unsigned int base_len = IDENTIFIER_LENGTH (id);
1270 const char *suffix = ".eh";
1272 int need_quotes = name_needs_quotes (base);
1273 int quotes_len = need_quotes ? 2 : 0;
1279 lab = xmalloc (prefix_len + base_len + strlen (suffix) + quotes_len + 1);
1284 strcat(lab, prefix);
1286 strcat(lab, suffix);
1290 if (TREE_PUBLIC (decl))
1291 fprintf (file, "\t%s %s\n",
1292 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1294 : ".private_extern"),
1297 if (DECL_WEAK (decl))
1298 fprintf (file, "\t.weak_definition %s\n", lab);
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);
1311 fprintf (file, "%s:\n", lab);
1316 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1319 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1321 const char *nlp_name;
1323 if (GET_CODE (addr) != SYMBOL_REF)
1326 nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1327 fputs ("\t.long\t", file);
1328 ASM_OUTPUT_LABELREF (file, nlp_name);
1332 /* Emit an assembler directive to set visibility for a symbol. The
1333 only supported visibilities are VISIBILITY_DEFAULT and
1334 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1335 extern". There is no MACH-O equivalent of ELF's
1336 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1339 darwin_assemble_visibility (tree decl, int vis)
1341 if (vis == VISIBILITY_DEFAULT)
1343 else if (vis == VISIBILITY_HIDDEN)
1345 fputs ("\t.private_extern ", asm_out_file);
1346 assemble_name (asm_out_file,
1347 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1348 fputs ("\n", asm_out_file);
1351 warning ("internal and protected visibility attributes not supported "
1352 "in this configuration; ignored");
1355 /* Output a difference of two labels that will be an assembly time
1356 constant if the two labels are local. (.long lab1-lab2 will be
1357 very different if lab1 is at the boundary between two sections; it
1358 will be relocated according to the second section, not the first,
1359 so one ends up with a difference between labels in different
1360 sections, which is bad in the dwarf2 eh context for instance.) */
1362 static int darwin_dwarf_label_counter;
1365 darwin_asm_output_dwarf_delta (FILE *file, int size,
1366 const char *lab1, const char *lab2)
1368 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1369 && lab2[0] == '*' && lab2[1] == 'L');
1370 const char *directive = (size == 8 ? ".quad" : ".long");
1373 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1375 fprintf (file, "\t%s\t", directive);
1376 assemble_name_raw (file, lab1);
1377 fprintf (file, "-");
1378 assemble_name_raw (file, lab2);
1380 fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1384 darwin_file_end (void)
1386 machopic_finish (asm_out_file);
1387 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1389 constructor_section ();
1390 destructor_section ();
1391 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1393 fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1396 #include "gt-darwin.h"