1 /* Functions for generic Darwin as target machine for GNU C compiler.
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001
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 STRIP_NAME_ENCODING (name
, 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 STRIP_NAME_ENCODING (temp_name
, 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 STRIP_NAME_ENCODING (name
, 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 STRIP_NAME_ENCODING (real_name
, IDENTIFIER_POINTER (TREE_VALUE (temp
)));
418 id2
= maybe_get_identifier (real_name
);
420 TREE_SYMBOL_REFERENCED (id2
) = 1;
424 /* Transform ORIG, which may be any data source, to the corresponding
425 source using indirections. */
428 machopic_indirect_data_reference (orig
, reg
)
433 if (! MACHOPIC_INDIRECT
)
436 if (GET_CODE (orig
) == SYMBOL_REF
)
438 const char *name
= XSTR (orig
, 0);
440 if (machopic_data_defined_p (name
))
442 rtx pic_base
= gen_rtx (SYMBOL_REF
, Pmode
,
443 machopic_function_base_name ());
444 rtx offset
= gen_rtx (CONST
, Pmode
,
445 gen_rtx (MINUS
, Pmode
, orig
, pic_base
));
447 #if defined (TARGET_TOC) /* i.e., PowerPC */
448 rtx hi_sum_reg
= reg
;
453 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
454 gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
,
455 gen_rtx (HIGH
, Pmode
, offset
))));
456 emit_insn (gen_rtx (SET
, Pmode
, reg
,
457 gen_rtx (LO_SUM
, Pmode
, hi_sum_reg
, offset
)));
461 #if defined (HAVE_lo_sum)
462 if (reg
== 0) abort ();
464 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
465 gen_rtx (HIGH
, Pmode
, offset
)));
466 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
467 gen_rtx (LO_SUM
, Pmode
, reg
, offset
)));
468 emit_insn (gen_rtx (USE
, VOIDmode
,
469 gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
471 orig
= gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
, reg
);
477 ptr_ref
= gen_rtx (SYMBOL_REF
, Pmode
,
478 machopic_non_lazy_ptr_name (name
));
480 ptr_ref
= gen_rtx_MEM (Pmode
, ptr_ref
);
481 RTX_UNCHANGING_P (ptr_ref
) = 1;
485 else if (GET_CODE (orig
) == CONST
)
489 /* legitimize both operands of the PLUS */
490 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
492 base
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 0),
494 orig
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 1),
495 (base
== reg
? 0 : reg
));
500 if (MACHOPIC_PURE
&& GET_CODE (orig
) == CONST_INT
)
501 result
= plus_constant (base
, INTVAL (orig
));
503 result
= gen_rtx (PLUS
, Pmode
, base
, orig
);
505 if (RTX_UNCHANGING_P (base
) && RTX_UNCHANGING_P (orig
))
506 RTX_UNCHANGING_P (result
) = 1;
508 if (MACHOPIC_JUST_INDIRECT
&& GET_CODE (base
) == MEM
)
512 emit_move_insn (reg
, result
);
517 result
= force_reg (GET_MODE (result
), result
);
524 else if (GET_CODE (orig
) == MEM
)
525 XEXP (ptr_ref
, 0) = machopic_indirect_data_reference (XEXP (orig
, 0), reg
);
526 /* When the target is i386, this code prevents crashes due to the
527 compiler's ignorance on how to move the PIC base register to
528 other registers. (The reload phase sometimes introduces such
530 else if (GET_CODE (orig
) == PLUS
531 && GET_CODE (XEXP (orig
, 0)) == REG
532 && REGNO (XEXP (orig
, 0)) == PIC_OFFSET_TABLE_REGNUM
534 /* Prevent the same register from being erroneously used
535 as both the base and index registers. */
536 && GET_CODE (XEXP (orig
, 1)) == CONST
540 emit_move_insn (reg
, XEXP (orig
, 0));
541 XEXP (ptr_ref
, 0) = reg
;
546 /* Transform TARGET (a MEM), which is a function call target, to the
547 corresponding symbol_stub if necessary. Return a new MEM. */
550 machopic_indirect_call_target (target
)
553 if (GET_CODE (target
) != MEM
)
556 if (MACHOPIC_INDIRECT
&& GET_CODE (XEXP (target
, 0)) == SYMBOL_REF
)
558 enum machine_mode mode
= GET_MODE (XEXP (target
, 0));
559 const char *name
= XSTR (XEXP (target
, 0), 0);
561 /* If the name is already defined, we need do nothing. */
562 if (name
[0] == '!' && name
[1] == 'T')
565 if (!machopic_name_defined_p (name
))
567 const char *stub_name
= machopic_stub_name (name
);
569 XEXP (target
, 0) = gen_rtx (SYMBOL_REF
, mode
, stub_name
);
570 RTX_UNCHANGING_P (target
) = 1;
578 machopic_legitimize_pic_address (orig
, mode
, reg
)
580 enum machine_mode mode
;
587 /* First handle a simple SYMBOL_REF or LABEL_REF */
588 if (GET_CODE (orig
) == LABEL_REF
589 || (GET_CODE (orig
) == SYMBOL_REF
592 /* addr(foo) = &func+(foo-func) */
595 orig
= machopic_indirect_data_reference (orig
, reg
);
597 if (GET_CODE (orig
) == PLUS
598 && GET_CODE (XEXP (orig
, 0)) == REG
)
601 return force_reg (mode
, orig
);
603 emit_move_insn (reg
, orig
);
607 pic_base
= gen_rtx (SYMBOL_REF
, Pmode
, machopic_function_base_name ());
609 if (GET_CODE (orig
) == MEM
)
613 if (reload_in_progress
)
616 reg
= gen_reg_rtx (Pmode
);
620 if (GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
621 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
623 rtx offset
= gen_rtx (CONST
, Pmode
,
624 gen_rtx (MINUS
, Pmode
,
625 XEXP (orig
, 0), pic_base
));
626 #if defined (TARGET_TOC) /* i.e., PowerPC */
627 /* Generating a new reg may expose opportunities for
628 common subexpression elimination. */
630 (reload_in_progress
? reg
: gen_reg_rtx (SImode
));
632 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
633 gen_rtx (PLUS
, Pmode
,
634 pic_offset_table_rtx
,
635 gen_rtx (HIGH
, Pmode
, offset
))));
636 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
637 gen_rtx (MEM
, GET_MODE (orig
),
638 gen_rtx (LO_SUM
, Pmode
,
639 hi_sum_reg
, offset
))));
643 emit_insn (gen_rtx (USE
, VOIDmode
,
644 gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
646 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
647 gen_rtx (HIGH
, Pmode
,
648 gen_rtx (CONST
, Pmode
, offset
))));
649 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
650 gen_rtx (LO_SUM
, Pmode
, reg
,
651 gen_rtx (CONST
, Pmode
, offset
))));
652 pic_ref
= gen_rtx (PLUS
, Pmode
,
653 pic_offset_table_rtx
, reg
);
657 #endif /* HAVE_lo_sum */
659 rtx pic
= pic_offset_table_rtx
;
660 if (GET_CODE (pic
) != REG
)
662 emit_move_insn (reg
, pic
);
666 emit_insn (gen_rtx (USE
, VOIDmode
,
667 gen_rtx (REG
, Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
670 pic_ref
= gen_rtx (PLUS
, Pmode
,
672 gen_rtx (CONST
, Pmode
,
673 gen_rtx (MINUS
, Pmode
,
678 #if !defined (TARGET_TOC)
679 RTX_UNCHANGING_P (pic_ref
) = 1;
680 emit_move_insn (reg
, pic_ref
);
681 pic_ref
= gen_rtx (MEM
, GET_MODE (orig
), reg
);
688 if (GET_CODE (orig
) == SYMBOL_REF
689 || GET_CODE (orig
) == LABEL_REF
)
691 rtx offset
= gen_rtx (CONST
, Pmode
,
692 gen_rtx (MINUS
, Pmode
, orig
, pic_base
));
693 #if defined (TARGET_TOC) /* i.e., PowerPC */
698 if (reload_in_progress
)
701 reg
= gen_reg_rtx (SImode
);
706 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
707 gen_rtx (PLUS
, Pmode
,
708 pic_offset_table_rtx
,
709 gen_rtx (HIGH
, Pmode
, offset
))));
710 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
711 gen_rtx (LO_SUM
, Pmode
,
712 hi_sum_reg
, offset
)));
715 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
716 gen_rtx (HIGH
, Pmode
, offset
)));
717 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
718 gen_rtx (LO_SUM
, Pmode
, reg
, offset
)));
719 pic_ref
= gen_rtx (PLUS
, Pmode
,
720 pic_offset_table_rtx
, reg
);
724 #endif /* HAVE_lo_sum */
726 if (GET_CODE (orig
) == REG
)
732 rtx pic
= pic_offset_table_rtx
;
733 if (GET_CODE (pic
) != REG
)
735 emit_move_insn (reg
, pic
);
739 emit_insn (gen_rtx (USE
, VOIDmode
,
740 pic_offset_table_rtx
));
742 pic_ref
= gen_rtx (PLUS
, Pmode
,
744 gen_rtx (CONST
, Pmode
,
745 gen_rtx (MINUS
, Pmode
,
751 RTX_UNCHANGING_P (pic_ref
) = 1;
753 if (GET_CODE (pic_ref
) != REG
)
757 emit_move_insn (reg
, pic_ref
);
762 return force_reg (mode
, pic_ref
);
771 else if (GET_CODE (orig
) == SYMBOL_REF
)
774 else if (GET_CODE (orig
) == PLUS
775 && (GET_CODE (XEXP (orig
, 0)) == MEM
776 || GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
777 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
778 && XEXP (orig
, 0) != pic_offset_table_rtx
779 && GET_CODE (XEXP (orig
, 1)) != REG
)
783 int is_complex
= (GET_CODE (XEXP (orig
, 0)) == MEM
);
785 base
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
786 orig
= machopic_legitimize_pic_address (XEXP (orig
, 1),
787 Pmode
, (base
== reg
? 0 : reg
));
788 if (GET_CODE (orig
) == CONST_INT
)
790 pic_ref
= plus_constant (base
, INTVAL (orig
));
794 pic_ref
= gen_rtx (PLUS
, Pmode
, base
, orig
);
796 if (RTX_UNCHANGING_P (base
) && RTX_UNCHANGING_P (orig
))
797 RTX_UNCHANGING_P (pic_ref
) = 1;
799 if (reg
&& is_complex
)
801 emit_move_insn (reg
, pic_ref
);
804 /* Likewise, should we set special REG_NOTEs here? */
807 else if (GET_CODE (orig
) == CONST
)
809 return machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
812 else if (GET_CODE (orig
) == MEM
813 && GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
)
815 rtx addr
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
817 addr
= gen_rtx (MEM
, GET_MODE (orig
), addr
);
818 RTX_UNCHANGING_P (addr
) = RTX_UNCHANGING_P (orig
);
819 emit_move_insn (reg
, addr
);
828 machopic_finish (asm_out_file
)
833 for (temp
= machopic_stubs
;
835 temp
= TREE_CHAIN (temp
))
837 const char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
838 const char *stub_name
= IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
842 if (! TREE_USED (temp
))
845 /* If the symbol is actually defined, we don't need a stub. */
846 if (sym_name
[0] == '!' && sym_name
[1] == 'T')
849 STRIP_NAME_ENCODING (sym_name
, sym_name
);
851 sym
= alloca (strlen (sym_name
) + 2);
852 if (sym_name
[0] == '*' || sym_name
[0] == '&')
853 strcpy (sym
, sym_name
+ 1);
854 else if (sym_name
[0] == '-' || sym_name
[0] == '+')
855 strcpy (sym
, sym_name
);
857 sym
[0] = '_', strcpy (sym
+ 1, sym_name
);
859 stub
= alloca (strlen (stub_name
) + 2);
860 if (stub_name
[0] == '*' || stub_name
[0] == '&')
861 strcpy (stub
, stub_name
+ 1);
863 stub
[0] = '_', strcpy (stub
+ 1, stub_name
);
865 machopic_output_stub (asm_out_file
, sym
, stub
);
868 for (temp
= machopic_non_lazy_pointers
;
870 temp
= TREE_CHAIN (temp
))
872 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
873 char *lazy_name
= IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
875 tree decl
= lookup_name_darwin (TREE_VALUE (temp
));
878 if (! TREE_USED (temp
))
881 if (machopic_ident_defined_p (TREE_VALUE (temp
))
882 #if 0 /* add back when we have private externs */
883 || (decl
&& DECL_PRIVATE_EXTERN (decl
))
888 assemble_align (GET_MODE_ALIGNMENT (Pmode
));
889 assemble_label (lazy_name
);
890 assemble_integer (gen_rtx (SYMBOL_REF
, Pmode
, sym_name
),
891 GET_MODE_SIZE (Pmode
),
892 GET_MODE_ALIGNMENT (Pmode
), 1);
896 machopic_nl_symbol_ptr_section ();
897 assemble_name (asm_out_file
, lazy_name
);
898 fprintf (asm_out_file
, ":\n");
900 fprintf (asm_out_file
, "\t.indirect_symbol ");
901 assemble_name (asm_out_file
, sym_name
);
902 fprintf (asm_out_file
, "\n");
904 assemble_integer (const0_rtx
, GET_MODE_SIZE (Pmode
),
905 GET_MODE_ALIGNMENT (Pmode
), 1);
911 machopic_operand_p (op
)
914 if (MACHOPIC_JUST_INDIRECT
)
916 while (GET_CODE (op
) == CONST
)
919 if (GET_CODE (op
) == SYMBOL_REF
)
920 return machopic_name_defined_p (XSTR (op
, 0));
925 while (GET_CODE (op
) == CONST
)
928 if (GET_CODE (op
) == MINUS
929 && GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
930 && GET_CODE (XEXP (op
, 1)) == SYMBOL_REF
931 && machopic_name_defined_p (XSTR (XEXP (op
, 0), 0))
932 && machopic_name_defined_p (XSTR (XEXP (op
, 1), 0)))
935 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
936 /* Without this statement, the compiler crashes while compiling enquire.c
937 when targetting PowerPC. It is not known why this code is not needed
938 when targetting other processors. */
939 else if (GET_CODE (op
) == SYMBOL_REF
940 && (machopic_classify_name (XSTR (op
, 0))
941 == MACHOPIC_DEFINED_FUNCTION
))
950 /* This function records whether a given name corresponds to a defined
951 or undefined function or variable, for machopic_classify_ident to
955 darwin_encode_section_info (decl
)
961 const char *orig_str
;
965 if ((TREE_CODE (decl
) == FUNCTION_DECL
966 || TREE_CODE (decl
) == VAR_DECL
)
967 && !DECL_EXTERNAL (decl
)
968 && ((TREE_STATIC (decl
)
969 && (!DECL_COMMON (decl
) || !TREE_PUBLIC (decl
)))
970 || (DECL_INITIAL (decl
)
971 && DECL_INITIAL (decl
) != error_mark_node
)))
974 if (TREE_CODE (decl
) == FUNCTION_DECL
)
975 code
= (defined
? 'T' : 't');
976 else if (TREE_CODE (decl
) == VAR_DECL
)
977 code
= (defined
? 'D' : 'd');
982 sym_ref
= XEXP (DECL_RTL (decl
), 0);
983 orig_str
= XSTR (sym_ref
, 0);
984 len
= strlen (orig_str
) + 1;
986 if (orig_str
[0] == '!')
988 /* Already encoded; see if we need to change it. */
989 if (code
== orig_str
[1])
991 /* Yes, tweak a copy of the name and put it in a new string. */
992 new_str
= alloca (len
);
993 memcpy (new_str
, orig_str
, len
);
995 XSTR (sym_ref
, 0) = ggc_alloc_string (new_str
, len
);
999 /* Add the encoding. */
1001 new_str
= alloca (new_len
);
1006 memcpy (new_str
+ 4, orig_str
, len
);
1007 XSTR (sym_ref
, 0) = ggc_alloc_string (new_str
, new_len
);
1009 /* The non-lazy pointer list may have captured references to the
1010 old encoded name, change them. */
1011 if (TREE_CODE (decl
) == VAR_DECL
)
1012 update_non_lazy_ptrs (XSTR (sym_ref
, 0));
1014 update_stubs (XSTR (sym_ref
, 0));
1017 /* Scan the list of non-lazy pointers and update any recorded names whose
1018 stripped name matches the argument. */
1021 update_non_lazy_ptrs (name
)
1024 const char *name1
, *name2
;
1027 STRIP_NAME_ENCODING (name1
, name
);
1029 for (temp
= machopic_non_lazy_pointers
;
1031 temp
= TREE_CHAIN (temp
))
1033 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1035 if (*sym_name
== '!')
1037 STRIP_NAME_ENCODING (name2
, sym_name
);
1038 if (strcmp (name1
, name2
) == 0)
1040 IDENTIFIER_POINTER (TREE_VALUE (temp
)) = name
;
1047 /* Function NAME is being defined, and its label has just been output.
1048 If there's already a reference to a stub for this function, we can
1049 just emit the stub label now and we don't bother emitting the stub later. */
1052 machopic_output_possible_stub_label (file
, name
)
1059 /* Ensure we're looking at a section-encoded name. */
1060 if (name
[0] != '!' || (name
[1] != 't' && name
[1] != 'T'))
1063 for (temp
= machopic_stubs
;
1065 temp
= TREE_CHAIN (temp
))
1067 const char *sym_name
;
1069 sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1070 if (sym_name
[0] == '!' && sym_name
[1] == 'T'
1071 && ! strcmp (name
+2, sym_name
+2))
1073 ASM_OUTPUT_LABEL (file
, IDENTIFIER_POINTER (TREE_PURPOSE (temp
)));
1074 /* Avoid generating a stub for this. */
1075 TREE_USED (temp
) = 0;
1081 /* Scan the list of stubs and update any recorded names whose
1082 stripped name matches the argument. */
1088 const char *name1
, *name2
;
1091 STRIP_NAME_ENCODING (name1
, name
);
1093 for (temp
= machopic_stubs
;
1095 temp
= TREE_CHAIN (temp
))
1097 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1099 if (*sym_name
== '!')
1101 STRIP_NAME_ENCODING (name2
, sym_name
);
1102 if (strcmp (name1
, name2
) == 0)
1104 IDENTIFIER_POINTER (TREE_VALUE (temp
)) = name
;
1112 machopic_asm_out_constructor (symbol
, priority
)
1114 int priority ATTRIBUTE_UNUSED
;
1117 mod_init_section ();
1119 constructor_section ();
1120 assemble_align (POINTER_SIZE
);
1121 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1124 fprintf (asm_out_file
, ".reference .constructors_used\n");
1128 machopic_asm_out_destructor (symbol
, priority
)
1130 int priority ATTRIBUTE_UNUSED
;
1133 mod_term_section ();
1135 destructor_section ();
1136 assemble_align (POINTER_SIZE
);
1137 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1140 fprintf (asm_out_file
, ".reference .destructors_used\n");