1 /* Functions for generic Darwin as target machine for GNU C compiler.
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Apple Computer Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-flags.h"
35 #include "insn-attr.h"
42 #include "langhooks.h"
45 static int machopic_data_defined_p PARAMS ((const char *));
46 static void update_non_lazy_ptrs PARAMS ((const char *));
47 static void update_stubs PARAMS ((const char *));
50 name_needs_quotes (name)
54 while ((c = *name++) != '\0')
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 GTY(()) 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 /* It is possible that someone is holding a "stale" name, which has
120 since been defined. See if there is a "defined" name (i.e,
121 different from NAME only in having a '!D_' or a '!T_' instead of
122 a '!d_' or '!t_' prefix) in the identifier hash tables. If so, say
123 that this identifier is defined. */
124 else if (name[1] == 'd' || name[1] == 't')
127 new_name = (char *)alloca (strlen (name) + 1);
128 strcpy (new_name, name);
129 new_name[1] = (name[1] == 'd') ? 'D' : 'T';
130 if (maybe_get_identifier (new_name) != NULL)
131 return (name[1] == 'd') ? MACHOPIC_DEFINED_DATA
132 : MACHOPIC_DEFINED_FUNCTION;
135 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
137 if (ident == TREE_VALUE (temp))
140 return MACHOPIC_DEFINED_FUNCTION;
142 return MACHOPIC_DEFINED_DATA;
146 if (name[1] == 't' || name[1] == 'T')
149 return MACHOPIC_DEFINED_FUNCTION;
151 return MACHOPIC_UNDEFINED_FUNCTION;
156 return MACHOPIC_DEFINED_DATA;
158 return MACHOPIC_UNDEFINED_DATA;
163 enum machopic_addr_class
164 machopic_classify_name (name)
167 return machopic_classify_ident (get_identifier (name));
171 machopic_ident_defined_p (ident)
174 switch (machopic_classify_ident (ident))
176 case MACHOPIC_UNDEFINED:
177 case MACHOPIC_UNDEFINED_DATA:
178 case MACHOPIC_UNDEFINED_FUNCTION:
186 machopic_data_defined_p (name)
189 switch (machopic_classify_ident (get_identifier (name)))
191 case MACHOPIC_DEFINED_DATA:
199 machopic_name_defined_p (name)
202 return machopic_ident_defined_p (get_identifier (name));
206 machopic_define_ident (ident)
209 if (!machopic_ident_defined_p (ident))
210 machopic_defined_list =
211 tree_cons (NULL_TREE, ident, machopic_defined_list);
215 machopic_define_name (name)
218 machopic_define_ident (get_identifier (name));
221 /* This is a static to make inline functions work. The rtx
222 representing the PIC base symbol always points to here. */
224 static char function_base[32];
226 static int current_pic_label_num;
229 machopic_function_base_name ()
231 static const char *name = NULL;
232 static const char *current_name;
234 current_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
236 if (name != current_name)
238 current_function_uses_pic_offset_table = 1;
240 /* Save mucho space and time. Some of the C++ mangled names are over
241 700 characters long! Note that we produce a label containing a '-'
242 if the function we're compiling is an Objective-C method, as evinced
243 by the incredibly scientific test below. This is because code in
244 rs6000.c makes the same ugly test when loading the PIC reg. */
246 ++current_pic_label_num;
247 if (*current_name == '+' || *current_name == '-')
248 sprintf (function_base, "*\"L-%d$pb\"", current_pic_label_num);
250 sprintf (function_base, "*L%d$pb", current_pic_label_num);
255 return function_base;
258 static GTY(()) tree machopic_non_lazy_pointers;
260 /* Return a non-lazy pointer name corresponding to the given name,
261 either by finding it in our list of pointer names, or by generating
265 machopic_non_lazy_ptr_name (name)
268 const char *temp_name;
269 tree temp, ident = get_identifier (name);
271 for (temp = machopic_non_lazy_pointers;
273 temp = TREE_CHAIN (temp))
275 if (ident == TREE_VALUE (temp))
276 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
279 name = darwin_strip_name_encoding (name);
281 /* Try again, but comparing names this time. */
282 for (temp = machopic_non_lazy_pointers;
284 temp = TREE_CHAIN (temp))
286 if (TREE_VALUE (temp))
288 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
289 temp_name = darwin_strip_name_encoding (temp_name);
290 if (strcmp (name, temp_name) == 0)
291 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
299 buffer = alloca (strlen (name) + 20);
301 strcpy (buffer, "&L");
303 strcat (buffer, name+1);
306 strcat (buffer, "_");
307 strcat (buffer, name);
310 strcat (buffer, "$non_lazy_ptr");
311 ptr_name = get_identifier (buffer);
313 machopic_non_lazy_pointers
314 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
316 TREE_USED (machopic_non_lazy_pointers) = 0;
318 return IDENTIFIER_POINTER (ptr_name);
322 static GTY(()) tree machopic_stubs;
324 /* Return the name of the stub corresponding to the given name,
325 generating a new stub name if necessary. */
328 machopic_stub_name (name)
331 tree temp, ident = get_identifier (name);
334 for (temp = machopic_stubs;
336 temp = TREE_CHAIN (temp))
338 if (ident == TREE_VALUE (temp))
339 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
340 tname = IDENTIFIER_POINTER (TREE_VALUE (temp));
341 if (strcmp (name, tname) == 0)
342 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
343 /* A library call name might not be section-encoded yet, so try
344 it against a stripped name. */
347 && strcmp (name, tname + 4) == 0)
348 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
351 name = darwin_strip_name_encoding (name);
356 int needs_quotes = name_needs_quotes (name);
358 buffer = alloca (strlen (name) + 20);
361 strcpy (buffer, "&\"L");
363 strcpy (buffer, "&L");
366 strcat (buffer, name+1);
370 strcat (buffer, "_");
371 strcat (buffer, name);
375 strcat (buffer, "$stub\"");
377 strcat (buffer, "$stub");
378 ptr_name = get_identifier (buffer);
380 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
381 TREE_USED (machopic_stubs) = 0;
383 return IDENTIFIER_POINTER (ptr_name);
388 machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
392 const char *real_name;
393 tree temp, ident = get_identifier (name), id2;
395 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
397 temp = TREE_CHAIN (temp))
398 if (ident == TREE_PURPOSE (temp))
400 /* Mark both the stub or non-lazy pointer as well as the
401 original symbol as being referenced. */
402 TREE_USED (temp) = 1;
403 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
404 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
405 real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
406 real_name = darwin_strip_name_encoding (real_name);
407 id2 = maybe_get_identifier (real_name);
409 TREE_SYMBOL_REFERENCED (id2) = 1;
413 /* Transform ORIG, which may be any data source, to the corresponding
414 source using indirections. */
417 machopic_indirect_data_reference (orig, reg)
422 if (! MACHOPIC_INDIRECT)
425 if (GET_CODE (orig) == SYMBOL_REF)
427 const char *name = XSTR (orig, 0);
429 if (machopic_data_defined_p (name))
431 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
432 rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
433 machopic_function_base_name ());
434 rtx offset = gen_rtx (CONST, Pmode,
435 gen_rtx (MINUS, Pmode, orig, pic_base));
438 #if defined (TARGET_TOC) /* i.e., PowerPC */
439 rtx hi_sum_reg = reg;
444 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
445 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
446 gen_rtx (HIGH, Pmode, offset))));
447 emit_insn (gen_rtx (SET, Pmode, reg,
448 gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
452 #if defined (HAVE_lo_sum)
453 if (reg == 0) abort ();
455 emit_insn (gen_rtx (SET, VOIDmode, reg,
456 gen_rtx (HIGH, Pmode, offset)));
457 emit_insn (gen_rtx (SET, VOIDmode, reg,
458 gen_rtx (LO_SUM, Pmode, reg, offset)));
459 emit_insn (gen_rtx (USE, VOIDmode,
460 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
462 orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
468 ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
469 machopic_non_lazy_ptr_name (name));
471 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
472 RTX_UNCHANGING_P (ptr_ref) = 1;
476 else if (GET_CODE (orig) == CONST)
480 /* legitimize both operands of the PLUS */
481 if (GET_CODE (XEXP (orig, 0)) == PLUS)
483 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
485 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
486 (base == reg ? 0 : reg));
491 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
492 result = plus_constant (base, INTVAL (orig));
494 result = gen_rtx (PLUS, Pmode, base, orig);
496 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
500 emit_move_insn (reg, result);
505 result = force_reg (GET_MODE (result), result);
512 else if (GET_CODE (orig) == MEM)
513 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
514 /* When the target is i386, this code prevents crashes due to the
515 compiler's ignorance on how to move the PIC base register to
516 other registers. (The reload phase sometimes introduces such
518 else if (GET_CODE (orig) == PLUS
519 && GET_CODE (XEXP (orig, 0)) == REG
520 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
522 /* Prevent the same register from being erroneously used
523 as both the base and index registers. */
524 && GET_CODE (XEXP (orig, 1)) == CONST
528 emit_move_insn (reg, XEXP (orig, 0));
529 XEXP (ptr_ref, 0) = reg;
534 /* Transform TARGET (a MEM), which is a function call target, to the
535 corresponding symbol_stub if necessary. Return a new MEM. */
538 machopic_indirect_call_target (target)
541 if (GET_CODE (target) != MEM)
544 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
546 enum machine_mode mode = GET_MODE (XEXP (target, 0));
547 const char *name = XSTR (XEXP (target, 0), 0);
549 /* If the name is already defined, we need do nothing. */
550 if (name[0] == '!' && name[1] == 'T')
553 if (!machopic_name_defined_p (name))
555 const char *stub_name = machopic_stub_name (name);
557 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
558 RTX_UNCHANGING_P (target) = 1;
566 machopic_legitimize_pic_address (orig, mode, reg)
568 enum machine_mode mode;
575 /* First handle a simple SYMBOL_REF or LABEL_REF */
576 if (GET_CODE (orig) == LABEL_REF
577 || (GET_CODE (orig) == SYMBOL_REF
580 /* addr(foo) = &func+(foo-func) */
583 orig = machopic_indirect_data_reference (orig, reg);
585 if (GET_CODE (orig) == PLUS
586 && GET_CODE (XEXP (orig, 0)) == REG)
589 return force_reg (mode, orig);
591 emit_move_insn (reg, orig);
595 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
597 if (GET_CODE (orig) == MEM)
601 if (reload_in_progress)
604 reg = gen_reg_rtx (Pmode);
608 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
609 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
611 rtx offset = gen_rtx (CONST, Pmode,
612 gen_rtx (MINUS, Pmode,
613 XEXP (orig, 0), pic_base));
614 #if defined (TARGET_TOC) /* i.e., PowerPC */
615 /* Generating a new reg may expose opportunities for
616 common subexpression elimination. */
618 (reload_in_progress ? reg : gen_reg_rtx (SImode));
620 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
621 gen_rtx (PLUS, Pmode,
622 pic_offset_table_rtx,
623 gen_rtx (HIGH, Pmode, offset))));
624 emit_insn (gen_rtx (SET, VOIDmode, reg,
625 gen_rtx (MEM, GET_MODE (orig),
626 gen_rtx (LO_SUM, Pmode,
627 hi_sum_reg, offset))));
631 emit_insn (gen_rtx (USE, VOIDmode,
632 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
634 emit_insn (gen_rtx (SET, VOIDmode, reg,
635 gen_rtx (HIGH, Pmode,
636 gen_rtx (CONST, Pmode, offset))));
637 emit_insn (gen_rtx (SET, VOIDmode, reg,
638 gen_rtx (LO_SUM, Pmode, reg,
639 gen_rtx (CONST, Pmode, offset))));
640 pic_ref = gen_rtx (PLUS, Pmode,
641 pic_offset_table_rtx, reg);
645 #endif /* HAVE_lo_sum */
647 rtx pic = pic_offset_table_rtx;
648 if (GET_CODE (pic) != REG)
650 emit_move_insn (reg, pic);
654 emit_insn (gen_rtx (USE, VOIDmode,
655 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
658 pic_ref = gen_rtx (PLUS, Pmode,
660 gen_rtx (CONST, Pmode,
661 gen_rtx (MINUS, Pmode,
666 #if !defined (TARGET_TOC)
667 emit_move_insn (reg, pic_ref);
668 pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
670 RTX_UNCHANGING_P (pic_ref) = 1;
676 if (GET_CODE (orig) == SYMBOL_REF
677 || GET_CODE (orig) == LABEL_REF)
679 rtx offset = gen_rtx (CONST, Pmode,
680 gen_rtx (MINUS, Pmode, orig, pic_base));
681 #if defined (TARGET_TOC) /* i.e., PowerPC */
686 if (reload_in_progress)
689 reg = gen_reg_rtx (SImode);
694 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
695 gen_rtx (PLUS, Pmode,
696 pic_offset_table_rtx,
697 gen_rtx (HIGH, Pmode, offset))));
698 emit_insn (gen_rtx (SET, VOIDmode, reg,
699 gen_rtx (LO_SUM, Pmode,
700 hi_sum_reg, offset)));
702 RTX_UNCHANGING_P (pic_ref) = 1;
704 emit_insn (gen_rtx (SET, VOIDmode, reg,
705 gen_rtx (HIGH, Pmode, offset)));
706 emit_insn (gen_rtx (SET, VOIDmode, reg,
707 gen_rtx (LO_SUM, Pmode, reg, offset)));
708 pic_ref = gen_rtx (PLUS, Pmode,
709 pic_offset_table_rtx, reg);
710 RTX_UNCHANGING_P (pic_ref) = 1;
714 #endif /* HAVE_lo_sum */
716 if (GET_CODE (orig) == REG)
722 rtx pic = pic_offset_table_rtx;
723 if (GET_CODE (pic) != REG)
725 emit_move_insn (reg, pic);
729 emit_insn (gen_rtx (USE, VOIDmode,
730 pic_offset_table_rtx));
732 pic_ref = gen_rtx (PLUS, Pmode,
734 gen_rtx (CONST, Pmode,
735 gen_rtx (MINUS, Pmode,
741 if (GET_CODE (pic_ref) != REG)
745 emit_move_insn (reg, pic_ref);
750 return force_reg (mode, pic_ref);
759 else if (GET_CODE (orig) == SYMBOL_REF)
762 else if (GET_CODE (orig) == PLUS
763 && (GET_CODE (XEXP (orig, 0)) == MEM
764 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
765 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
766 && XEXP (orig, 0) != pic_offset_table_rtx
767 && GET_CODE (XEXP (orig, 1)) != REG)
771 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
773 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
774 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
775 Pmode, (base == reg ? 0 : reg));
776 if (GET_CODE (orig) == CONST_INT)
778 pic_ref = plus_constant (base, INTVAL (orig));
782 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
784 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
785 RTX_UNCHANGING_P (pic_ref) = 1;
787 if (reg && is_complex)
789 emit_move_insn (reg, pic_ref);
792 /* Likewise, should we set special REG_NOTEs here? */
795 else if (GET_CODE (orig) == CONST)
797 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
800 else if (GET_CODE (orig) == MEM
801 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
803 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
805 addr = gen_rtx (MEM, GET_MODE (orig), addr);
806 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
807 emit_move_insn (reg, addr);
816 machopic_finish (asm_out_file)
821 for (temp = machopic_stubs;
823 temp = TREE_CHAIN (temp))
825 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
826 const char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
830 if (! TREE_USED (temp))
833 /* If the symbol is actually defined, we don't need a stub. */
834 if (sym_name[0] == '!' && sym_name[1] == 'T')
837 sym_name = darwin_strip_name_encoding (sym_name);
839 sym = alloca (strlen (sym_name) + 2);
840 if (sym_name[0] == '*' || sym_name[0] == '&')
841 strcpy (sym, sym_name + 1);
842 else if (sym_name[0] == '-' || sym_name[0] == '+')
843 strcpy (sym, sym_name);
845 sym[0] = '_', strcpy (sym + 1, sym_name);
847 stub = alloca (strlen (stub_name) + 2);
848 if (stub_name[0] == '*' || stub_name[0] == '&')
849 strcpy (stub, stub_name + 1);
851 stub[0] = '_', strcpy (stub + 1, stub_name);
853 machopic_output_stub (asm_out_file, sym, stub);
856 for (temp = machopic_non_lazy_pointers;
858 temp = TREE_CHAIN (temp))
860 const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
861 const char *const lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
863 if (! TREE_USED (temp))
866 if (machopic_ident_defined_p (TREE_VALUE (temp)))
869 assemble_align (GET_MODE_ALIGNMENT (Pmode));
870 assemble_label (lazy_name);
871 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
872 GET_MODE_SIZE (Pmode),
873 GET_MODE_ALIGNMENT (Pmode), 1);
877 machopic_nl_symbol_ptr_section ();
878 assemble_name (asm_out_file, lazy_name);
879 fprintf (asm_out_file, ":\n");
881 fprintf (asm_out_file, "\t.indirect_symbol ");
882 assemble_name (asm_out_file, sym_name);
883 fprintf (asm_out_file, "\n");
885 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
886 GET_MODE_ALIGNMENT (Pmode), 1);
892 machopic_operand_p (op)
895 if (MACHOPIC_JUST_INDIRECT)
897 while (GET_CODE (op) == CONST)
900 if (GET_CODE (op) == SYMBOL_REF)
901 return machopic_name_defined_p (XSTR (op, 0));
906 while (GET_CODE (op) == CONST)
909 if (GET_CODE (op) == MINUS
910 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
911 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
912 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
913 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
919 /* This function records whether a given name corresponds to a defined
920 or undefined function or variable, for machopic_classify_ident to
924 darwin_encode_section_info (decl, first)
926 int first ATTRIBUTE_UNUSED;
931 const char *orig_str;
935 if ((TREE_CODE (decl) == FUNCTION_DECL
936 || TREE_CODE (decl) == VAR_DECL)
937 && !DECL_EXTERNAL (decl)
938 && ((TREE_STATIC (decl)
939 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
940 || (DECL_INITIAL (decl)
941 && DECL_INITIAL (decl) != error_mark_node)))
944 if (TREE_CODE (decl) == FUNCTION_DECL)
945 code = (defined ? 'T' : 't');
946 else if (TREE_CODE (decl) == VAR_DECL)
947 code = (defined ? 'D' : 'd');
952 sym_ref = XEXP (DECL_RTL (decl), 0);
953 orig_str = XSTR (sym_ref, 0);
954 len = strlen (orig_str) + 1;
956 if (orig_str[0] == '!')
958 /* Already encoded; see if we need to change it. */
959 if (code == orig_str[1])
961 /* Yes, tweak a copy of the name and put it in a new string. */
962 new_str = alloca (len);
963 memcpy (new_str, orig_str, len);
965 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
969 /* Add the encoding. */
971 new_str = alloca (new_len);
976 memcpy (new_str + 4, orig_str, len);
977 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
979 /* The non-lazy pointer list may have captured references to the
980 old encoded name, change them. */
981 if (TREE_CODE (decl) == VAR_DECL)
982 update_non_lazy_ptrs (XSTR (sym_ref, 0));
984 update_stubs (XSTR (sym_ref, 0));
987 /* Undo the effects of the above. */
990 darwin_strip_name_encoding (str)
993 return str[0] == '!' ? str + 4 : str;
996 /* Scan the list of non-lazy pointers and update any recorded names whose
997 stripped name matches the argument. */
1000 update_non_lazy_ptrs (name)
1003 const char *name1, *name2;
1006 name1 = darwin_strip_name_encoding (name);
1008 for (temp = machopic_non_lazy_pointers;
1010 temp = TREE_CHAIN (temp))
1012 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1014 if (*sym_name == '!')
1016 name2 = darwin_strip_name_encoding (sym_name);
1017 if (strcmp (name1, name2) == 0)
1019 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1026 /* Function NAME is being defined, and its label has just been output.
1027 If there's already a reference to a stub for this function, we can
1028 just emit the stub label now and we don't bother emitting the stub later. */
1031 machopic_output_possible_stub_label (file, name)
1038 /* Ensure we're looking at a section-encoded name. */
1039 if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
1042 for (temp = machopic_stubs;
1044 temp = TREE_CHAIN (temp))
1046 const char *sym_name;
1048 sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1049 if (sym_name[0] == '!' && sym_name[1] == 'T'
1050 && ! strcmp (name+2, sym_name+2))
1052 ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
1053 /* Avoid generating a stub for this. */
1054 TREE_USED (temp) = 0;
1060 /* Scan the list of stubs and update any recorded names whose
1061 stripped name matches the argument. */
1067 const char *name1, *name2;
1070 name1 = darwin_strip_name_encoding (name);
1072 for (temp = machopic_stubs;
1074 temp = TREE_CHAIN (temp))
1076 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1078 if (*sym_name == '!')
1080 name2 = darwin_strip_name_encoding (sym_name);
1081 if (strcmp (name1, name2) == 0)
1083 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1091 machopic_select_section (exp, reloc, align)
1094 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1096 if (TREE_CODE (exp) == STRING_CST)
1098 if (flag_writable_strings)
1100 else if (TREE_STRING_LENGTH (exp) !=
1101 strlen (TREE_STRING_POINTER (exp)) + 1)
1102 readonly_data_section ();
1106 else if (TREE_CODE (exp) == INTEGER_CST
1107 || TREE_CODE (exp) == REAL_CST)
1109 tree size = TYPE_SIZE (TREE_TYPE (exp));
1111 if (TREE_CODE (size) == INTEGER_CST &&
1112 TREE_INT_CST_LOW (size) == 4 &&
1113 TREE_INT_CST_HIGH (size) == 0)
1114 literal4_section ();
1115 else if (TREE_CODE (size) == INTEGER_CST &&
1116 TREE_INT_CST_LOW (size) == 8 &&
1117 TREE_INT_CST_HIGH (size) == 0)
1118 literal8_section ();
1120 readonly_data_section ();
1122 else if (TREE_CODE (exp) == CONSTRUCTOR
1124 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1125 && TYPE_NAME (TREE_TYPE (exp)))
1127 tree name = TYPE_NAME (TREE_TYPE (exp));
1128 if (TREE_CODE (name) == TYPE_DECL)
1129 name = DECL_NAME (name);
1130 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1131 objc_constant_string_object_section ();
1132 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1133 objc_string_object_section ();
1134 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1136 if (TREE_SIDE_EFFECTS (exp) || (flag_pic && reloc))
1137 const_data_section ();
1139 readonly_data_section ();
1144 else if (TREE_CODE (exp) == VAR_DECL &&
1146 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1147 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1148 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1150 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1152 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1153 objc_cls_meth_section ();
1154 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1155 objc_inst_meth_section ();
1156 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1157 objc_cat_cls_meth_section ();
1158 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1159 objc_cat_inst_meth_section ();
1160 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1161 objc_class_vars_section ();
1162 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1163 objc_instance_vars_section ();
1164 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1165 objc_cat_cls_meth_section ();
1166 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1167 objc_class_names_section ();
1168 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1169 objc_meth_var_names_section ();
1170 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1171 objc_meth_var_types_section ();
1172 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1173 objc_cls_refs_section ();
1174 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1175 objc_class_section ();
1176 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1177 objc_meta_class_section ();
1178 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1179 objc_category_section ();
1180 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1181 objc_selector_refs_section ();
1182 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1183 objc_selector_fixup_section ();
1184 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1185 objc_symbols_section ();
1186 else if (!strncmp (name, "_OBJC_MODULES", 13))
1187 objc_module_info_section ();
1188 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1189 objc_cat_inst_meth_section ();
1190 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1191 objc_cat_cls_meth_section ();
1192 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1193 objc_cat_cls_meth_section ();
1194 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1195 objc_protocol_section ();
1196 else if ((TREE_READONLY (exp) || TREE_CONSTANT (exp))
1197 && !TREE_SIDE_EFFECTS (exp))
1199 if (flag_pic && reloc)
1200 const_data_section ();
1202 readonly_data_section ();
1207 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1209 if (TREE_SIDE_EFFECTS (exp) || (flag_pic && reloc))
1210 const_data_section ();
1212 readonly_data_section ();
1218 /* This can be called with address expressions as "rtx".
1219 They must go in "const". */
1222 machopic_select_rtx_section (mode, x, align)
1223 enum machine_mode mode;
1225 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1227 if (GET_MODE_SIZE (mode) == 8)
1228 literal8_section ();
1229 else if (GET_MODE_SIZE (mode) == 4
1230 && (GET_CODE (x) == CONST_INT
1231 || GET_CODE (x) == CONST_DOUBLE))
1232 literal4_section ();
1238 machopic_asm_out_constructor (symbol, priority)
1240 int priority ATTRIBUTE_UNUSED;
1243 mod_init_section ();
1245 constructor_section ();
1246 assemble_align (POINTER_SIZE);
1247 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1250 fprintf (asm_out_file, ".reference .constructors_used\n");
1254 machopic_asm_out_destructor (symbol, priority)
1256 int priority ATTRIBUTE_UNUSED;
1259 mod_term_section ();
1261 destructor_section ();
1262 assemble_align (POINTER_SIZE);
1263 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1266 fprintf (asm_out_file, ".reference .destructors_used\n");
1270 darwin_globalize_label (stream, name)
1274 if (!!strncmp (name, "_OBJC_", 6))
1275 default_globalize_label (stream, name);
1278 /* Output a difference of two labels that will be an assembly time
1279 constant if the two labels are local. (.long lab1-lab2 will be
1280 very different if lab1 is at the boundary between two sections; it
1281 will be relocated according to the second section, not the first,
1282 so one ends up with a difference between labels in different
1283 sections, which is bad in the dwarf2 eh context for instance.) */
1285 static int darwin_dwarf_label_counter;
1288 darwin_asm_output_dwarf_delta (file, size, lab1, lab2)
1290 int size ATTRIBUTE_UNUSED;
1291 const char *lab1, *lab2;
1293 const char *p = lab1 + (lab1[0] == '*');
1294 int islocaldiff = (p[0] == 'L');
1297 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1299 fprintf (file, "\t%s\t", ".long");
1300 assemble_name (file, lab1);
1301 fprintf (file, "-");
1302 assemble_name (file, lab2);
1304 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1307 #include "gt-darwin.h"