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. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
40 #include "langhooks.h"
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 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)
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)
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 rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
432 machopic_function_base_name ());
433 rtx offset = gen_rtx (CONST, Pmode,
434 gen_rtx (MINUS, Pmode, orig, pic_base));
436 #if defined (TARGET_TOC) /* i.e., PowerPC */
437 rtx hi_sum_reg = reg;
442 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
443 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
444 gen_rtx (HIGH, Pmode, offset))));
445 emit_insn (gen_rtx (SET, Pmode, reg,
446 gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
450 #if defined (HAVE_lo_sum)
451 if (reg == 0) abort ();
453 emit_insn (gen_rtx (SET, VOIDmode, reg,
454 gen_rtx (HIGH, Pmode, offset)));
455 emit_insn (gen_rtx (SET, VOIDmode, reg,
456 gen_rtx (LO_SUM, Pmode, reg, offset)));
457 emit_insn (gen_rtx (USE, VOIDmode,
458 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
460 orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
466 ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
467 machopic_non_lazy_ptr_name (name));
469 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
470 RTX_UNCHANGING_P (ptr_ref) = 1;
474 else if (GET_CODE (orig) == CONST)
478 /* legitimize both operands of the PLUS */
479 if (GET_CODE (XEXP (orig, 0)) == PLUS)
481 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
483 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
484 (base == reg ? 0 : reg));
489 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
490 result = plus_constant (base, INTVAL (orig));
492 result = gen_rtx (PLUS, Pmode, base, orig);
494 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
495 RTX_UNCHANGING_P (result) = 1;
497 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
501 emit_move_insn (reg, result);
506 result = force_reg (GET_MODE (result), result);
513 else if (GET_CODE (orig) == MEM)
514 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
515 /* When the target is i386, this code prevents crashes due to the
516 compiler's ignorance on how to move the PIC base register to
517 other registers. (The reload phase sometimes introduces such
519 else if (GET_CODE (orig) == PLUS
520 && GET_CODE (XEXP (orig, 0)) == REG
521 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
523 /* Prevent the same register from being erroneously used
524 as both the base and index registers. */
525 && GET_CODE (XEXP (orig, 1)) == CONST
529 emit_move_insn (reg, XEXP (orig, 0));
530 XEXP (ptr_ref, 0) = reg;
535 /* Transform TARGET (a MEM), which is a function call target, to the
536 corresponding symbol_stub if necessary. Return a new MEM. */
539 machopic_indirect_call_target (target)
542 if (GET_CODE (target) != MEM)
545 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
547 enum machine_mode mode = GET_MODE (XEXP (target, 0));
548 const char *name = XSTR (XEXP (target, 0), 0);
550 /* If the name is already defined, we need do nothing. */
551 if (name[0] == '!' && name[1] == 'T')
554 if (!machopic_name_defined_p (name))
556 const char *stub_name = machopic_stub_name (name);
558 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
559 RTX_UNCHANGING_P (target) = 1;
567 machopic_legitimize_pic_address (orig, mode, reg)
569 enum machine_mode mode;
576 /* First handle a simple SYMBOL_REF or LABEL_REF */
577 if (GET_CODE (orig) == LABEL_REF
578 || (GET_CODE (orig) == SYMBOL_REF
581 /* addr(foo) = &func+(foo-func) */
584 orig = machopic_indirect_data_reference (orig, reg);
586 if (GET_CODE (orig) == PLUS
587 && GET_CODE (XEXP (orig, 0)) == REG)
590 return force_reg (mode, orig);
592 emit_move_insn (reg, orig);
596 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
598 if (GET_CODE (orig) == MEM)
602 if (reload_in_progress)
605 reg = gen_reg_rtx (Pmode);
609 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
610 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
612 rtx offset = gen_rtx (CONST, Pmode,
613 gen_rtx (MINUS, Pmode,
614 XEXP (orig, 0), pic_base));
615 #if defined (TARGET_TOC) /* i.e., PowerPC */
616 /* Generating a new reg may expose opportunities for
617 common subexpression elimination. */
619 (reload_in_progress ? reg : gen_reg_rtx (SImode));
621 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
622 gen_rtx (PLUS, Pmode,
623 pic_offset_table_rtx,
624 gen_rtx (HIGH, Pmode, offset))));
625 emit_insn (gen_rtx (SET, VOIDmode, reg,
626 gen_rtx (MEM, GET_MODE (orig),
627 gen_rtx (LO_SUM, Pmode,
628 hi_sum_reg, offset))));
632 emit_insn (gen_rtx (USE, VOIDmode,
633 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
635 emit_insn (gen_rtx (SET, VOIDmode, reg,
636 gen_rtx (HIGH, Pmode,
637 gen_rtx (CONST, Pmode, offset))));
638 emit_insn (gen_rtx (SET, VOIDmode, reg,
639 gen_rtx (LO_SUM, Pmode, reg,
640 gen_rtx (CONST, Pmode, offset))));
641 pic_ref = gen_rtx (PLUS, Pmode,
642 pic_offset_table_rtx, reg);
646 #endif /* HAVE_lo_sum */
648 rtx pic = pic_offset_table_rtx;
649 if (GET_CODE (pic) != REG)
651 emit_move_insn (reg, pic);
655 emit_insn (gen_rtx (USE, VOIDmode,
656 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
659 pic_ref = gen_rtx (PLUS, Pmode,
661 gen_rtx (CONST, Pmode,
662 gen_rtx (MINUS, Pmode,
667 #if !defined (TARGET_TOC)
668 RTX_UNCHANGING_P (pic_ref) = 1;
669 emit_move_insn (reg, pic_ref);
670 pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
677 if (GET_CODE (orig) == SYMBOL_REF
678 || GET_CODE (orig) == LABEL_REF)
680 rtx offset = gen_rtx (CONST, Pmode,
681 gen_rtx (MINUS, Pmode, orig, pic_base));
682 #if defined (TARGET_TOC) /* i.e., PowerPC */
687 if (reload_in_progress)
690 reg = gen_reg_rtx (SImode);
695 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
696 gen_rtx (PLUS, Pmode,
697 pic_offset_table_rtx,
698 gen_rtx (HIGH, Pmode, offset))));
699 emit_insn (gen_rtx (SET, VOIDmode, reg,
700 gen_rtx (LO_SUM, Pmode,
701 hi_sum_reg, offset)));
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);
713 #endif /* HAVE_lo_sum */
715 if (GET_CODE (orig) == REG)
721 rtx pic = pic_offset_table_rtx;
722 if (GET_CODE (pic) != REG)
724 emit_move_insn (reg, pic);
728 emit_insn (gen_rtx (USE, VOIDmode,
729 pic_offset_table_rtx));
731 pic_ref = gen_rtx (PLUS, Pmode,
733 gen_rtx (CONST, Pmode,
734 gen_rtx (MINUS, Pmode,
740 RTX_UNCHANGING_P (pic_ref) = 1;
742 if (GET_CODE (pic_ref) != REG)
746 emit_move_insn (reg, pic_ref);
751 return force_reg (mode, pic_ref);
760 else if (GET_CODE (orig) == SYMBOL_REF)
763 else if (GET_CODE (orig) == PLUS
764 && (GET_CODE (XEXP (orig, 0)) == MEM
765 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
766 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
767 && XEXP (orig, 0) != pic_offset_table_rtx
768 && GET_CODE (XEXP (orig, 1)) != REG)
772 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
774 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
775 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
776 Pmode, (base == reg ? 0 : reg));
777 if (GET_CODE (orig) == CONST_INT)
779 pic_ref = plus_constant (base, INTVAL (orig));
783 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
785 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
786 RTX_UNCHANGING_P (pic_ref) = 1;
788 if (reg && is_complex)
790 emit_move_insn (reg, pic_ref);
793 /* Likewise, should we set special REG_NOTEs here? */
796 else if (GET_CODE (orig) == CONST)
798 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
801 else if (GET_CODE (orig) == MEM
802 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
804 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
806 addr = gen_rtx (MEM, GET_MODE (orig), addr);
807 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
808 emit_move_insn (reg, addr);
817 machopic_finish (asm_out_file)
822 for (temp = machopic_stubs;
824 temp = TREE_CHAIN (temp))
826 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
827 const char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
831 if (! TREE_USED (temp))
834 /* If the symbol is actually defined, we don't need a stub. */
835 if (sym_name[0] == '!' && sym_name[1] == 'T')
838 sym_name = darwin_strip_name_encoding (sym_name);
840 sym = alloca (strlen (sym_name) + 2);
841 if (sym_name[0] == '*' || sym_name[0] == '&')
842 strcpy (sym, sym_name + 1);
843 else if (sym_name[0] == '-' || sym_name[0] == '+')
844 strcpy (sym, sym_name);
846 sym[0] = '_', strcpy (sym + 1, sym_name);
848 stub = alloca (strlen (stub_name) + 2);
849 if (stub_name[0] == '*' || stub_name[0] == '&')
850 strcpy (stub, stub_name + 1);
852 stub[0] = '_', strcpy (stub + 1, stub_name);
854 machopic_output_stub (asm_out_file, sym, stub);
857 for (temp = machopic_non_lazy_pointers;
859 temp = TREE_CHAIN (temp))
861 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
862 char *lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
864 tree decl = lookup_name_darwin (TREE_VALUE (temp));
867 if (! TREE_USED (temp))
870 if (machopic_ident_defined_p (TREE_VALUE (temp))
871 #if 0 /* add back when we have private externs */
872 || (decl && DECL_PRIVATE_EXTERN (decl))
877 assemble_align (GET_MODE_ALIGNMENT (Pmode));
878 assemble_label (lazy_name);
879 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
880 GET_MODE_SIZE (Pmode),
881 GET_MODE_ALIGNMENT (Pmode), 1);
885 machopic_nl_symbol_ptr_section ();
886 assemble_name (asm_out_file, lazy_name);
887 fprintf (asm_out_file, ":\n");
889 fprintf (asm_out_file, "\t.indirect_symbol ");
890 assemble_name (asm_out_file, sym_name);
891 fprintf (asm_out_file, "\n");
893 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
894 GET_MODE_ALIGNMENT (Pmode), 1);
900 machopic_operand_p (op)
903 if (MACHOPIC_JUST_INDIRECT)
905 while (GET_CODE (op) == CONST)
908 if (GET_CODE (op) == SYMBOL_REF)
909 return machopic_name_defined_p (XSTR (op, 0));
914 while (GET_CODE (op) == CONST)
917 if (GET_CODE (op) == MINUS
918 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
919 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
920 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
921 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
924 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
925 /* Without this statement, the compiler crashes while compiling enquire.c
926 when targetting PowerPC. It is not known why this code is not needed
927 when targetting other processors. */
928 else if (GET_CODE (op) == SYMBOL_REF
929 && (machopic_classify_name (XSTR (op, 0))
930 == MACHOPIC_DEFINED_FUNCTION))
939 /* This function records whether a given name corresponds to a defined
940 or undefined function or variable, for machopic_classify_ident to
944 darwin_encode_section_info (decl, first)
946 int first ATTRIBUTE_UNUSED;
951 const char *orig_str;
955 if ((TREE_CODE (decl) == FUNCTION_DECL
956 || TREE_CODE (decl) == VAR_DECL)
957 && !DECL_EXTERNAL (decl)
958 && ((TREE_STATIC (decl)
959 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
960 || (DECL_INITIAL (decl)
961 && DECL_INITIAL (decl) != error_mark_node)))
964 if (TREE_CODE (decl) == FUNCTION_DECL)
965 code = (defined ? 'T' : 't');
966 else if (TREE_CODE (decl) == VAR_DECL)
967 code = (defined ? 'D' : 'd');
972 sym_ref = XEXP (DECL_RTL (decl), 0);
973 orig_str = XSTR (sym_ref, 0);
974 len = strlen (orig_str) + 1;
976 if (orig_str[0] == '!')
978 /* Already encoded; see if we need to change it. */
979 if (code == orig_str[1])
981 /* Yes, tweak a copy of the name and put it in a new string. */
982 new_str = alloca (len);
983 memcpy (new_str, orig_str, len);
985 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
989 /* Add the encoding. */
991 new_str = alloca (new_len);
996 memcpy (new_str + 4, orig_str, len);
997 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
999 /* The non-lazy pointer list may have captured references to the
1000 old encoded name, change them. */
1001 if (TREE_CODE (decl) == VAR_DECL)
1002 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1004 update_stubs (XSTR (sym_ref, 0));
1007 /* Undo the effects of the above. */
1010 darwin_strip_name_encoding (str)
1013 return str[0] == '!' ? str + 4 : str;
1016 /* Scan the list of non-lazy pointers and update any recorded names whose
1017 stripped name matches the argument. */
1020 update_non_lazy_ptrs (name)
1023 const char *name1, *name2;
1026 name1 = darwin_strip_name_encoding (name);
1028 for (temp = machopic_non_lazy_pointers;
1030 temp = TREE_CHAIN (temp))
1032 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1034 if (*sym_name == '!')
1036 name2 = darwin_strip_name_encoding (sym_name);
1037 if (strcmp (name1, name2) == 0)
1039 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1046 /* Function NAME is being defined, and its label has just been output.
1047 If there's already a reference to a stub for this function, we can
1048 just emit the stub label now and we don't bother emitting the stub later. */
1051 machopic_output_possible_stub_label (file, name)
1058 /* Ensure we're looking at a section-encoded name. */
1059 if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
1062 for (temp = machopic_stubs;
1064 temp = TREE_CHAIN (temp))
1066 const char *sym_name;
1068 sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1069 if (sym_name[0] == '!' && sym_name[1] == 'T'
1070 && ! strcmp (name+2, sym_name+2))
1072 ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
1073 /* Avoid generating a stub for this. */
1074 TREE_USED (temp) = 0;
1080 /* Scan the list of stubs and update any recorded names whose
1081 stripped name matches the argument. */
1087 const char *name1, *name2;
1090 name1 = darwin_strip_name_encoding (name);
1092 for (temp = machopic_stubs;
1094 temp = TREE_CHAIN (temp))
1096 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1098 if (*sym_name == '!')
1100 name2 = darwin_strip_name_encoding (sym_name);
1101 if (strcmp (name1, name2) == 0)
1103 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1111 machopic_select_section (exp, reloc, align)
1114 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1116 if (TREE_CODE (exp) == STRING_CST)
1118 if (flag_writable_strings)
1120 else if (TREE_STRING_LENGTH (exp) !=
1121 strlen (TREE_STRING_POINTER (exp)) + 1)
1122 readonly_data_section ();
1126 else if (TREE_CODE (exp) == INTEGER_CST
1127 || TREE_CODE (exp) == REAL_CST)
1129 tree size = TYPE_SIZE (TREE_TYPE (exp));
1131 if (TREE_CODE (size) == INTEGER_CST &&
1132 TREE_INT_CST_LOW (size) == 4 &&
1133 TREE_INT_CST_HIGH (size) == 0)
1134 literal4_section ();
1135 else if (TREE_CODE (size) == INTEGER_CST &&
1136 TREE_INT_CST_LOW (size) == 8 &&
1137 TREE_INT_CST_HIGH (size) == 0)
1138 literal8_section ();
1140 readonly_data_section ();
1142 else if (TREE_CODE (exp) == CONSTRUCTOR
1144 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1145 && TYPE_NAME (TREE_TYPE (exp)))
1147 tree name = TYPE_NAME (TREE_TYPE (exp));
1148 if (TREE_CODE (name) == TYPE_DECL)
1149 name = DECL_NAME (name);
1150 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1151 objc_constant_string_object_section ();
1152 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1153 objc_string_object_section ();
1154 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1156 if (TREE_SIDE_EFFECTS (exp) || flag_pic && reloc)
1157 const_data_section ();
1159 readonly_data_section ();
1164 else if (TREE_CODE (exp) == VAR_DECL &&
1166 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1167 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1168 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1170 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1172 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1173 objc_cls_meth_section ();
1174 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1175 objc_inst_meth_section ();
1176 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1177 objc_cat_cls_meth_section ();
1178 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1179 objc_cat_inst_meth_section ();
1180 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1181 objc_class_vars_section ();
1182 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1183 objc_instance_vars_section ();
1184 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1185 objc_cat_cls_meth_section ();
1186 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1187 objc_class_names_section ();
1188 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1189 objc_meth_var_names_section ();
1190 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1191 objc_meth_var_types_section ();
1192 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1193 objc_cls_refs_section ();
1194 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1195 objc_class_section ();
1196 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1197 objc_meta_class_section ();
1198 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1199 objc_category_section ();
1200 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1201 objc_selector_refs_section ();
1202 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1203 objc_selector_fixup_section ();
1204 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1205 objc_symbols_section ();
1206 else if (!strncmp (name, "_OBJC_MODULES", 13))
1207 objc_module_info_section ();
1208 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1209 objc_cat_inst_meth_section ();
1210 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1211 objc_cat_cls_meth_section ();
1212 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1213 objc_cat_cls_meth_section ();
1214 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1215 objc_protocol_section ();
1216 else if ((TREE_READONLY (exp) || TREE_CONSTANT (exp))
1217 && !TREE_SIDE_EFFECTS (exp))
1219 if (flag_pic && reloc)
1220 const_data_section ();
1222 readonly_data_section ();
1227 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1229 if (TREE_SIDE_EFFECTS (exp) || flag_pic && reloc)
1230 const_data_section ();
1232 readonly_data_section ();
1238 /* This can be called with address expressions as "rtx".
1239 They must go in "const". */
1242 machopic_select_rtx_section (mode, x, align)
1243 enum machine_mode mode;
1245 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1247 if (GET_MODE_SIZE (mode) == 8)
1248 literal8_section ();
1249 else if (GET_MODE_SIZE (mode) == 4
1250 && (GET_CODE (x) == CONST_INT
1251 || GET_CODE (x) == CONST_DOUBLE))
1252 literal4_section ();
1258 machopic_asm_out_constructor (symbol, priority)
1260 int priority ATTRIBUTE_UNUSED;
1263 mod_init_section ();
1265 constructor_section ();
1266 assemble_align (POINTER_SIZE);
1267 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1270 fprintf (asm_out_file, ".reference .constructors_used\n");
1274 machopic_asm_out_destructor (symbol, priority)
1276 int priority ATTRIBUTE_UNUSED;
1279 mod_term_section ();
1281 destructor_section ();
1282 assemble_align (POINTER_SIZE);
1283 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1286 fprintf (asm_out_file, ".reference .destructors_used\n");
1289 #include "gt-darwin.h"