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 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 static GTY(()) const char * function_base_func_name
;
231 static GTY(()) int current_pic_label_num
;
234 machopic_output_function_base_name (FILE *file
)
236 const char *current_name
;
238 /* If dynamic-no-pic is on, we should not get here. */
239 gcc_assert (!MACHO_DYNAMIC_NO_PIC_P
);
241 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
));
242 if (function_base_func_name
!= current_name
)
244 ++current_pic_label_num
;
245 function_base_func_name
= current_name
;
247 fprintf (file
, "\"L%011d$pb\"", current_pic_label_num
);
250 /* The suffix attached to non-lazy pointer symbols. */
251 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
252 /* The suffix attached to stub symbols. */
253 #define STUB_SUFFIX "$stub"
255 typedef struct machopic_indirection
GTY (())
257 /* The SYMBOL_REF for the entity referenced. */
259 /* The name of the stub or non-lazy pointer. */
260 const char * ptr_name
;
261 /* True iff this entry is for a stub (as opposed to a non-lazy
264 /* True iff this stub or pointer pointer has been referenced. */
266 } machopic_indirection
;
268 /* A table mapping stub names and non-lazy pointer names to
269 SYMBOL_REFs for the stubbed-to and pointed-to entities. */
271 static GTY ((param_is (struct machopic_indirection
))) htab_t
272 machopic_indirections
;
274 /* Return a hash value for a SLOT in the indirections hash table. */
277 machopic_indirection_hash (const void *slot
)
279 const machopic_indirection
*p
= (const machopic_indirection
*) slot
;
280 return htab_hash_string (p
->ptr_name
);
283 /* Returns true if the KEY is the same as that associated with
287 machopic_indirection_eq (const void *slot
, const void *key
)
289 return strcmp (((const machopic_indirection
*) slot
)->ptr_name
, key
) == 0;
292 /* Return the name of the non-lazy pointer (if STUB_P is false) or
293 stub (if STUB_B is true) corresponding to the given name. */
296 machopic_indirection_name (rtx sym_ref
, bool stub_p
)
299 const char *name
= XSTR (sym_ref
, 0);
300 size_t namelen
= strlen (name
);
301 machopic_indirection
*p
;
303 bool saw_star
= false;
306 const char *prefix
= user_label_prefix
;
307 const char *quote
= "";
317 needs_quotes
= name_needs_quotes (name
);
324 suffix
= STUB_SUFFIX
;
326 suffix
= NON_LAZY_POINTER_SUFFIX
;
328 buffer
= alloca (strlen ("&L")
335 /* Construct the name of the non-lazy pointer or stub. */
336 sprintf (buffer
, "&%sL%s%s%s%s", quote
, prefix
, name
, suffix
, quote
);
338 if (!machopic_indirections
)
339 machopic_indirections
= htab_create_ggc (37,
340 machopic_indirection_hash
,
341 machopic_indirection_eq
,
344 slot
= htab_find_slot_with_hash (machopic_indirections
, buffer
,
345 htab_hash_string (buffer
), INSERT
);
348 p
= (machopic_indirection
*) *slot
;
352 p
= (machopic_indirection
*) ggc_alloc (sizeof (machopic_indirection
));
354 p
->ptr_name
= xstrdup (buffer
);
363 /* Return the name of the stub for the mcount function. */
366 machopic_mcount_stub_name (void)
368 rtx symbol
= gen_rtx_SYMBOL_REF (Pmode
, "*mcount");
369 return machopic_indirection_name (symbol
, /*stub_p=*/true);
372 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
373 or non-lazy pointer as used -- and mark the object to which the
374 pointer/stub refers as used as well, since the pointer/stub will
375 emit a reference to it. */
378 machopic_validate_stub_or_non_lazy_ptr (const char *name
)
380 machopic_indirection
*p
;
382 p
= ((machopic_indirection
*)
383 (htab_find_with_hash (machopic_indirections
, name
,
384 htab_hash_string (name
))));
387 const char *real_name
;
392 /* Do what output_addr_const will do when we actually call it. */
393 if (SYMBOL_REF_DECL (p
->symbol
))
394 mark_decl_referenced (SYMBOL_REF_DECL (p
->symbol
));
396 real_name
= targetm
.strip_name_encoding (XSTR (p
->symbol
, 0));
398 id
= maybe_get_identifier (real_name
);
400 mark_referenced (id
);
404 /* Transform ORIG, which may be any data source, to the corresponding
405 source using indirections. */
408 machopic_indirect_data_reference (rtx orig
, rtx reg
)
412 if (! MACHOPIC_INDIRECT
)
415 if (GET_CODE (orig
) == SYMBOL_REF
)
417 int defined
= machopic_data_defined_p (orig
);
419 if (defined
&& MACHO_DYNAMIC_NO_PIC_P
)
421 #if defined (TARGET_TOC)
422 emit_insn (gen_macho_high (reg
, orig
));
423 emit_insn (gen_macho_low (reg
, reg
, orig
));
425 /* some other cpu -- writeme! */
432 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
433 rtx pic_base
= machopic_function_base_sym ();
434 rtx offset
= gen_rtx_CONST (Pmode
,
435 gen_rtx_MINUS (Pmode
, orig
, pic_base
));
438 #if defined (TARGET_TOC) /* i.e., PowerPC */
439 rtx hi_sum_reg
= (no_new_pseudos
? reg
: gen_reg_rtx (Pmode
));
443 emit_insn (gen_rtx_SET (Pmode
, hi_sum_reg
,
444 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
445 gen_rtx_HIGH (Pmode
, offset
))));
446 emit_insn (gen_rtx_SET (Pmode
, reg
,
447 gen_rtx_LO_SUM (Pmode
, hi_sum_reg
, offset
)));
451 #if defined (HAVE_lo_sum)
454 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
455 gen_rtx_HIGH (Pmode
, offset
)));
456 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
457 gen_rtx_LO_SUM (Pmode
, reg
, offset
)));
458 emit_insn (gen_rtx_USE (VOIDmode
, pic_offset_table_rtx
));
460 orig
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, reg
);
466 ptr_ref
= (gen_rtx_SYMBOL_REF
468 machopic_indirection_name (orig
, /*stub_p=*/false)));
470 SYMBOL_REF_DECL (ptr_ref
) = SYMBOL_REF_DECL (orig
);
472 ptr_ref
= gen_const_mem (Pmode
, ptr_ref
);
473 machopic_define_symbol (ptr_ref
);
477 else if (GET_CODE (orig
) == CONST
)
481 /* legitimize both operands of the PLUS */
482 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
484 base
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 0),
486 orig
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 1),
487 (base
== reg
? 0 : reg
));
492 if (MACHOPIC_PURE
&& GET_CODE (orig
) == CONST_INT
)
493 result
= plus_constant (base
, INTVAL (orig
));
495 result
= gen_rtx_PLUS (Pmode
, base
, orig
);
497 if (MACHOPIC_JUST_INDIRECT
&& GET_CODE (base
) == MEM
)
501 emit_move_insn (reg
, result
);
506 result
= force_reg (GET_MODE (result
), result
);
513 else if (GET_CODE (orig
) == MEM
)
514 XEXP (ptr_ref
, 0) = machopic_indirect_data_reference (XEXP (orig
, 0), reg
);
515 /* When the target is i386, this code prevents crashes due to the
516 compiler's ignorance on how to move the PIC base register to
517 other registers. (The reload phase sometimes introduces such
519 else if (GET_CODE (orig
) == PLUS
520 && GET_CODE (XEXP (orig
, 0)) == REG
521 && REGNO (XEXP (orig
, 0)) == PIC_OFFSET_TABLE_REGNUM
523 /* Prevent the same register from being erroneously used
524 as both the base and index registers. */
525 && GET_CODE (XEXP (orig
, 1)) == CONST
529 emit_move_insn (reg
, XEXP (orig
, 0));
530 XEXP (ptr_ref
, 0) = reg
;
535 /* Transform TARGET (a MEM), which is a function call target, to the
536 corresponding symbol_stub if necessary. Return a new MEM. */
539 machopic_indirect_call_target (rtx target
)
541 if (GET_CODE (target
) != MEM
)
544 if (MACHOPIC_INDIRECT
545 && GET_CODE (XEXP (target
, 0)) == SYMBOL_REF
546 && !(SYMBOL_REF_FLAGS (XEXP (target
, 0))
547 & MACHO_SYMBOL_FLAG_DEFINED
))
549 rtx sym_ref
= XEXP (target
, 0);
550 const char *stub_name
= machopic_indirection_name (sym_ref
,
552 enum machine_mode mode
= GET_MODE (sym_ref
);
553 tree decl
= SYMBOL_REF_DECL (sym_ref
);
555 XEXP (target
, 0) = gen_rtx_SYMBOL_REF (mode
, stub_name
);
556 SYMBOL_REF_DECL (XEXP (target
, 0)) = decl
;
557 MEM_READONLY_P (target
) = 1;
558 MEM_NOTRAP_P (target
) = 1;
565 machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
, rtx reg
)
569 if (! MACHOPIC_INDIRECT
)
572 /* First handle a simple SYMBOL_REF or LABEL_REF */
573 if (GET_CODE (orig
) == LABEL_REF
574 || (GET_CODE (orig
) == SYMBOL_REF
577 /* addr(foo) = &func+(foo-func) */
580 orig
= machopic_indirect_data_reference (orig
, reg
);
582 if (GET_CODE (orig
) == PLUS
583 && GET_CODE (XEXP (orig
, 0)) == REG
)
586 return force_reg (mode
, orig
);
588 emit_move_insn (reg
, orig
);
592 /* if dynamic-no-pic then use 0 as the pic base */
593 if (MACHO_DYNAMIC_NO_PIC_P
)
594 pic_base
= CONST0_RTX (Pmode
);
596 pic_base
= machopic_function_base_sym ();
598 if (GET_CODE (orig
) == MEM
)
602 gcc_assert (!reload_in_progress
);
603 reg
= gen_reg_rtx (Pmode
);
607 if (MACHO_DYNAMIC_NO_PIC_P
608 && (GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
609 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
))
611 #if defined (TARGET_TOC) /* ppc */
612 rtx temp_reg
= (no_new_pseudos
) ? reg
: gen_reg_rtx (Pmode
);
613 rtx asym
= XEXP (orig
, 0);
616 emit_insn (gen_macho_high (temp_reg
, asym
));
617 mem
= gen_const_mem (GET_MODE (orig
),
618 gen_rtx_LO_SUM (Pmode
, temp_reg
, asym
));
619 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
621 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
627 if (GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
628 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
630 rtx offset
= gen_rtx_CONST (Pmode
,
631 gen_rtx_MINUS (Pmode
,
634 #if defined (TARGET_TOC) /* i.e., PowerPC */
635 /* Generating a new reg may expose opportunities for
636 common subexpression elimination. */
637 rtx hi_sum_reg
= no_new_pseudos
? reg
: gen_reg_rtx (Pmode
);
642 sum
= gen_rtx_HIGH (Pmode
, offset
);
643 if (! MACHO_DYNAMIC_NO_PIC_P
)
644 sum
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, sum
);
646 emit_insn (gen_rtx_SET (Pmode
, hi_sum_reg
, sum
));
648 mem
= gen_const_mem (GET_MODE (orig
),
649 gen_rtx_LO_SUM (Pmode
,
650 hi_sum_reg
, offset
));
651 insn
= emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
652 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_EQUAL
, pic_ref
,
657 emit_insn (gen_rtx_USE (VOIDmode
,
659 PIC_OFFSET_TABLE_REGNUM
)));
661 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
663 gen_rtx_CONST (Pmode
,
665 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
666 gen_rtx_LO_SUM (Pmode
, reg
,
667 gen_rtx_CONST (Pmode
, offset
))));
668 pic_ref
= gen_rtx_PLUS (Pmode
,
669 pic_offset_table_rtx
, reg
);
673 #endif /* HAVE_lo_sum */
675 rtx pic
= pic_offset_table_rtx
;
676 if (GET_CODE (pic
) != REG
)
678 emit_move_insn (reg
, pic
);
682 emit_insn (gen_rtx_USE (VOIDmode
,
684 PIC_OFFSET_TABLE_REGNUM
)));
687 pic_ref
= gen_rtx_PLUS (Pmode
,
689 gen_rtx_CONST (Pmode
,
690 gen_rtx_MINUS (Pmode
,
695 #if !defined (TARGET_TOC)
696 emit_move_insn (reg
, pic_ref
);
697 pic_ref
= gen_const_mem (GET_MODE (orig
), reg
);
704 if (GET_CODE (orig
) == SYMBOL_REF
705 || GET_CODE (orig
) == LABEL_REF
)
707 rtx offset
= gen_rtx_CONST (Pmode
,
708 gen_rtx_MINUS (Pmode
,
710 #if defined (TARGET_TOC) /* i.e., PowerPC */
715 gcc_assert (!reload_in_progress
);
716 reg
= gen_reg_rtx (Pmode
);
721 emit_insn (gen_rtx_SET (Pmode
, hi_sum_reg
,
722 (MACHO_DYNAMIC_NO_PIC_P
)
723 ? gen_rtx_HIGH (Pmode
, offset
)
724 : gen_rtx_PLUS (Pmode
,
725 pic_offset_table_rtx
,
728 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
729 gen_rtx_LO_SUM (Pmode
,
730 hi_sum_reg
, offset
)));
733 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
734 gen_rtx_HIGH (Pmode
, offset
)));
735 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
736 gen_rtx_LO_SUM (Pmode
, reg
, offset
)));
737 pic_ref
= gen_rtx_PLUS (Pmode
,
738 pic_offset_table_rtx
, reg
);
742 #endif /* HAVE_lo_sum */
745 || GET_CODE (orig
) == SUBREG
)
751 rtx pic
= pic_offset_table_rtx
;
752 if (GET_CODE (pic
) != REG
)
754 emit_move_insn (reg
, pic
);
758 emit_insn (gen_rtx_USE (VOIDmode
,
759 pic_offset_table_rtx
));
761 pic_ref
= gen_rtx_PLUS (Pmode
,
763 gen_rtx_CONST (Pmode
,
764 gen_rtx_MINUS (Pmode
,
770 if (GET_CODE (pic_ref
) != REG
)
774 emit_move_insn (reg
, pic_ref
);
779 return force_reg (mode
, pic_ref
);
788 else if (GET_CODE (orig
) == SYMBOL_REF
)
791 else if (GET_CODE (orig
) == PLUS
792 && (GET_CODE (XEXP (orig
, 0)) == MEM
793 || GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
794 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
795 && XEXP (orig
, 0) != pic_offset_table_rtx
796 && GET_CODE (XEXP (orig
, 1)) != REG
)
800 int is_complex
= (GET_CODE (XEXP (orig
, 0)) == MEM
);
802 base
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
803 orig
= machopic_legitimize_pic_address (XEXP (orig
, 1),
804 Pmode
, (base
== reg
? 0 : reg
));
805 if (GET_CODE (orig
) == CONST_INT
)
807 pic_ref
= plus_constant (base
, INTVAL (orig
));
811 pic_ref
= gen_rtx_PLUS (Pmode
, base
, orig
);
813 if (reg
&& is_complex
)
815 emit_move_insn (reg
, pic_ref
);
818 /* Likewise, should we set special REG_NOTEs here? */
821 else if (GET_CODE (orig
) == CONST
)
823 return machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
826 else if (GET_CODE (orig
) == MEM
827 && GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
)
829 rtx addr
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
830 addr
= replace_equiv_address (orig
, addr
);
831 emit_move_insn (reg
, addr
);
838 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
839 DATA is the FILE* for assembly output. Called from
843 machopic_output_indirection (void **slot
, void *data
)
845 machopic_indirection
*p
= *((machopic_indirection
**) slot
);
846 FILE *asm_out_file
= (FILE *) data
;
848 const char *sym_name
;
849 const char *ptr_name
;
855 sym_name
= XSTR (symbol
, 0);
856 ptr_name
= p
->ptr_name
;
863 sym
= alloca (strlen (sym_name
) + 2);
864 if (sym_name
[0] == '*' || sym_name
[0] == '&')
865 strcpy (sym
, sym_name
+ 1);
866 else if (sym_name
[0] == '-' || sym_name
[0] == '+')
867 strcpy (sym
, sym_name
);
869 sprintf (sym
, "%s%s", user_label_prefix
, sym_name
);
871 stub
= alloca (strlen (ptr_name
) + 2);
872 if (ptr_name
[0] == '*' || ptr_name
[0] == '&')
873 strcpy (stub
, ptr_name
+ 1);
875 sprintf (stub
, "%s%s", user_label_prefix
, ptr_name
);
877 machopic_output_stub (asm_out_file
, sym
, stub
);
879 else if (! indirect_data (symbol
)
880 && (machopic_symbol_defined_p (symbol
)
881 || SYMBOL_REF_LOCAL_P (symbol
)))
884 assemble_align (GET_MODE_ALIGNMENT (Pmode
));
885 assemble_label (ptr_name
);
886 assemble_integer (gen_rtx_SYMBOL_REF (Pmode
, sym_name
),
887 GET_MODE_SIZE (Pmode
),
888 GET_MODE_ALIGNMENT (Pmode
), 1);
892 rtx init
= const0_rtx
;
894 machopic_nl_symbol_ptr_section ();
895 assemble_name (asm_out_file
, ptr_name
);
896 fprintf (asm_out_file
, ":\n");
898 fprintf (asm_out_file
, "\t.indirect_symbol ");
899 assemble_name (asm_out_file
, sym_name
);
900 fprintf (asm_out_file
, "\n");
902 /* Variables that are marked with MACHO_SYMBOL_STATIC need to
903 have their symbol name instead of 0 in the second entry of
904 the non-lazy symbol pointer data structure when they are
905 defined. This allows the runtime to rebind newer instances
906 of the translation unit with the original instance of the
909 if ((SYMBOL_REF_FLAGS (symbol
) & MACHO_SYMBOL_STATIC
)
910 && machopic_symbol_defined_p (symbol
))
911 init
= gen_rtx_SYMBOL_REF (Pmode
, sym_name
);
913 assemble_integer (init
, GET_MODE_SIZE (Pmode
),
914 GET_MODE_ALIGNMENT (Pmode
), 1);
921 machopic_finish (FILE *asm_out_file
)
923 if (machopic_indirections
)
924 htab_traverse_noresize (machopic_indirections
,
925 machopic_output_indirection
,
930 machopic_operand_p (rtx op
)
932 if (MACHOPIC_JUST_INDIRECT
)
934 while (GET_CODE (op
) == CONST
)
937 if (GET_CODE (op
) == SYMBOL_REF
)
938 return machopic_symbol_defined_p (op
);
943 while (GET_CODE (op
) == CONST
)
946 if (GET_CODE (op
) == MINUS
947 && GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
948 && GET_CODE (XEXP (op
, 1)) == SYMBOL_REF
949 && machopic_symbol_defined_p (XEXP (op
, 0))
950 && machopic_symbol_defined_p (XEXP (op
, 1)))
956 /* This function records whether a given name corresponds to a defined
957 or undefined function or variable, for machopic_classify_ident to
961 darwin_encode_section_info (tree decl
, rtx rtl
, int first ATTRIBUTE_UNUSED
)
965 /* Do the standard encoding things first. */
966 default_encode_section_info (decl
, rtl
, first
);
968 if (TREE_CODE (decl
) != FUNCTION_DECL
&& TREE_CODE (decl
) != VAR_DECL
)
971 sym_ref
= XEXP (rtl
, 0);
972 if (TREE_CODE (decl
) == VAR_DECL
)
973 SYMBOL_REF_FLAGS (sym_ref
) |= MACHO_SYMBOL_FLAG_VARIABLE
;
975 if (!DECL_EXTERNAL (decl
)
976 && (!TREE_PUBLIC (decl
) || !DECL_WEAK (decl
))
977 && ((TREE_STATIC (decl
)
978 && (!DECL_COMMON (decl
) || !TREE_PUBLIC (decl
)))
979 || (!DECL_COMMON (decl
) && DECL_INITIAL (decl
)
980 && DECL_INITIAL (decl
) != error_mark_node
)))
981 SYMBOL_REF_FLAGS (sym_ref
) |= MACHO_SYMBOL_FLAG_DEFINED
;
983 if (! TREE_PUBLIC (decl
))
984 SYMBOL_REF_FLAGS (sym_ref
) |= MACHO_SYMBOL_STATIC
;
988 darwin_mark_decl_preserved (const char *name
)
990 fprintf (asm_out_file
, ".no_dead_strip ");
991 assemble_name (asm_out_file
, name
);
992 fputc ('\n', asm_out_file
);
996 machopic_select_section (tree exp
, int reloc
,
997 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
999 void (*base_function
)(void);
1000 bool weak_p
= DECL_P (exp
) && DECL_WEAK (exp
);
1001 static void (* const base_funs
[][2])(void) = {
1002 { text_section
, text_coal_section
},
1003 { unlikely_text_section
, text_unlikely_coal_section
},
1004 { readonly_data_section
, const_coal_section
},
1005 { const_data_section
, const_data_coal_section
},
1006 { data_section
, data_coal_section
}
1010 && (last_text_section
== in_text_unlikely
1011 || last_text_section
== in_text_unlikely_coal
))
1014 if (TREE_CODE (exp
) == FUNCTION_DECL
)
1015 base_function
= base_funs
[reloc
][weak_p
];
1016 else if (decl_readonly_section_1 (exp
, reloc
, MACHOPIC_INDIRECT
))
1017 base_function
= base_funs
[2][weak_p
];
1018 else if (TREE_READONLY (exp
) || TREE_CONSTANT (exp
))
1019 base_function
= base_funs
[3][weak_p
];
1021 base_function
= base_funs
[4][weak_p
];
1023 if (TREE_CODE (exp
) == STRING_CST
1024 && ((size_t) TREE_STRING_LENGTH (exp
)
1025 == strlen (TREE_STRING_POINTER (exp
)) + 1))
1027 else if ((TREE_CODE (exp
) == INTEGER_CST
|| TREE_CODE (exp
) == REAL_CST
)
1028 && flag_merge_constants
)
1030 tree size
= TYPE_SIZE_UNIT (TREE_TYPE (exp
));
1032 if (TREE_CODE (size
) == INTEGER_CST
&&
1033 TREE_INT_CST_LOW (size
) == 4 &&
1034 TREE_INT_CST_HIGH (size
) == 0)
1035 literal4_section ();
1036 else if (TREE_CODE (size
) == INTEGER_CST
&&
1037 TREE_INT_CST_LOW (size
) == 8 &&
1038 TREE_INT_CST_HIGH (size
) == 0)
1039 literal8_section ();
1043 else if (TREE_CODE (exp
) == CONSTRUCTOR
1045 && TREE_CODE (TREE_TYPE (exp
)) == RECORD_TYPE
1046 && TYPE_NAME (TREE_TYPE (exp
)))
1048 tree name
= TYPE_NAME (TREE_TYPE (exp
));
1049 if (TREE_CODE (name
) == TYPE_DECL
)
1050 name
= DECL_NAME (name
);
1051 if (!strcmp (IDENTIFIER_POINTER (name
), "NSConstantString"))
1052 objc_constant_string_object_section ();
1053 else if (!strcmp (IDENTIFIER_POINTER (name
), "NXConstantString"))
1054 objc_string_object_section ();
1058 else if (TREE_CODE (exp
) == VAR_DECL
&&
1060 TREE_CODE (DECL_NAME (exp
)) == IDENTIFIER_NODE
&&
1061 IDENTIFIER_POINTER (DECL_NAME (exp
)) &&
1062 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), "_OBJC_", 6))
1064 const char *name
= IDENTIFIER_POINTER (DECL_NAME (exp
));
1066 if (!strncmp (name
, "_OBJC_CLASS_METHODS_", 20))
1067 objc_cls_meth_section ();
1068 else if (!strncmp (name
, "_OBJC_INSTANCE_METHODS_", 23))
1069 objc_inst_meth_section ();
1070 else if (!strncmp (name
, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1071 objc_cat_cls_meth_section ();
1072 else if (!strncmp (name
, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1073 objc_cat_inst_meth_section ();
1074 else if (!strncmp (name
, "_OBJC_CLASS_VARIABLES_", 22))
1075 objc_class_vars_section ();
1076 else if (!strncmp (name
, "_OBJC_INSTANCE_VARIABLES_", 25))
1077 objc_instance_vars_section ();
1078 else if (!strncmp (name
, "_OBJC_CLASS_PROTOCOLS_", 22))
1079 objc_cat_cls_meth_section ();
1080 else if (!strncmp (name
, "_OBJC_CLASS_NAME_", 17))
1081 objc_class_names_section ();
1082 else if (!strncmp (name
, "_OBJC_METH_VAR_NAME_", 20))
1083 objc_meth_var_names_section ();
1084 else if (!strncmp (name
, "_OBJC_METH_VAR_TYPE_", 20))
1085 objc_meth_var_types_section ();
1086 else if (!strncmp (name
, "_OBJC_CLASS_REFERENCES", 22))
1087 objc_cls_refs_section ();
1088 else if (!strncmp (name
, "_OBJC_CLASS_", 12))
1089 objc_class_section ();
1090 else if (!strncmp (name
, "_OBJC_METACLASS_", 16))
1091 objc_meta_class_section ();
1092 else if (!strncmp (name
, "_OBJC_CATEGORY_", 15))
1093 objc_category_section ();
1094 else if (!strncmp (name
, "_OBJC_SELECTOR_REFERENCES", 25))
1095 objc_selector_refs_section ();
1096 else if (!strncmp (name
, "_OBJC_SELECTOR_FIXUP", 20))
1097 objc_selector_fixup_section ();
1098 else if (!strncmp (name
, "_OBJC_SYMBOLS", 13))
1099 objc_symbols_section ();
1100 else if (!strncmp (name
, "_OBJC_MODULES", 13))
1101 objc_module_info_section ();
1102 else if (!strncmp (name
, "_OBJC_IMAGE_INFO", 16))
1103 objc_image_info_section ();
1104 else if (!strncmp (name
, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1105 objc_cat_inst_meth_section ();
1106 else if (!strncmp (name
, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1107 objc_cat_cls_meth_section ();
1108 else if (!strncmp (name
, "_OBJC_PROTOCOL_REFS_", 20))
1109 objc_cat_cls_meth_section ();
1110 else if (!strncmp (name
, "_OBJC_PROTOCOL_", 15))
1111 objc_protocol_section ();
1115 /* ::operator new and ::operator delete must be coalesced, even
1116 if not weak. There are 8 variants that we look for. */
1117 else if (TREE_CODE (exp
) == FUNCTION_DECL
1118 && ! DECL_ONE_ONLY (exp
))
1120 const char * name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (exp
));
1121 if (name
[0] == '_' && name
[1] == 'Z'
1122 && ((name
[2] == 'n' && (name
[3] == 'a' || name
[3] == 'w')
1124 || (name
[2] == 'd' && (name
[3] == 'a' || name
[3] == 'l')
1125 && name
[4] == 'P' && name
[5] == 'v')))
1127 bool delete_p
= name
[2] == 'd';
1128 if (name
[5 + delete_p
] == 0
1129 || strcmp (name
+ 5 + delete_p
, "KSt9nothrow_t") == 0)
1130 base_funs
[reloc
][1] ();
1141 /* This can be called with address expressions as "rtx".
1142 They must go in "const". */
1145 machopic_select_rtx_section (enum machine_mode mode
, rtx x
,
1146 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
1148 if (GET_MODE_SIZE (mode
) == 8
1149 && (GET_CODE (x
) == CONST_INT
1150 || GET_CODE (x
) == CONST_DOUBLE
))
1151 literal8_section ();
1152 else if (GET_MODE_SIZE (mode
) == 4
1153 && (GET_CODE (x
) == CONST_INT
1154 || GET_CODE (x
) == CONST_DOUBLE
))
1155 literal4_section ();
1156 else if (MACHOPIC_INDIRECT
1157 && (GET_CODE (x
) == SYMBOL_REF
1158 || GET_CODE (x
) == CONST
1159 || GET_CODE (x
) == LABEL_REF
))
1160 const_data_section ();
1166 machopic_asm_out_constructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
1168 if (MACHOPIC_INDIRECT
)
1169 mod_init_section ();
1171 constructor_section ();
1172 assemble_align (POINTER_SIZE
);
1173 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1175 if (! MACHOPIC_INDIRECT
)
1176 fprintf (asm_out_file
, ".reference .constructors_used\n");
1180 machopic_asm_out_destructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
1182 if (MACHOPIC_INDIRECT
)
1183 mod_term_section ();
1185 destructor_section ();
1186 assemble_align (POINTER_SIZE
);
1187 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1189 if (! MACHOPIC_INDIRECT
)
1190 fprintf (asm_out_file
, ".reference .destructors_used\n");
1194 darwin_globalize_label (FILE *stream
, const char *name
)
1196 if (!!strncmp (name
, "_OBJC_", 6))
1197 default_globalize_label (stream
, name
);
1201 darwin_asm_named_section (const char *name
,
1202 unsigned int flags ATTRIBUTE_UNUSED
,
1203 tree decl ATTRIBUTE_UNUSED
)
1205 fprintf (asm_out_file
, "\t.section %s\n", name
);
1209 darwin_unique_section (tree decl ATTRIBUTE_UNUSED
, int reloc ATTRIBUTE_UNUSED
)
1211 /* Darwin does not use unique sections. */
1214 /* Handle a "weak_import" attribute; arguments as in
1215 struct attribute_spec.handler. */
1218 darwin_handle_weak_import_attribute (tree
*node
, tree name
,
1219 tree
ARG_UNUSED (args
),
1220 int ARG_UNUSED (flags
),
1221 bool * no_add_attrs
)
1223 if (TREE_CODE (*node
) != FUNCTION_DECL
&& TREE_CODE (*node
) != VAR_DECL
)
1225 warning (0, "%qs attribute ignored", IDENTIFIER_POINTER (name
));
1226 *no_add_attrs
= true;
1229 declare_weak (*node
);
1235 no_dead_strip (FILE *file
, const char *lab
)
1237 fprintf (file
, ".no_dead_strip %s\n", lab
);
1240 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1241 The third parameter is nonzero if this is for exception handling.
1242 The fourth parameter is nonzero if this is just a placeholder for an
1243 FDE that we are omitting. */
1246 darwin_emit_unwind_label (FILE *file
, tree decl
, int for_eh
, int empty
)
1248 tree id
= DECL_ASSEMBLER_NAME (decl
)
1249 ? DECL_ASSEMBLER_NAME (decl
)
1252 const char *prefix
= user_label_prefix
;
1254 const char *base
= IDENTIFIER_POINTER (id
);
1255 unsigned int base_len
= IDENTIFIER_LENGTH (id
);
1257 const char *suffix
= ".eh";
1259 int need_quotes
= name_needs_quotes (base
);
1260 int quotes_len
= need_quotes
? 2 : 0;
1266 lab
= xmalloc (strlen (prefix
)
1267 + base_len
+ strlen (suffix
) + quotes_len
+ 1);
1272 strcat(lab
, prefix
);
1274 strcat(lab
, suffix
);
1278 if (TREE_PUBLIC (decl
))
1279 fprintf (file
, "\t%s %s\n",
1280 (DECL_VISIBILITY (decl
) != VISIBILITY_HIDDEN
1282 : ".private_extern"),
1285 if (DECL_WEAK (decl
))
1286 fprintf (file
, "\t.weak_definition %s\n", lab
);
1290 fprintf (file
, "%s = 0\n", lab
);
1292 /* Mark the absolute .eh and .eh1 style labels as needed to
1293 ensure that we don't dead code strip them and keep such
1294 labels from another instantiation point until we can fix this
1295 properly with group comdat support. */
1296 no_dead_strip (file
, lab
);
1299 fprintf (file
, "%s:\n", lab
);
1304 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1307 darwin_non_lazy_pcrel (FILE *file
, rtx addr
)
1309 const char *nlp_name
;
1311 gcc_assert (GET_CODE (addr
) == SYMBOL_REF
);
1313 nlp_name
= machopic_indirection_name (addr
, /*stub_p=*/false);
1314 fputs ("\t.long\t", file
);
1315 ASM_OUTPUT_LABELREF (file
, nlp_name
);
1319 /* Emit an assembler directive to set visibility for a symbol. The
1320 only supported visibilities are VISIBILITY_DEFAULT and
1321 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1322 extern". There is no MACH-O equivalent of ELF's
1323 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1326 darwin_assemble_visibility (tree decl
, int vis
)
1328 if (vis
== VISIBILITY_DEFAULT
)
1330 else if (vis
== VISIBILITY_HIDDEN
)
1332 fputs ("\t.private_extern ", asm_out_file
);
1333 assemble_name (asm_out_file
,
1334 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
1335 fputs ("\n", asm_out_file
);
1338 warning (0, "internal and protected visibility attributes not supported "
1339 "in this configuration; ignored");
1342 /* Output a difference of two labels that will be an assembly time
1343 constant if the two labels are local. (.long lab1-lab2 will be
1344 very different if lab1 is at the boundary between two sections; it
1345 will be relocated according to the second section, not the first,
1346 so one ends up with a difference between labels in different
1347 sections, which is bad in the dwarf2 eh context for instance.) */
1349 static int darwin_dwarf_label_counter
;
1352 darwin_asm_output_dwarf_delta (FILE *file
, int size
,
1353 const char *lab1
, const char *lab2
)
1355 int islocaldiff
= (lab1
[0] == '*' && lab1
[1] == 'L'
1356 && lab2
[0] == '*' && lab2
[1] == 'L');
1357 const char *directive
= (size
== 8 ? ".quad" : ".long");
1360 fprintf (file
, "\t.set L$set$%d,", darwin_dwarf_label_counter
);
1362 fprintf (file
, "\t%s\t", directive
);
1363 assemble_name_raw (file
, lab1
);
1364 fprintf (file
, "-");
1365 assemble_name_raw (file
, lab2
);
1367 fprintf (file
, "\n\t%s L$set$%d", directive
, darwin_dwarf_label_counter
++);
1371 darwin_file_end (void)
1373 machopic_finish (asm_out_file
);
1374 if (strcmp (lang_hooks
.name
, "GNU C++") == 0)
1376 constructor_section ();
1377 destructor_section ();
1378 ASM_OUTPUT_ALIGN (asm_out_file
, 1);
1380 fprintf (asm_out_file
, "\t.subsections_via_symbols\n");
1383 #include "gt-darwin.h"