1 /* Functions for generic Darwin as target machine for GNU C compiler.
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Apple Computer Inc.
6 This file is part of GCC.
8 GCC 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 GCC 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 GCC; 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"
46 static int machopic_data_defined_p (const char *);
47 static void update_non_lazy_ptrs (const char *);
48 static void update_stubs (const char *);
49 static const char *machopic_non_lazy_ptr_name (const char*);
52 name_needs_quotes (const char *name)
55 while ((c = *name++) != '\0')
56 if (! ISIDNUM (c) && c != '.' && c != '$')
62 * flag_pic = 1 ... generate only indirections
63 * flag_pic = 2 ... generate indirections and pure code
66 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
67 reference, which will not be changed. */
69 static GTY(()) tree machopic_defined_list;
71 enum machopic_addr_class
72 machopic_classify_ident (tree ident)
74 const char *name = IDENTIFIER_POINTER (ident);
75 int lprefix = (((name[0] == '*' || name[0] == '&')
76 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
85 /* The PIC base symbol is always defined. */
86 if (! strcmp (name, "<pic base>"))
87 return MACHOPIC_DEFINED_DATA;
91 /* Here if no special encoding to be found. */
94 const char *name = IDENTIFIER_POINTER (ident);
95 int len = strlen (name);
97 if ((len > 5 && !strcmp (name + len - 5, "$stub"))
98 || (len > 6 && !strcmp (name + len - 6, "$stub\"")))
99 return MACHOPIC_DEFINED_FUNCTION;
100 return MACHOPIC_DEFINED_DATA;
103 for (temp = machopic_defined_list;
105 temp = TREE_CHAIN (temp))
107 if (ident == TREE_VALUE (temp))
108 return MACHOPIC_DEFINED_DATA;
111 if (TREE_ASM_WRITTEN (ident))
112 return MACHOPIC_DEFINED_DATA;
114 return MACHOPIC_UNDEFINED;
117 else if (name[1] == 'D')
118 return MACHOPIC_DEFINED_DATA;
120 else if (name[1] == 'T')
121 return MACHOPIC_DEFINED_FUNCTION;
123 /* It is possible that someone is holding a "stale" name, which has
124 since been defined. See if there is a "defined" name (i.e,
125 different from NAME only in having a '!D_' or a '!T_' instead of
126 a '!d_' or '!t_' prefix) in the identifier hash tables. If so, say
127 that this identifier is defined. */
128 else if (name[1] == 'd' || name[1] == 't')
131 new_name = (char *)alloca (strlen (name) + 1);
132 strcpy (new_name, name);
133 new_name[1] = (name[1] == 'd') ? 'D' : 'T';
134 if (maybe_get_identifier (new_name) != NULL)
135 return (name[1] == 'd') ? MACHOPIC_DEFINED_DATA
136 : MACHOPIC_DEFINED_FUNCTION;
139 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
141 if (ident == TREE_VALUE (temp))
144 return MACHOPIC_DEFINED_FUNCTION;
146 return MACHOPIC_DEFINED_DATA;
150 if (name[1] == 't' || name[1] == 'T')
153 return MACHOPIC_DEFINED_FUNCTION;
155 return MACHOPIC_UNDEFINED_FUNCTION;
160 return MACHOPIC_DEFINED_DATA;
162 return MACHOPIC_UNDEFINED_DATA;
167 enum machopic_addr_class
168 machopic_classify_name (const char *name)
170 return machopic_classify_ident (get_identifier (name));
174 machopic_ident_defined_p (tree 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 (const char *name)
190 switch (machopic_classify_ident (get_identifier (name)))
192 case MACHOPIC_DEFINED_DATA:
200 machopic_name_defined_p (const char *name)
202 return machopic_ident_defined_p (get_identifier (name));
206 machopic_define_ident (tree ident)
208 if (!machopic_ident_defined_p (ident))
209 machopic_defined_list =
210 tree_cons (NULL_TREE, ident, machopic_defined_list);
214 machopic_define_name (const char *name)
216 machopic_define_ident (get_identifier (name));
219 static GTY(()) char * function_base;
222 machopic_function_base_name (void)
224 /* if dynamic-no-pic is on, we should not get here */
225 if (MACHO_DYNAMIC_NO_PIC_P)
228 if (function_base == NULL)
230 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
232 current_function_uses_pic_offset_table = 1;
234 return function_base;
237 static GTY(()) const char * function_base_func_name;
238 static GTY(()) int current_pic_label_num;
241 machopic_output_function_base_name (FILE *file)
243 const char *current_name;
245 /* If dynamic-no-pic is on, we should not get here. */
246 if (MACHO_DYNAMIC_NO_PIC_P)
249 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
250 if (function_base_func_name != current_name)
252 ++current_pic_label_num;
253 function_base_func_name = current_name;
255 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
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 (const char *name)
267 const char *temp_name;
268 tree temp, ident = get_identifier (name);
270 for (temp = machopic_non_lazy_pointers;
272 temp = TREE_CHAIN (temp))
274 if (ident == TREE_VALUE (temp))
275 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
278 name = darwin_strip_name_encoding (name);
280 /* Try again, but comparing names this time. */
281 for (temp = machopic_non_lazy_pointers;
283 temp = TREE_CHAIN (temp))
285 if (TREE_VALUE (temp))
287 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
288 temp_name = darwin_strip_name_encoding (temp_name);
289 if (strcmp (name, temp_name) == 0)
290 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
296 int namelen = strlen (name);
300 buffer = alloca (namelen + strlen("$non_lazy_ptr") + 5);
302 strcpy (buffer, "&L");
306 memcpy (buffer + bufferlen, name+1, namelen-1+1);
307 bufferlen += namelen-1;
311 strcpy (buffer + bufferlen, user_label_prefix);
312 bufferlen += strlen (user_label_prefix);
313 memcpy (buffer + bufferlen, name, namelen+1);
314 bufferlen += namelen;
317 memcpy (buffer + bufferlen, "$non_lazy_ptr", strlen("$non_lazy_ptr")+1);
318 bufferlen += strlen("$non_lazy_ptr");
319 ptr_name = get_identifier (buffer);
321 machopic_non_lazy_pointers
322 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
324 TREE_USED (machopic_non_lazy_pointers) = 0;
326 return IDENTIFIER_POINTER (ptr_name);
330 static GTY(()) tree machopic_stubs;
332 /* Return the name of the stub corresponding to the given name,
333 generating a new stub name if necessary. */
336 machopic_stub_name (const char *name)
338 tree temp, ident = get_identifier (name);
341 for (temp = machopic_stubs;
343 temp = TREE_CHAIN (temp))
345 if (ident == TREE_VALUE (temp))
346 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
347 tname = IDENTIFIER_POINTER (TREE_VALUE (temp));
348 if (strcmp (name, tname) == 0)
349 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
350 /* A library call name might not be section-encoded yet, so try
351 it against a stripped name. */
354 && strcmp (name, tname + 4) == 0)
355 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
358 name = darwin_strip_name_encoding (name);
363 int namelen = strlen (name);
365 int needs_quotes = name_needs_quotes (name);
367 buffer = alloca (namelen + 20);
371 strcpy (buffer, "&\"L");
372 bufferlen = strlen("&\"L");
376 strcpy (buffer, "&L");
377 bufferlen = strlen("&L");
382 memcpy (buffer + bufferlen, name+1, namelen - 1 +1);
383 bufferlen += namelen - 1;
387 strcpy (buffer + bufferlen, user_label_prefix);
388 bufferlen += strlen (user_label_prefix);
389 memcpy (buffer + bufferlen, name, namelen+1);
390 bufferlen += namelen;
395 memcpy (buffer + bufferlen, "$stub\"", strlen("$stub\"")+1);
396 bufferlen += strlen("$stub\"");
400 memcpy (buffer + bufferlen, "$stub", strlen("$stub")+1);
401 bufferlen += strlen("$stub");
403 ptr_name = get_identifier (buffer);
405 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
406 TREE_USED (machopic_stubs) = 0;
408 return IDENTIFIER_POINTER (ptr_name);
413 machopic_validate_stub_or_non_lazy_ptr (const char *name, int validate_stub)
415 const char *real_name;
416 tree temp, ident = get_identifier (name), id2;
418 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
420 temp = TREE_CHAIN (temp))
421 if (ident == TREE_PURPOSE (temp))
423 /* Mark both the stub or non-lazy pointer as well as the
424 original symbol as being referenced. */
425 TREE_USED (temp) = 1;
426 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
427 mark_referenced (TREE_VALUE (temp));
428 real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
429 real_name = darwin_strip_name_encoding (real_name);
430 id2 = maybe_get_identifier (real_name);
432 mark_referenced (id2);
436 /* Transform ORIG, which may be any data source, to the corresponding
437 source using indirections. */
440 machopic_indirect_data_reference (rtx orig, rtx reg)
444 if (! MACHOPIC_INDIRECT)
447 if (GET_CODE (orig) == SYMBOL_REF)
449 const char *name = XSTR (orig, 0);
450 int defined = machopic_data_defined_p (name);
452 if (defined && MACHO_DYNAMIC_NO_PIC_P)
454 #if defined (TARGET_TOC)
455 emit_insn (gen_macho_high (reg, orig));
456 emit_insn (gen_macho_low (reg, reg, orig));
458 /* some other cpu -- writeme! */
465 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
466 rtx pic_base = gen_rtx_SYMBOL_REF (Pmode,
467 machopic_function_base_name ());
468 rtx offset = gen_rtx_CONST (Pmode,
469 gen_rtx_MINUS (Pmode, orig, pic_base));
472 #if defined (TARGET_TOC) /* i.e., PowerPC */
473 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
478 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
479 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
480 gen_rtx_HIGH (Pmode, offset))));
481 emit_insn (gen_rtx_SET (Pmode, reg,
482 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
486 #if defined (HAVE_lo_sum)
487 if (reg == 0) abort ();
489 emit_insn (gen_rtx_SET (VOIDmode, reg,
490 gen_rtx_HIGH (Pmode, offset)));
491 emit_insn (gen_rtx_SET (VOIDmode, reg,
492 gen_rtx_LO_SUM (Pmode, reg, offset)));
493 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
495 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
501 ptr_ref = gen_rtx_SYMBOL_REF (Pmode,
502 machopic_non_lazy_ptr_name (name));
504 SYMBOL_REF_DECL (ptr_ref) = SYMBOL_REF_DECL (orig);
506 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
507 RTX_UNCHANGING_P (ptr_ref) = 1;
511 else if (GET_CODE (orig) == CONST)
515 /* legitimize both operands of the PLUS */
516 if (GET_CODE (XEXP (orig, 0)) == PLUS)
518 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
520 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
521 (base == reg ? 0 : reg));
526 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
527 result = plus_constant (base, INTVAL (orig));
529 result = gen_rtx_PLUS (Pmode, base, orig);
531 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
535 emit_move_insn (reg, result);
540 result = force_reg (GET_MODE (result), result);
547 else if (GET_CODE (orig) == MEM)
548 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
549 /* When the target is i386, this code prevents crashes due to the
550 compiler's ignorance on how to move the PIC base register to
551 other registers. (The reload phase sometimes introduces such
553 else if (GET_CODE (orig) == PLUS
554 && GET_CODE (XEXP (orig, 0)) == REG
555 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
557 /* Prevent the same register from being erroneously used
558 as both the base and index registers. */
559 && GET_CODE (XEXP (orig, 1)) == CONST
563 emit_move_insn (reg, XEXP (orig, 0));
564 XEXP (ptr_ref, 0) = reg;
569 /* Transform TARGET (a MEM), which is a function call target, to the
570 corresponding symbol_stub if necessary. Return a new MEM. */
573 machopic_indirect_call_target (rtx target)
575 if (GET_CODE (target) != MEM)
578 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
580 enum machine_mode mode = GET_MODE (XEXP (target, 0));
581 const char *name = XSTR (XEXP (target, 0), 0);
583 /* If the name is already defined, we need do nothing. */
584 if (name[0] == '!' && name[1] == 'T')
587 if (!machopic_name_defined_p (name))
589 const char *stub_name = machopic_stub_name (name);
590 tree decl = SYMBOL_REF_DECL (XEXP (target, 0));
592 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
593 SYMBOL_REF_DECL (XEXP (target, 0)) = decl;
594 RTX_UNCHANGING_P (target) = 1;
602 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
606 if (! MACHOPIC_INDIRECT)
609 /* First handle a simple SYMBOL_REF or LABEL_REF */
610 if (GET_CODE (orig) == LABEL_REF
611 || (GET_CODE (orig) == SYMBOL_REF
614 /* addr(foo) = &func+(foo-func) */
617 orig = machopic_indirect_data_reference (orig, reg);
619 if (GET_CODE (orig) == PLUS
620 && GET_CODE (XEXP (orig, 0)) == REG)
623 return force_reg (mode, orig);
625 emit_move_insn (reg, orig);
629 /* if dynamic-no-pic then use 0 as the pic base */
630 if (MACHO_DYNAMIC_NO_PIC_P)
631 pic_base = CONST0_RTX (Pmode);
633 pic_base = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
635 if (GET_CODE (orig) == MEM)
639 if (reload_in_progress)
642 reg = gen_reg_rtx (Pmode);
646 if (MACHO_DYNAMIC_NO_PIC_P
647 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
648 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
650 #if defined (TARGET_TOC) /* ppc */
651 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
652 rtx asym = XEXP (orig, 0);
655 emit_insn (gen_macho_high (temp_reg, asym));
656 mem = gen_rtx_MEM (GET_MODE (orig),
657 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
658 RTX_UNCHANGING_P (mem) = 1;
659 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
661 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
667 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
668 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
670 rtx offset = gen_rtx_CONST (Pmode,
671 gen_rtx_MINUS (Pmode,
674 #if defined (TARGET_TOC) /* i.e., PowerPC */
675 /* Generating a new reg may expose opportunities for
676 common subexpression elimination. */
677 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (SImode);
682 sum = gen_rtx_HIGH (Pmode, offset);
683 if (! MACHO_DYNAMIC_NO_PIC_P)
684 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
686 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
688 mem = gen_rtx_MEM (GET_MODE (orig),
689 gen_rtx_LO_SUM (Pmode,
690 hi_sum_reg, offset));
691 RTX_UNCHANGING_P (mem) = 1;
692 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
693 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
698 emit_insn (gen_rtx_USE (VOIDmode,
700 PIC_OFFSET_TABLE_REGNUM)));
702 emit_insn (gen_rtx_SET (VOIDmode, reg,
704 gen_rtx_CONST (Pmode,
706 emit_insn (gen_rtx_SET (VOIDmode, reg,
707 gen_rtx_LO_SUM (Pmode, reg,
708 gen_rtx_CONST (Pmode, offset))));
709 pic_ref = gen_rtx_PLUS (Pmode,
710 pic_offset_table_rtx, reg);
714 #endif /* HAVE_lo_sum */
716 rtx pic = pic_offset_table_rtx;
717 if (GET_CODE (pic) != REG)
719 emit_move_insn (reg, pic);
723 emit_insn (gen_rtx_USE (VOIDmode,
725 PIC_OFFSET_TABLE_REGNUM)));
728 pic_ref = gen_rtx_PLUS (Pmode,
730 gen_rtx_CONST (Pmode,
731 gen_rtx_MINUS (Pmode,
736 #if !defined (TARGET_TOC)
737 emit_move_insn (reg, pic_ref);
738 pic_ref = gen_rtx_MEM (GET_MODE (orig), reg);
740 RTX_UNCHANGING_P (pic_ref) = 1;
746 if (GET_CODE (orig) == SYMBOL_REF
747 || GET_CODE (orig) == LABEL_REF)
749 rtx offset = gen_rtx_CONST (Pmode,
750 gen_rtx_MINUS (Pmode,
752 #if defined (TARGET_TOC) /* i.e., PowerPC */
757 if (reload_in_progress)
760 reg = gen_reg_rtx (SImode);
765 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
766 (MACHO_DYNAMIC_NO_PIC_P)
767 ? gen_rtx_HIGH (Pmode, offset)
768 : gen_rtx_PLUS (Pmode,
769 pic_offset_table_rtx,
772 emit_insn (gen_rtx_SET (VOIDmode, reg,
773 gen_rtx_LO_SUM (Pmode,
774 hi_sum_reg, offset)));
776 RTX_UNCHANGING_P (pic_ref) = 1;
778 emit_insn (gen_rtx_SET (VOIDmode, reg,
779 gen_rtx_HIGH (Pmode, offset)));
780 emit_insn (gen_rtx_SET (VOIDmode, reg,
781 gen_rtx_LO_SUM (Pmode, reg, offset)));
782 pic_ref = gen_rtx_PLUS (Pmode,
783 pic_offset_table_rtx, reg);
784 RTX_UNCHANGING_P (pic_ref) = 1;
788 #endif /* HAVE_lo_sum */
790 if (GET_CODE (orig) == REG)
796 rtx pic = pic_offset_table_rtx;
797 if (GET_CODE (pic) != REG)
799 emit_move_insn (reg, pic);
803 emit_insn (gen_rtx_USE (VOIDmode,
804 pic_offset_table_rtx));
806 pic_ref = gen_rtx_PLUS (Pmode,
808 gen_rtx_CONST (Pmode,
809 gen_rtx_MINUS (Pmode,
815 if (GET_CODE (pic_ref) != REG)
819 emit_move_insn (reg, pic_ref);
824 return force_reg (mode, pic_ref);
833 else if (GET_CODE (orig) == SYMBOL_REF)
836 else if (GET_CODE (orig) == PLUS
837 && (GET_CODE (XEXP (orig, 0)) == MEM
838 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
839 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
840 && XEXP (orig, 0) != pic_offset_table_rtx
841 && GET_CODE (XEXP (orig, 1)) != REG)
845 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
847 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
848 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
849 Pmode, (base == reg ? 0 : reg));
850 if (GET_CODE (orig) == CONST_INT)
852 pic_ref = plus_constant (base, INTVAL (orig));
856 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
858 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
859 RTX_UNCHANGING_P (pic_ref) = 1;
861 if (reg && is_complex)
863 emit_move_insn (reg, pic_ref);
866 /* Likewise, should we set special REG_NOTEs here? */
869 else if (GET_CODE (orig) == CONST)
871 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
874 else if (GET_CODE (orig) == MEM
875 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
877 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
879 addr = gen_rtx_MEM (GET_MODE (orig), addr);
880 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
881 emit_move_insn (reg, addr);
890 machopic_finish (FILE *asm_out_file)
894 for (temp = machopic_stubs;
896 temp = TREE_CHAIN (temp))
898 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
899 const char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
903 if (! TREE_USED (temp))
906 sym_name = darwin_strip_name_encoding (sym_name);
908 sym = alloca (strlen (sym_name) + 2);
909 if (sym_name[0] == '*' || sym_name[0] == '&')
910 strcpy (sym, sym_name + 1);
911 else if (sym_name[0] == '-' || sym_name[0] == '+')
912 strcpy (sym, sym_name);
914 sprintf (sym, "%s%s", user_label_prefix, sym_name);
916 stub = alloca (strlen (stub_name) + 2);
917 if (stub_name[0] == '*' || stub_name[0] == '&')
918 strcpy (stub, stub_name + 1);
920 sprintf (stub, "%s%s", user_label_prefix, stub_name);
922 machopic_output_stub (asm_out_file, sym, stub);
925 for (temp = machopic_non_lazy_pointers;
927 temp = TREE_CHAIN (temp))
929 const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
930 const char *const lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
932 if (! TREE_USED (temp))
935 if (machopic_ident_defined_p (TREE_VALUE (temp)))
938 assemble_align (GET_MODE_ALIGNMENT (Pmode));
939 assemble_label (lazy_name);
940 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
941 GET_MODE_SIZE (Pmode),
942 GET_MODE_ALIGNMENT (Pmode), 1);
946 machopic_nl_symbol_ptr_section ();
947 assemble_name (asm_out_file, lazy_name);
948 fprintf (asm_out_file, ":\n");
950 fprintf (asm_out_file, "\t.indirect_symbol ");
951 assemble_name (asm_out_file, sym_name);
952 fprintf (asm_out_file, "\n");
954 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
955 GET_MODE_ALIGNMENT (Pmode), 1);
961 machopic_operand_p (rtx op)
963 if (MACHOPIC_JUST_INDIRECT)
965 while (GET_CODE (op) == CONST)
968 if (GET_CODE (op) == SYMBOL_REF)
969 return machopic_name_defined_p (XSTR (op, 0));
974 while (GET_CODE (op) == CONST)
977 if (GET_CODE (op) == MINUS
978 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
979 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
980 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
981 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
987 /* This function records whether a given name corresponds to a defined
988 or undefined function or variable, for machopic_classify_ident to
992 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
997 const char *orig_str;
1001 /* Do the standard encoding things first. */
1002 default_encode_section_info (decl, rtl, first);
1004 /* With the introduction of symbol_ref flags, some of the following
1005 code has become redundant and should be removed at some point. */
1007 if ((TREE_CODE (decl) == FUNCTION_DECL
1008 || TREE_CODE (decl) == VAR_DECL)
1009 && !DECL_EXTERNAL (decl)
1010 && (!TREE_PUBLIC (decl) || (!DECL_ONE_ONLY (decl) && !DECL_WEAK (decl)))
1011 && ((TREE_STATIC (decl)
1012 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1013 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
1014 && DECL_INITIAL (decl) != error_mark_node)))
1017 if (TREE_CODE (decl) == FUNCTION_DECL)
1018 code = (defined ? 'T' : 't');
1019 else if (TREE_CODE (decl) == VAR_DECL)
1020 code = (defined ? 'D' : 'd');
1025 sym_ref = XEXP (rtl, 0);
1026 orig_str = XSTR (sym_ref, 0);
1027 len = strlen (orig_str) + 1;
1029 if (orig_str[0] == '!')
1031 /* Already encoded; see if we need to change it. */
1032 if (code == orig_str[1])
1034 /* Yes, tweak a copy of the name and put it in a new string. */
1035 new_str = alloca (len);
1036 memcpy (new_str, orig_str, len);
1038 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
1042 /* Add the encoding. */
1044 new_str = alloca (new_len);
1049 memcpy (new_str + 4, orig_str, len);
1050 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
1052 /* The non-lazy pointer list may have captured references to the
1053 old encoded name, change them. */
1054 if (TREE_CODE (decl) == VAR_DECL)
1055 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1057 update_stubs (XSTR (sym_ref, 0));
1060 /* Undo the effects of the above. */
1063 darwin_strip_name_encoding (const char *str)
1065 return str[0] == '!' ? str + 4 : str;
1068 /* Scan the list of non-lazy pointers and update any recorded names whose
1069 stripped name matches the argument. */
1072 update_non_lazy_ptrs (const char *name)
1074 const char *name1, *name2;
1077 name1 = darwin_strip_name_encoding (name);
1079 for (temp = machopic_non_lazy_pointers;
1081 temp = TREE_CHAIN (temp))
1083 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1085 if (*sym_name == '!')
1087 name2 = darwin_strip_name_encoding (sym_name);
1088 if (strcmp (name1, name2) == 0)
1090 /* FIXME: This breaks the identifier hash table. */
1091 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1092 = (unsigned char *) name;
1099 /* Scan the list of stubs and update any recorded names whose
1100 stripped name matches the argument. */
1103 update_stubs (const char *name)
1105 const char *name1, *name2;
1108 name1 = darwin_strip_name_encoding (name);
1110 for (temp = machopic_stubs;
1112 temp = TREE_CHAIN (temp))
1114 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1116 if (*sym_name == '!')
1118 name2 = darwin_strip_name_encoding (sym_name);
1119 if (strcmp (name1, name2) == 0)
1121 /* FIXME: This breaks the identifier hash table. */
1122 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1123 = (unsigned char *) name;
1131 darwin_make_decl_one_only (tree decl)
1133 static const char *text_section = "__TEXT,__textcoal_nt,coalesced,no_toc";
1134 static const char *data_section = "__DATA,__datacoal_nt,coalesced,no_toc";
1136 const char *sec = TREE_CODE (decl) == FUNCTION_DECL
1139 TREE_PUBLIC (decl) = 1;
1140 DECL_ONE_ONLY (decl) = 1;
1141 DECL_SECTION_NAME (decl) = build_string (strlen (sec), sec);
1145 machopic_select_section (tree exp, int reloc,
1146 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1148 void (*base_function)(void);
1150 if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1151 base_function = readonly_data_section;
1152 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1153 base_function = const_data_section;
1155 base_function = data_section;
1157 if (TREE_CODE (exp) == STRING_CST
1158 && ((size_t) TREE_STRING_LENGTH (exp)
1159 == strlen (TREE_STRING_POINTER (exp)) + 1))
1161 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1162 && flag_merge_constants)
1164 tree size = TYPE_SIZE (TREE_TYPE (exp));
1166 if (TREE_CODE (size) == INTEGER_CST &&
1167 TREE_INT_CST_LOW (size) == 4 &&
1168 TREE_INT_CST_HIGH (size) == 0)
1169 literal4_section ();
1170 else if (TREE_CODE (size) == INTEGER_CST &&
1171 TREE_INT_CST_LOW (size) == 8 &&
1172 TREE_INT_CST_HIGH (size) == 0)
1173 literal8_section ();
1177 else if (TREE_CODE (exp) == CONSTRUCTOR
1179 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1180 && TYPE_NAME (TREE_TYPE (exp)))
1182 tree name = TYPE_NAME (TREE_TYPE (exp));
1183 if (TREE_CODE (name) == TYPE_DECL)
1184 name = DECL_NAME (name);
1185 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1186 objc_constant_string_object_section ();
1187 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1188 objc_string_object_section ();
1192 else if (TREE_CODE (exp) == VAR_DECL &&
1194 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1195 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1196 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1198 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1200 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1201 objc_cls_meth_section ();
1202 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1203 objc_inst_meth_section ();
1204 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1205 objc_cat_cls_meth_section ();
1206 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1207 objc_cat_inst_meth_section ();
1208 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1209 objc_class_vars_section ();
1210 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1211 objc_instance_vars_section ();
1212 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1213 objc_cat_cls_meth_section ();
1214 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1215 objc_class_names_section ();
1216 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1217 objc_meth_var_names_section ();
1218 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1219 objc_meth_var_types_section ();
1220 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1221 objc_cls_refs_section ();
1222 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1223 objc_class_section ();
1224 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1225 objc_meta_class_section ();
1226 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1227 objc_category_section ();
1228 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1229 objc_selector_refs_section ();
1230 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1231 objc_selector_fixup_section ();
1232 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1233 objc_symbols_section ();
1234 else if (!strncmp (name, "_OBJC_MODULES", 13))
1235 objc_module_info_section ();
1236 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1237 objc_image_info_section ();
1238 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1239 objc_cat_inst_meth_section ();
1240 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1241 objc_cat_cls_meth_section ();
1242 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1243 objc_cat_cls_meth_section ();
1244 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1245 objc_protocol_section ();
1253 /* This can be called with address expressions as "rtx".
1254 They must go in "const". */
1257 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1258 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1260 if (GET_MODE_SIZE (mode) == 8)
1261 literal8_section ();
1262 else if (GET_MODE_SIZE (mode) == 4
1263 && (GET_CODE (x) == CONST_INT
1264 || GET_CODE (x) == CONST_DOUBLE))
1265 literal4_section ();
1266 else if (MACHOPIC_INDIRECT
1267 && (GET_CODE (x) == SYMBOL_REF
1268 || GET_CODE (x) == CONST
1269 || GET_CODE (x) == LABEL_REF))
1270 const_data_section ();
1276 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1278 if (MACHOPIC_INDIRECT)
1279 mod_init_section ();
1281 constructor_section ();
1282 assemble_align (POINTER_SIZE);
1283 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1285 if (! MACHOPIC_INDIRECT)
1286 fprintf (asm_out_file, ".reference .constructors_used\n");
1290 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1292 if (MACHOPIC_INDIRECT)
1293 mod_term_section ();
1295 destructor_section ();
1296 assemble_align (POINTER_SIZE);
1297 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1299 if (! MACHOPIC_INDIRECT)
1300 fprintf (asm_out_file, ".reference .destructors_used\n");
1304 darwin_globalize_label (FILE *stream, const char *name)
1306 if (!!strncmp (name, "_OBJC_", 6))
1307 default_globalize_label (stream, name);
1311 darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
1313 if (flag_reorder_blocks_and_partition)
1314 fprintf (asm_out_file, SECTION_FORMAT_STRING, name);
1316 fprintf (asm_out_file, ".section %s\n", name);
1320 darwin_section_type_flags (tree decl, const char *name, int reloc)
1322 unsigned int flags = default_section_type_flags (decl, name, reloc);
1324 /* Weak or linkonce variables live in a writable section. */
1325 if (decl != 0 && TREE_CODE (decl) != FUNCTION_DECL
1326 && (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)))
1327 flags |= SECTION_WRITE;
1333 darwin_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
1335 /* Darwin does not use unique sections. However, the target's
1336 unique_section hook is called for linkonce symbols. We need
1337 to set an appropriate section for such symbols. */
1338 if (DECL_ONE_ONLY (decl) && !DECL_SECTION_NAME (decl))
1339 darwin_make_decl_one_only (decl);
1342 #define HAVE_DEAD_STRIP 0
1345 no_dead_strip (FILE *file, const char *lab)
1347 if (HAVE_DEAD_STRIP)
1348 fprintf (file, ".no_dead_strip %s\n", lab);
1351 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1352 The third parameter is nonzero if this is for exception handling.
1353 The fourth parameter is nonzero if this is just a placeholder for an
1354 FDE that we are omitting. */
1357 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1359 tree id = DECL_ASSEMBLER_NAME (decl)
1360 ? DECL_ASSEMBLER_NAME (decl)
1363 const char *prefix = "_";
1364 const int prefix_len = 1;
1366 const char *base = IDENTIFIER_POINTER (id);
1367 unsigned int base_len = IDENTIFIER_LENGTH (id);
1369 const char *suffix = ".eh";
1371 int need_quotes = name_needs_quotes (base);
1372 int quotes_len = need_quotes ? 2 : 0;
1378 lab = xmalloc (prefix_len + base_len + strlen (suffix) + quotes_len + 1);
1383 strcat(lab, prefix);
1385 strcat(lab, suffix);
1389 if (TREE_PUBLIC (decl))
1390 fprintf (file, "%s %s\n",
1391 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1393 : ".private_extern"),
1396 if (DECL_ONE_ONLY (decl) && TREE_PUBLIC (decl))
1397 fprintf (file, ".weak_definition %s\n", lab);
1401 fprintf (file, "%s = 0\n", lab);
1403 /* Mark the absolute .eh and .eh1 style labels as needed to
1404 ensure that we don't dead code strip them and keep such
1405 labels from another instantiation point until we can fix this
1406 properly with group comdat support. */
1407 no_dead_strip (file, lab);
1410 fprintf (file, "%s:\n", lab);
1415 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1418 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1421 const char *nlp_name;
1423 if (GET_CODE (addr) != SYMBOL_REF)
1426 str = darwin_strip_name_encoding (XSTR (addr, 0));
1427 nlp_name = machopic_non_lazy_ptr_name (str);
1428 fputs ("\t.long\t", file);
1429 ASM_OUTPUT_LABELREF (file, nlp_name);
1433 /* Emit an assembler directive to set visibility for a symbol. The
1434 only supported visibilities are VISIBILITY_DEFAULT and
1435 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1436 extern". There is no MACH-O equivalent of ELF's
1437 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1440 darwin_assemble_visibility (tree decl, int vis)
1442 if (vis == VISIBILITY_DEFAULT)
1444 else if (vis == VISIBILITY_HIDDEN)
1446 fputs ("\t.private_extern ", asm_out_file);
1447 assemble_name (asm_out_file,
1448 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1449 fputs ("\n", asm_out_file);
1452 warning ("internal and protected visibility attributes not supported"
1453 "in this configuration; ignored");
1456 /* Output a difference of two labels that will be an assembly time
1457 constant if the two labels are local. (.long lab1-lab2 will be
1458 very different if lab1 is at the boundary between two sections; it
1459 will be relocated according to the second section, not the first,
1460 so one ends up with a difference between labels in different
1461 sections, which is bad in the dwarf2 eh context for instance.) */
1463 static int darwin_dwarf_label_counter;
1466 darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
1467 const char *lab1, const char *lab2)
1469 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1470 && lab2[0] == '*' && lab2[1] == 'L');
1473 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1475 fprintf (file, "\t%s\t", ".long");
1476 assemble_name (file, lab1);
1477 fprintf (file, "-");
1478 assemble_name (file, lab2);
1480 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1484 darwin_file_end (void)
1486 machopic_finish (asm_out_file);
1487 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1489 constructor_section ();
1490 destructor_section ();
1491 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1495 #include "gt-darwin.h"