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;
305 bool saw_star = false;
308 const char *prefix = user_label_prefix;
309 const char *quote = "";
319 needs_quotes = name_needs_quotes (name);
326 suffix = STUB_SUFFIX;
328 suffix = NON_LAZY_POINTER_SUFFIX;
330 buffer = alloca (strlen ("&L")
337 /* Construct the name of the non-lazy pointer or stub. */
338 sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
340 if (!machopic_indirections)
341 machopic_indirections = htab_create_ggc (37,
342 machopic_indirection_hash,
343 machopic_indirection_eq,
346 slot = htab_find_slot_with_hash (machopic_indirections, buffer,
347 htab_hash_string (buffer), INSERT);
350 p = (machopic_indirection *) *slot;
354 p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
356 p->ptr_name = xstrdup (buffer);
365 /* Return the name of the stub for the mcount function. */
368 machopic_mcount_stub_name (void)
370 rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
371 return machopic_indirection_name (symbol, /*stub_p=*/true);
374 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
375 or non-lazy pointer as used -- and mark the object to which the
376 pointer/stub refers as used as well, since the pointer/stub will
377 emit a reference to it. */
380 machopic_validate_stub_or_non_lazy_ptr (const char *name)
382 machopic_indirection *p;
384 p = ((machopic_indirection *)
385 (htab_find_with_hash (machopic_indirections, name,
386 htab_hash_string (name))));
389 const char *real_name;
394 /* Do what output_addr_const will do when we actually call it. */
395 if (SYMBOL_REF_DECL (p->symbol))
396 mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
398 real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
400 id = maybe_get_identifier (real_name);
402 mark_referenced (id);
406 /* Transform ORIG, which may be any data source, to the corresponding
407 source using indirections. */
410 machopic_indirect_data_reference (rtx orig, rtx reg)
414 if (! MACHOPIC_INDIRECT)
417 if (GET_CODE (orig) == SYMBOL_REF)
419 int defined = machopic_data_defined_p (orig);
421 if (defined && MACHO_DYNAMIC_NO_PIC_P)
423 #if defined (TARGET_TOC)
424 emit_insn (gen_macho_high (reg, orig));
425 emit_insn (gen_macho_low (reg, reg, orig));
427 /* some other cpu -- writeme! */
434 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
435 rtx pic_base = machopic_function_base_sym ();
436 rtx offset = gen_rtx_CONST (Pmode,
437 gen_rtx_MINUS (Pmode, orig, pic_base));
440 #if defined (TARGET_TOC) /* i.e., PowerPC */
441 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
446 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
447 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
448 gen_rtx_HIGH (Pmode, offset))));
449 emit_insn (gen_rtx_SET (Pmode, reg,
450 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
454 #if defined (HAVE_lo_sum)
455 if (reg == 0) abort ();
457 emit_insn (gen_rtx_SET (VOIDmode, reg,
458 gen_rtx_HIGH (Pmode, offset)));
459 emit_insn (gen_rtx_SET (VOIDmode, reg,
460 gen_rtx_LO_SUM (Pmode, reg, offset)));
461 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
463 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
469 ptr_ref = (gen_rtx_SYMBOL_REF
471 machopic_indirection_name (orig, /*stub_p=*/false)));
473 SYMBOL_REF_DECL (ptr_ref) = SYMBOL_REF_DECL (orig);
475 ptr_ref = gen_const_mem (Pmode, ptr_ref);
476 machopic_define_symbol (ptr_ref);
480 else if (GET_CODE (orig) == CONST)
484 /* legitimize both operands of the PLUS */
485 if (GET_CODE (XEXP (orig, 0)) == PLUS)
487 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
489 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
490 (base == reg ? 0 : reg));
495 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
496 result = plus_constant (base, INTVAL (orig));
498 result = gen_rtx_PLUS (Pmode, base, orig);
500 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
504 emit_move_insn (reg, result);
509 result = force_reg (GET_MODE (result), result);
516 else if (GET_CODE (orig) == MEM)
517 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
518 /* When the target is i386, this code prevents crashes due to the
519 compiler's ignorance on how to move the PIC base register to
520 other registers. (The reload phase sometimes introduces such
522 else if (GET_CODE (orig) == PLUS
523 && GET_CODE (XEXP (orig, 0)) == REG
524 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
526 /* Prevent the same register from being erroneously used
527 as both the base and index registers. */
528 && GET_CODE (XEXP (orig, 1)) == CONST
532 emit_move_insn (reg, XEXP (orig, 0));
533 XEXP (ptr_ref, 0) = reg;
538 /* Transform TARGET (a MEM), which is a function call target, to the
539 corresponding symbol_stub if necessary. Return a new MEM. */
542 machopic_indirect_call_target (rtx target)
544 if (GET_CODE (target) != MEM)
547 if (MACHOPIC_INDIRECT
548 && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
549 && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
550 & MACHO_SYMBOL_FLAG_DEFINED))
552 rtx sym_ref = XEXP (target, 0);
553 const char *stub_name = machopic_indirection_name (sym_ref,
555 enum machine_mode mode = GET_MODE (sym_ref);
556 tree decl = SYMBOL_REF_DECL (sym_ref);
558 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
559 SYMBOL_REF_DECL (XEXP (target, 0)) = decl;
560 MEM_READONLY_P (target) = 1;
561 MEM_NOTRAP_P (target) = 1;
568 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
572 if (! MACHOPIC_INDIRECT)
575 /* First handle a simple SYMBOL_REF or LABEL_REF */
576 if (GET_CODE (orig) == LABEL_REF
577 || (GET_CODE (orig) == SYMBOL_REF
580 /* addr(foo) = &func+(foo-func) */
583 orig = machopic_indirect_data_reference (orig, reg);
585 if (GET_CODE (orig) == PLUS
586 && GET_CODE (XEXP (orig, 0)) == REG)
589 return force_reg (mode, orig);
591 emit_move_insn (reg, orig);
595 /* if dynamic-no-pic then use 0 as the pic base */
596 if (MACHO_DYNAMIC_NO_PIC_P)
597 pic_base = CONST0_RTX (Pmode);
599 pic_base = machopic_function_base_sym ();
601 if (GET_CODE (orig) == MEM)
605 if (reload_in_progress)
608 reg = gen_reg_rtx (Pmode);
612 if (MACHO_DYNAMIC_NO_PIC_P
613 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
614 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
616 #if defined (TARGET_TOC) /* ppc */
617 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
618 rtx asym = XEXP (orig, 0);
621 emit_insn (gen_macho_high (temp_reg, asym));
622 mem = gen_const_mem (GET_MODE (orig),
623 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
624 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
626 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
632 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
633 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
635 rtx offset = gen_rtx_CONST (Pmode,
636 gen_rtx_MINUS (Pmode,
639 #if defined (TARGET_TOC) /* i.e., PowerPC */
640 /* Generating a new reg may expose opportunities for
641 common subexpression elimination. */
642 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
647 sum = gen_rtx_HIGH (Pmode, offset);
648 if (! MACHO_DYNAMIC_NO_PIC_P)
649 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
651 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
653 mem = gen_const_mem (GET_MODE (orig),
654 gen_rtx_LO_SUM (Pmode,
655 hi_sum_reg, offset));
656 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
657 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
662 emit_insn (gen_rtx_USE (VOIDmode,
664 PIC_OFFSET_TABLE_REGNUM)));
666 emit_insn (gen_rtx_SET (VOIDmode, reg,
668 gen_rtx_CONST (Pmode,
670 emit_insn (gen_rtx_SET (VOIDmode, reg,
671 gen_rtx_LO_SUM (Pmode, reg,
672 gen_rtx_CONST (Pmode, offset))));
673 pic_ref = gen_rtx_PLUS (Pmode,
674 pic_offset_table_rtx, reg);
678 #endif /* HAVE_lo_sum */
680 rtx pic = pic_offset_table_rtx;
681 if (GET_CODE (pic) != REG)
683 emit_move_insn (reg, pic);
687 emit_insn (gen_rtx_USE (VOIDmode,
689 PIC_OFFSET_TABLE_REGNUM)));
692 pic_ref = gen_rtx_PLUS (Pmode,
694 gen_rtx_CONST (Pmode,
695 gen_rtx_MINUS (Pmode,
700 #if !defined (TARGET_TOC)
701 emit_move_insn (reg, pic_ref);
702 pic_ref = gen_const_mem (GET_MODE (orig), reg);
709 if (GET_CODE (orig) == SYMBOL_REF
710 || GET_CODE (orig) == LABEL_REF)
712 rtx offset = gen_rtx_CONST (Pmode,
713 gen_rtx_MINUS (Pmode,
715 #if defined (TARGET_TOC) /* i.e., PowerPC */
720 if (reload_in_progress)
723 reg = gen_reg_rtx (Pmode);
728 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
729 (MACHO_DYNAMIC_NO_PIC_P)
730 ? gen_rtx_HIGH (Pmode, offset)
731 : gen_rtx_PLUS (Pmode,
732 pic_offset_table_rtx,
735 emit_insn (gen_rtx_SET (VOIDmode, reg,
736 gen_rtx_LO_SUM (Pmode,
737 hi_sum_reg, offset)));
740 emit_insn (gen_rtx_SET (VOIDmode, reg,
741 gen_rtx_HIGH (Pmode, offset)));
742 emit_insn (gen_rtx_SET (VOIDmode, reg,
743 gen_rtx_LO_SUM (Pmode, reg, offset)));
744 pic_ref = gen_rtx_PLUS (Pmode,
745 pic_offset_table_rtx, reg);
749 #endif /* HAVE_lo_sum */
752 || GET_CODE (orig) == SUBREG)
758 rtx pic = pic_offset_table_rtx;
759 if (GET_CODE (pic) != REG)
761 emit_move_insn (reg, pic);
765 emit_insn (gen_rtx_USE (VOIDmode,
766 pic_offset_table_rtx));
768 pic_ref = gen_rtx_PLUS (Pmode,
770 gen_rtx_CONST (Pmode,
771 gen_rtx_MINUS (Pmode,
777 if (GET_CODE (pic_ref) != REG)
781 emit_move_insn (reg, pic_ref);
786 return force_reg (mode, pic_ref);
795 else if (GET_CODE (orig) == SYMBOL_REF)
798 else if (GET_CODE (orig) == PLUS
799 && (GET_CODE (XEXP (orig, 0)) == MEM
800 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
801 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
802 && XEXP (orig, 0) != pic_offset_table_rtx
803 && GET_CODE (XEXP (orig, 1)) != REG)
807 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
809 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
810 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
811 Pmode, (base == reg ? 0 : reg));
812 if (GET_CODE (orig) == CONST_INT)
814 pic_ref = plus_constant (base, INTVAL (orig));
818 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
820 if (reg && is_complex)
822 emit_move_insn (reg, pic_ref);
825 /* Likewise, should we set special REG_NOTEs here? */
828 else if (GET_CODE (orig) == CONST)
830 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
833 else if (GET_CODE (orig) == MEM
834 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
836 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
837 addr = replace_equiv_address (orig, addr);
838 emit_move_insn (reg, addr);
845 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
846 DATA is the FILE* for assembly output. Called from
850 machopic_output_indirection (void **slot, void *data)
852 machopic_indirection *p = *((machopic_indirection **) slot);
853 FILE *asm_out_file = (FILE *) data;
855 const char *sym_name;
856 const char *ptr_name;
862 sym_name = XSTR (symbol, 0);
863 ptr_name = p->ptr_name;
870 sym = alloca (strlen (sym_name) + 2);
871 if (sym_name[0] == '*' || sym_name[0] == '&')
872 strcpy (sym, sym_name + 1);
873 else if (sym_name[0] == '-' || sym_name[0] == '+')
874 strcpy (sym, sym_name);
876 sprintf (sym, "%s%s", user_label_prefix, sym_name);
878 stub = alloca (strlen (ptr_name) + 2);
879 if (ptr_name[0] == '*' || ptr_name[0] == '&')
880 strcpy (stub, ptr_name + 1);
882 sprintf (stub, "%s%s", user_label_prefix, ptr_name);
884 machopic_output_stub (asm_out_file, sym, stub);
886 else if (! indirect_data (symbol)
887 && (machopic_symbol_defined_p (symbol)
888 || SYMBOL_REF_LOCAL_P (symbol)))
891 assemble_align (GET_MODE_ALIGNMENT (Pmode));
892 assemble_label (ptr_name);
893 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
894 GET_MODE_SIZE (Pmode),
895 GET_MODE_ALIGNMENT (Pmode), 1);
899 rtx init = const0_rtx;
901 machopic_nl_symbol_ptr_section ();
902 assemble_name (asm_out_file, ptr_name);
903 fprintf (asm_out_file, ":\n");
905 fprintf (asm_out_file, "\t.indirect_symbol ");
906 assemble_name (asm_out_file, sym_name);
907 fprintf (asm_out_file, "\n");
909 /* Variables that are marked with MACHO_SYMBOL_STATIC need to
910 have their symbol name instead of 0 in the second entry of
911 the non-lazy symbol pointer data structure when they are
912 defined. This allows the runtime to rebind newer instances
913 of the translation unit with the original instance of the
916 if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
917 && machopic_symbol_defined_p (symbol))
918 init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
920 assemble_integer (init, GET_MODE_SIZE (Pmode),
921 GET_MODE_ALIGNMENT (Pmode), 1);
928 machopic_finish (FILE *asm_out_file)
930 if (machopic_indirections)
931 htab_traverse_noresize (machopic_indirections,
932 machopic_output_indirection,
937 machopic_operand_p (rtx op)
939 if (MACHOPIC_JUST_INDIRECT)
941 while (GET_CODE (op) == CONST)
944 if (GET_CODE (op) == SYMBOL_REF)
945 return machopic_symbol_defined_p (op);
950 while (GET_CODE (op) == CONST)
953 if (GET_CODE (op) == MINUS
954 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
955 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
956 && machopic_symbol_defined_p (XEXP (op, 0))
957 && machopic_symbol_defined_p (XEXP (op, 1)))
963 /* This function records whether a given name corresponds to a defined
964 or undefined function or variable, for machopic_classify_ident to
968 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
972 /* Do the standard encoding things first. */
973 default_encode_section_info (decl, rtl, first);
975 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
978 sym_ref = XEXP (rtl, 0);
979 if (TREE_CODE (decl) == VAR_DECL)
980 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
982 if (!DECL_EXTERNAL (decl)
983 && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
984 && ((TREE_STATIC (decl)
985 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
986 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
987 && DECL_INITIAL (decl) != error_mark_node)))
988 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
990 if (TREE_CODE (decl) == VAR_DECL
991 && indirect_data (sym_ref)
992 && ! TREE_PUBLIC (decl))
993 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
997 darwin_mark_decl_preserved (const char *name)
999 fprintf (asm_out_file, ".no_dead_strip ");
1000 assemble_name (asm_out_file, name);
1001 fputc ('\n', asm_out_file);
1005 machopic_select_section (tree exp, int reloc,
1006 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1008 void (*base_function)(void);
1009 bool weak_p = DECL_P (exp) && DECL_WEAK (exp);
1010 static void (* const base_funs[][2])(void) = {
1011 { text_section, text_coal_section },
1012 { unlikely_text_section, text_unlikely_coal_section },
1013 { readonly_data_section, const_coal_section },
1014 { const_data_section, const_data_coal_section },
1015 { data_section, data_coal_section }
1019 && (last_text_section == in_text_unlikely
1020 || last_text_section == in_text_unlikely_coal))
1023 if (TREE_CODE (exp) == FUNCTION_DECL)
1024 base_function = base_funs[reloc][weak_p];
1025 else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1026 base_function = base_funs[2][weak_p];
1027 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1028 base_function = base_funs[3][weak_p];
1030 base_function = base_funs[4][weak_p];
1032 if (TREE_CODE (exp) == STRING_CST
1033 && ((size_t) TREE_STRING_LENGTH (exp)
1034 == strlen (TREE_STRING_POINTER (exp)) + 1))
1036 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1037 && flag_merge_constants)
1039 tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1041 if (TREE_CODE (size) == INTEGER_CST &&
1042 TREE_INT_CST_LOW (size) == 4 &&
1043 TREE_INT_CST_HIGH (size) == 0)
1044 literal4_section ();
1045 else if (TREE_CODE (size) == INTEGER_CST &&
1046 TREE_INT_CST_LOW (size) == 8 &&
1047 TREE_INT_CST_HIGH (size) == 0)
1048 literal8_section ();
1052 else if (TREE_CODE (exp) == CONSTRUCTOR
1054 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1055 && TYPE_NAME (TREE_TYPE (exp)))
1057 tree name = TYPE_NAME (TREE_TYPE (exp));
1058 if (TREE_CODE (name) == TYPE_DECL)
1059 name = DECL_NAME (name);
1060 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1061 objc_constant_string_object_section ();
1062 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1063 objc_string_object_section ();
1067 else if (TREE_CODE (exp) == VAR_DECL &&
1069 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1070 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1071 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1073 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1075 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1076 objc_cls_meth_section ();
1077 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1078 objc_inst_meth_section ();
1079 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1080 objc_cat_cls_meth_section ();
1081 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1082 objc_cat_inst_meth_section ();
1083 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1084 objc_class_vars_section ();
1085 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1086 objc_instance_vars_section ();
1087 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1088 objc_cat_cls_meth_section ();
1089 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1090 objc_class_names_section ();
1091 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1092 objc_meth_var_names_section ();
1093 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1094 objc_meth_var_types_section ();
1095 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1096 objc_cls_refs_section ();
1097 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1098 objc_class_section ();
1099 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1100 objc_meta_class_section ();
1101 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1102 objc_category_section ();
1103 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1104 objc_selector_refs_section ();
1105 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1106 objc_selector_fixup_section ();
1107 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1108 objc_symbols_section ();
1109 else if (!strncmp (name, "_OBJC_MODULES", 13))
1110 objc_module_info_section ();
1111 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1112 objc_image_info_section ();
1113 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1114 objc_cat_inst_meth_section ();
1115 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1116 objc_cat_cls_meth_section ();
1117 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1118 objc_cat_cls_meth_section ();
1119 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1120 objc_protocol_section ();
1124 /* ::operator new and ::operator delete must be coalesced, even
1125 if not weak. There are 8 variants that we look for. */
1126 else if (TREE_CODE (exp) == FUNCTION_DECL
1127 && ! DECL_ONE_ONLY (exp))
1129 const char * name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (exp));
1130 if (name[0] == '_' && name[1] == 'Z'
1131 && ((name[2] == 'n' && (name[3] == 'a' || name[3] == 'w')
1133 || (name[2] == 'd' && (name[3] == 'a' || name[3] == 'l')
1134 && name[4] == 'P' && name[5] == 'v')))
1136 bool delete_p = name[2] == 'd';
1137 if (name[5 + delete_p] == 0
1138 || strcmp (name + 5 + delete_p, "KSt9nothrow_t") == 0)
1139 base_funs[reloc][1] ();
1150 /* This can be called with address expressions as "rtx".
1151 They must go in "const". */
1154 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1155 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1157 if (GET_MODE_SIZE (mode) == 8
1158 && (GET_CODE (x) == CONST_INT
1159 || GET_CODE (x) == CONST_DOUBLE))
1160 literal8_section ();
1161 else if (GET_MODE_SIZE (mode) == 4
1162 && (GET_CODE (x) == CONST_INT
1163 || GET_CODE (x) == CONST_DOUBLE))
1164 literal4_section ();
1165 else if (MACHOPIC_INDIRECT
1166 && (GET_CODE (x) == SYMBOL_REF
1167 || GET_CODE (x) == CONST
1168 || GET_CODE (x) == LABEL_REF))
1169 const_data_section ();
1175 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1177 if (MACHOPIC_INDIRECT)
1178 mod_init_section ();
1180 constructor_section ();
1181 assemble_align (POINTER_SIZE);
1182 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1184 if (! MACHOPIC_INDIRECT)
1185 fprintf (asm_out_file, ".reference .constructors_used\n");
1189 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1191 if (MACHOPIC_INDIRECT)
1192 mod_term_section ();
1194 destructor_section ();
1195 assemble_align (POINTER_SIZE);
1196 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1198 if (! MACHOPIC_INDIRECT)
1199 fprintf (asm_out_file, ".reference .destructors_used\n");
1203 darwin_globalize_label (FILE *stream, const char *name)
1205 if (!!strncmp (name, "_OBJC_", 6))
1206 default_globalize_label (stream, name);
1210 darwin_asm_named_section (const char *name,
1211 unsigned int flags ATTRIBUTE_UNUSED,
1212 tree decl ATTRIBUTE_UNUSED)
1214 fprintf (asm_out_file, "\t.section %s\n", name);
1218 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1220 /* Darwin does not use unique sections. */
1223 /* Handle a "weak_import" attribute; arguments as in
1224 struct attribute_spec.handler. */
1227 darwin_handle_weak_import_attribute (tree *node, tree name,
1228 tree ARG_UNUSED (args),
1229 int ARG_UNUSED (flags),
1230 bool * no_add_attrs)
1232 if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1234 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
1235 *no_add_attrs = true;
1238 declare_weak (*node);
1244 no_dead_strip (FILE *file, const char *lab)
1246 fprintf (file, ".no_dead_strip %s\n", lab);
1249 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1250 The third parameter is nonzero if this is for exception handling.
1251 The fourth parameter is nonzero if this is just a placeholder for an
1252 FDE that we are omitting. */
1255 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1257 tree id = DECL_ASSEMBLER_NAME (decl)
1258 ? DECL_ASSEMBLER_NAME (decl)
1261 const char *prefix = user_label_prefix;
1263 const char *base = IDENTIFIER_POINTER (id);
1264 unsigned int base_len = IDENTIFIER_LENGTH (id);
1266 const char *suffix = ".eh";
1268 int need_quotes = name_needs_quotes (base);
1269 int quotes_len = need_quotes ? 2 : 0;
1275 lab = xmalloc (strlen (prefix)
1276 + base_len + strlen (suffix) + quotes_len + 1);
1281 strcat(lab, prefix);
1283 strcat(lab, suffix);
1287 if (TREE_PUBLIC (decl))
1288 fprintf (file, "\t%s %s\n",
1289 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1291 : ".private_extern"),
1294 if (DECL_WEAK (decl))
1295 fprintf (file, "\t.weak_definition %s\n", lab);
1299 fprintf (file, "%s = 0\n", lab);
1301 /* Mark the absolute .eh and .eh1 style labels as needed to
1302 ensure that we don't dead code strip them and keep such
1303 labels from another instantiation point until we can fix this
1304 properly with group comdat support. */
1305 no_dead_strip (file, lab);
1308 fprintf (file, "%s:\n", lab);
1313 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1316 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1318 const char *nlp_name;
1320 if (GET_CODE (addr) != SYMBOL_REF)
1323 nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1324 fputs ("\t.long\t", file);
1325 ASM_OUTPUT_LABELREF (file, nlp_name);
1329 /* Emit an assembler directive to set visibility for a symbol. The
1330 only supported visibilities are VISIBILITY_DEFAULT and
1331 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1332 extern". There is no MACH-O equivalent of ELF's
1333 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1336 darwin_assemble_visibility (tree decl, int vis)
1338 if (vis == VISIBILITY_DEFAULT)
1340 else if (vis == VISIBILITY_HIDDEN)
1342 fputs ("\t.private_extern ", asm_out_file);
1343 assemble_name (asm_out_file,
1344 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1345 fputs ("\n", asm_out_file);
1348 warning ("internal and protected visibility attributes not supported "
1349 "in this configuration; ignored");
1352 /* Output a difference of two labels that will be an assembly time
1353 constant if the two labels are local. (.long lab1-lab2 will be
1354 very different if lab1 is at the boundary between two sections; it
1355 will be relocated according to the second section, not the first,
1356 so one ends up with a difference between labels in different
1357 sections, which is bad in the dwarf2 eh context for instance.) */
1359 static int darwin_dwarf_label_counter;
1362 darwin_asm_output_dwarf_delta (FILE *file, int size,
1363 const char *lab1, const char *lab2)
1365 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1366 && lab2[0] == '*' && lab2[1] == 'L');
1367 const char *directive = (size == 8 ? ".quad" : ".long");
1370 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1372 fprintf (file, "\t%s\t", directive);
1373 assemble_name_raw (file, lab1);
1374 fprintf (file, "-");
1375 assemble_name_raw (file, lab2);
1377 fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1381 darwin_file_end (void)
1383 machopic_finish (asm_out_file);
1384 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1386 constructor_section ();
1387 destructor_section ();
1388 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1390 fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1393 #include "gt-darwin.h"