1 /* Functions for generic Darwin as target machine for GNU C compiler.
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Apple Computer Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
40 #include "langhooks.h"
42 #include "darwin-protos.h"
44 extern void machopic_output_stub
PARAMS ((FILE *, const char *, const char *));
46 static int machopic_data_defined_p
PARAMS ((const char *));
47 static int func_name_maybe_scoped
PARAMS ((const char *));
48 static void update_non_lazy_ptrs
PARAMS ((const char *));
49 static void update_stubs
PARAMS ((const char *));
52 name_needs_quotes (name
)
56 while ((c
= *name
++) != '\0')
63 * flag_pic = 1 ... generate only indirections
64 * flag_pic = 2 ... generate indirections and pure code
67 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
68 reference, which will not be changed. */
70 static tree machopic_defined_list
;
72 enum machopic_addr_class
73 machopic_classify_ident (ident
)
76 const char *name
= IDENTIFIER_POINTER (ident
);
77 int lprefix
= (((name
[0] == '*' || name
[0] == '&')
78 && (name
[1] == 'L' || (name
[1] == '"' && name
[2] == 'L')))
89 /* Here if no special encoding to be found. */
92 const char *name
= IDENTIFIER_POINTER (ident
);
93 int len
= strlen (name
);
95 if ((len
> 5 && !strcmp (name
+ len
- 5, "$stub"))
96 || (len
> 6 && !strcmp (name
+ len
- 6, "$stub\"")))
97 return MACHOPIC_DEFINED_FUNCTION
;
98 return MACHOPIC_DEFINED_DATA
;
101 for (temp
= machopic_defined_list
;
103 temp
= TREE_CHAIN (temp
))
105 if (ident
== TREE_VALUE (temp
))
106 return MACHOPIC_DEFINED_DATA
;
109 if (TREE_ASM_WRITTEN (ident
))
110 return MACHOPIC_DEFINED_DATA
;
112 return MACHOPIC_UNDEFINED
;
115 else if (name
[1] == 'D')
116 return MACHOPIC_DEFINED_DATA
;
118 else if (name
[1] == 'T')
119 return MACHOPIC_DEFINED_FUNCTION
;
121 /* It is possible that someone is holding a "stale" name, which has
122 since been defined. See if there is a "defined" name (i.e,
123 different from NAME only in having a '!D_' or a '!T_' instead of
124 a '!d_' or '!t_' prefix) in the identifier hash tables. If so, say
125 that this identifier is defined. */
126 else if (name
[1] == 'd' || name
[1] == 't')
129 new_name
= (char *)alloca (strlen (name
) + 1);
130 strcpy (new_name
, name
);
131 new_name
[1] = (name
[1] == 'd') ? 'D' : 'T';
132 if (maybe_get_identifier (new_name
) != NULL
)
133 return (name
[1] == 'd') ? MACHOPIC_DEFINED_DATA
134 : MACHOPIC_DEFINED_FUNCTION
;
137 for (temp
= machopic_defined_list
; temp
!= NULL_TREE
; temp
= TREE_CHAIN (temp
))
139 if (ident
== TREE_VALUE (temp
))
142 return MACHOPIC_DEFINED_FUNCTION
;
144 return MACHOPIC_DEFINED_DATA
;
148 if (name
[1] == 't' || name
[1] == 'T')
151 return MACHOPIC_DEFINED_FUNCTION
;
153 return MACHOPIC_UNDEFINED_FUNCTION
;
158 return MACHOPIC_DEFINED_DATA
;
160 return MACHOPIC_UNDEFINED_DATA
;
165 enum machopic_addr_class
166 machopic_classify_name (name
)
169 return machopic_classify_ident (get_identifier (name
));
173 machopic_ident_defined_p (ident
)
176 switch (machopic_classify_ident (ident
))
178 case MACHOPIC_UNDEFINED
:
179 case MACHOPIC_UNDEFINED_DATA
:
180 case MACHOPIC_UNDEFINED_FUNCTION
:
188 machopic_data_defined_p (name
)
191 switch (machopic_classify_ident (get_identifier (name
)))
193 case MACHOPIC_DEFINED_DATA
:
201 machopic_name_defined_p (name
)
204 return machopic_ident_defined_p (get_identifier (name
));
208 machopic_define_ident (ident
)
211 if (!machopic_ident_defined_p (ident
))
212 machopic_defined_list
=
213 tree_cons (NULL_TREE
, ident
, machopic_defined_list
);
217 machopic_define_name (name
)
220 machopic_define_ident (get_identifier (name
));
223 /* This is a static to make inline functions work. The rtx
224 representing the PIC base symbol always points to here. */
226 static char function_base
[32];
228 static int current_pic_label_num
;
231 machopic_function_base_name ()
233 static const char *name
= NULL
;
234 static const char *current_name
;
236 current_name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
));
238 if (name
!= current_name
)
240 current_function_uses_pic_offset_table
= 1;
242 /* Save mucho space and time. Some of the C++ mangled names are over
243 700 characters long! Note that we produce a label containing a '-'
244 if the function we're compiling is an Objective-C method, as evinced
245 by the incredibly scientific test below. This is because code in
246 rs6000.c makes the same ugly test when loading the PIC reg. */
248 ++current_pic_label_num
;
249 if (*current_name
== '+' || *current_name
== '-')
250 sprintf (function_base
, "*\"L-%d$pb\"", current_pic_label_num
);
252 sprintf (function_base
, "*L%d$pb", current_pic_label_num
);
257 return function_base
;
260 static tree machopic_non_lazy_pointers
= NULL
;
262 /* Return a non-lazy pointer name corresponding to the given name,
263 either by finding it in our list of pointer names, or by generating
267 machopic_non_lazy_ptr_name (name
)
271 tree temp
, ident
= get_identifier (name
);
273 for (temp
= machopic_non_lazy_pointers
;
275 temp
= TREE_CHAIN (temp
))
277 if (ident
== TREE_VALUE (temp
))
278 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
281 name
= darwin_strip_name_encoding (name
);
283 /* Try again, but comparing names this time. */
284 for (temp
= machopic_non_lazy_pointers
;
286 temp
= TREE_CHAIN (temp
))
288 if (TREE_VALUE (temp
))
290 temp_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
291 temp_name
= darwin_strip_name_encoding (temp_name
);
292 if (strcmp (name
, temp_name
) == 0)
293 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
301 buffer
= alloca (strlen (name
) + 20);
303 strcpy (buffer
, "&L");
305 strcat (buffer
, name
+1);
308 strcat (buffer
, "_");
309 strcat (buffer
, name
);
312 strcat (buffer
, "$non_lazy_ptr");
313 ptr_name
= get_identifier (buffer
);
315 machopic_non_lazy_pointers
316 = tree_cons (ptr_name
, ident
, machopic_non_lazy_pointers
);
318 TREE_USED (machopic_non_lazy_pointers
) = 0;
320 return IDENTIFIER_POINTER (ptr_name
);
324 static tree machopic_stubs
= 0;
326 /* Make sure the GC knows about our homemade lists. */
329 machopic_add_gc_roots ()
331 ggc_add_tree_root (&machopic_defined_list
, 1);
332 ggc_add_tree_root (&machopic_non_lazy_pointers
, 1);
333 ggc_add_tree_root (&machopic_stubs
, 1);
336 /* Return the name of the stub corresponding to the given name,
337 generating a new stub name if necessary. */
340 machopic_stub_name (name
)
343 tree temp
, ident
= get_identifier (name
);
346 for (temp
= machopic_stubs
;
348 temp
= TREE_CHAIN (temp
))
350 if (ident
== TREE_VALUE (temp
))
351 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
352 tname
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
353 if (strcmp (name
, tname
) == 0)
354 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
355 /* A library call name might not be section-encoded yet, so try
356 it against a stripped name. */
359 && strcmp (name
, tname
+ 4) == 0)
360 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
363 name
= darwin_strip_name_encoding (name
);
368 int needs_quotes
= name_needs_quotes (name
);
370 buffer
= alloca (strlen (name
) + 20);
373 strcpy (buffer
, "&\"L");
375 strcpy (buffer
, "&L");
378 strcat (buffer
, name
+1);
382 strcat (buffer
, "_");
383 strcat (buffer
, name
);
387 strcat (buffer
, "$stub\"");
389 strcat (buffer
, "$stub");
390 ptr_name
= get_identifier (buffer
);
392 machopic_stubs
= tree_cons (ptr_name
, ident
, machopic_stubs
);
393 TREE_USED (machopic_stubs
) = 0;
395 return IDENTIFIER_POINTER (ptr_name
);
400 machopic_validate_stub_or_non_lazy_ptr (name
, validate_stub
)
405 tree temp
, ident
= get_identifier (name
), id2
;
407 for (temp
= (validate_stub
? machopic_stubs
: machopic_non_lazy_pointers
);
409 temp
= TREE_CHAIN (temp
))
410 if (ident
== TREE_PURPOSE (temp
))
412 /* Mark both the stub or non-lazy pointer as well as the
413 original symbol as being referenced. */
414 TREE_USED (temp
) = 1;
415 if (TREE_CODE (TREE_VALUE (temp
)) == IDENTIFIER_NODE
)
416 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp
)) = 1;
417 real_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
418 real_name
= darwin_strip_name_encoding (real_name
);
419 id2
= maybe_get_identifier (real_name
);
421 TREE_SYMBOL_REFERENCED (id2
) = 1;
425 /* Transform ORIG, which may be any data source, to the corresponding
426 source using indirections. */
429 machopic_indirect_data_reference (orig
, reg
)
434 if (! MACHOPIC_INDIRECT
)
437 if (GET_CODE (orig
) == SYMBOL_REF
)
439 const char *name
= XSTR (orig
, 0);
441 if (machopic_data_defined_p (name
))
443 rtx pic_base
= gen_rtx (SYMBOL_REF
, Pmode
,
444 machopic_function_base_name ());
445 rtx offset
= gen_rtx (CONST
, Pmode
,
446 gen_rtx (MINUS
, Pmode
, orig
, pic_base
));
448 #if defined (TARGET_TOC) /* i.e., PowerPC */
449 rtx hi_sum_reg
= reg
;
454 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
455 gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
,
456 gen_rtx (HIGH
, Pmode
, offset
))));
457 emit_insn (gen_rtx (SET
, Pmode
, reg
,
458 gen_rtx (LO_SUM
, Pmode
, hi_sum_reg
, offset
)));
462 #if defined (HAVE_lo_sum)
463 if (reg
== 0) abort ();
465 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
466 gen_rtx (HIGH
, Pmode
, offset
)));
467 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
468 gen_rtx (LO_SUM
, Pmode
, reg
, offset
)));
469 emit_insn (gen_rtx (USE
, VOIDmode
,
470 gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
472 orig
= gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
, reg
);
478 ptr_ref
= gen_rtx (SYMBOL_REF
, Pmode
,
479 machopic_non_lazy_ptr_name (name
));
481 ptr_ref
= gen_rtx_MEM (Pmode
, ptr_ref
);
482 RTX_UNCHANGING_P (ptr_ref
) = 1;
486 else if (GET_CODE (orig
) == CONST
)
490 /* legitimize both operands of the PLUS */
491 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
493 base
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 0),
495 orig
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 1),
496 (base
== reg
? 0 : reg
));
501 if (MACHOPIC_PURE
&& GET_CODE (orig
) == CONST_INT
)
502 result
= plus_constant (base
, INTVAL (orig
));
504 result
= gen_rtx (PLUS
, Pmode
, base
, orig
);
506 if (RTX_UNCHANGING_P (base
) && RTX_UNCHANGING_P (orig
))
507 RTX_UNCHANGING_P (result
) = 1;
509 if (MACHOPIC_JUST_INDIRECT
&& GET_CODE (base
) == MEM
)
513 emit_move_insn (reg
, result
);
518 result
= force_reg (GET_MODE (result
), result
);
525 else if (GET_CODE (orig
) == MEM
)
526 XEXP (ptr_ref
, 0) = machopic_indirect_data_reference (XEXP (orig
, 0), reg
);
527 /* When the target is i386, this code prevents crashes due to the
528 compiler's ignorance on how to move the PIC base register to
529 other registers. (The reload phase sometimes introduces such
531 else if (GET_CODE (orig
) == PLUS
532 && GET_CODE (XEXP (orig
, 0)) == REG
533 && REGNO (XEXP (orig
, 0)) == PIC_OFFSET_TABLE_REGNUM
535 /* Prevent the same register from being erroneously used
536 as both the base and index registers. */
537 && GET_CODE (XEXP (orig
, 1)) == CONST
541 emit_move_insn (reg
, XEXP (orig
, 0));
542 XEXP (ptr_ref
, 0) = reg
;
547 /* Transform TARGET (a MEM), which is a function call target, to the
548 corresponding symbol_stub if necessary. Return a new MEM. */
551 machopic_indirect_call_target (target
)
554 if (GET_CODE (target
) != MEM
)
557 if (MACHOPIC_INDIRECT
&& GET_CODE (XEXP (target
, 0)) == SYMBOL_REF
)
559 enum machine_mode mode
= GET_MODE (XEXP (target
, 0));
560 const char *name
= XSTR (XEXP (target
, 0), 0);
562 /* If the name is already defined, we need do nothing. */
563 if (name
[0] == '!' && name
[1] == 'T')
566 if (!machopic_name_defined_p (name
))
568 const char *stub_name
= machopic_stub_name (name
);
570 XEXP (target
, 0) = gen_rtx (SYMBOL_REF
, mode
, stub_name
);
571 RTX_UNCHANGING_P (target
) = 1;
579 machopic_legitimize_pic_address (orig
, mode
, reg
)
581 enum machine_mode mode
;
588 /* First handle a simple SYMBOL_REF or LABEL_REF */
589 if (GET_CODE (orig
) == LABEL_REF
590 || (GET_CODE (orig
) == SYMBOL_REF
593 /* addr(foo) = &func+(foo-func) */
596 orig
= machopic_indirect_data_reference (orig
, reg
);
598 if (GET_CODE (orig
) == PLUS
599 && GET_CODE (XEXP (orig
, 0)) == REG
)
602 return force_reg (mode
, orig
);
604 emit_move_insn (reg
, orig
);
608 pic_base
= gen_rtx (SYMBOL_REF
, Pmode
, machopic_function_base_name ());
610 if (GET_CODE (orig
) == MEM
)
614 if (reload_in_progress
)
617 reg
= gen_reg_rtx (Pmode
);
621 if (GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
622 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
624 rtx offset
= gen_rtx (CONST
, Pmode
,
625 gen_rtx (MINUS
, Pmode
,
626 XEXP (orig
, 0), pic_base
));
627 #if defined (TARGET_TOC) /* i.e., PowerPC */
628 /* Generating a new reg may expose opportunities for
629 common subexpression elimination. */
631 (reload_in_progress
? reg
: gen_reg_rtx (SImode
));
633 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
634 gen_rtx (PLUS
, Pmode
,
635 pic_offset_table_rtx
,
636 gen_rtx (HIGH
, Pmode
, offset
))));
637 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
638 gen_rtx (MEM
, GET_MODE (orig
),
639 gen_rtx (LO_SUM
, Pmode
,
640 hi_sum_reg
, offset
))));
644 emit_insn (gen_rtx (USE
, VOIDmode
,
645 gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
647 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
648 gen_rtx (HIGH
, Pmode
,
649 gen_rtx (CONST
, Pmode
, offset
))));
650 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
651 gen_rtx (LO_SUM
, Pmode
, reg
,
652 gen_rtx (CONST
, Pmode
, offset
))));
653 pic_ref
= gen_rtx (PLUS
, Pmode
,
654 pic_offset_table_rtx
, reg
);
658 #endif /* HAVE_lo_sum */
660 rtx pic
= pic_offset_table_rtx
;
661 if (GET_CODE (pic
) != REG
)
663 emit_move_insn (reg
, pic
);
667 emit_insn (gen_rtx (USE
, VOIDmode
,
668 gen_rtx (REG
, Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
671 pic_ref
= gen_rtx (PLUS
, Pmode
,
673 gen_rtx (CONST
, Pmode
,
674 gen_rtx (MINUS
, Pmode
,
679 #if !defined (TARGET_TOC)
680 RTX_UNCHANGING_P (pic_ref
) = 1;
681 emit_move_insn (reg
, pic_ref
);
682 pic_ref
= gen_rtx (MEM
, GET_MODE (orig
), reg
);
689 if (GET_CODE (orig
) == SYMBOL_REF
690 || GET_CODE (orig
) == LABEL_REF
)
692 rtx offset
= gen_rtx (CONST
, Pmode
,
693 gen_rtx (MINUS
, Pmode
, orig
, pic_base
));
694 #if defined (TARGET_TOC) /* i.e., PowerPC */
699 if (reload_in_progress
)
702 reg
= gen_reg_rtx (SImode
);
707 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
708 gen_rtx (PLUS
, Pmode
,
709 pic_offset_table_rtx
,
710 gen_rtx (HIGH
, Pmode
, offset
))));
711 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
712 gen_rtx (LO_SUM
, Pmode
,
713 hi_sum_reg
, offset
)));
716 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
717 gen_rtx (HIGH
, Pmode
, offset
)));
718 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
719 gen_rtx (LO_SUM
, Pmode
, reg
, offset
)));
720 pic_ref
= gen_rtx (PLUS
, Pmode
,
721 pic_offset_table_rtx
, reg
);
725 #endif /* HAVE_lo_sum */
727 if (GET_CODE (orig
) == REG
)
733 rtx pic
= pic_offset_table_rtx
;
734 if (GET_CODE (pic
) != REG
)
736 emit_move_insn (reg
, pic
);
740 emit_insn (gen_rtx (USE
, VOIDmode
,
741 pic_offset_table_rtx
));
743 pic_ref
= gen_rtx (PLUS
, Pmode
,
745 gen_rtx (CONST
, Pmode
,
746 gen_rtx (MINUS
, Pmode
,
752 RTX_UNCHANGING_P (pic_ref
) = 1;
754 if (GET_CODE (pic_ref
) != REG
)
758 emit_move_insn (reg
, pic_ref
);
763 return force_reg (mode
, pic_ref
);
772 else if (GET_CODE (orig
) == SYMBOL_REF
)
775 else if (GET_CODE (orig
) == PLUS
776 && (GET_CODE (XEXP (orig
, 0)) == MEM
777 || GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
778 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
779 && XEXP (orig
, 0) != pic_offset_table_rtx
780 && GET_CODE (XEXP (orig
, 1)) != REG
)
784 int is_complex
= (GET_CODE (XEXP (orig
, 0)) == MEM
);
786 base
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
787 orig
= machopic_legitimize_pic_address (XEXP (orig
, 1),
788 Pmode
, (base
== reg
? 0 : reg
));
789 if (GET_CODE (orig
) == CONST_INT
)
791 pic_ref
= plus_constant (base
, INTVAL (orig
));
795 pic_ref
= gen_rtx (PLUS
, Pmode
, base
, orig
);
797 if (RTX_UNCHANGING_P (base
) && RTX_UNCHANGING_P (orig
))
798 RTX_UNCHANGING_P (pic_ref
) = 1;
800 if (reg
&& is_complex
)
802 emit_move_insn (reg
, pic_ref
);
805 /* Likewise, should we set special REG_NOTEs here? */
808 else if (GET_CODE (orig
) == CONST
)
810 return machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
813 else if (GET_CODE (orig
) == MEM
814 && GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
)
816 rtx addr
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
818 addr
= gen_rtx (MEM
, GET_MODE (orig
), addr
);
819 RTX_UNCHANGING_P (addr
) = RTX_UNCHANGING_P (orig
);
820 emit_move_insn (reg
, addr
);
829 machopic_finish (asm_out_file
)
834 for (temp
= machopic_stubs
;
836 temp
= TREE_CHAIN (temp
))
838 const char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
839 const char *stub_name
= IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
843 if (! TREE_USED (temp
))
846 /* If the symbol is actually defined, we don't need a stub. */
847 if (sym_name
[0] == '!' && sym_name
[1] == 'T')
850 sym_name
= darwin_strip_name_encoding (sym_name
);
852 sym
= alloca (strlen (sym_name
) + 2);
853 if (sym_name
[0] == '*' || sym_name
[0] == '&')
854 strcpy (sym
, sym_name
+ 1);
855 else if (sym_name
[0] == '-' || sym_name
[0] == '+')
856 strcpy (sym
, sym_name
);
858 sym
[0] = '_', strcpy (sym
+ 1, sym_name
);
860 stub
= alloca (strlen (stub_name
) + 2);
861 if (stub_name
[0] == '*' || stub_name
[0] == '&')
862 strcpy (stub
, stub_name
+ 1);
864 stub
[0] = '_', strcpy (stub
+ 1, stub_name
);
866 machopic_output_stub (asm_out_file
, sym
, stub
);
869 for (temp
= machopic_non_lazy_pointers
;
871 temp
= TREE_CHAIN (temp
))
873 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
874 char *lazy_name
= IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
876 tree decl
= lookup_name_darwin (TREE_VALUE (temp
));
879 if (! TREE_USED (temp
))
882 if (machopic_ident_defined_p (TREE_VALUE (temp
))
883 #if 0 /* add back when we have private externs */
884 || (decl
&& DECL_PRIVATE_EXTERN (decl
))
889 assemble_align (GET_MODE_ALIGNMENT (Pmode
));
890 assemble_label (lazy_name
);
891 assemble_integer (gen_rtx (SYMBOL_REF
, Pmode
, sym_name
),
892 GET_MODE_SIZE (Pmode
),
893 GET_MODE_ALIGNMENT (Pmode
), 1);
897 machopic_nl_symbol_ptr_section ();
898 assemble_name (asm_out_file
, lazy_name
);
899 fprintf (asm_out_file
, ":\n");
901 fprintf (asm_out_file
, "\t.indirect_symbol ");
902 assemble_name (asm_out_file
, sym_name
);
903 fprintf (asm_out_file
, "\n");
905 assemble_integer (const0_rtx
, GET_MODE_SIZE (Pmode
),
906 GET_MODE_ALIGNMENT (Pmode
), 1);
912 machopic_operand_p (op
)
915 if (MACHOPIC_JUST_INDIRECT
)
917 while (GET_CODE (op
) == CONST
)
920 if (GET_CODE (op
) == SYMBOL_REF
)
921 return machopic_name_defined_p (XSTR (op
, 0));
926 while (GET_CODE (op
) == CONST
)
929 if (GET_CODE (op
) == MINUS
930 && GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
931 && GET_CODE (XEXP (op
, 1)) == SYMBOL_REF
932 && machopic_name_defined_p (XSTR (XEXP (op
, 0), 0))
933 && machopic_name_defined_p (XSTR (XEXP (op
, 1), 0)))
936 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
937 /* Without this statement, the compiler crashes while compiling enquire.c
938 when targetting PowerPC. It is not known why this code is not needed
939 when targetting other processors. */
940 else if (GET_CODE (op
) == SYMBOL_REF
941 && (machopic_classify_name (XSTR (op
, 0))
942 == MACHOPIC_DEFINED_FUNCTION
))
951 /* This function records whether a given name corresponds to a defined
952 or undefined function or variable, for machopic_classify_ident to
956 darwin_encode_section_info (decl
, first
)
958 int first ATTRIBUTE_UNUSED
;
963 const char *orig_str
;
967 if ((TREE_CODE (decl
) == FUNCTION_DECL
968 || TREE_CODE (decl
) == VAR_DECL
)
969 && !DECL_EXTERNAL (decl
)
970 && ((TREE_STATIC (decl
)
971 && (!DECL_COMMON (decl
) || !TREE_PUBLIC (decl
)))
972 || (DECL_INITIAL (decl
)
973 && DECL_INITIAL (decl
) != error_mark_node
)))
976 if (TREE_CODE (decl
) == FUNCTION_DECL
)
977 code
= (defined
? 'T' : 't');
978 else if (TREE_CODE (decl
) == VAR_DECL
)
979 code
= (defined
? 'D' : 'd');
984 sym_ref
= XEXP (DECL_RTL (decl
), 0);
985 orig_str
= XSTR (sym_ref
, 0);
986 len
= strlen (orig_str
) + 1;
988 if (orig_str
[0] == '!')
990 /* Already encoded; see if we need to change it. */
991 if (code
== orig_str
[1])
993 /* Yes, tweak a copy of the name and put it in a new string. */
994 new_str
= alloca (len
);
995 memcpy (new_str
, orig_str
, len
);
997 XSTR (sym_ref
, 0) = ggc_alloc_string (new_str
, len
);
1001 /* Add the encoding. */
1003 new_str
= alloca (new_len
);
1008 memcpy (new_str
+ 4, orig_str
, len
);
1009 XSTR (sym_ref
, 0) = ggc_alloc_string (new_str
, new_len
);
1011 /* The non-lazy pointer list may have captured references to the
1012 old encoded name, change them. */
1013 if (TREE_CODE (decl
) == VAR_DECL
)
1014 update_non_lazy_ptrs (XSTR (sym_ref
, 0));
1016 update_stubs (XSTR (sym_ref
, 0));
1019 /* Undo the effects of the above. */
1022 darwin_strip_name_encoding (str
)
1025 return str
[0] == '!' ? str
+ 4 : str
;
1028 /* Scan the list of non-lazy pointers and update any recorded names whose
1029 stripped name matches the argument. */
1032 update_non_lazy_ptrs (name
)
1035 const char *name1
, *name2
;
1038 name1
= darwin_strip_name_encoding (name
);
1040 for (temp
= machopic_non_lazy_pointers
;
1042 temp
= TREE_CHAIN (temp
))
1044 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1046 if (*sym_name
== '!')
1048 name2
= darwin_strip_name_encoding (sym_name
);
1049 if (strcmp (name1
, name2
) == 0)
1051 IDENTIFIER_POINTER (TREE_VALUE (temp
)) = name
;
1058 /* Function NAME is being defined, and its label has just been output.
1059 If there's already a reference to a stub for this function, we can
1060 just emit the stub label now and we don't bother emitting the stub later. */
1063 machopic_output_possible_stub_label (file
, name
)
1070 /* Ensure we're looking at a section-encoded name. */
1071 if (name
[0] != '!' || (name
[1] != 't' && name
[1] != 'T'))
1074 for (temp
= machopic_stubs
;
1076 temp
= TREE_CHAIN (temp
))
1078 const char *sym_name
;
1080 sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1081 if (sym_name
[0] == '!' && sym_name
[1] == 'T'
1082 && ! strcmp (name
+2, sym_name
+2))
1084 ASM_OUTPUT_LABEL (file
, IDENTIFIER_POINTER (TREE_PURPOSE (temp
)));
1085 /* Avoid generating a stub for this. */
1086 TREE_USED (temp
) = 0;
1092 /* Scan the list of stubs and update any recorded names whose
1093 stripped name matches the argument. */
1099 const char *name1
, *name2
;
1102 name1
= darwin_strip_name_encoding (name
);
1104 for (temp
= machopic_stubs
;
1106 temp
= TREE_CHAIN (temp
))
1108 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1110 if (*sym_name
== '!')
1112 name2
= darwin_strip_name_encoding (sym_name
);
1113 if (strcmp (name1
, name2
) == 0)
1115 IDENTIFIER_POINTER (TREE_VALUE (temp
)) = name
;
1123 machopic_select_section (exp
, reloc
, align
)
1126 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
;
1128 if (TREE_CODE (exp
) == STRING_CST
)
1130 if (flag_writable_strings
)
1132 else if (TREE_STRING_LENGTH (exp
) !=
1133 strlen (TREE_STRING_POINTER (exp
)) + 1)
1134 readonly_data_section ();
1138 else if (TREE_CODE (exp
) == INTEGER_CST
1139 || TREE_CODE (exp
) == REAL_CST
)
1141 tree size
= TYPE_SIZE (TREE_TYPE (exp
));
1143 if (TREE_CODE (size
) == INTEGER_CST
&&
1144 TREE_INT_CST_LOW (size
) == 4 &&
1145 TREE_INT_CST_HIGH (size
) == 0)
1146 literal4_section ();
1147 else if (TREE_CODE (size
) == INTEGER_CST
&&
1148 TREE_INT_CST_LOW (size
) == 8 &&
1149 TREE_INT_CST_HIGH (size
) == 0)
1150 literal8_section ();
1152 readonly_data_section ();
1154 else if (TREE_CODE (exp
) == CONSTRUCTOR
1156 && TREE_CODE (TREE_TYPE (exp
)) == RECORD_TYPE
1157 && TYPE_NAME (TREE_TYPE (exp
)))
1159 tree name
= TYPE_NAME (TREE_TYPE (exp
));
1160 if (TREE_CODE (name
) == TYPE_DECL
)
1161 name
= DECL_NAME (name
);
1162 if (!strcmp (IDENTIFIER_POINTER (name
), "NSConstantString"))
1163 objc_constant_string_object_section ();
1164 else if (!strcmp (IDENTIFIER_POINTER (name
), "NXConstantString"))
1165 objc_string_object_section ();
1166 else if (TREE_READONLY (exp
) || TREE_CONSTANT (exp
))
1168 if (TREE_SIDE_EFFECTS (exp
) || flag_pic
&& reloc
)
1169 const_data_section ();
1171 readonly_data_section ();
1176 else if (TREE_CODE (exp
) == VAR_DECL
&&
1178 TREE_CODE (DECL_NAME (exp
)) == IDENTIFIER_NODE
&&
1179 IDENTIFIER_POINTER (DECL_NAME (exp
)) &&
1180 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), "_OBJC_", 6))
1182 const char *name
= IDENTIFIER_POINTER (DECL_NAME (exp
));
1184 if (!strncmp (name
, "_OBJC_CLASS_METHODS_", 20))
1185 objc_cls_meth_section ();
1186 else if (!strncmp (name
, "_OBJC_INSTANCE_METHODS_", 23))
1187 objc_inst_meth_section ();
1188 else if (!strncmp (name
, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1189 objc_cat_cls_meth_section ();
1190 else if (!strncmp (name
, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1191 objc_cat_inst_meth_section ();
1192 else if (!strncmp (name
, "_OBJC_CLASS_VARIABLES_", 22))
1193 objc_class_vars_section ();
1194 else if (!strncmp (name
, "_OBJC_INSTANCE_VARIABLES_", 25))
1195 objc_instance_vars_section ();
1196 else if (!strncmp (name
, "_OBJC_CLASS_PROTOCOLS_", 22))
1197 objc_cat_cls_meth_section ();
1198 else if (!strncmp (name
, "_OBJC_CLASS_NAME_", 17))
1199 objc_class_names_section ();
1200 else if (!strncmp (name
, "_OBJC_METH_VAR_NAME_", 20))
1201 objc_meth_var_names_section ();
1202 else if (!strncmp (name
, "_OBJC_METH_VAR_TYPE_", 20))
1203 objc_meth_var_types_section ();
1204 else if (!strncmp (name
, "_OBJC_CLASS_REFERENCES", 22))
1205 objc_cls_refs_section ();
1206 else if (!strncmp (name
, "_OBJC_CLASS_", 12))
1207 objc_class_section ();
1208 else if (!strncmp (name
, "_OBJC_METACLASS_", 16))
1209 objc_meta_class_section ();
1210 else if (!strncmp (name
, "_OBJC_CATEGORY_", 15))
1211 objc_category_section ();
1212 else if (!strncmp (name
, "_OBJC_SELECTOR_REFERENCES", 25))
1213 objc_selector_refs_section ();
1214 else if (!strncmp (name
, "_OBJC_SELECTOR_FIXUP", 20))
1215 objc_selector_fixup_section ();
1216 else if (!strncmp (name
, "_OBJC_SYMBOLS", 13))
1217 objc_symbols_section ();
1218 else if (!strncmp (name
, "_OBJC_MODULES", 13))
1219 objc_module_info_section ();
1220 else if (!strncmp (name
, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1221 objc_cat_inst_meth_section ();
1222 else if (!strncmp (name
, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1223 objc_cat_cls_meth_section ();
1224 else if (!strncmp (name
, "_OBJC_PROTOCOL_REFS_", 20))
1225 objc_cat_cls_meth_section ();
1226 else if (!strncmp (name
, "_OBJC_PROTOCOL_", 15))
1227 objc_protocol_section ();
1228 else if ((TREE_READONLY (exp
) || TREE_CONSTANT (exp
))
1229 && !TREE_SIDE_EFFECTS (exp
))
1231 if (flag_pic
&& reloc
)
1232 const_data_section ();
1234 readonly_data_section ();
1239 else if (TREE_READONLY (exp
) || TREE_CONSTANT (exp
))
1241 if (TREE_SIDE_EFFECTS (exp
) || flag_pic
&& reloc
)
1242 const_data_section ();
1244 readonly_data_section ();
1250 /* This can be called with address expressions as "rtx".
1251 They must go in "const". */
1254 machopic_select_rtx_section (mode
, x
, align
)
1255 enum machine_mode mode
;
1257 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
;
1259 if (GET_MODE_SIZE (mode
) == 8)
1260 literal8_section ();
1261 else if (GET_MODE_SIZE (mode
) == 4
1262 && (GET_CODE (x
) == CONST_INT
1263 || GET_CODE (x
) == CONST_DOUBLE
))
1264 literal4_section ();
1270 machopic_asm_out_constructor (symbol
, priority
)
1272 int priority ATTRIBUTE_UNUSED
;
1275 mod_init_section ();
1277 constructor_section ();
1278 assemble_align (POINTER_SIZE
);
1279 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1282 fprintf (asm_out_file
, ".reference .constructors_used\n");
1286 machopic_asm_out_destructor (symbol
, priority
)
1288 int priority ATTRIBUTE_UNUSED
;
1291 mod_term_section ();
1293 destructor_section ();
1294 assemble_align (POINTER_SIZE
);
1295 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1298 fprintf (asm_out_file
, ".reference .destructors_used\n");