1 /* Functions for generic Darwin as target machine for GNU C compiler.
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003
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 FIXME: The rest of the compiler doesn't expect strings to change. */
226 static GTY(()) char * function_base;
227 static GTY(()) const char * function_base_func_name;
228 static GTY(()) int current_pic_label_num;
231 machopic_function_base_name ()
233 const char *current_name;
235 /* if dynamic-no-pic is on, we should not get here */
236 if (MACHO_DYNAMIC_NO_PIC_P)
239 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
241 if (function_base_func_name != current_name)
243 current_function_uses_pic_offset_table = 1;
245 /* Save mucho space and time. Some of the C++ mangled names are over
246 700 characters long! Note that we produce a label containing a '-'
247 if the function we're compiling is an Objective-C method, as evinced
248 by the incredibly scientific test below. This is because code in
249 rs6000.c makes the same ugly test when loading the PIC reg. */
251 /* It's hard to describe just how ugly this is. The reason for
252 the '%011d' is that after a PCH load, we can't change the
253 size of the string, because PCH will have uniqued it and
254 allocated it in the string pool. */
255 if (function_base == NULL)
257 (char *) ggc_alloc_string ("", sizeof ("*\"L12345678901$pb\""));
259 ++current_pic_label_num;
260 if (*current_name == '+' || *current_name == '-')
261 sprintf (function_base, "*\"L-%010d$pb\"", current_pic_label_num);
263 sprintf (function_base, "*\"L%011d$pb\"", current_pic_label_num);
265 function_base_func_name = current_name;
268 return function_base;
271 static GTY(()) tree machopic_non_lazy_pointers;
273 /* Return a non-lazy pointer name corresponding to the given name,
274 either by finding it in our list of pointer names, or by generating
278 machopic_non_lazy_ptr_name (name)
281 const char *temp_name;
282 tree temp, ident = get_identifier (name);
284 for (temp = machopic_non_lazy_pointers;
286 temp = TREE_CHAIN (temp))
288 if (ident == TREE_VALUE (temp))
289 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
292 name = darwin_strip_name_encoding (name);
294 /* Try again, but comparing names this time. */
295 for (temp = machopic_non_lazy_pointers;
297 temp = TREE_CHAIN (temp))
299 if (TREE_VALUE (temp))
301 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
302 temp_name = darwin_strip_name_encoding (temp_name);
303 if (strcmp (name, temp_name) == 0)
304 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
312 buffer = alloca (strlen (name) + 20);
314 strcpy (buffer, "&L");
316 strcat (buffer, name+1);
319 strcat (buffer, "_");
320 strcat (buffer, name);
323 strcat (buffer, "$non_lazy_ptr");
324 ptr_name = get_identifier (buffer);
326 machopic_non_lazy_pointers
327 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
329 TREE_USED (machopic_non_lazy_pointers) = 0;
331 return IDENTIFIER_POINTER (ptr_name);
335 static GTY(()) tree machopic_stubs;
337 /* Return the name of the stub corresponding to the given name,
338 generating a new stub name if necessary. */
341 machopic_stub_name (name)
344 tree temp, ident = get_identifier (name);
347 for (temp = machopic_stubs;
349 temp = TREE_CHAIN (temp))
351 if (ident == TREE_VALUE (temp))
352 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
353 tname = IDENTIFIER_POINTER (TREE_VALUE (temp));
354 if (strcmp (name, tname) == 0)
355 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
356 /* A library call name might not be section-encoded yet, so try
357 it against a stripped name. */
360 && strcmp (name, tname + 4) == 0)
361 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
364 name = darwin_strip_name_encoding (name);
369 int needs_quotes = name_needs_quotes (name);
371 buffer = alloca (strlen (name) + 20);
374 strcpy (buffer, "&\"L");
376 strcpy (buffer, "&L");
379 strcat (buffer, name+1);
383 strcat (buffer, "_");
384 strcat (buffer, name);
388 strcat (buffer, "$stub\"");
390 strcat (buffer, "$stub");
391 ptr_name = get_identifier (buffer);
393 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
394 TREE_USED (machopic_stubs) = 0;
396 return IDENTIFIER_POINTER (ptr_name);
401 machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
405 const char *real_name;
406 tree temp, ident = get_identifier (name), id2;
408 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
410 temp = TREE_CHAIN (temp))
411 if (ident == TREE_PURPOSE (temp))
413 /* Mark both the stub or non-lazy pointer as well as the
414 original symbol as being referenced. */
415 TREE_USED (temp) = 1;
416 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
417 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
418 real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
419 real_name = darwin_strip_name_encoding (real_name);
420 id2 = maybe_get_identifier (real_name);
422 TREE_SYMBOL_REFERENCED (id2) = 1;
426 /* Transform ORIG, which may be any data source, to the corresponding
427 source using indirections. */
430 machopic_indirect_data_reference (orig, reg)
435 if (! MACHOPIC_INDIRECT)
438 if (GET_CODE (orig) == SYMBOL_REF)
440 const char *name = XSTR (orig, 0);
442 int defined = machopic_data_defined_p (name);
444 if (defined && MACHO_DYNAMIC_NO_PIC_P)
446 #if defined (TARGET_TOC)
447 emit_insn (gen_macho_high (reg, orig));
448 emit_insn (gen_macho_low (reg, reg, orig));
450 /* some other cpu -- writeme! */
457 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
458 rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
459 machopic_function_base_name ());
460 rtx offset = gen_rtx (CONST, Pmode,
461 gen_rtx (MINUS, Pmode, orig, pic_base));
464 #if defined (TARGET_TOC) /* i.e., PowerPC */
465 rtx hi_sum_reg = reg;
470 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
471 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
472 gen_rtx (HIGH, Pmode, offset))));
473 emit_insn (gen_rtx (SET, Pmode, reg,
474 gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
478 #if defined (HAVE_lo_sum)
479 if (reg == 0) abort ();
481 emit_insn (gen_rtx (SET, VOIDmode, reg,
482 gen_rtx (HIGH, Pmode, offset)));
483 emit_insn (gen_rtx (SET, VOIDmode, reg,
484 gen_rtx (LO_SUM, Pmode, reg, offset)));
485 emit_insn (gen_rtx (USE, VOIDmode,
486 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
488 orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
494 ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
495 machopic_non_lazy_ptr_name (name));
497 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
498 RTX_UNCHANGING_P (ptr_ref) = 1;
502 else if (GET_CODE (orig) == CONST)
506 /* legitimize both operands of the PLUS */
507 if (GET_CODE (XEXP (orig, 0)) == PLUS)
509 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
511 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
512 (base == reg ? 0 : reg));
517 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
518 result = plus_constant (base, INTVAL (orig));
520 result = gen_rtx (PLUS, Pmode, base, orig);
522 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
526 emit_move_insn (reg, result);
531 result = force_reg (GET_MODE (result), result);
538 else if (GET_CODE (orig) == MEM)
539 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
540 /* When the target is i386, this code prevents crashes due to the
541 compiler's ignorance on how to move the PIC base register to
542 other registers. (The reload phase sometimes introduces such
544 else if (GET_CODE (orig) == PLUS
545 && GET_CODE (XEXP (orig, 0)) == REG
546 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
548 /* Prevent the same register from being erroneously used
549 as both the base and index registers. */
550 && GET_CODE (XEXP (orig, 1)) == CONST
554 emit_move_insn (reg, XEXP (orig, 0));
555 XEXP (ptr_ref, 0) = reg;
560 /* Transform TARGET (a MEM), which is a function call target, to the
561 corresponding symbol_stub if necessary. Return a new MEM. */
564 machopic_indirect_call_target (target)
567 if (GET_CODE (target) != MEM)
570 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
572 enum machine_mode mode = GET_MODE (XEXP (target, 0));
573 const char *name = XSTR (XEXP (target, 0), 0);
575 /* If the name is already defined, we need do nothing. */
576 if (name[0] == '!' && name[1] == 'T')
579 if (!machopic_name_defined_p (name))
581 const char *stub_name = machopic_stub_name (name);
583 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
584 RTX_UNCHANGING_P (target) = 1;
592 machopic_legitimize_pic_address (orig, mode, reg)
594 enum machine_mode mode;
598 if (! MACHOPIC_INDIRECT)
601 /* First handle a simple SYMBOL_REF or LABEL_REF */
602 if (GET_CODE (orig) == LABEL_REF
603 || (GET_CODE (orig) == SYMBOL_REF
606 /* addr(foo) = &func+(foo-func) */
609 orig = machopic_indirect_data_reference (orig, reg);
611 if (GET_CODE (orig) == PLUS
612 && GET_CODE (XEXP (orig, 0)) == REG)
615 return force_reg (mode, orig);
617 emit_move_insn (reg, orig);
621 /* if dynamic-no-pic then use 0 as the pic base */
622 if (MACHO_DYNAMIC_NO_PIC_P)
623 pic_base = CONST0_RTX (Pmode);
625 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
627 if (GET_CODE (orig) == MEM)
631 if (reload_in_progress)
634 reg = gen_reg_rtx (Pmode);
638 if (MACHO_DYNAMIC_NO_PIC_P
639 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
640 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
642 #if defined (TARGET_TOC) /* ppc */
643 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
644 rtx asym = XEXP (orig, 0);
647 emit_insn (gen_macho_high (temp_reg, asym));
648 mem = gen_rtx_MEM (GET_MODE (orig),
649 gen_rtx (LO_SUM, Pmode, temp_reg, asym));
650 RTX_UNCHANGING_P (mem) = 1;
651 emit_insn (gen_rtx (SET, VOIDmode, reg, mem));
653 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
659 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
660 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
662 rtx offset = gen_rtx (CONST, Pmode,
663 gen_rtx (MINUS, Pmode,
664 XEXP (orig, 0), pic_base));
665 #if defined (TARGET_TOC) /* i.e., PowerPC */
666 /* Generating a new reg may expose opportunities for
667 common subexpression elimination. */
669 (reload_in_progress ? reg : gen_reg_rtx (SImode));
671 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
672 gen_rtx (PLUS, Pmode,
673 pic_offset_table_rtx,
674 gen_rtx (HIGH, Pmode, offset))));
675 emit_insn (gen_rtx (SET, VOIDmode, reg,
676 gen_rtx (MEM, GET_MODE (orig),
677 gen_rtx (LO_SUM, Pmode,
678 hi_sum_reg, offset))));
682 emit_insn (gen_rtx (USE, VOIDmode,
683 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
685 emit_insn (gen_rtx (SET, VOIDmode, reg,
686 gen_rtx (HIGH, Pmode,
687 gen_rtx (CONST, Pmode, offset))));
688 emit_insn (gen_rtx (SET, VOIDmode, reg,
689 gen_rtx (LO_SUM, Pmode, reg,
690 gen_rtx (CONST, Pmode, offset))));
691 pic_ref = gen_rtx (PLUS, Pmode,
692 pic_offset_table_rtx, reg);
696 #endif /* HAVE_lo_sum */
698 rtx pic = pic_offset_table_rtx;
699 if (GET_CODE (pic) != REG)
701 emit_move_insn (reg, pic);
705 emit_insn (gen_rtx (USE, VOIDmode,
706 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
709 pic_ref = gen_rtx (PLUS, Pmode,
711 gen_rtx (CONST, Pmode,
712 gen_rtx (MINUS, Pmode,
717 #if !defined (TARGET_TOC)
718 emit_move_insn (reg, pic_ref);
719 pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
721 RTX_UNCHANGING_P (pic_ref) = 1;
727 if (GET_CODE (orig) == SYMBOL_REF
728 || GET_CODE (orig) == LABEL_REF)
730 rtx offset = gen_rtx (CONST, Pmode,
731 gen_rtx (MINUS, Pmode, orig, pic_base));
732 #if defined (TARGET_TOC) /* i.e., PowerPC */
737 if (reload_in_progress)
740 reg = gen_reg_rtx (SImode);
745 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
746 (MACHO_DYNAMIC_NO_PIC_P)
747 ? gen_rtx (HIGH, Pmode, offset)
748 : gen_rtx (PLUS, Pmode,
749 pic_offset_table_rtx,
750 gen_rtx (HIGH, Pmode, offset))));
751 emit_insn (gen_rtx (SET, VOIDmode, reg,
752 gen_rtx (LO_SUM, Pmode,
753 hi_sum_reg, offset)));
755 RTX_UNCHANGING_P (pic_ref) = 1;
757 emit_insn (gen_rtx (SET, VOIDmode, reg,
758 gen_rtx (HIGH, Pmode, offset)));
759 emit_insn (gen_rtx (SET, VOIDmode, reg,
760 gen_rtx (LO_SUM, Pmode, reg, offset)));
761 pic_ref = gen_rtx (PLUS, Pmode,
762 pic_offset_table_rtx, reg);
763 RTX_UNCHANGING_P (pic_ref) = 1;
767 #endif /* HAVE_lo_sum */
769 if (GET_CODE (orig) == REG)
775 rtx pic = pic_offset_table_rtx;
776 if (GET_CODE (pic) != REG)
778 emit_move_insn (reg, pic);
782 emit_insn (gen_rtx (USE, VOIDmode,
783 pic_offset_table_rtx));
785 pic_ref = gen_rtx (PLUS, Pmode,
787 gen_rtx (CONST, Pmode,
788 gen_rtx (MINUS, Pmode,
794 if (GET_CODE (pic_ref) != REG)
798 emit_move_insn (reg, pic_ref);
803 return force_reg (mode, pic_ref);
812 else if (GET_CODE (orig) == SYMBOL_REF)
815 else if (GET_CODE (orig) == PLUS
816 && (GET_CODE (XEXP (orig, 0)) == MEM
817 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
818 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
819 && XEXP (orig, 0) != pic_offset_table_rtx
820 && GET_CODE (XEXP (orig, 1)) != REG)
824 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
826 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
827 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
828 Pmode, (base == reg ? 0 : reg));
829 if (GET_CODE (orig) == CONST_INT)
831 pic_ref = plus_constant (base, INTVAL (orig));
835 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
837 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
838 RTX_UNCHANGING_P (pic_ref) = 1;
840 if (reg && is_complex)
842 emit_move_insn (reg, pic_ref);
845 /* Likewise, should we set special REG_NOTEs here? */
848 else if (GET_CODE (orig) == CONST)
850 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
853 else if (GET_CODE (orig) == MEM
854 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
856 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
858 addr = gen_rtx (MEM, GET_MODE (orig), addr);
859 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
860 emit_move_insn (reg, addr);
869 machopic_finish (asm_out_file)
874 for (temp = machopic_stubs;
876 temp = TREE_CHAIN (temp))
878 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
879 const char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
883 if (! TREE_USED (temp))
886 /* If the symbol is actually defined, we don't need a stub. */
887 if (sym_name[0] == '!' && sym_name[1] == 'T')
890 sym_name = darwin_strip_name_encoding (sym_name);
892 sym = alloca (strlen (sym_name) + 2);
893 if (sym_name[0] == '*' || sym_name[0] == '&')
894 strcpy (sym, sym_name + 1);
895 else if (sym_name[0] == '-' || sym_name[0] == '+')
896 strcpy (sym, sym_name);
898 sym[0] = '_', strcpy (sym + 1, sym_name);
900 stub = alloca (strlen (stub_name) + 2);
901 if (stub_name[0] == '*' || stub_name[0] == '&')
902 strcpy (stub, stub_name + 1);
904 stub[0] = '_', strcpy (stub + 1, stub_name);
906 machopic_output_stub (asm_out_file, sym, stub);
909 for (temp = machopic_non_lazy_pointers;
911 temp = TREE_CHAIN (temp))
913 const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
914 const char *const lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
916 if (! TREE_USED (temp))
919 if (machopic_ident_defined_p (TREE_VALUE (temp)))
922 assemble_align (GET_MODE_ALIGNMENT (Pmode));
923 assemble_label (lazy_name);
924 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
925 GET_MODE_SIZE (Pmode),
926 GET_MODE_ALIGNMENT (Pmode), 1);
930 machopic_nl_symbol_ptr_section ();
931 assemble_name (asm_out_file, lazy_name);
932 fprintf (asm_out_file, ":\n");
934 fprintf (asm_out_file, "\t.indirect_symbol ");
935 assemble_name (asm_out_file, sym_name);
936 fprintf (asm_out_file, "\n");
938 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
939 GET_MODE_ALIGNMENT (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)))
972 /* This function records whether a given name corresponds to a defined
973 or undefined function or variable, for machopic_classify_ident to
977 darwin_encode_section_info (decl, rtl, first)
980 int first ATTRIBUTE_UNUSED;
985 const char *orig_str;
989 /* Do the standard encoding things first. */
990 default_encode_section_info (decl, rtl, first);
992 /* With the introduction of symbol_ref flags, some of the following
993 code has become redundant and should be removed at some point. */
995 if ((TREE_CODE (decl) == FUNCTION_DECL
996 || TREE_CODE (decl) == VAR_DECL)
997 && !DECL_EXTERNAL (decl)
998 && ((TREE_STATIC (decl)
999 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1000 || (DECL_INITIAL (decl)
1001 && DECL_INITIAL (decl) != error_mark_node)))
1004 if (TREE_CODE (decl) == FUNCTION_DECL)
1005 code = (defined ? 'T' : 't');
1006 else if (TREE_CODE (decl) == VAR_DECL)
1007 code = (defined ? 'D' : 'd');
1012 sym_ref = XEXP (rtl, 0);
1013 orig_str = XSTR (sym_ref, 0);
1014 len = strlen (orig_str) + 1;
1016 if (orig_str[0] == '!')
1018 /* Already encoded; see if we need to change it. */
1019 if (code == orig_str[1])
1021 /* Yes, tweak a copy of the name and put it in a new string. */
1022 new_str = alloca (len);
1023 memcpy (new_str, orig_str, len);
1025 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
1029 /* Add the encoding. */
1031 new_str = alloca (new_len);
1036 memcpy (new_str + 4, orig_str, len);
1037 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
1039 /* The non-lazy pointer list may have captured references to the
1040 old encoded name, change them. */
1041 if (TREE_CODE (decl) == VAR_DECL)
1042 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1044 update_stubs (XSTR (sym_ref, 0));
1047 /* Undo the effects of the above. */
1050 darwin_strip_name_encoding (str)
1053 return str[0] == '!' ? str + 4 : str;
1056 /* Scan the list of non-lazy pointers and update any recorded names whose
1057 stripped name matches the argument. */
1060 update_non_lazy_ptrs (name)
1063 const char *name1, *name2;
1066 name1 = darwin_strip_name_encoding (name);
1068 for (temp = machopic_non_lazy_pointers;
1070 temp = TREE_CHAIN (temp))
1072 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1074 if (*sym_name == '!')
1076 name2 = darwin_strip_name_encoding (sym_name);
1077 if (strcmp (name1, name2) == 0)
1079 /* FIXME: This breaks the identifier hash table. */
1080 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1081 = (unsigned char *) name;
1088 /* Function NAME is being defined, and its label has just been output.
1089 If there's already a reference to a stub for this function, we can
1090 just emit the stub label now and we don't bother emitting the stub later. */
1093 machopic_output_possible_stub_label (file, name)
1100 /* Ensure we're looking at a section-encoded name. */
1101 if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
1104 for (temp = machopic_stubs;
1106 temp = TREE_CHAIN (temp))
1108 const char *sym_name;
1110 sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1111 if (sym_name[0] == '!' && sym_name[1] == 'T'
1112 && ! strcmp (name+2, sym_name+2))
1114 ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
1115 /* Avoid generating a stub for this. */
1116 TREE_USED (temp) = 0;
1122 /* Scan the list of stubs and update any recorded names whose
1123 stripped name matches the argument. */
1129 const char *name1, *name2;
1132 name1 = darwin_strip_name_encoding (name);
1134 for (temp = machopic_stubs;
1136 temp = TREE_CHAIN (temp))
1138 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1140 if (*sym_name == '!')
1142 name2 = darwin_strip_name_encoding (sym_name);
1143 if (strcmp (name1, name2) == 0)
1145 /* FIXME: This breaks the identifier hash table. */
1146 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1147 = (unsigned char *) name;
1155 machopic_select_section (exp, reloc, align)
1158 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1160 if (TREE_CODE (exp) == STRING_CST)
1162 if (flag_writable_strings)
1164 else if ((size_t) TREE_STRING_LENGTH (exp) !=
1165 strlen (TREE_STRING_POINTER (exp)) + 1)
1166 readonly_data_section ();
1170 else if (TREE_CODE (exp) == INTEGER_CST
1171 || TREE_CODE (exp) == REAL_CST)
1173 tree size = TYPE_SIZE (TREE_TYPE (exp));
1175 if (TREE_CODE (size) == INTEGER_CST &&
1176 TREE_INT_CST_LOW (size) == 4 &&
1177 TREE_INT_CST_HIGH (size) == 0)
1178 literal4_section ();
1179 else if (TREE_CODE (size) == INTEGER_CST &&
1180 TREE_INT_CST_LOW (size) == 8 &&
1181 TREE_INT_CST_HIGH (size) == 0)
1182 literal8_section ();
1184 readonly_data_section ();
1186 else if (TREE_CODE (exp) == CONSTRUCTOR
1188 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1189 && TYPE_NAME (TREE_TYPE (exp)))
1191 tree name = TYPE_NAME (TREE_TYPE (exp));
1192 if (TREE_CODE (name) == TYPE_DECL)
1193 name = DECL_NAME (name);
1194 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1195 objc_constant_string_object_section ();
1196 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1197 objc_string_object_section ();
1198 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1201 if (TREE_SIDE_EFFECTS (exp) || (MACHOPIC_INDIRECT && reloc))
1202 const_data_section ();
1204 readonly_data_section ();
1209 else if (TREE_CODE (exp) == VAR_DECL &&
1211 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1212 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1213 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1215 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1217 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1218 objc_cls_meth_section ();
1219 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1220 objc_inst_meth_section ();
1221 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1222 objc_cat_cls_meth_section ();
1223 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1224 objc_cat_inst_meth_section ();
1225 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1226 objc_class_vars_section ();
1227 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1228 objc_instance_vars_section ();
1229 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1230 objc_cat_cls_meth_section ();
1231 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1232 objc_class_names_section ();
1233 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1234 objc_meth_var_names_section ();
1235 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1236 objc_meth_var_types_section ();
1237 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1238 objc_cls_refs_section ();
1239 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1240 objc_class_section ();
1241 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1242 objc_meta_class_section ();
1243 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1244 objc_category_section ();
1245 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1246 objc_selector_refs_section ();
1247 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1248 objc_selector_fixup_section ();
1249 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1250 objc_symbols_section ();
1251 else if (!strncmp (name, "_OBJC_MODULES", 13))
1252 objc_module_info_section ();
1253 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1254 objc_cat_inst_meth_section ();
1255 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1256 objc_cat_cls_meth_section ();
1257 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1258 objc_cat_cls_meth_section ();
1259 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1260 objc_protocol_section ();
1261 else if ((TREE_READONLY (exp) || TREE_CONSTANT (exp))
1262 && !TREE_SIDE_EFFECTS (exp))
1265 if (MACHOPIC_INDIRECT && reloc)
1266 const_data_section ();
1268 readonly_data_section ();
1273 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1276 if (TREE_SIDE_EFFECTS (exp) || (MACHOPIC_INDIRECT && reloc))
1277 const_data_section ();
1279 readonly_data_section ();
1285 /* This can be called with address expressions as "rtx".
1286 They must go in "const". */
1289 machopic_select_rtx_section (mode, x, align)
1290 enum machine_mode mode;
1292 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1294 if (GET_MODE_SIZE (mode) == 8)
1295 literal8_section ();
1296 else if (GET_MODE_SIZE (mode) == 4
1297 && (GET_CODE (x) == CONST_INT
1298 || GET_CODE (x) == CONST_DOUBLE))
1299 literal4_section ();
1305 machopic_asm_out_constructor (symbol, priority)
1307 int priority ATTRIBUTE_UNUSED;
1310 if (MACHOPIC_INDIRECT)
1311 mod_init_section ();
1313 constructor_section ();
1314 assemble_align (POINTER_SIZE);
1315 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1318 if (! MACHOPIC_INDIRECT)
1319 fprintf (asm_out_file, ".reference .constructors_used\n");
1323 machopic_asm_out_destructor (symbol, priority)
1325 int priority ATTRIBUTE_UNUSED;
1328 if (MACHOPIC_INDIRECT)
1329 mod_term_section ();
1331 destructor_section ();
1332 assemble_align (POINTER_SIZE);
1333 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1335 if (! MACHOPIC_INDIRECT)
1336 fprintf (asm_out_file, ".reference .destructors_used\n");
1340 darwin_globalize_label (stream, name)
1344 if (!!strncmp (name, "_OBJC_", 6))
1345 default_globalize_label (stream, name);
1348 /* Output a difference of two labels that will be an assembly time
1349 constant if the two labels are local. (.long lab1-lab2 will be
1350 very different if lab1 is at the boundary between two sections; it
1351 will be relocated according to the second section, not the first,
1352 so one ends up with a difference between labels in different
1353 sections, which is bad in the dwarf2 eh context for instance.) */
1355 static int darwin_dwarf_label_counter;
1358 darwin_asm_output_dwarf_delta (file, size, lab1, lab2)
1360 int size ATTRIBUTE_UNUSED;
1361 const char *lab1, *lab2;
1363 const char *p = lab1 + (lab1[0] == '*');
1364 int islocaldiff = (p[0] == 'L');
1367 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1369 fprintf (file, "\t%s\t", ".long");
1370 assemble_name (file, lab1);
1371 fprintf (file, "-");
1372 assemble_name (file, lab2);
1374 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1377 #include "gt-darwin.h"