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 *));
48 static void update_stubs PARAMS ((const char *));
51 name_needs_quotes (name)
55 while ((c = *name++) != '\0')
56 if (!isalnum (c) && c != '_')
62 * flag_pic = 1 ... generate only indirections
63 * flag_pic = 2 ... generate indirections and pure code
66 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
67 reference, which will not be changed. */
69 static tree machopic_defined_list;
71 enum machopic_addr_class
72 machopic_classify_ident (ident)
75 const char *name = IDENTIFIER_POINTER (ident);
76 int lprefix = (((name[0] == '*' || name[0] == '&')
77 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
88 /* Here if no special encoding to be found. */
91 const char *name = IDENTIFIER_POINTER (ident);
92 int len = strlen (name);
94 if ((len > 5 && !strcmp (name + len - 5, "$stub"))
95 || (len > 6 && !strcmp (name + len - 6, "$stub\"")))
96 return MACHOPIC_DEFINED_FUNCTION;
97 return MACHOPIC_DEFINED_DATA;
100 for (temp = machopic_defined_list;
102 temp = TREE_CHAIN (temp))
104 if (ident == TREE_VALUE (temp))
105 return MACHOPIC_DEFINED_DATA;
108 if (TREE_ASM_WRITTEN (ident))
109 return MACHOPIC_DEFINED_DATA;
111 return MACHOPIC_UNDEFINED;
114 else if (name[1] == 'D')
115 return MACHOPIC_DEFINED_DATA;
117 else if (name[1] == 'T')
118 return MACHOPIC_DEFINED_FUNCTION;
120 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
122 if (ident == TREE_VALUE (temp))
125 return MACHOPIC_DEFINED_FUNCTION;
127 return MACHOPIC_DEFINED_DATA;
131 if (name[1] == 't' || name[1] == 'T')
134 return MACHOPIC_DEFINED_FUNCTION;
136 return MACHOPIC_UNDEFINED_FUNCTION;
141 return MACHOPIC_DEFINED_DATA;
143 return MACHOPIC_UNDEFINED_DATA;
148 enum machopic_addr_class
149 machopic_classify_name (name)
152 return machopic_classify_ident (get_identifier (name));
156 machopic_ident_defined_p (ident)
159 switch (machopic_classify_ident (ident))
161 case MACHOPIC_UNDEFINED:
162 case MACHOPIC_UNDEFINED_DATA:
163 case MACHOPIC_UNDEFINED_FUNCTION:
171 machopic_data_defined_p (name)
174 switch (machopic_classify_ident (get_identifier (name)))
176 case MACHOPIC_DEFINED_DATA:
184 machopic_name_defined_p (name)
187 return machopic_ident_defined_p (get_identifier (name));
191 machopic_define_ident (ident)
194 if (!machopic_ident_defined_p (ident))
195 machopic_defined_list =
196 tree_cons (NULL_TREE, ident, machopic_defined_list);
200 machopic_define_name (name)
203 machopic_define_ident (get_identifier (name));
206 /* This is a static to make inline functions work. The rtx
207 representing the PIC base symbol always points to here. */
209 static char function_base[32];
211 static int current_pic_label_num;
214 machopic_function_base_name ()
216 static char *name = NULL;
217 static const char *current_name;
219 current_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
221 if (name != current_name)
223 current_function_uses_pic_offset_table = 1;
225 /* Save mucho space and time. Some of the C++ mangled names are over
226 700 characters long! Note that we produce a label containing a '-'
227 if the function we're compiling is an Objective-C method, as evinced
228 by the incredibly scientific test below. This is because code in
229 rs6000.c makes the same ugly test when loading the PIC reg. */
231 ++current_pic_label_num;
232 if (*current_name == '+' || *current_name == '-')
233 sprintf (function_base, "*\"L-%d$pb\"", current_pic_label_num);
235 sprintf (function_base, "*L%d$pb", current_pic_label_num);
240 return function_base;
243 static tree machopic_non_lazy_pointers = NULL;
245 /* Return a non-lazy pointer name corresponding to the given name,
246 either by finding it in our list of pointer names, or by generating
250 machopic_non_lazy_ptr_name (name)
254 tree temp, ident = get_identifier (name);
256 for (temp = machopic_non_lazy_pointers;
258 temp = TREE_CHAIN (temp))
260 if (ident == TREE_VALUE (temp))
261 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
264 STRIP_NAME_ENCODING (name, name);
266 /* Try again, but comparing names this time. */
267 for (temp = machopic_non_lazy_pointers;
269 temp = TREE_CHAIN (temp))
271 if (TREE_VALUE (temp))
273 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
274 STRIP_NAME_ENCODING (temp_name, temp_name);
275 if (strcmp (name, temp_name) == 0)
276 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
284 buffer = alloca (strlen (name) + 20);
286 strcpy (buffer, "&L");
288 strcat (buffer, name+1);
291 strcat (buffer, "_");
292 strcat (buffer, name);
295 strcat (buffer, "$non_lazy_ptr");
296 ptr_name = get_identifier (buffer);
298 machopic_non_lazy_pointers
299 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
301 TREE_USED (machopic_non_lazy_pointers) = 0;
303 return IDENTIFIER_POINTER (ptr_name);
307 static tree machopic_stubs = 0;
309 /* Make sure the GC knows about our homemade lists. */
312 machopic_add_gc_roots ()
314 ggc_add_tree_root (&machopic_defined_list, 1);
315 ggc_add_tree_root (&machopic_non_lazy_pointers, 1);
316 ggc_add_tree_root (&machopic_stubs, 1);
319 /* Return the name of the stub corresponding to the given name,
320 generating a new stub name if necessary. */
323 machopic_stub_name (name)
326 tree temp, ident = get_identifier (name);
328 for (temp = machopic_stubs;
330 temp = TREE_CHAIN (temp))
332 if (ident == TREE_VALUE (temp))
333 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
334 if (strcmp (name, IDENTIFIER_POINTER (TREE_VALUE (temp))) == 0)
335 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
338 STRIP_NAME_ENCODING (name, name);
343 int needs_quotes = name_needs_quotes (name);
345 buffer = alloca (strlen (name) + 20);
348 strcpy (buffer, "&\"L");
350 strcpy (buffer, "&L");
353 strcat (buffer, name+1);
357 strcat (buffer, "_");
358 strcat (buffer, name);
362 strcat (buffer, "$stub\"");
364 strcat (buffer, "$stub");
365 ptr_name = get_identifier (buffer);
367 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
368 TREE_USED (machopic_stubs) = 0;
370 return IDENTIFIER_POINTER (ptr_name);
375 machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
380 tree temp, ident = get_identifier (name), id2;
382 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
384 temp = TREE_CHAIN (temp))
385 if (ident == TREE_PURPOSE (temp))
387 /* Mark both the stub or non-lazy pointer as well as the
388 original symbol as being referenced. */
389 TREE_USED (temp) = 1;
390 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
391 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
392 STRIP_NAME_ENCODING (real_name, IDENTIFIER_POINTER (TREE_VALUE (temp)));
393 id2 = maybe_get_identifier (real_name);
395 TREE_SYMBOL_REFERENCED (id2) = 1;
399 /* Transform ORIG, which may be any data source, to the corresponding
400 source using indirections. */
403 machopic_indirect_data_reference (orig, reg)
408 if (! MACHOPIC_INDIRECT)
411 if (GET_CODE (orig) == SYMBOL_REF)
413 const char *name = XSTR (orig, 0);
415 if (machopic_data_defined_p (name))
417 rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
418 machopic_function_base_name ());
419 rtx offset = gen_rtx (CONST, Pmode,
420 gen_rtx (MINUS, Pmode, orig, pic_base));
422 #if defined (TARGET_TOC) /* i.e., PowerPC */
423 rtx hi_sum_reg = reg;
428 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
429 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
430 gen_rtx (HIGH, Pmode, offset))));
431 emit_insn (gen_rtx (SET, Pmode, reg,
432 gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
436 #if defined (HAVE_lo_sum)
437 if (reg == 0) abort ();
439 emit_insn (gen_rtx (SET, VOIDmode, reg,
440 gen_rtx (HIGH, Pmode, offset)));
441 emit_insn (gen_rtx (SET, VOIDmode, reg,
442 gen_rtx (LO_SUM, Pmode, reg, offset)));
443 emit_insn (gen_rtx (USE, VOIDmode,
444 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
446 orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
452 ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
453 machopic_non_lazy_ptr_name (name));
455 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
456 RTX_UNCHANGING_P (ptr_ref) = 1;
460 else if (GET_CODE (orig) == CONST)
464 /* legitimize both operands of the PLUS */
465 if (GET_CODE (XEXP (orig, 0)) == PLUS)
467 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
469 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
470 (base == reg ? 0 : reg));
475 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
476 result = plus_constant (base, INTVAL (orig));
478 result = gen_rtx (PLUS, Pmode, base, orig);
480 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
481 RTX_UNCHANGING_P (result) = 1;
483 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
487 emit_move_insn (reg, result);
492 result = force_reg (GET_MODE (result), result);
499 else if (GET_CODE (orig) == MEM)
500 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
501 /* When the target is i386, this code prevents crashes due to the
502 compiler's ignorance on how to move the PIC base register to
503 other registers. (The reload phase sometimes introduces such
505 else if (GET_CODE (orig) == PLUS
506 && GET_CODE (XEXP (orig, 0)) == REG
507 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
509 /* Prevent the same register from being erroneously used
510 as both the base and index registers. */
511 && GET_CODE (XEXP (orig, 1)) == CONST
515 emit_move_insn (reg, XEXP (orig, 0));
516 XEXP (ptr_ref, 0) = reg;
521 /* For MACHOPIC_INDIRECT_CALL_TARGET below, we need to beware of:
523 extern "C" { int f(); }
524 struct X { int f(); int g(); };
525 int X::f() { ::f(); }
526 int X::g() { ::f(); f();}
528 This is hairy. Both calls to "::f()" need to be indirect (i.e., to
529 appropriate symbol stubs), but since MACHOPIC_NAME_DEFINED_P calls
530 GET_IDENTIFIER which treats "f" as "X::f", and "X::f" is indeed (being)
531 defined somewhere in "X"'s inheritance hierarchy, MACHOPIC_NAME_DEFINED_P
532 returns TRUE when called with "f", which means that
533 MACHOPIC_INDIRECT_CALL_TARGET uses an "internal" call instead of an
534 indirect one as it should.
536 Our quick-n-dirty solution to this is to call the following
537 FUNC_NAME_MAYBE_SCOPED routine which (only for C++) checks whether
538 FNAME -- the name of the function which we're calling -- is NOT a
539 mangled C++ name, AND if the current function being compiled is a
540 method, and if so, use an "external" or "indirect" call.
542 Note that this function will be called ONLY when MACHOPIC_INDIRECT_TARGET_P
543 has already indicated that the target is NOT indirect.
545 This conservative solution will sometimes make indirect calls where
546 it might have been possible to make direct ones.
548 FUNC_NAME_MAYBE_SCOPED returns 1 to indicate a "C" name (not scoped),
549 which in turns means we should create a stub for an indirect call.
552 static int is_cplusplus = -1;
555 func_name_maybe_scoped (fname)
559 if (is_cplusplus < 0)
560 is_cplusplus = (strcmp (lang_identify (), "cplusplus") == 0);
564 /* If we have a method, then check whether the function we're trying to
565 call is a "C" function. If so, we should use an indirect call.
567 It turns out to be hard to tell whether "we have a method", since
568 static member functions have a TREE_CODE of FUNCTION_TYPE, as do
569 namespace-level non-member functions. So here, we always look for
570 an extern-"C"-like name, and make stubs for them no matter the
571 calling context. This is temporary, and leaves nagging suspicion
572 that improvements should be possible here. (I.e., I suspect that
573 it can still sometimes make stubs where it needn't.) */
575 /* if (1 || TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE) */
577 /* If fname is of the form "f__1X" or "f__Fv", it's C++. */
578 while (*fname == '_') ++fname; /* skip leading underscores */
581 if (fname[0] == '_' && fname[1] == '_'
582 && (fname[2] == 'F' || (fname[2] >= '0' && fname[2] <= '9')))
586 /* Not a C++ mangled name: must be "C", in which case play safe. */
593 /* Transform TARGET (a MEM), which is a function call target, to the
594 corresponding symbol_stub if necessary. Return a new MEM. */
597 machopic_indirect_call_target (target)
600 if (GET_CODE (target) != MEM)
603 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
605 enum machine_mode mode = GET_MODE (XEXP (target, 0));
606 const char *name = XSTR (XEXP (target, 0), 0);
608 if (!machopic_name_defined_p (name) || func_name_maybe_scoped (name))
610 const char *stub_name = machopic_stub_name (name);
612 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
613 RTX_UNCHANGING_P (target) = 1;
621 machopic_legitimize_pic_address (orig, mode, reg)
623 enum machine_mode mode;
630 /* First handle a simple SYMBOL_REF or LABEL_REF */
631 if (GET_CODE (orig) == LABEL_REF
632 || (GET_CODE (orig) == SYMBOL_REF
635 /* addr(foo) = &func+(foo-func) */
638 orig = machopic_indirect_data_reference (orig, reg);
640 if (GET_CODE (orig) == PLUS
641 && GET_CODE (XEXP (orig, 0)) == REG)
644 return force_reg (mode, orig);
646 emit_move_insn (reg, orig);
650 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
652 if (GET_CODE (orig) == MEM)
656 if (reload_in_progress)
659 reg = gen_reg_rtx (Pmode);
663 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
664 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
666 rtx offset = gen_rtx (CONST, Pmode,
667 gen_rtx (MINUS, Pmode,
668 XEXP (orig, 0), pic_base));
669 #if defined (TARGET_TOC) /* i.e., PowerPC */
670 /* Generating a new reg may expose opportunities for
671 common subexpression elimination. */
673 (reload_in_progress ? reg : gen_reg_rtx (SImode));
675 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
676 gen_rtx (PLUS, Pmode,
677 pic_offset_table_rtx,
678 gen_rtx (HIGH, Pmode, offset))));
679 emit_insn (gen_rtx (SET, VOIDmode, reg,
680 gen_rtx (MEM, GET_MODE (orig),
681 gen_rtx (LO_SUM, Pmode,
682 hi_sum_reg, offset))));
686 emit_insn (gen_rtx (USE, VOIDmode,
687 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
689 emit_insn (gen_rtx (SET, VOIDmode, reg,
690 gen_rtx (HIGH, Pmode,
691 gen_rtx (CONST, Pmode, offset))));
692 emit_insn (gen_rtx (SET, VOIDmode, reg,
693 gen_rtx (LO_SUM, Pmode, reg,
694 gen_rtx (CONST, Pmode, offset))));
695 pic_ref = gen_rtx (PLUS, Pmode,
696 pic_offset_table_rtx, reg);
700 #endif /* HAVE_lo_sum */
702 rtx pic = pic_offset_table_rtx;
703 if (GET_CODE (pic) != REG)
705 emit_move_insn (reg, pic);
709 emit_insn (gen_rtx (USE, VOIDmode,
710 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
713 pic_ref = gen_rtx (PLUS, Pmode,
715 gen_rtx (CONST, Pmode,
716 gen_rtx (MINUS, Pmode,
721 #if !defined (TARGET_TOC)
722 RTX_UNCHANGING_P (pic_ref) = 1;
723 emit_move_insn (reg, pic_ref);
724 pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
731 if (GET_CODE (orig) == SYMBOL_REF
732 || GET_CODE (orig) == LABEL_REF)
734 rtx offset = gen_rtx (CONST, Pmode,
735 gen_rtx (MINUS, Pmode, orig, pic_base));
736 #if defined (TARGET_TOC) /* i.e., PowerPC */
741 if (reload_in_progress)
744 reg = gen_reg_rtx (SImode);
749 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
750 gen_rtx (PLUS, Pmode,
751 pic_offset_table_rtx,
752 gen_rtx (HIGH, Pmode, offset))));
753 emit_insn (gen_rtx (SET, VOIDmode, reg,
754 gen_rtx (LO_SUM, Pmode,
755 hi_sum_reg, offset)));
758 emit_insn (gen_rtx (SET, VOIDmode, reg,
759 gen_rtx (HIGH, Pmode, offset)));
760 emit_insn (gen_rtx (SET, VOIDmode, reg,
761 gen_rtx (LO_SUM, Pmode, reg, offset)));
762 pic_ref = gen_rtx (PLUS, Pmode,
763 pic_offset_table_rtx, reg);
767 #endif /* HAVE_lo_sum */
769 if (GET_CODE (orig) == REG)
775 rtx pic = pic_offset_table_rtx;
776 if (GET_CODE (pic) != REG)
778 emit_move_insn (reg, pic);
782 emit_insn (gen_rtx (USE, VOIDmode,
783 pic_offset_table_rtx));
785 pic_ref = gen_rtx (PLUS, Pmode,
787 gen_rtx (CONST, Pmode,
788 gen_rtx (MINUS, Pmode,
794 RTX_UNCHANGING_P (pic_ref) = 1;
796 if (GET_CODE (pic_ref) != REG)
800 emit_move_insn (reg, pic_ref);
805 return force_reg (mode, pic_ref);
814 else if (GET_CODE (orig) == SYMBOL_REF)
817 else if (GET_CODE (orig) == PLUS
818 && (GET_CODE (XEXP (orig, 0)) == MEM
819 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
820 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
821 && XEXP (orig, 0) != pic_offset_table_rtx
822 && GET_CODE (XEXP (orig, 1)) != REG)
826 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
828 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
829 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
830 Pmode, (base == reg ? 0 : reg));
831 if (GET_CODE (orig) == CONST_INT)
833 pic_ref = plus_constant (base, INTVAL (orig));
837 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
839 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
840 RTX_UNCHANGING_P (pic_ref) = 1;
842 if (reg && is_complex)
844 emit_move_insn (reg, pic_ref);
847 /* Likewise, should we set special REG_NOTEs here? */
850 else if (GET_CODE (orig) == CONST)
852 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
855 else if (GET_CODE (orig) == MEM
856 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
858 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
860 addr = gen_rtx (MEM, GET_MODE (orig), addr);
861 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
862 emit_move_insn (reg, addr);
871 machopic_finish (asm_out_file)
876 for (temp = machopic_stubs;
878 temp = TREE_CHAIN (temp))
880 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
881 char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
885 if (! TREE_USED (temp))
888 STRIP_NAME_ENCODING (sym_name, sym_name);
890 sym = alloca (strlen (sym_name) + 2);
891 if (sym_name[0] == '*' || sym_name[0] == '&')
892 strcpy (sym, sym_name + 1);
893 else if (sym_name[0] == '-' || sym_name[0] == '+')
894 strcpy (sym, sym_name);
896 sym[0] = '_', strcpy (sym + 1, sym_name);
898 stub = alloca (strlen (stub_name) + 2);
899 if (stub_name[0] == '*' || stub_name[0] == '&')
900 strcpy (stub, stub_name + 1);
902 stub[0] = '_', strcpy (stub + 1, stub_name);
904 machopic_output_stub (asm_out_file, sym, stub);
907 for (temp = machopic_non_lazy_pointers;
909 temp = TREE_CHAIN (temp))
911 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
912 char *lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
914 tree decl = lookup_name_darwin (TREE_VALUE (temp));
917 if (! TREE_USED (temp))
920 if (machopic_ident_defined_p (TREE_VALUE (temp))
921 #if 0 /* add back when we have private externs */
922 || (decl && DECL_PRIVATE_EXTERN (decl))
927 assemble_align (GET_MODE_ALIGNMENT (Pmode));
928 assemble_label (lazy_name);
929 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
930 GET_MODE_SIZE (Pmode),
931 GET_MODE_ALIGNMENT (Pmode), 1);
935 machopic_nl_symbol_ptr_section ();
936 assemble_name (asm_out_file, lazy_name);
937 fprintf (asm_out_file, ":\n");
939 fprintf (asm_out_file, "\t.indirect_symbol ");
940 assemble_name (asm_out_file, sym_name);
941 fprintf (asm_out_file, "\n");
943 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
944 GET_MODE_ALIGNMENT (Pmode), 1);
950 machopic_operand_p (op)
953 if (MACHOPIC_JUST_INDIRECT)
955 while (GET_CODE (op) == CONST)
958 if (GET_CODE (op) == SYMBOL_REF)
959 return machopic_name_defined_p (XSTR (op, 0));
964 while (GET_CODE (op) == CONST)
967 if (GET_CODE (op) == MINUS
968 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
969 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
970 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
971 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
974 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
975 /* Without this statement, the compiler crashes while compiling enquire.c
976 when targetting PowerPC. It is not known why this code is not needed
977 when targetting other processors. */
978 else if (GET_CODE (op) == SYMBOL_REF
979 && (machopic_classify_name (XSTR (op, 0))
980 == MACHOPIC_DEFINED_FUNCTION))
989 /* This function records whether a given name corresponds to a defined
990 or undefined function or variable, for machopic_classify_ident to
994 darwin_encode_section_info (decl)
1000 char *orig_str, *new_str;
1001 size_t len, new_len;
1003 if ((TREE_CODE (decl) == FUNCTION_DECL
1004 || TREE_CODE (decl) == VAR_DECL)
1005 && !DECL_EXTERNAL (decl)
1006 && ((TREE_STATIC (decl)
1007 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1008 || DECL_INITIAL (decl)))
1011 if (TREE_CODE (decl) == FUNCTION_DECL)
1012 code = (defined ? 'T' : 't');
1013 else if (TREE_CODE (decl) == VAR_DECL)
1014 code = (defined ? 'D' : 'd');
1019 sym_ref = XEXP (DECL_RTL (decl), 0);
1020 orig_str = XSTR (sym_ref, 0);
1021 len = strlen (orig_str) + 1;
1023 if (orig_str[0] == '!')
1025 /* Already encoded; see if we need to change it. */
1026 if (code == orig_str[1])
1028 /* Yes, tweak a copy of the name and put it in a new string. */
1029 new_str = alloca (len);
1030 memcpy (new_str, orig_str, len);
1032 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
1036 /* Add the encoding. */
1038 new_str = alloca (new_len);
1043 memcpy (new_str + 4, orig_str, len);
1044 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
1046 /* The non-lazy pointer list may have captured references to the
1047 old encoded name, change them. */
1048 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1049 update_stubs (XSTR (sym_ref, 0));
1052 /* Scan the list of non-lazy pointers and update any recorded names whose
1053 stripped name matches the argument. */
1056 update_non_lazy_ptrs (name)
1059 char *name1, *name2;
1062 STRIP_NAME_ENCODING (name1, name);
1064 for (temp = machopic_non_lazy_pointers;
1066 temp = TREE_CHAIN (temp))
1068 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1070 if (*sym_name == '!')
1072 STRIP_NAME_ENCODING (name2, sym_name);
1073 if (strcmp (name1, name2) == 0)
1075 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1083 /* Scan the list of stubs and update any recorded names whose
1084 stripped name matches the argument. */
1090 char *name1, *name2;
1093 STRIP_NAME_ENCODING (name1, name);
1095 for (temp = machopic_stubs;
1097 temp = TREE_CHAIN (temp))
1099 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1101 if (*sym_name == '!')
1103 STRIP_NAME_ENCODING (name2, sym_name);
1104 if (strcmp (name1, name2) == 0)
1106 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1114 machopic_asm_out_constructor (symbol, priority)
1116 int priority ATTRIBUTE_UNUSED;
1119 mod_init_section ();
1121 constructor_section ();
1122 assemble_align (POINTER_SIZE);
1123 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1126 fprintf (asm_out_file, ".reference .constructors_used\n");
1130 machopic_asm_out_destructor (symbol, priority)
1132 int priority ATTRIBUTE_UNUSED;
1135 mod_term_section ();
1137 destructor_section ();
1138 assemble_align (POINTER_SIZE);
1139 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1142 fprintf (asm_out_file, ".reference .destructors_used\n");