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"
41 #include "darwin-protos.h"
43 extern void machopic_output_stub PARAMS ((FILE *, const char *, const char *));
45 static int machopic_data_defined_p PARAMS ((const char *));
46 static int func_name_maybe_scoped PARAMS ((const char *));
47 static void update_non_lazy_ptrs PARAMS ((const char *));
49 /* Make everything that used to go in the text section really go there. */
51 int flag_no_mach_text_sections = 0;
54 name_needs_quotes (name)
58 while ((c = *name++) != '\0')
59 if (!isalnum (c) && c != '_')
65 * flag_pic = 1 ... generate only indirections
66 * flag_pic = 2 ... generate indirections and pure code
69 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
70 reference, which will not be changed. */
72 static tree machopic_defined_list;
74 enum machopic_addr_class
75 machopic_classify_ident (ident)
78 const char *name = IDENTIFIER_POINTER (ident);
79 int lprefix = (((name[0] == '*' || name[0] == '&')
80 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
91 /* Here if no special encoding to be found. */
94 const char *name = IDENTIFIER_POINTER (ident);
95 int len = strlen (name);
97 if ((len > 5 && !strcmp (name + len - 5, "$stub"))
98 || (len > 6 && !strcmp (name + len - 6, "$stub\"")))
99 return MACHOPIC_DEFINED_FUNCTION;
100 return MACHOPIC_DEFINED_DATA;
103 for (temp = machopic_defined_list;
105 temp = TREE_CHAIN (temp))
107 if (ident == TREE_VALUE (temp))
108 return MACHOPIC_DEFINED_DATA;
111 if (TREE_ASM_WRITTEN (ident))
112 return MACHOPIC_DEFINED_DATA;
114 return MACHOPIC_UNDEFINED;
117 else if (name[1] == 'D')
118 return MACHOPIC_DEFINED_DATA;
120 else if (name[1] == 'T')
121 return MACHOPIC_DEFINED_FUNCTION;
123 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
125 if (ident == TREE_VALUE (temp))
128 return MACHOPIC_DEFINED_FUNCTION;
130 return MACHOPIC_DEFINED_DATA;
134 if (name[1] == 't' || name[1] == 'T')
137 return MACHOPIC_DEFINED_FUNCTION;
139 return MACHOPIC_UNDEFINED_FUNCTION;
144 return MACHOPIC_DEFINED_DATA;
146 return MACHOPIC_UNDEFINED_DATA;
151 enum machopic_addr_class
152 machopic_classify_name (name)
155 return machopic_classify_ident (get_identifier (name));
159 machopic_ident_defined_p (ident)
162 switch (machopic_classify_ident (ident))
164 case MACHOPIC_UNDEFINED:
165 case MACHOPIC_UNDEFINED_DATA:
166 case MACHOPIC_UNDEFINED_FUNCTION:
174 machopic_data_defined_p (name)
177 switch (machopic_classify_ident (get_identifier (name)))
179 case MACHOPIC_DEFINED_DATA:
187 machopic_name_defined_p (name)
190 return machopic_ident_defined_p (get_identifier (name));
194 machopic_define_ident (ident)
197 if (!machopic_ident_defined_p (ident))
198 machopic_defined_list =
199 tree_cons (NULL_TREE, ident, machopic_defined_list);
203 machopic_define_name (name)
206 machopic_define_ident (get_identifier (name));
209 /* This is a static to make inline functions work. The rtx
210 representing the PIC base symbol always points to here. */
212 static char function_base[32];
214 static int current_pic_label_num;
217 machopic_function_base_name ()
219 static char *name = NULL;
220 static const char *current_name;
222 current_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
224 if (name != current_name)
226 current_function_uses_pic_offset_table = 1;
228 /* Save mucho space and time. Some of the C++ mangled names are over
229 700 characters long! Note that we produce a label containing a '-'
230 if the function we're compiling is an Objective-C method, as evinced
231 by the incredibly scientific test below. This is because code in
232 rs6000.c makes the same ugly test when loading the PIC reg. */
234 ++current_pic_label_num;
235 if (*current_name == '+' || *current_name == '-')
236 sprintf (function_base, "*\"L-%d$pb\"", current_pic_label_num);
238 sprintf (function_base, "*L%d$pb", current_pic_label_num);
243 return function_base;
246 static tree machopic_non_lazy_pointers = NULL;
248 /* Return a non-lazy pointer name corresponding to the given name,
249 either by finding it in our list of pointer names, or by generating
253 machopic_non_lazy_ptr_name (name)
257 tree temp, ident = get_identifier (name);
259 for (temp = machopic_non_lazy_pointers;
261 temp = TREE_CHAIN (temp))
263 if (ident == TREE_VALUE (temp))
264 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
267 STRIP_NAME_ENCODING (name, name);
269 /* Try again, but comparing names this time. */
270 for (temp = machopic_non_lazy_pointers;
272 temp = TREE_CHAIN (temp))
274 if (TREE_VALUE (temp))
276 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
277 STRIP_NAME_ENCODING (temp_name, temp_name);
278 if (strcmp (name, temp_name) == 0)
279 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
287 buffer = alloca (strlen (name) + 20);
289 strcpy (buffer, "&L");
291 strcat (buffer, name+1);
294 strcat (buffer, "_");
295 strcat (buffer, name);
298 strcat (buffer, "$non_lazy_ptr");
299 ptr_name = get_identifier (buffer);
301 machopic_non_lazy_pointers
302 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
304 TREE_USED (machopic_non_lazy_pointers) = 0;
306 return IDENTIFIER_POINTER (ptr_name);
310 static tree machopic_stubs = 0;
312 /* Make sure the GC knows about our homemade lists. */
315 machopic_add_gc_roots ()
317 ggc_add_tree_root (&machopic_defined_list, 1);
318 ggc_add_tree_root (&machopic_non_lazy_pointers, 1);
319 ggc_add_tree_root (&machopic_stubs, 1);
322 /* Return the name of the stub corresponding to the given name,
323 generating a new stub name if necessary. */
326 machopic_stub_name (name)
329 tree temp, ident = get_identifier (name);
331 for (temp = machopic_stubs;
333 temp = TREE_CHAIN (temp))
335 if (ident == TREE_VALUE (temp))
336 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
339 STRIP_NAME_ENCODING (name, name);
344 int needs_quotes = name_needs_quotes (name);
346 buffer = alloca (strlen (name) + 20);
349 strcpy (buffer, "&\"L");
351 strcpy (buffer, "&L");
354 strcat (buffer, name+1);
358 strcat (buffer, "_");
359 strcat (buffer, name);
363 strcat (buffer, "$stub\"");
365 strcat (buffer, "$stub");
366 ptr_name = get_identifier (buffer);
368 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
369 TREE_USED (machopic_stubs) = 0;
371 return IDENTIFIER_POINTER (ptr_name);
376 machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
381 tree temp, ident = get_identifier (name), id2;
383 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
385 temp = TREE_CHAIN (temp))
386 if (ident == TREE_PURPOSE (temp))
388 /* Mark both the stub or non-lazy pointer as well as the
389 original symbol as being referenced. */
390 TREE_USED (temp) = 1;
391 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
392 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
393 STRIP_NAME_ENCODING (real_name, IDENTIFIER_POINTER (TREE_VALUE (temp)));
394 id2 = maybe_get_identifier (real_name);
396 TREE_SYMBOL_REFERENCED (id2) = 1;
400 /* Transform ORIG, which may be any data source, to the corresponding
401 source using indirections. */
404 machopic_indirect_data_reference (orig, reg)
409 if (! MACHOPIC_INDIRECT)
412 if (GET_CODE (orig) == SYMBOL_REF)
414 const char *name = XSTR (orig, 0);
416 if (machopic_data_defined_p (name))
418 rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
419 machopic_function_base_name ());
420 rtx offset = gen_rtx (CONST, Pmode,
421 gen_rtx (MINUS, Pmode, orig, pic_base));
423 #if defined (TARGET_TOC) /* i.e., PowerPC */
424 rtx hi_sum_reg = reg;
429 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
430 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
431 gen_rtx (HIGH, Pmode, offset))));
432 emit_insn (gen_rtx (SET, Pmode, reg,
433 gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
437 #if defined (HAVE_lo_sum)
438 if (reg == 0) abort ();
440 emit_insn (gen_rtx (SET, VOIDmode, reg,
441 gen_rtx (HIGH, Pmode, offset)));
442 emit_insn (gen_rtx (SET, VOIDmode, reg,
443 gen_rtx (LO_SUM, Pmode, reg, offset)));
444 emit_insn (gen_rtx (USE, VOIDmode,
445 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
447 orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
453 ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
454 machopic_non_lazy_ptr_name (name));
456 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
457 RTX_UNCHANGING_P (ptr_ref) = 1;
461 else if (GET_CODE (orig) == CONST)
465 /* legitimize both operands of the PLUS */
466 if (GET_CODE (XEXP (orig, 0)) == PLUS)
468 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
470 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
471 (base == reg ? 0 : reg));
476 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
478 result = plus_constant_for_output (base, INTVAL (orig));
482 result = gen_rtx (PLUS, Pmode, base, orig);
485 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
486 RTX_UNCHANGING_P (result) = 1;
488 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
492 emit_move_insn (reg, result);
497 result = force_reg (GET_MODE (result), result);
504 else if (GET_CODE (orig) == MEM)
505 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
506 /* When the target is i386, this code prevents crashes due to the
507 compiler's ignorance on how to move the PIC base register to
508 other registers. (The reload phase sometimes introduces such
510 else if (GET_CODE (orig) == PLUS
511 && GET_CODE (XEXP (orig, 0)) == REG
512 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
514 /* Prevent the same register from being erroneously used
515 as both the base and index registers. */
516 && GET_CODE (XEXP (orig, 1)) == CONST
520 emit_move_insn (reg, XEXP (orig, 0));
521 XEXP (ptr_ref, 0) = reg;
526 /* For MACHOPIC_INDIRECT_CALL_TARGET below, we need to beware of:
528 extern "C" { int f(); }
529 struct X { int f(); int g(); };
530 int X::f() { ::f(); }
531 int X::g() { ::f(); f();}
533 This is hairy. Both calls to "::f()" need to be indirect (i.e., to
534 appropriate symbol stubs), but since MACHOPIC_NAME_DEFINED_P calls
535 GET_IDENTIFIER which treats "f" as "X::f", and "X::f" is indeed (being)
536 defined somewhere in "X"'s inheritance hierarchy, MACHOPIC_NAME_DEFINED_P
537 returns TRUE when called with "f", which means that
538 MACHOPIC_INDIRECT_CALL_TARGET uses an "internal" call instead of an
539 indirect one as it should.
541 Our quick-n-dirty solution to this is to call the following
542 FUNC_NAME_MAYBE_SCOPED routine which (only for C++) checks whether
543 FNAME -- the name of the function which we're calling -- is NOT a
544 mangled C++ name, AND if the current function being compiled is a
545 method, and if so, use an "external" or "indirect" call.
547 Note that this function will be called ONLY when MACHOPIC_INDIRECT_TARGET_P
548 has already indicated that the target is NOT indirect.
550 This conservative solution will sometimes make indirect calls where
551 it might have been possible to make direct ones.
553 FUNC_NAME_MAYBE_SCOPED returns 1 to indicate a "C" name (not scoped),
554 which in turns means we should create a stub for an indirect call.
557 static int is_cplusplus = -1;
560 func_name_maybe_scoped (fname)
564 if (is_cplusplus < 0)
565 is_cplusplus = (strcmp (lang_identify (), "cplusplus") == 0);
569 /* If we have a method, then check whether the function we're trying to
570 call is a "C" function. If so, we should use an indirect call.
572 It turns out to be hard to tell whether "we have a method", since
573 static member functions have a TREE_CODE of FUNCTION_TYPE, as do
574 namespace-level non-member functions. So here, we always look for
575 an extern-"C"-like name, and make stubs for them no matter the
576 calling context. This is temporary, and leaves nagging suspicion
577 that improvements should be possible here. (I.e., I suspect that
578 it can still sometimes make stubs where it needn't.) */
580 /* if (1 || TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE) */
582 /* If fname is of the form "f__1X" or "f__Fv", it's C++. */
583 while (*fname == '_') ++fname; /* skip leading underscores */
586 if (fname[0] == '_' && fname[1] == '_'
587 && (fname[2] == 'F' || (fname[2] >= '0' && fname[2] <= '9')))
591 /* Not a C++ mangled name: must be "C", in which case play safe. */
598 /* Transform TARGET (a MEM), which is a function call target, to the
599 corresponding symbol_stub if necessary. Return a new MEM. */
602 machopic_indirect_call_target (target)
605 if (GET_CODE (target) != MEM)
608 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
610 enum machine_mode mode = GET_MODE (XEXP (target, 0));
611 const char *name = XSTR (XEXP (target, 0), 0);
613 if (!machopic_name_defined_p (name) || func_name_maybe_scoped (name))
615 const char *stub_name = machopic_stub_name (name);
617 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
618 RTX_UNCHANGING_P (target) = 1;
626 machopic_legitimize_pic_address (orig, mode, reg)
628 enum machine_mode mode;
635 /* First handle a simple SYMBOL_REF or LABEL_REF */
636 if (GET_CODE (orig) == LABEL_REF
637 || (GET_CODE (orig) == SYMBOL_REF
640 /* addr(foo) = &func+(foo-func) */
643 orig = machopic_indirect_data_reference (orig, reg);
645 if (GET_CODE (orig) == PLUS
646 && GET_CODE (XEXP (orig, 0)) == REG)
649 return force_reg (mode, orig);
651 emit_move_insn (reg, orig);
655 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
657 if (GET_CODE (orig) == MEM)
661 if (reload_in_progress)
664 reg = gen_reg_rtx (Pmode);
668 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
669 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
671 rtx offset = gen_rtx (CONST, Pmode,
672 gen_rtx (MINUS, Pmode,
673 XEXP (orig, 0), pic_base));
674 #if defined (TARGET_TOC) /* i.e., PowerPC */
675 /* Generating a new reg may expose opportunities for
676 common subexpression elimination. */
678 (reload_in_progress ? reg : gen_reg_rtx (SImode));
680 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
681 gen_rtx (PLUS, Pmode,
682 pic_offset_table_rtx,
683 gen_rtx (HIGH, Pmode, offset))));
684 emit_insn (gen_rtx (SET, VOIDmode, reg,
685 gen_rtx (MEM, GET_MODE (orig),
686 gen_rtx (LO_SUM, Pmode,
687 hi_sum_reg, offset))));
691 emit_insn (gen_rtx (USE, VOIDmode,
692 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
694 emit_insn (gen_rtx (SET, VOIDmode, reg,
695 gen_rtx (HIGH, Pmode,
696 gen_rtx (CONST, Pmode, offset))));
697 emit_insn (gen_rtx (SET, VOIDmode, reg,
698 gen_rtx (LO_SUM, Pmode, reg,
699 gen_rtx (CONST, Pmode, offset))));
700 pic_ref = gen_rtx (PLUS, Pmode,
701 pic_offset_table_rtx, reg);
705 #endif /* HAVE_lo_sum */
707 rtx pic = pic_offset_table_rtx;
708 if (GET_CODE (pic) != REG)
710 emit_move_insn (reg, pic);
714 emit_insn (gen_rtx (USE, VOIDmode,
715 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
718 pic_ref = gen_rtx (PLUS, Pmode,
720 gen_rtx (CONST, Pmode,
721 gen_rtx (MINUS, Pmode,
726 #if !defined (TARGET_TOC)
727 RTX_UNCHANGING_P (pic_ref) = 1;
728 emit_move_insn (reg, pic_ref);
729 pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
736 if (GET_CODE (orig) == SYMBOL_REF
737 || GET_CODE (orig) == LABEL_REF)
739 rtx offset = gen_rtx (CONST, Pmode,
740 gen_rtx (MINUS, Pmode, orig, pic_base));
741 #if defined (TARGET_TOC) /* i.e., PowerPC */
746 if (reload_in_progress)
749 reg = gen_reg_rtx (SImode);
754 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
755 gen_rtx (PLUS, Pmode,
756 pic_offset_table_rtx,
757 gen_rtx (HIGH, Pmode, offset))));
758 emit_insn (gen_rtx (SET, VOIDmode, reg,
759 gen_rtx (LO_SUM, Pmode,
760 hi_sum_reg, offset)));
763 emit_insn (gen_rtx (SET, VOIDmode, reg,
764 gen_rtx (HIGH, Pmode, offset)));
765 emit_insn (gen_rtx (SET, VOIDmode, reg,
766 gen_rtx (LO_SUM, Pmode, reg, offset)));
767 pic_ref = gen_rtx (PLUS, Pmode,
768 pic_offset_table_rtx, reg);
772 #endif /* HAVE_lo_sum */
774 if (GET_CODE (orig) == REG)
780 rtx pic = pic_offset_table_rtx;
781 if (GET_CODE (pic) != REG)
783 emit_move_insn (reg, pic);
787 emit_insn (gen_rtx (USE, VOIDmode,
788 pic_offset_table_rtx));
790 pic_ref = gen_rtx (PLUS, Pmode,
792 gen_rtx (CONST, Pmode,
793 gen_rtx (MINUS, Pmode,
799 RTX_UNCHANGING_P (pic_ref) = 1;
801 if (GET_CODE (pic_ref) != REG)
805 emit_move_insn (reg, pic_ref);
810 return force_reg (mode, pic_ref);
819 else if (GET_CODE (orig) == SYMBOL_REF)
822 else if (GET_CODE (orig) == PLUS
823 && (GET_CODE (XEXP (orig, 0)) == MEM
824 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
825 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
826 && XEXP (orig, 0) != pic_offset_table_rtx
827 && GET_CODE (XEXP (orig, 1)) != REG)
831 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
833 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
834 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
835 Pmode, (base == reg ? 0 : reg));
836 if (GET_CODE (orig) == CONST_INT)
838 pic_ref = plus_constant_for_output (base, INTVAL (orig));
843 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
846 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
847 RTX_UNCHANGING_P (pic_ref) = 1;
849 if (reg && is_complex)
851 emit_move_insn (reg, pic_ref);
854 /* Likewise, should we set special REG_NOTEs here? */
857 else if (GET_CODE (orig) == CONST)
859 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
862 else if (GET_CODE (orig) == MEM
863 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
865 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
867 addr = gen_rtx (MEM, GET_MODE (orig), addr);
868 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
869 emit_move_insn (reg, addr);
878 machopic_finish (asm_out_file)
883 for (temp = machopic_stubs;
885 temp = TREE_CHAIN (temp))
887 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
888 char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
892 if (! TREE_USED (temp))
895 STRIP_NAME_ENCODING (sym_name, sym_name);
897 sym = alloca (strlen (sym_name) + 2);
898 if (sym_name[0] == '*' || sym_name[0] == '&')
899 strcpy (sym, sym_name + 1);
900 else if (sym_name[0] == '-' || sym_name[0] == '+')
901 strcpy (sym, sym_name);
903 sym[0] = '_', strcpy (sym + 1, sym_name);
905 stub = alloca (strlen (stub_name) + 2);
906 if (stub_name[0] == '*' || stub_name[0] == '&')
907 strcpy (stub, stub_name + 1);
909 stub[0] = '_', strcpy (stub + 1, stub_name);
911 machopic_output_stub (asm_out_file, sym, stub);
914 for (temp = machopic_non_lazy_pointers;
916 temp = TREE_CHAIN (temp))
918 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
919 char *lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
921 tree decl = lookup_name_darwin (TREE_VALUE (temp));
924 if (! TREE_USED (temp))
927 if (machopic_ident_defined_p (TREE_VALUE (temp))
928 #if 0 /* add back when we have private externs */
929 || (decl && DECL_PRIVATE_EXTERN (decl))
934 assemble_align (UNITS_PER_WORD * BITS_PER_UNIT);
935 assemble_label (lazy_name);
936 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
937 GET_MODE_SIZE (Pmode), 1);
941 machopic_nl_symbol_ptr_section ();
942 assemble_name (asm_out_file, lazy_name);
943 fprintf (asm_out_file, ":\n");
945 fprintf (asm_out_file, "\t.indirect_symbol ");
946 assemble_name (asm_out_file, sym_name);
947 fprintf (asm_out_file, "\n");
949 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode), 1);
955 machopic_operand_p (op)
958 if (MACHOPIC_JUST_INDIRECT)
960 while (GET_CODE (op) == CONST)
963 if (GET_CODE (op) == SYMBOL_REF)
964 return machopic_name_defined_p (XSTR (op, 0));
969 while (GET_CODE (op) == CONST)
972 if (GET_CODE (op) == MINUS
973 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
974 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
975 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
976 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
979 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
980 /* Without this statement, the compiler crashes while compiling enquire.c
981 when targetting PowerPC. It is not known why this code is not needed
982 when targetting other processors. */
983 else if (GET_CODE (op) == SYMBOL_REF
984 && (machopic_classify_name (XSTR (op, 0))
985 == MACHOPIC_DEFINED_FUNCTION))
994 /* This function records whether a given name corresponds to a defined
995 or undefined function or variable, for machopic_classify_ident to
999 darwin_encode_section_info (decl)
1005 if ((TREE_CODE (decl) == FUNCTION_DECL
1006 || TREE_CODE (decl) == VAR_DECL)
1007 && ((TREE_STATIC (decl)
1008 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1009 || DECL_INITIAL (decl)))
1012 if (TREE_CODE (decl) == FUNCTION_DECL)
1013 code = (defined ? 'T' : 't');
1014 else if (TREE_CODE (decl) == VAR_DECL)
1015 code = (defined ? 'D' : 'd');
1019 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
1021 if (*(XSTR (sym_ref, 0)) == '!')
1023 (XSTR(sym_ref, 0))[1] = code;
1024 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1029 size_t len = strlen (XSTR (sym_ref, 0));
1030 size_t newlen = len + 4;
1031 char *str = alloca (newlen);
1037 memcpy (str + 4, XSTR (sym_ref, 0), len + 1);
1039 XSTR (sym_ref, 0) = ggc_alloc_string (str, newlen);
1044 /* Scan the list of non-lazy pointers and update any recorded names whose
1045 stripped name matches the argument. */
1048 update_non_lazy_ptrs (name)
1051 char *name1, *name2;
1054 STRIP_NAME_ENCODING (name1, name);
1056 for (temp = machopic_non_lazy_pointers;
1058 temp = TREE_CHAIN (temp))
1060 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1062 if (*sym_name == '!')
1064 STRIP_NAME_ENCODING (name2, sym_name);
1065 if (strcmp (name1, name2) == 0)
1067 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;