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 *));
50 name_needs_quotes (name)
54 while ((c = *name++) != '\0')
55 if (!isalnum (c) && c != '_')
61 * flag_pic = 1 ... generate only indirections
62 * flag_pic = 2 ... generate indirections and pure code
65 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
66 reference, which will not be changed. */
68 static tree machopic_defined_list;
70 enum machopic_addr_class
71 machopic_classify_ident (ident)
74 const char *name = IDENTIFIER_POINTER (ident);
75 int lprefix = (((name[0] == '*' || name[0] == '&')
76 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
87 /* Here if no special encoding to be found. */
90 const char *name = IDENTIFIER_POINTER (ident);
91 int len = strlen (name);
93 if ((len > 5 && !strcmp (name + len - 5, "$stub"))
94 || (len > 6 && !strcmp (name + len - 6, "$stub\"")))
95 return MACHOPIC_DEFINED_FUNCTION;
96 return MACHOPIC_DEFINED_DATA;
99 for (temp = machopic_defined_list;
101 temp = TREE_CHAIN (temp))
103 if (ident == TREE_VALUE (temp))
104 return MACHOPIC_DEFINED_DATA;
107 if (TREE_ASM_WRITTEN (ident))
108 return MACHOPIC_DEFINED_DATA;
110 return MACHOPIC_UNDEFINED;
113 else if (name[1] == 'D')
114 return MACHOPIC_DEFINED_DATA;
116 else if (name[1] == 'T')
117 return MACHOPIC_DEFINED_FUNCTION;
119 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
121 if (ident == TREE_VALUE (temp))
124 return MACHOPIC_DEFINED_FUNCTION;
126 return MACHOPIC_DEFINED_DATA;
130 if (name[1] == 't' || name[1] == 'T')
133 return MACHOPIC_DEFINED_FUNCTION;
135 return MACHOPIC_UNDEFINED_FUNCTION;
140 return MACHOPIC_DEFINED_DATA;
142 return MACHOPIC_UNDEFINED_DATA;
147 enum machopic_addr_class
148 machopic_classify_name (name)
151 return machopic_classify_ident (get_identifier (name));
155 machopic_ident_defined_p (ident)
158 switch (machopic_classify_ident (ident))
160 case MACHOPIC_UNDEFINED:
161 case MACHOPIC_UNDEFINED_DATA:
162 case MACHOPIC_UNDEFINED_FUNCTION:
170 machopic_data_defined_p (name)
173 switch (machopic_classify_ident (get_identifier (name)))
175 case MACHOPIC_DEFINED_DATA:
183 machopic_name_defined_p (name)
186 return machopic_ident_defined_p (get_identifier (name));
190 machopic_define_ident (ident)
193 if (!machopic_ident_defined_p (ident))
194 machopic_defined_list =
195 tree_cons (NULL_TREE, ident, machopic_defined_list);
199 machopic_define_name (name)
202 machopic_define_ident (get_identifier (name));
205 /* This is a static to make inline functions work. The rtx
206 representing the PIC base symbol always points to here. */
208 static char function_base[32];
210 static int current_pic_label_num;
213 machopic_function_base_name ()
215 static char *name = NULL;
216 static const char *current_name;
218 current_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
220 if (name != current_name)
222 current_function_uses_pic_offset_table = 1;
224 /* Save mucho space and time. Some of the C++ mangled names are over
225 700 characters long! Note that we produce a label containing a '-'
226 if the function we're compiling is an Objective-C method, as evinced
227 by the incredibly scientific test below. This is because code in
228 rs6000.c makes the same ugly test when loading the PIC reg. */
230 ++current_pic_label_num;
231 if (*current_name == '+' || *current_name == '-')
232 sprintf (function_base, "*\"L-%d$pb\"", current_pic_label_num);
234 sprintf (function_base, "*L%d$pb", current_pic_label_num);
239 return function_base;
242 static tree machopic_non_lazy_pointers = NULL;
244 /* Return a non-lazy pointer name corresponding to the given name,
245 either by finding it in our list of pointer names, or by generating
249 machopic_non_lazy_ptr_name (name)
253 tree temp, ident = get_identifier (name);
255 for (temp = machopic_non_lazy_pointers;
257 temp = TREE_CHAIN (temp))
259 if (ident == TREE_VALUE (temp))
260 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
263 STRIP_NAME_ENCODING (name, name);
265 /* Try again, but comparing names this time. */
266 for (temp = machopic_non_lazy_pointers;
268 temp = TREE_CHAIN (temp))
270 if (TREE_VALUE (temp))
272 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
273 STRIP_NAME_ENCODING (temp_name, temp_name);
274 if (strcmp (name, temp_name) == 0)
275 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
283 buffer = alloca (strlen (name) + 20);
285 strcpy (buffer, "&L");
287 strcat (buffer, name+1);
290 strcat (buffer, "_");
291 strcat (buffer, name);
294 strcat (buffer, "$non_lazy_ptr");
295 ptr_name = get_identifier (buffer);
297 machopic_non_lazy_pointers
298 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
300 TREE_USED (machopic_non_lazy_pointers) = 0;
302 return IDENTIFIER_POINTER (ptr_name);
306 static tree machopic_stubs = 0;
308 /* Make sure the GC knows about our homemade lists. */
311 machopic_add_gc_roots ()
313 ggc_add_tree_root (&machopic_defined_list, 1);
314 ggc_add_tree_root (&machopic_non_lazy_pointers, 1);
315 ggc_add_tree_root (&machopic_stubs, 1);
318 /* Return the name of the stub corresponding to the given name,
319 generating a new stub name if necessary. */
322 machopic_stub_name (name)
325 tree temp, ident = get_identifier (name);
327 for (temp = machopic_stubs;
329 temp = TREE_CHAIN (temp))
331 if (ident == TREE_VALUE (temp))
332 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
335 STRIP_NAME_ENCODING (name, name);
340 int needs_quotes = name_needs_quotes (name);
342 buffer = alloca (strlen (name) + 20);
345 strcpy (buffer, "&\"L");
347 strcpy (buffer, "&L");
350 strcat (buffer, name+1);
354 strcat (buffer, "_");
355 strcat (buffer, name);
359 strcat (buffer, "$stub\"");
361 strcat (buffer, "$stub");
362 ptr_name = get_identifier (buffer);
364 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
365 TREE_USED (machopic_stubs) = 0;
367 return IDENTIFIER_POINTER (ptr_name);
372 machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
377 tree temp, ident = get_identifier (name), id2;
379 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
381 temp = TREE_CHAIN (temp))
382 if (ident == TREE_PURPOSE (temp))
384 /* Mark both the stub or non-lazy pointer as well as the
385 original symbol as being referenced. */
386 TREE_USED (temp) = 1;
387 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
388 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
389 STRIP_NAME_ENCODING (real_name, IDENTIFIER_POINTER (TREE_VALUE (temp)));
390 id2 = maybe_get_identifier (real_name);
392 TREE_SYMBOL_REFERENCED (id2) = 1;
396 /* Transform ORIG, which may be any data source, to the corresponding
397 source using indirections. */
400 machopic_indirect_data_reference (orig, reg)
405 if (! MACHOPIC_INDIRECT)
408 if (GET_CODE (orig) == SYMBOL_REF)
410 const char *name = XSTR (orig, 0);
412 if (machopic_data_defined_p (name))
414 rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
415 machopic_function_base_name ());
416 rtx offset = gen_rtx (CONST, Pmode,
417 gen_rtx (MINUS, Pmode, orig, pic_base));
419 #if defined (TARGET_TOC) /* i.e., PowerPC */
420 rtx hi_sum_reg = reg;
425 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
426 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
427 gen_rtx (HIGH, Pmode, offset))));
428 emit_insn (gen_rtx (SET, Pmode, reg,
429 gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
433 #if defined (HAVE_lo_sum)
434 if (reg == 0) abort ();
436 emit_insn (gen_rtx (SET, VOIDmode, reg,
437 gen_rtx (HIGH, Pmode, offset)));
438 emit_insn (gen_rtx (SET, VOIDmode, reg,
439 gen_rtx (LO_SUM, Pmode, reg, offset)));
440 emit_insn (gen_rtx (USE, VOIDmode,
441 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
443 orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
449 ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
450 machopic_non_lazy_ptr_name (name));
452 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
453 RTX_UNCHANGING_P (ptr_ref) = 1;
457 else if (GET_CODE (orig) == CONST)
461 /* legitimize both operands of the PLUS */
462 if (GET_CODE (XEXP (orig, 0)) == PLUS)
464 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
466 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
467 (base == reg ? 0 : reg));
472 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
473 result = plus_constant (base, INTVAL (orig));
475 result = gen_rtx (PLUS, Pmode, base, orig);
477 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
478 RTX_UNCHANGING_P (result) = 1;
480 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
484 emit_move_insn (reg, result);
489 result = force_reg (GET_MODE (result), result);
496 else if (GET_CODE (orig) == MEM)
497 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
498 /* When the target is i386, this code prevents crashes due to the
499 compiler's ignorance on how to move the PIC base register to
500 other registers. (The reload phase sometimes introduces such
502 else if (GET_CODE (orig) == PLUS
503 && GET_CODE (XEXP (orig, 0)) == REG
504 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
506 /* Prevent the same register from being erroneously used
507 as both the base and index registers. */
508 && GET_CODE (XEXP (orig, 1)) == CONST
512 emit_move_insn (reg, XEXP (orig, 0));
513 XEXP (ptr_ref, 0) = reg;
518 /* For MACHOPIC_INDIRECT_CALL_TARGET below, we need to beware of:
520 extern "C" { int f(); }
521 struct X { int f(); int g(); };
522 int X::f() { ::f(); }
523 int X::g() { ::f(); f();}
525 This is hairy. Both calls to "::f()" need to be indirect (i.e., to
526 appropriate symbol stubs), but since MACHOPIC_NAME_DEFINED_P calls
527 GET_IDENTIFIER which treats "f" as "X::f", and "X::f" is indeed (being)
528 defined somewhere in "X"'s inheritance hierarchy, MACHOPIC_NAME_DEFINED_P
529 returns TRUE when called with "f", which means that
530 MACHOPIC_INDIRECT_CALL_TARGET uses an "internal" call instead of an
531 indirect one as it should.
533 Our quick-n-dirty solution to this is to call the following
534 FUNC_NAME_MAYBE_SCOPED routine which (only for C++) checks whether
535 FNAME -- the name of the function which we're calling -- is NOT a
536 mangled C++ name, AND if the current function being compiled is a
537 method, and if so, use an "external" or "indirect" call.
539 Note that this function will be called ONLY when MACHOPIC_INDIRECT_TARGET_P
540 has already indicated that the target is NOT indirect.
542 This conservative solution will sometimes make indirect calls where
543 it might have been possible to make direct ones.
545 FUNC_NAME_MAYBE_SCOPED returns 1 to indicate a "C" name (not scoped),
546 which in turns means we should create a stub for an indirect call.
549 static int is_cplusplus = -1;
552 func_name_maybe_scoped (fname)
556 if (is_cplusplus < 0)
557 is_cplusplus = (strcmp (lang_identify (), "cplusplus") == 0);
561 /* If we have a method, then check whether the function we're trying to
562 call is a "C" function. If so, we should use an indirect call.
564 It turns out to be hard to tell whether "we have a method", since
565 static member functions have a TREE_CODE of FUNCTION_TYPE, as do
566 namespace-level non-member functions. So here, we always look for
567 an extern-"C"-like name, and make stubs for them no matter the
568 calling context. This is temporary, and leaves nagging suspicion
569 that improvements should be possible here. (I.e., I suspect that
570 it can still sometimes make stubs where it needn't.) */
572 /* if (1 || TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE) */
574 /* If fname is of the form "f__1X" or "f__Fv", it's C++. */
575 while (*fname == '_') ++fname; /* skip leading underscores */
578 if (fname[0] == '_' && fname[1] == '_'
579 && (fname[2] == 'F' || (fname[2] >= '0' && fname[2] <= '9')))
583 /* Not a C++ mangled name: must be "C", in which case play safe. */
590 /* Transform TARGET (a MEM), which is a function call target, to the
591 corresponding symbol_stub if necessary. Return a new MEM. */
594 machopic_indirect_call_target (target)
597 if (GET_CODE (target) != MEM)
600 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
602 enum machine_mode mode = GET_MODE (XEXP (target, 0));
603 const char *name = XSTR (XEXP (target, 0), 0);
605 if (!machopic_name_defined_p (name) || func_name_maybe_scoped (name))
607 const char *stub_name = machopic_stub_name (name);
609 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
610 RTX_UNCHANGING_P (target) = 1;
618 machopic_legitimize_pic_address (orig, mode, reg)
620 enum machine_mode mode;
627 /* First handle a simple SYMBOL_REF or LABEL_REF */
628 if (GET_CODE (orig) == LABEL_REF
629 || (GET_CODE (orig) == SYMBOL_REF
632 /* addr(foo) = &func+(foo-func) */
635 orig = machopic_indirect_data_reference (orig, reg);
637 if (GET_CODE (orig) == PLUS
638 && GET_CODE (XEXP (orig, 0)) == REG)
641 return force_reg (mode, orig);
643 emit_move_insn (reg, orig);
647 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
649 if (GET_CODE (orig) == MEM)
653 if (reload_in_progress)
656 reg = gen_reg_rtx (Pmode);
660 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
661 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
663 rtx offset = gen_rtx (CONST, Pmode,
664 gen_rtx (MINUS, Pmode,
665 XEXP (orig, 0), pic_base));
666 #if defined (TARGET_TOC) /* i.e., PowerPC */
667 /* Generating a new reg may expose opportunities for
668 common subexpression elimination. */
670 (reload_in_progress ? reg : gen_reg_rtx (SImode));
672 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
673 gen_rtx (PLUS, Pmode,
674 pic_offset_table_rtx,
675 gen_rtx (HIGH, Pmode, offset))));
676 emit_insn (gen_rtx (SET, VOIDmode, reg,
677 gen_rtx (MEM, GET_MODE (orig),
678 gen_rtx (LO_SUM, Pmode,
679 hi_sum_reg, offset))));
683 emit_insn (gen_rtx (USE, VOIDmode,
684 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
686 emit_insn (gen_rtx (SET, VOIDmode, reg,
687 gen_rtx (HIGH, Pmode,
688 gen_rtx (CONST, Pmode, offset))));
689 emit_insn (gen_rtx (SET, VOIDmode, reg,
690 gen_rtx (LO_SUM, Pmode, reg,
691 gen_rtx (CONST, Pmode, offset))));
692 pic_ref = gen_rtx (PLUS, Pmode,
693 pic_offset_table_rtx, reg);
697 #endif /* HAVE_lo_sum */
699 rtx pic = pic_offset_table_rtx;
700 if (GET_CODE (pic) != REG)
702 emit_move_insn (reg, pic);
706 emit_insn (gen_rtx (USE, VOIDmode,
707 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
710 pic_ref = gen_rtx (PLUS, Pmode,
712 gen_rtx (CONST, Pmode,
713 gen_rtx (MINUS, Pmode,
718 #if !defined (TARGET_TOC)
719 RTX_UNCHANGING_P (pic_ref) = 1;
720 emit_move_insn (reg, pic_ref);
721 pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
728 if (GET_CODE (orig) == SYMBOL_REF
729 || GET_CODE (orig) == LABEL_REF)
731 rtx offset = gen_rtx (CONST, Pmode,
732 gen_rtx (MINUS, Pmode, orig, pic_base));
733 #if defined (TARGET_TOC) /* i.e., PowerPC */
738 if (reload_in_progress)
741 reg = gen_reg_rtx (SImode);
746 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
747 gen_rtx (PLUS, Pmode,
748 pic_offset_table_rtx,
749 gen_rtx (HIGH, Pmode, offset))));
750 emit_insn (gen_rtx (SET, VOIDmode, reg,
751 gen_rtx (LO_SUM, Pmode,
752 hi_sum_reg, offset)));
755 emit_insn (gen_rtx (SET, VOIDmode, reg,
756 gen_rtx (HIGH, Pmode, offset)));
757 emit_insn (gen_rtx (SET, VOIDmode, reg,
758 gen_rtx (LO_SUM, Pmode, reg, offset)));
759 pic_ref = gen_rtx (PLUS, Pmode,
760 pic_offset_table_rtx, reg);
764 #endif /* HAVE_lo_sum */
766 if (GET_CODE (orig) == REG)
772 rtx pic = pic_offset_table_rtx;
773 if (GET_CODE (pic) != REG)
775 emit_move_insn (reg, pic);
779 emit_insn (gen_rtx (USE, VOIDmode,
780 pic_offset_table_rtx));
782 pic_ref = gen_rtx (PLUS, Pmode,
784 gen_rtx (CONST, Pmode,
785 gen_rtx (MINUS, Pmode,
791 RTX_UNCHANGING_P (pic_ref) = 1;
793 if (GET_CODE (pic_ref) != REG)
797 emit_move_insn (reg, pic_ref);
802 return force_reg (mode, pic_ref);
811 else if (GET_CODE (orig) == SYMBOL_REF)
814 else if (GET_CODE (orig) == PLUS
815 && (GET_CODE (XEXP (orig, 0)) == MEM
816 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
817 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
818 && XEXP (orig, 0) != pic_offset_table_rtx
819 && GET_CODE (XEXP (orig, 1)) != REG)
823 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
825 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
826 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
827 Pmode, (base == reg ? 0 : reg));
828 if (GET_CODE (orig) == CONST_INT)
830 pic_ref = plus_constant (base, INTVAL (orig));
834 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
836 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
837 RTX_UNCHANGING_P (pic_ref) = 1;
839 if (reg && is_complex)
841 emit_move_insn (reg, pic_ref);
844 /* Likewise, should we set special REG_NOTEs here? */
847 else if (GET_CODE (orig) == CONST)
849 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
852 else if (GET_CODE (orig) == MEM
853 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
855 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
857 addr = gen_rtx (MEM, GET_MODE (orig), addr);
858 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
859 emit_move_insn (reg, addr);
868 machopic_finish (asm_out_file)
873 for (temp = machopic_stubs;
875 temp = TREE_CHAIN (temp))
877 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
878 char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
882 if (! TREE_USED (temp))
885 STRIP_NAME_ENCODING (sym_name, sym_name);
887 sym = alloca (strlen (sym_name) + 2);
888 if (sym_name[0] == '*' || sym_name[0] == '&')
889 strcpy (sym, sym_name + 1);
890 else if (sym_name[0] == '-' || sym_name[0] == '+')
891 strcpy (sym, sym_name);
893 sym[0] = '_', strcpy (sym + 1, sym_name);
895 stub = alloca (strlen (stub_name) + 2);
896 if (stub_name[0] == '*' || stub_name[0] == '&')
897 strcpy (stub, stub_name + 1);
899 stub[0] = '_', strcpy (stub + 1, stub_name);
901 machopic_output_stub (asm_out_file, sym, stub);
904 for (temp = machopic_non_lazy_pointers;
906 temp = TREE_CHAIN (temp))
908 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
909 char *lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
911 tree decl = lookup_name_darwin (TREE_VALUE (temp));
914 if (! TREE_USED (temp))
917 if (machopic_ident_defined_p (TREE_VALUE (temp))
918 #if 0 /* add back when we have private externs */
919 || (decl && DECL_PRIVATE_EXTERN (decl))
924 assemble_align (UNITS_PER_WORD * BITS_PER_UNIT);
925 assemble_label (lazy_name);
926 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
927 GET_MODE_SIZE (Pmode), 1);
931 machopic_nl_symbol_ptr_section ();
932 assemble_name (asm_out_file, lazy_name);
933 fprintf (asm_out_file, ":\n");
935 fprintf (asm_out_file, "\t.indirect_symbol ");
936 assemble_name (asm_out_file, sym_name);
937 fprintf (asm_out_file, "\n");
939 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode), 1);
945 machopic_operand_p (op)
948 if (MACHOPIC_JUST_INDIRECT)
950 while (GET_CODE (op) == CONST)
953 if (GET_CODE (op) == SYMBOL_REF)
954 return machopic_name_defined_p (XSTR (op, 0));
959 while (GET_CODE (op) == CONST)
962 if (GET_CODE (op) == MINUS
963 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
964 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
965 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
966 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
969 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
970 /* Without this statement, the compiler crashes while compiling enquire.c
971 when targetting PowerPC. It is not known why this code is not needed
972 when targetting other processors. */
973 else if (GET_CODE (op) == SYMBOL_REF
974 && (machopic_classify_name (XSTR (op, 0))
975 == MACHOPIC_DEFINED_FUNCTION))
984 /* This function records whether a given name corresponds to a defined
985 or undefined function or variable, for machopic_classify_ident to
989 darwin_encode_section_info (decl)
995 char *orig_str, *new_str;
998 if ((TREE_CODE (decl) == FUNCTION_DECL
999 || TREE_CODE (decl) == VAR_DECL)
1000 && !DECL_EXTERNAL (decl)
1001 && ((TREE_STATIC (decl)
1002 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1003 || DECL_INITIAL (decl)))
1006 if (TREE_CODE (decl) == FUNCTION_DECL)
1007 code = (defined ? 'T' : 't');
1008 else if (TREE_CODE (decl) == VAR_DECL)
1009 code = (defined ? 'D' : 'd');
1014 sym_ref = XEXP (DECL_RTL (decl), 0);
1015 orig_str = XSTR (sym_ref, 0);
1016 len = strlen (orig_str) + 1;
1018 if (orig_str[0] == '!')
1020 /* Already encoded; see if we need to change it. */
1021 if (code == orig_str[1])
1023 /* Yes, tweak a copy of the name and put it in a new string. */
1024 new_str = alloca (len);
1025 memcpy (new_str, orig_str, len);
1027 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
1028 /* The non-lazy pointer list may have captured references to the
1029 old encoded name, change them. */
1030 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1034 /* Add the encoding. */
1036 new_str = alloca (new_len);
1041 memcpy (new_str + 4, orig_str, len);
1042 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
1046 /* Scan the list of non-lazy pointers and update any recorded names whose
1047 stripped name matches the argument. */
1050 update_non_lazy_ptrs (name)
1053 char *name1, *name2;
1056 STRIP_NAME_ENCODING (name1, name);
1058 for (temp = machopic_non_lazy_pointers;
1060 temp = TREE_CHAIN (temp))
1062 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1064 if (*sym_name == '!')
1066 STRIP_NAME_ENCODING (name2, sym_name);
1067 if (strcmp (name1, name2) == 0)
1069 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;