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"
42 #include "darwin-protos.h"
44 extern void machopic_output_stub PARAMS ((FILE *, const char *, const char *));
46 static int machopic_data_defined_p PARAMS ((const char *));
47 static int func_name_maybe_scoped PARAMS ((const char *));
48 static void update_non_lazy_ptrs PARAMS ((const char *));
49 static void update_stubs PARAMS ((const char *));
52 name_needs_quotes (name)
56 while ((c = *name++) != '\0')
63 * flag_pic = 1 ... generate only indirections
64 * flag_pic = 2 ... generate indirections and pure code
67 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
68 reference, which will not be changed. */
70 static GTY(()) tree machopic_defined_list;
72 enum machopic_addr_class
73 machopic_classify_ident (ident)
76 const char *name = IDENTIFIER_POINTER (ident);
77 int lprefix = (((name[0] == '*' || name[0] == '&')
78 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
89 /* Here if no special encoding to be found. */
92 const char *name = IDENTIFIER_POINTER (ident);
93 int len = strlen (name);
95 if ((len > 5 && !strcmp (name + len - 5, "$stub"))
96 || (len > 6 && !strcmp (name + len - 6, "$stub\"")))
97 return MACHOPIC_DEFINED_FUNCTION;
98 return MACHOPIC_DEFINED_DATA;
101 for (temp = machopic_defined_list;
103 temp = TREE_CHAIN (temp))
105 if (ident == TREE_VALUE (temp))
106 return MACHOPIC_DEFINED_DATA;
109 if (TREE_ASM_WRITTEN (ident))
110 return MACHOPIC_DEFINED_DATA;
112 return MACHOPIC_UNDEFINED;
115 else if (name[1] == 'D')
116 return MACHOPIC_DEFINED_DATA;
118 else if (name[1] == 'T')
119 return MACHOPIC_DEFINED_FUNCTION;
121 /* It is possible that someone is holding a "stale" name, which has
122 since been defined. See if there is a "defined" name (i.e,
123 different from NAME only in having a '!D_' or a '!T_' instead of
124 a '!d_' or '!t_' prefix) in the identifier hash tables. If so, say
125 that this identifier is defined. */
126 else if (name[1] == 'd' || name[1] == 't')
129 new_name = (char *)alloca (strlen (name) + 1);
130 strcpy (new_name, name);
131 new_name[1] = (name[1] == 'd') ? 'D' : 'T';
132 if (maybe_get_identifier (new_name) != NULL)
133 return (name[1] == 'd') ? MACHOPIC_DEFINED_DATA
134 : MACHOPIC_DEFINED_FUNCTION;
137 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
139 if (ident == TREE_VALUE (temp))
142 return MACHOPIC_DEFINED_FUNCTION;
144 return MACHOPIC_DEFINED_DATA;
148 if (name[1] == 't' || name[1] == 'T')
151 return MACHOPIC_DEFINED_FUNCTION;
153 return MACHOPIC_UNDEFINED_FUNCTION;
158 return MACHOPIC_DEFINED_DATA;
160 return MACHOPIC_UNDEFINED_DATA;
165 enum machopic_addr_class
166 machopic_classify_name (name)
169 return machopic_classify_ident (get_identifier (name));
173 machopic_ident_defined_p (ident)
176 switch (machopic_classify_ident (ident))
178 case MACHOPIC_UNDEFINED:
179 case MACHOPIC_UNDEFINED_DATA:
180 case MACHOPIC_UNDEFINED_FUNCTION:
188 machopic_data_defined_p (name)
191 switch (machopic_classify_ident (get_identifier (name)))
193 case MACHOPIC_DEFINED_DATA:
201 machopic_name_defined_p (name)
204 return machopic_ident_defined_p (get_identifier (name));
208 machopic_define_ident (ident)
211 if (!machopic_ident_defined_p (ident))
212 machopic_defined_list =
213 tree_cons (NULL_TREE, ident, machopic_defined_list);
217 machopic_define_name (name)
220 machopic_define_ident (get_identifier (name));
223 /* This is a static to make inline functions work. The rtx
224 representing the PIC base symbol always points to here. */
226 static char function_base[32];
228 static int current_pic_label_num;
231 machopic_function_base_name ()
233 static const char *name = NULL;
234 static const char *current_name;
236 current_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
238 if (name != current_name)
240 current_function_uses_pic_offset_table = 1;
242 /* Save mucho space and time. Some of the C++ mangled names are over
243 700 characters long! Note that we produce a label containing a '-'
244 if the function we're compiling is an Objective-C method, as evinced
245 by the incredibly scientific test below. This is because code in
246 rs6000.c makes the same ugly test when loading the PIC reg. */
248 ++current_pic_label_num;
249 if (*current_name == '+' || *current_name == '-')
250 sprintf (function_base, "*\"L-%d$pb\"", current_pic_label_num);
252 sprintf (function_base, "*L%d$pb", current_pic_label_num);
257 return function_base;
260 static GTY(()) tree machopic_non_lazy_pointers;
262 /* Return a non-lazy pointer name corresponding to the given name,
263 either by finding it in our list of pointer names, or by generating
267 machopic_non_lazy_ptr_name (name)
271 tree temp, ident = get_identifier (name);
273 for (temp = machopic_non_lazy_pointers;
275 temp = TREE_CHAIN (temp))
277 if (ident == TREE_VALUE (temp))
278 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
281 name = darwin_strip_name_encoding (name);
283 /* Try again, but comparing names this time. */
284 for (temp = machopic_non_lazy_pointers;
286 temp = TREE_CHAIN (temp))
288 if (TREE_VALUE (temp))
290 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
291 temp_name = darwin_strip_name_encoding (temp_name);
292 if (strcmp (name, temp_name) == 0)
293 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
301 buffer = alloca (strlen (name) + 20);
303 strcpy (buffer, "&L");
305 strcat (buffer, name+1);
308 strcat (buffer, "_");
309 strcat (buffer, name);
312 strcat (buffer, "$non_lazy_ptr");
313 ptr_name = get_identifier (buffer);
315 machopic_non_lazy_pointers
316 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
318 TREE_USED (machopic_non_lazy_pointers) = 0;
320 return IDENTIFIER_POINTER (ptr_name);
324 static GTY(()) tree machopic_stubs;
326 /* Return the name of the stub corresponding to the given name,
327 generating a new stub name if necessary. */
330 machopic_stub_name (name)
333 tree temp, ident = get_identifier (name);
336 for (temp = machopic_stubs;
338 temp = TREE_CHAIN (temp))
340 if (ident == TREE_VALUE (temp))
341 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
342 tname = IDENTIFIER_POINTER (TREE_VALUE (temp));
343 if (strcmp (name, tname) == 0)
344 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
345 /* A library call name might not be section-encoded yet, so try
346 it against a stripped name. */
349 && strcmp (name, tname + 4) == 0)
350 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
353 name = darwin_strip_name_encoding (name);
358 int needs_quotes = name_needs_quotes (name);
360 buffer = alloca (strlen (name) + 20);
363 strcpy (buffer, "&\"L");
365 strcpy (buffer, "&L");
368 strcat (buffer, name+1);
372 strcat (buffer, "_");
373 strcat (buffer, name);
377 strcat (buffer, "$stub\"");
379 strcat (buffer, "$stub");
380 ptr_name = get_identifier (buffer);
382 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
383 TREE_USED (machopic_stubs) = 0;
385 return IDENTIFIER_POINTER (ptr_name);
390 machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
395 tree temp, ident = get_identifier (name), id2;
397 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
399 temp = TREE_CHAIN (temp))
400 if (ident == TREE_PURPOSE (temp))
402 /* Mark both the stub or non-lazy pointer as well as the
403 original symbol as being referenced. */
404 TREE_USED (temp) = 1;
405 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
406 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
407 real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
408 real_name = darwin_strip_name_encoding (real_name);
409 id2 = maybe_get_identifier (real_name);
411 TREE_SYMBOL_REFERENCED (id2) = 1;
415 /* Transform ORIG, which may be any data source, to the corresponding
416 source using indirections. */
419 machopic_indirect_data_reference (orig, reg)
424 if (! MACHOPIC_INDIRECT)
427 if (GET_CODE (orig) == SYMBOL_REF)
429 const char *name = XSTR (orig, 0);
431 if (machopic_data_defined_p (name))
433 rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
434 machopic_function_base_name ());
435 rtx offset = gen_rtx (CONST, Pmode,
436 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 (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
497 RTX_UNCHANGING_P (result) = 1;
499 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
503 emit_move_insn (reg, result);
508 result = force_reg (GET_MODE (result), result);
515 else if (GET_CODE (orig) == MEM)
516 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
517 /* When the target is i386, this code prevents crashes due to the
518 compiler's ignorance on how to move the PIC base register to
519 other registers. (The reload phase sometimes introduces such
521 else if (GET_CODE (orig) == PLUS
522 && GET_CODE (XEXP (orig, 0)) == REG
523 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
525 /* Prevent the same register from being erroneously used
526 as both the base and index registers. */
527 && GET_CODE (XEXP (orig, 1)) == CONST
531 emit_move_insn (reg, XEXP (orig, 0));
532 XEXP (ptr_ref, 0) = reg;
537 /* Transform TARGET (a MEM), which is a function call target, to the
538 corresponding symbol_stub if necessary. Return a new MEM. */
541 machopic_indirect_call_target (target)
544 if (GET_CODE (target) != MEM)
547 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
549 enum machine_mode mode = GET_MODE (XEXP (target, 0));
550 const char *name = XSTR (XEXP (target, 0), 0);
552 /* If the name is already defined, we need do nothing. */
553 if (name[0] == '!' && name[1] == 'T')
556 if (!machopic_name_defined_p (name))
558 const char *stub_name = machopic_stub_name (name);
560 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
561 RTX_UNCHANGING_P (target) = 1;
569 machopic_legitimize_pic_address (orig, mode, reg)
571 enum machine_mode mode;
578 /* First handle a simple SYMBOL_REF or LABEL_REF */
579 if (GET_CODE (orig) == LABEL_REF
580 || (GET_CODE (orig) == SYMBOL_REF
583 /* addr(foo) = &func+(foo-func) */
586 orig = machopic_indirect_data_reference (orig, reg);
588 if (GET_CODE (orig) == PLUS
589 && GET_CODE (XEXP (orig, 0)) == REG)
592 return force_reg (mode, orig);
594 emit_move_insn (reg, orig);
598 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
600 if (GET_CODE (orig) == MEM)
604 if (reload_in_progress)
607 reg = gen_reg_rtx (Pmode);
611 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
612 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
614 rtx offset = gen_rtx (CONST, Pmode,
615 gen_rtx (MINUS, Pmode,
616 XEXP (orig, 0), pic_base));
617 #if defined (TARGET_TOC) /* i.e., PowerPC */
618 /* Generating a new reg may expose opportunities for
619 common subexpression elimination. */
621 (reload_in_progress ? reg : gen_reg_rtx (SImode));
623 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
624 gen_rtx (PLUS, Pmode,
625 pic_offset_table_rtx,
626 gen_rtx (HIGH, Pmode, offset))));
627 emit_insn (gen_rtx (SET, VOIDmode, reg,
628 gen_rtx (MEM, GET_MODE (orig),
629 gen_rtx (LO_SUM, Pmode,
630 hi_sum_reg, offset))));
634 emit_insn (gen_rtx (USE, VOIDmode,
635 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
637 emit_insn (gen_rtx (SET, VOIDmode, reg,
638 gen_rtx (HIGH, Pmode,
639 gen_rtx (CONST, Pmode, offset))));
640 emit_insn (gen_rtx (SET, VOIDmode, reg,
641 gen_rtx (LO_SUM, Pmode, reg,
642 gen_rtx (CONST, Pmode, offset))));
643 pic_ref = gen_rtx (PLUS, Pmode,
644 pic_offset_table_rtx, reg);
648 #endif /* HAVE_lo_sum */
650 rtx pic = pic_offset_table_rtx;
651 if (GET_CODE (pic) != REG)
653 emit_move_insn (reg, pic);
657 emit_insn (gen_rtx (USE, VOIDmode,
658 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
661 pic_ref = gen_rtx (PLUS, Pmode,
663 gen_rtx (CONST, Pmode,
664 gen_rtx (MINUS, Pmode,
669 #if !defined (TARGET_TOC)
670 RTX_UNCHANGING_P (pic_ref) = 1;
671 emit_move_insn (reg, pic_ref);
672 pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
679 if (GET_CODE (orig) == SYMBOL_REF
680 || GET_CODE (orig) == LABEL_REF)
682 rtx offset = gen_rtx (CONST, Pmode,
683 gen_rtx (MINUS, Pmode, orig, pic_base));
684 #if defined (TARGET_TOC) /* i.e., PowerPC */
689 if (reload_in_progress)
692 reg = gen_reg_rtx (SImode);
697 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
698 gen_rtx (PLUS, Pmode,
699 pic_offset_table_rtx,
700 gen_rtx (HIGH, Pmode, offset))));
701 emit_insn (gen_rtx (SET, VOIDmode, reg,
702 gen_rtx (LO_SUM, Pmode,
703 hi_sum_reg, offset)));
706 emit_insn (gen_rtx (SET, VOIDmode, reg,
707 gen_rtx (HIGH, Pmode, offset)));
708 emit_insn (gen_rtx (SET, VOIDmode, reg,
709 gen_rtx (LO_SUM, Pmode, reg, offset)));
710 pic_ref = gen_rtx (PLUS, Pmode,
711 pic_offset_table_rtx, reg);
715 #endif /* HAVE_lo_sum */
717 if (GET_CODE (orig) == REG)
723 rtx pic = pic_offset_table_rtx;
724 if (GET_CODE (pic) != REG)
726 emit_move_insn (reg, pic);
730 emit_insn (gen_rtx (USE, VOIDmode,
731 pic_offset_table_rtx));
733 pic_ref = gen_rtx (PLUS, Pmode,
735 gen_rtx (CONST, Pmode,
736 gen_rtx (MINUS, Pmode,
742 RTX_UNCHANGING_P (pic_ref) = 1;
744 if (GET_CODE (pic_ref) != REG)
748 emit_move_insn (reg, pic_ref);
753 return force_reg (mode, pic_ref);
762 else if (GET_CODE (orig) == SYMBOL_REF)
765 else if (GET_CODE (orig) == PLUS
766 && (GET_CODE (XEXP (orig, 0)) == MEM
767 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
768 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
769 && XEXP (orig, 0) != pic_offset_table_rtx
770 && GET_CODE (XEXP (orig, 1)) != REG)
774 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
776 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
777 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
778 Pmode, (base == reg ? 0 : reg));
779 if (GET_CODE (orig) == CONST_INT)
781 pic_ref = plus_constant (base, INTVAL (orig));
785 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
787 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
788 RTX_UNCHANGING_P (pic_ref) = 1;
790 if (reg && is_complex)
792 emit_move_insn (reg, pic_ref);
795 /* Likewise, should we set special REG_NOTEs here? */
798 else if (GET_CODE (orig) == CONST)
800 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
803 else if (GET_CODE (orig) == MEM
804 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
806 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
808 addr = gen_rtx (MEM, GET_MODE (orig), addr);
809 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
810 emit_move_insn (reg, addr);
819 machopic_finish (asm_out_file)
824 for (temp = machopic_stubs;
826 temp = TREE_CHAIN (temp))
828 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
829 const char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
833 if (! TREE_USED (temp))
836 /* If the symbol is actually defined, we don't need a stub. */
837 if (sym_name[0] == '!' && sym_name[1] == 'T')
840 sym_name = darwin_strip_name_encoding (sym_name);
842 sym = alloca (strlen (sym_name) + 2);
843 if (sym_name[0] == '*' || sym_name[0] == '&')
844 strcpy (sym, sym_name + 1);
845 else if (sym_name[0] == '-' || sym_name[0] == '+')
846 strcpy (sym, sym_name);
848 sym[0] = '_', strcpy (sym + 1, sym_name);
850 stub = alloca (strlen (stub_name) + 2);
851 if (stub_name[0] == '*' || stub_name[0] == '&')
852 strcpy (stub, stub_name + 1);
854 stub[0] = '_', strcpy (stub + 1, stub_name);
856 machopic_output_stub (asm_out_file, sym, stub);
859 for (temp = machopic_non_lazy_pointers;
861 temp = TREE_CHAIN (temp))
863 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
864 char *lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
866 tree decl = lookup_name_darwin (TREE_VALUE (temp));
869 if (! TREE_USED (temp))
872 if (machopic_ident_defined_p (TREE_VALUE (temp))
873 #if 0 /* add back when we have private externs */
874 || (decl && DECL_PRIVATE_EXTERN (decl))
879 assemble_align (GET_MODE_ALIGNMENT (Pmode));
880 assemble_label (lazy_name);
881 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
882 GET_MODE_SIZE (Pmode),
883 GET_MODE_ALIGNMENT (Pmode), 1);
887 machopic_nl_symbol_ptr_section ();
888 assemble_name (asm_out_file, lazy_name);
889 fprintf (asm_out_file, ":\n");
891 fprintf (asm_out_file, "\t.indirect_symbol ");
892 assemble_name (asm_out_file, sym_name);
893 fprintf (asm_out_file, "\n");
895 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
896 GET_MODE_ALIGNMENT (Pmode), 1);
902 machopic_operand_p (op)
905 if (MACHOPIC_JUST_INDIRECT)
907 while (GET_CODE (op) == CONST)
910 if (GET_CODE (op) == SYMBOL_REF)
911 return machopic_name_defined_p (XSTR (op, 0));
916 while (GET_CODE (op) == CONST)
919 if (GET_CODE (op) == MINUS
920 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
921 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
922 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
923 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
926 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
927 /* Without this statement, the compiler crashes while compiling enquire.c
928 when targetting PowerPC. It is not known why this code is not needed
929 when targetting other processors. */
930 else if (GET_CODE (op) == SYMBOL_REF
931 && (machopic_classify_name (XSTR (op, 0))
932 == MACHOPIC_DEFINED_FUNCTION))
941 /* This function records whether a given name corresponds to a defined
942 or undefined function or variable, for machopic_classify_ident to
946 darwin_encode_section_info (decl, first)
948 int first ATTRIBUTE_UNUSED;
953 const char *orig_str;
957 if ((TREE_CODE (decl) == FUNCTION_DECL
958 || TREE_CODE (decl) == VAR_DECL)
959 && !DECL_EXTERNAL (decl)
960 && ((TREE_STATIC (decl)
961 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
962 || (DECL_INITIAL (decl)
963 && DECL_INITIAL (decl) != error_mark_node)))
966 if (TREE_CODE (decl) == FUNCTION_DECL)
967 code = (defined ? 'T' : 't');
968 else if (TREE_CODE (decl) == VAR_DECL)
969 code = (defined ? 'D' : 'd');
974 sym_ref = XEXP (DECL_RTL (decl), 0);
975 orig_str = XSTR (sym_ref, 0);
976 len = strlen (orig_str) + 1;
978 if (orig_str[0] == '!')
980 /* Already encoded; see if we need to change it. */
981 if (code == orig_str[1])
983 /* Yes, tweak a copy of the name and put it in a new string. */
984 new_str = alloca (len);
985 memcpy (new_str, orig_str, len);
987 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
991 /* Add the encoding. */
993 new_str = alloca (new_len);
998 memcpy (new_str + 4, orig_str, len);
999 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
1001 /* The non-lazy pointer list may have captured references to the
1002 old encoded name, change them. */
1003 if (TREE_CODE (decl) == VAR_DECL)
1004 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1006 update_stubs (XSTR (sym_ref, 0));
1009 /* Undo the effects of the above. */
1012 darwin_strip_name_encoding (str)
1015 return str[0] == '!' ? str + 4 : str;
1018 /* Scan the list of non-lazy pointers and update any recorded names whose
1019 stripped name matches the argument. */
1022 update_non_lazy_ptrs (name)
1025 const char *name1, *name2;
1028 name1 = darwin_strip_name_encoding (name);
1030 for (temp = machopic_non_lazy_pointers;
1032 temp = TREE_CHAIN (temp))
1034 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1036 if (*sym_name == '!')
1038 name2 = darwin_strip_name_encoding (sym_name);
1039 if (strcmp (name1, name2) == 0)
1041 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1048 /* Function NAME is being defined, and its label has just been output.
1049 If there's already a reference to a stub for this function, we can
1050 just emit the stub label now and we don't bother emitting the stub later. */
1053 machopic_output_possible_stub_label (file, name)
1060 /* Ensure we're looking at a section-encoded name. */
1061 if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
1064 for (temp = machopic_stubs;
1066 temp = TREE_CHAIN (temp))
1068 const char *sym_name;
1070 sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1071 if (sym_name[0] == '!' && sym_name[1] == 'T'
1072 && ! strcmp (name+2, sym_name+2))
1074 ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
1075 /* Avoid generating a stub for this. */
1076 TREE_USED (temp) = 0;
1082 /* Scan the list of stubs and update any recorded names whose
1083 stripped name matches the argument. */
1089 const char *name1, *name2;
1092 name1 = darwin_strip_name_encoding (name);
1094 for (temp = machopic_stubs;
1096 temp = TREE_CHAIN (temp))
1098 char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1100 if (*sym_name == '!')
1102 name2 = darwin_strip_name_encoding (sym_name);
1103 if (strcmp (name1, name2) == 0)
1105 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1113 machopic_select_section (exp, reloc, align)
1116 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1118 if (TREE_CODE (exp) == STRING_CST)
1120 if (flag_writable_strings)
1122 else if (TREE_STRING_LENGTH (exp) !=
1123 strlen (TREE_STRING_POINTER (exp)) + 1)
1124 readonly_data_section ();
1128 else if (TREE_CODE (exp) == INTEGER_CST
1129 || TREE_CODE (exp) == REAL_CST)
1131 tree size = TYPE_SIZE (TREE_TYPE (exp));
1133 if (TREE_CODE (size) == INTEGER_CST &&
1134 TREE_INT_CST_LOW (size) == 4 &&
1135 TREE_INT_CST_HIGH (size) == 0)
1136 literal4_section ();
1137 else if (TREE_CODE (size) == INTEGER_CST &&
1138 TREE_INT_CST_LOW (size) == 8 &&
1139 TREE_INT_CST_HIGH (size) == 0)
1140 literal8_section ();
1142 readonly_data_section ();
1144 else if (TREE_CODE (exp) == CONSTRUCTOR
1146 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1147 && TYPE_NAME (TREE_TYPE (exp)))
1149 tree name = TYPE_NAME (TREE_TYPE (exp));
1150 if (TREE_CODE (name) == TYPE_DECL)
1151 name = DECL_NAME (name);
1152 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1153 objc_constant_string_object_section ();
1154 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1155 objc_string_object_section ();
1156 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1158 if (TREE_SIDE_EFFECTS (exp) || flag_pic && reloc)
1159 const_data_section ();
1161 readonly_data_section ();
1166 else if (TREE_CODE (exp) == VAR_DECL &&
1168 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1169 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1170 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1172 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1174 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1175 objc_cls_meth_section ();
1176 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1177 objc_inst_meth_section ();
1178 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1179 objc_cat_cls_meth_section ();
1180 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1181 objc_cat_inst_meth_section ();
1182 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1183 objc_class_vars_section ();
1184 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1185 objc_instance_vars_section ();
1186 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1187 objc_cat_cls_meth_section ();
1188 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1189 objc_class_names_section ();
1190 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1191 objc_meth_var_names_section ();
1192 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1193 objc_meth_var_types_section ();
1194 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1195 objc_cls_refs_section ();
1196 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1197 objc_class_section ();
1198 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1199 objc_meta_class_section ();
1200 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1201 objc_category_section ();
1202 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1203 objc_selector_refs_section ();
1204 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1205 objc_selector_fixup_section ();
1206 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1207 objc_symbols_section ();
1208 else if (!strncmp (name, "_OBJC_MODULES", 13))
1209 objc_module_info_section ();
1210 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1211 objc_cat_inst_meth_section ();
1212 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1213 objc_cat_cls_meth_section ();
1214 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1215 objc_cat_cls_meth_section ();
1216 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1217 objc_protocol_section ();
1218 else if ((TREE_READONLY (exp) || TREE_CONSTANT (exp))
1219 && !TREE_SIDE_EFFECTS (exp))
1221 if (flag_pic && reloc)
1222 const_data_section ();
1224 readonly_data_section ();
1229 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1231 if (TREE_SIDE_EFFECTS (exp) || flag_pic && reloc)
1232 const_data_section ();
1234 readonly_data_section ();
1240 /* This can be called with address expressions as "rtx".
1241 They must go in "const". */
1244 machopic_select_rtx_section (mode, x, align)
1245 enum machine_mode mode;
1247 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1249 if (GET_MODE_SIZE (mode) == 8)
1250 literal8_section ();
1251 else if (GET_MODE_SIZE (mode) == 4
1252 && (GET_CODE (x) == CONST_INT
1253 || GET_CODE (x) == CONST_DOUBLE))
1254 literal4_section ();
1260 machopic_asm_out_constructor (symbol, priority)
1262 int priority ATTRIBUTE_UNUSED;
1265 mod_init_section ();
1267 constructor_section ();
1268 assemble_align (POINTER_SIZE);
1269 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1272 fprintf (asm_out_file, ".reference .constructors_used\n");
1276 machopic_asm_out_destructor (symbol, priority)
1278 int priority ATTRIBUTE_UNUSED;
1281 mod_term_section ();
1283 destructor_section ();
1284 assemble_align (POINTER_SIZE);
1285 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1288 fprintf (asm_out_file, ".reference .destructors_used\n");
1291 #include "gt-darwin.h"