1 /* Functions for generic Darwin as target machine for GNU C compiler.
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001
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"
41 #include "darwin-protos.h"
43 extern void machopic_output_stub
PARAMS ((FILE *, const char *, const char *));
45 static int machopic_data_defined_p
PARAMS ((const char *));
46 static int func_name_maybe_scoped
PARAMS ((const char *));
47 static void update_non_lazy_ptrs
PARAMS ((const char *));
48 static void update_stubs
PARAMS ((const char *));
51 name_needs_quotes (name
)
55 while ((c
= *name
++) != '\0')
56 if (!isalnum (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 tree machopic_defined_list
;
71 enum machopic_addr_class
72 machopic_classify_ident (ident
)
75 const char *name
= IDENTIFIER_POINTER (ident
);
76 int lprefix
= (((name
[0] == '*' || name
[0] == '&')
77 && (name
[1] == 'L' || (name
[1] == '"' && name
[2] == 'L')))
88 /* Here if no special encoding to be found. */
91 const char *name
= IDENTIFIER_POINTER (ident
);
92 int len
= strlen (name
);
94 if ((len
> 5 && !strcmp (name
+ len
- 5, "$stub"))
95 || (len
> 6 && !strcmp (name
+ len
- 6, "$stub\"")))
96 return MACHOPIC_DEFINED_FUNCTION
;
97 return MACHOPIC_DEFINED_DATA
;
100 for (temp
= machopic_defined_list
;
102 temp
= TREE_CHAIN (temp
))
104 if (ident
== TREE_VALUE (temp
))
105 return MACHOPIC_DEFINED_DATA
;
108 if (TREE_ASM_WRITTEN (ident
))
109 return MACHOPIC_DEFINED_DATA
;
111 return MACHOPIC_UNDEFINED
;
114 else if (name
[1] == 'D')
115 return MACHOPIC_DEFINED_DATA
;
117 else if (name
[1] == 'T')
118 return MACHOPIC_DEFINED_FUNCTION
;
120 for (temp
= machopic_defined_list
; temp
!= NULL_TREE
; temp
= TREE_CHAIN (temp
))
122 if (ident
== TREE_VALUE (temp
))
125 return MACHOPIC_DEFINED_FUNCTION
;
127 return MACHOPIC_DEFINED_DATA
;
131 if (name
[1] == 't' || name
[1] == 'T')
134 return MACHOPIC_DEFINED_FUNCTION
;
136 return MACHOPIC_UNDEFINED_FUNCTION
;
141 return MACHOPIC_DEFINED_DATA
;
143 return MACHOPIC_UNDEFINED_DATA
;
148 enum machopic_addr_class
149 machopic_classify_name (name
)
152 return machopic_classify_ident (get_identifier (name
));
156 machopic_ident_defined_p (ident
)
159 switch (machopic_classify_ident (ident
))
161 case MACHOPIC_UNDEFINED
:
162 case MACHOPIC_UNDEFINED_DATA
:
163 case MACHOPIC_UNDEFINED_FUNCTION
:
171 machopic_data_defined_p (name
)
174 switch (machopic_classify_ident (get_identifier (name
)))
176 case MACHOPIC_DEFINED_DATA
:
184 machopic_name_defined_p (name
)
187 return machopic_ident_defined_p (get_identifier (name
));
191 machopic_define_ident (ident
)
194 if (!machopic_ident_defined_p (ident
))
195 machopic_defined_list
=
196 tree_cons (NULL_TREE
, ident
, machopic_defined_list
);
200 machopic_define_name (name
)
203 machopic_define_ident (get_identifier (name
));
206 /* This is a static to make inline functions work. The rtx
207 representing the PIC base symbol always points to here. */
209 static char function_base
[32];
211 static int current_pic_label_num
;
214 machopic_function_base_name ()
216 static const char *name
= NULL
;
217 static const char *current_name
;
219 current_name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
));
221 if (name
!= current_name
)
223 current_function_uses_pic_offset_table
= 1;
225 /* Save mucho space and time. Some of the C++ mangled names are over
226 700 characters long! Note that we produce a label containing a '-'
227 if the function we're compiling is an Objective-C method, as evinced
228 by the incredibly scientific test below. This is because code in
229 rs6000.c makes the same ugly test when loading the PIC reg. */
231 ++current_pic_label_num
;
232 if (*current_name
== '+' || *current_name
== '-')
233 sprintf (function_base
, "*\"L-%d$pb\"", current_pic_label_num
);
235 sprintf (function_base
, "*L%d$pb", current_pic_label_num
);
240 return function_base
;
243 static tree machopic_non_lazy_pointers
= NULL
;
245 /* Return a non-lazy pointer name corresponding to the given name,
246 either by finding it in our list of pointer names, or by generating
250 machopic_non_lazy_ptr_name (name
)
254 tree temp
, ident
= get_identifier (name
);
256 for (temp
= machopic_non_lazy_pointers
;
258 temp
= TREE_CHAIN (temp
))
260 if (ident
== TREE_VALUE (temp
))
261 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
264 STRIP_NAME_ENCODING (name
, name
);
266 /* Try again, but comparing names this time. */
267 for (temp
= machopic_non_lazy_pointers
;
269 temp
= TREE_CHAIN (temp
))
271 if (TREE_VALUE (temp
))
273 temp_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
274 STRIP_NAME_ENCODING (temp_name
, temp_name
);
275 if (strcmp (name
, temp_name
) == 0)
276 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
284 buffer
= alloca (strlen (name
) + 20);
286 strcpy (buffer
, "&L");
288 strcat (buffer
, name
+1);
291 strcat (buffer
, "_");
292 strcat (buffer
, name
);
295 strcat (buffer
, "$non_lazy_ptr");
296 ptr_name
= get_identifier (buffer
);
298 machopic_non_lazy_pointers
299 = tree_cons (ptr_name
, ident
, machopic_non_lazy_pointers
);
301 TREE_USED (machopic_non_lazy_pointers
) = 0;
303 return IDENTIFIER_POINTER (ptr_name
);
307 static tree machopic_stubs
= 0;
309 /* Make sure the GC knows about our homemade lists. */
312 machopic_add_gc_roots ()
314 ggc_add_tree_root (&machopic_defined_list
, 1);
315 ggc_add_tree_root (&machopic_non_lazy_pointers
, 1);
316 ggc_add_tree_root (&machopic_stubs
, 1);
319 /* Return the name of the stub corresponding to the given name,
320 generating a new stub name if necessary. */
323 machopic_stub_name (name
)
326 tree temp
, ident
= get_identifier (name
);
329 for (temp
= machopic_stubs
;
331 temp
= TREE_CHAIN (temp
))
333 if (ident
== TREE_VALUE (temp
))
334 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
335 tname
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
336 if (strcmp (name
, tname
) == 0)
337 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
338 /* A library call name might not be section-encoded yet, so try
339 it against a stripped name. */
342 && strcmp (name
, tname
+ 4) == 0)
343 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
346 STRIP_NAME_ENCODING (name
, name
);
351 int needs_quotes
= name_needs_quotes (name
);
353 buffer
= alloca (strlen (name
) + 20);
356 strcpy (buffer
, "&\"L");
358 strcpy (buffer
, "&L");
361 strcat (buffer
, name
+1);
365 strcat (buffer
, "_");
366 strcat (buffer
, name
);
370 strcat (buffer
, "$stub\"");
372 strcat (buffer
, "$stub");
373 ptr_name
= get_identifier (buffer
);
375 machopic_stubs
= tree_cons (ptr_name
, ident
, machopic_stubs
);
376 TREE_USED (machopic_stubs
) = 0;
378 return IDENTIFIER_POINTER (ptr_name
);
383 machopic_validate_stub_or_non_lazy_ptr (name
, validate_stub
)
388 tree temp
, ident
= get_identifier (name
), id2
;
390 for (temp
= (validate_stub
? machopic_stubs
: machopic_non_lazy_pointers
);
392 temp
= TREE_CHAIN (temp
))
393 if (ident
== TREE_PURPOSE (temp
))
395 /* Mark both the stub or non-lazy pointer as well as the
396 original symbol as being referenced. */
397 TREE_USED (temp
) = 1;
398 if (TREE_CODE (TREE_VALUE (temp
)) == IDENTIFIER_NODE
)
399 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp
)) = 1;
400 STRIP_NAME_ENCODING (real_name
, IDENTIFIER_POINTER (TREE_VALUE (temp
)));
401 id2
= maybe_get_identifier (real_name
);
403 TREE_SYMBOL_REFERENCED (id2
) = 1;
407 /* Transform ORIG, which may be any data source, to the corresponding
408 source using indirections. */
411 machopic_indirect_data_reference (orig
, reg
)
416 if (! MACHOPIC_INDIRECT
)
419 if (GET_CODE (orig
) == SYMBOL_REF
)
421 const char *name
= XSTR (orig
, 0);
423 if (machopic_data_defined_p (name
))
425 rtx pic_base
= gen_rtx (SYMBOL_REF
, Pmode
,
426 machopic_function_base_name ());
427 rtx offset
= gen_rtx (CONST
, Pmode
,
428 gen_rtx (MINUS
, Pmode
, orig
, pic_base
));
430 #if defined (TARGET_TOC) /* i.e., PowerPC */
431 rtx hi_sum_reg
= reg
;
436 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
437 gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
,
438 gen_rtx (HIGH
, Pmode
, offset
))));
439 emit_insn (gen_rtx (SET
, Pmode
, reg
,
440 gen_rtx (LO_SUM
, Pmode
, hi_sum_reg
, offset
)));
444 #if defined (HAVE_lo_sum)
445 if (reg
== 0) abort ();
447 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
448 gen_rtx (HIGH
, Pmode
, offset
)));
449 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
450 gen_rtx (LO_SUM
, Pmode
, reg
, offset
)));
451 emit_insn (gen_rtx (USE
, VOIDmode
,
452 gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
454 orig
= gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
, reg
);
460 ptr_ref
= gen_rtx (SYMBOL_REF
, Pmode
,
461 machopic_non_lazy_ptr_name (name
));
463 ptr_ref
= gen_rtx_MEM (Pmode
, ptr_ref
);
464 RTX_UNCHANGING_P (ptr_ref
) = 1;
468 else if (GET_CODE (orig
) == CONST
)
472 /* legitimize both operands of the PLUS */
473 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
475 base
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 0),
477 orig
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 1),
478 (base
== reg
? 0 : reg
));
483 if (MACHOPIC_PURE
&& GET_CODE (orig
) == CONST_INT
)
484 result
= plus_constant (base
, INTVAL (orig
));
486 result
= gen_rtx (PLUS
, Pmode
, base
, orig
);
488 if (RTX_UNCHANGING_P (base
) && RTX_UNCHANGING_P (orig
))
489 RTX_UNCHANGING_P (result
) = 1;
491 if (MACHOPIC_JUST_INDIRECT
&& GET_CODE (base
) == MEM
)
495 emit_move_insn (reg
, result
);
500 result
= force_reg (GET_MODE (result
), result
);
507 else if (GET_CODE (orig
) == MEM
)
508 XEXP (ptr_ref
, 0) = machopic_indirect_data_reference (XEXP (orig
, 0), reg
);
509 /* When the target is i386, this code prevents crashes due to the
510 compiler's ignorance on how to move the PIC base register to
511 other registers. (The reload phase sometimes introduces such
513 else if (GET_CODE (orig
) == PLUS
514 && GET_CODE (XEXP (orig
, 0)) == REG
515 && REGNO (XEXP (orig
, 0)) == PIC_OFFSET_TABLE_REGNUM
517 /* Prevent the same register from being erroneously used
518 as both the base and index registers. */
519 && GET_CODE (XEXP (orig
, 1)) == CONST
523 emit_move_insn (reg
, XEXP (orig
, 0));
524 XEXP (ptr_ref
, 0) = reg
;
529 /* For MACHOPIC_INDIRECT_CALL_TARGET below, we need to beware of:
531 extern "C" { int f(); }
532 struct X { int f(); int g(); };
533 int X::f() { ::f(); }
534 int X::g() { ::f(); f();}
536 This is hairy. Both calls to "::f()" need to be indirect (i.e., to
537 appropriate symbol stubs), but since MACHOPIC_NAME_DEFINED_P calls
538 GET_IDENTIFIER which treats "f" as "X::f", and "X::f" is indeed (being)
539 defined somewhere in "X"'s inheritance hierarchy, MACHOPIC_NAME_DEFINED_P
540 returns TRUE when called with "f", which means that
541 MACHOPIC_INDIRECT_CALL_TARGET uses an "internal" call instead of an
542 indirect one as it should.
544 Our quick-n-dirty solution to this is to call the following
545 FUNC_NAME_MAYBE_SCOPED routine which (only for C++) checks whether
546 FNAME -- the name of the function which we're calling -- is NOT a
547 mangled C++ name, AND if the current function being compiled is a
548 method, and if so, use an "external" or "indirect" call.
550 Note that this function will be called ONLY when MACHOPIC_INDIRECT_TARGET_P
551 has already indicated that the target is NOT indirect.
553 This conservative solution will sometimes make indirect calls where
554 it might have been possible to make direct ones.
556 FUNC_NAME_MAYBE_SCOPED returns 1 to indicate a "C" name (not scoped),
557 which in turns means we should create a stub for an indirect call.
560 static int is_cplusplus
= -1;
563 func_name_maybe_scoped (fname
)
567 if (is_cplusplus
< 0)
568 is_cplusplus
= (strcmp (lang_identify (), "cplusplus") == 0);
572 /* If we have a method, then check whether the function we're trying to
573 call is a "C" function. If so, we should use an indirect call.
575 It turns out to be hard to tell whether "we have a method", since
576 static member functions have a TREE_CODE of FUNCTION_TYPE, as do
577 namespace-level non-member functions. So here, we always look for
578 an extern-"C"-like name, and make stubs for them no matter the
579 calling context. This is temporary, and leaves nagging suspicion
580 that improvements should be possible here. (I.e., I suspect that
581 it can still sometimes make stubs where it needn't.) */
583 /* if (1 || TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE) */
585 /* If fname is of the form "f__1X" or "f__Fv", it's C++. */
586 while (*fname
== '_') ++fname
; /* skip leading underscores */
589 if (fname
[0] == '_' && fname
[1] == '_'
590 && (fname
[2] == 'F' || (fname
[2] >= '0' && fname
[2] <= '9')))
594 /* Not a C++ mangled name: must be "C", in which case play safe. */
601 /* Transform TARGET (a MEM), which is a function call target, to the
602 corresponding symbol_stub if necessary. Return a new MEM. */
605 machopic_indirect_call_target (target
)
608 if (GET_CODE (target
) != MEM
)
611 if (MACHOPIC_INDIRECT
&& GET_CODE (XEXP (target
, 0)) == SYMBOL_REF
)
613 enum machine_mode mode
= GET_MODE (XEXP (target
, 0));
614 const char *name
= XSTR (XEXP (target
, 0), 0);
616 if (!machopic_name_defined_p (name
) || func_name_maybe_scoped (name
))
618 const char *stub_name
= machopic_stub_name (name
);
620 XEXP (target
, 0) = gen_rtx (SYMBOL_REF
, mode
, stub_name
);
621 RTX_UNCHANGING_P (target
) = 1;
629 machopic_legitimize_pic_address (orig
, mode
, reg
)
631 enum machine_mode mode
;
638 /* First handle a simple SYMBOL_REF or LABEL_REF */
639 if (GET_CODE (orig
) == LABEL_REF
640 || (GET_CODE (orig
) == SYMBOL_REF
643 /* addr(foo) = &func+(foo-func) */
646 orig
= machopic_indirect_data_reference (orig
, reg
);
648 if (GET_CODE (orig
) == PLUS
649 && GET_CODE (XEXP (orig
, 0)) == REG
)
652 return force_reg (mode
, orig
);
654 emit_move_insn (reg
, orig
);
658 pic_base
= gen_rtx (SYMBOL_REF
, Pmode
, machopic_function_base_name ());
660 if (GET_CODE (orig
) == MEM
)
664 if (reload_in_progress
)
667 reg
= gen_reg_rtx (Pmode
);
671 if (GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
672 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
674 rtx offset
= gen_rtx (CONST
, Pmode
,
675 gen_rtx (MINUS
, Pmode
,
676 XEXP (orig
, 0), pic_base
));
677 #if defined (TARGET_TOC) /* i.e., PowerPC */
678 /* Generating a new reg may expose opportunities for
679 common subexpression elimination. */
681 (reload_in_progress
? reg
: gen_reg_rtx (SImode
));
683 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
684 gen_rtx (PLUS
, Pmode
,
685 pic_offset_table_rtx
,
686 gen_rtx (HIGH
, Pmode
, offset
))));
687 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
688 gen_rtx (MEM
, GET_MODE (orig
),
689 gen_rtx (LO_SUM
, Pmode
,
690 hi_sum_reg
, offset
))));
694 emit_insn (gen_rtx (USE
, VOIDmode
,
695 gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
697 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
698 gen_rtx (HIGH
, Pmode
,
699 gen_rtx (CONST
, Pmode
, offset
))));
700 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
701 gen_rtx (LO_SUM
, Pmode
, reg
,
702 gen_rtx (CONST
, Pmode
, offset
))));
703 pic_ref
= gen_rtx (PLUS
, Pmode
,
704 pic_offset_table_rtx
, reg
);
708 #endif /* HAVE_lo_sum */
710 rtx pic
= pic_offset_table_rtx
;
711 if (GET_CODE (pic
) != REG
)
713 emit_move_insn (reg
, pic
);
717 emit_insn (gen_rtx (USE
, VOIDmode
,
718 gen_rtx (REG
, Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
721 pic_ref
= gen_rtx (PLUS
, Pmode
,
723 gen_rtx (CONST
, Pmode
,
724 gen_rtx (MINUS
, Pmode
,
729 #if !defined (TARGET_TOC)
730 RTX_UNCHANGING_P (pic_ref
) = 1;
731 emit_move_insn (reg
, pic_ref
);
732 pic_ref
= gen_rtx (MEM
, GET_MODE (orig
), reg
);
739 if (GET_CODE (orig
) == SYMBOL_REF
740 || GET_CODE (orig
) == LABEL_REF
)
742 rtx offset
= gen_rtx (CONST
, Pmode
,
743 gen_rtx (MINUS
, Pmode
, orig
, pic_base
));
744 #if defined (TARGET_TOC) /* i.e., PowerPC */
749 if (reload_in_progress
)
752 reg
= gen_reg_rtx (SImode
);
757 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
758 gen_rtx (PLUS
, Pmode
,
759 pic_offset_table_rtx
,
760 gen_rtx (HIGH
, Pmode
, offset
))));
761 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
762 gen_rtx (LO_SUM
, Pmode
,
763 hi_sum_reg
, offset
)));
766 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
767 gen_rtx (HIGH
, Pmode
, offset
)));
768 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
769 gen_rtx (LO_SUM
, Pmode
, reg
, offset
)));
770 pic_ref
= gen_rtx (PLUS
, Pmode
,
771 pic_offset_table_rtx
, reg
);
775 #endif /* HAVE_lo_sum */
777 if (GET_CODE (orig
) == REG
)
783 rtx pic
= pic_offset_table_rtx
;
784 if (GET_CODE (pic
) != REG
)
786 emit_move_insn (reg
, pic
);
790 emit_insn (gen_rtx (USE
, VOIDmode
,
791 pic_offset_table_rtx
));
793 pic_ref
= gen_rtx (PLUS
, Pmode
,
795 gen_rtx (CONST
, Pmode
,
796 gen_rtx (MINUS
, Pmode
,
802 RTX_UNCHANGING_P (pic_ref
) = 1;
804 if (GET_CODE (pic_ref
) != REG
)
808 emit_move_insn (reg
, pic_ref
);
813 return force_reg (mode
, pic_ref
);
822 else if (GET_CODE (orig
) == SYMBOL_REF
)
825 else if (GET_CODE (orig
) == PLUS
826 && (GET_CODE (XEXP (orig
, 0)) == MEM
827 || GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
828 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
829 && XEXP (orig
, 0) != pic_offset_table_rtx
830 && GET_CODE (XEXP (orig
, 1)) != REG
)
834 int is_complex
= (GET_CODE (XEXP (orig
, 0)) == MEM
);
836 base
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
837 orig
= machopic_legitimize_pic_address (XEXP (orig
, 1),
838 Pmode
, (base
== reg
? 0 : reg
));
839 if (GET_CODE (orig
) == CONST_INT
)
841 pic_ref
= plus_constant (base
, INTVAL (orig
));
845 pic_ref
= gen_rtx (PLUS
, Pmode
, base
, orig
);
847 if (RTX_UNCHANGING_P (base
) && RTX_UNCHANGING_P (orig
))
848 RTX_UNCHANGING_P (pic_ref
) = 1;
850 if (reg
&& is_complex
)
852 emit_move_insn (reg
, pic_ref
);
855 /* Likewise, should we set special REG_NOTEs here? */
858 else if (GET_CODE (orig
) == CONST
)
860 return machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
863 else if (GET_CODE (orig
) == MEM
864 && GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
)
866 rtx addr
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
868 addr
= gen_rtx (MEM
, GET_MODE (orig
), addr
);
869 RTX_UNCHANGING_P (addr
) = RTX_UNCHANGING_P (orig
);
870 emit_move_insn (reg
, addr
);
879 machopic_finish (asm_out_file
)
884 for (temp
= machopic_stubs
;
886 temp
= TREE_CHAIN (temp
))
888 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
889 char *stub_name
= IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
893 if (! TREE_USED (temp
))
896 STRIP_NAME_ENCODING (sym_name
, sym_name
);
898 sym
= alloca (strlen (sym_name
) + 2);
899 if (sym_name
[0] == '*' || sym_name
[0] == '&')
900 strcpy (sym
, sym_name
+ 1);
901 else if (sym_name
[0] == '-' || sym_name
[0] == '+')
902 strcpy (sym
, sym_name
);
904 sym
[0] = '_', strcpy (sym
+ 1, sym_name
);
906 stub
= alloca (strlen (stub_name
) + 2);
907 if (stub_name
[0] == '*' || stub_name
[0] == '&')
908 strcpy (stub
, stub_name
+ 1);
910 stub
[0] = '_', strcpy (stub
+ 1, stub_name
);
912 machopic_output_stub (asm_out_file
, sym
, stub
);
915 for (temp
= machopic_non_lazy_pointers
;
917 temp
= TREE_CHAIN (temp
))
919 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
920 char *lazy_name
= IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
922 tree decl
= lookup_name_darwin (TREE_VALUE (temp
));
925 if (! TREE_USED (temp
))
928 if (machopic_ident_defined_p (TREE_VALUE (temp
))
929 #if 0 /* add back when we have private externs */
930 || (decl
&& DECL_PRIVATE_EXTERN (decl
))
935 assemble_align (GET_MODE_ALIGNMENT (Pmode
));
936 assemble_label (lazy_name
);
937 assemble_integer (gen_rtx (SYMBOL_REF
, Pmode
, sym_name
),
938 GET_MODE_SIZE (Pmode
),
939 GET_MODE_ALIGNMENT (Pmode
), 1);
943 machopic_nl_symbol_ptr_section ();
944 assemble_name (asm_out_file
, lazy_name
);
945 fprintf (asm_out_file
, ":\n");
947 fprintf (asm_out_file
, "\t.indirect_symbol ");
948 assemble_name (asm_out_file
, sym_name
);
949 fprintf (asm_out_file
, "\n");
951 assemble_integer (const0_rtx
, GET_MODE_SIZE (Pmode
),
952 GET_MODE_ALIGNMENT (Pmode
), 1);
958 machopic_operand_p (op
)
961 if (MACHOPIC_JUST_INDIRECT
)
963 while (GET_CODE (op
) == CONST
)
966 if (GET_CODE (op
) == SYMBOL_REF
)
967 return machopic_name_defined_p (XSTR (op
, 0));
972 while (GET_CODE (op
) == CONST
)
975 if (GET_CODE (op
) == MINUS
976 && GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
977 && GET_CODE (XEXP (op
, 1)) == SYMBOL_REF
978 && machopic_name_defined_p (XSTR (XEXP (op
, 0), 0))
979 && machopic_name_defined_p (XSTR (XEXP (op
, 1), 0)))
982 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
983 /* Without this statement, the compiler crashes while compiling enquire.c
984 when targetting PowerPC. It is not known why this code is not needed
985 when targetting other processors. */
986 else if (GET_CODE (op
) == SYMBOL_REF
987 && (machopic_classify_name (XSTR (op
, 0))
988 == MACHOPIC_DEFINED_FUNCTION
))
997 /* This function records whether a given name corresponds to a defined
998 or undefined function or variable, for machopic_classify_ident to
1002 darwin_encode_section_info (decl
)
1008 const char *orig_str
;
1010 size_t len
, new_len
;
1012 if ((TREE_CODE (decl
) == FUNCTION_DECL
1013 || TREE_CODE (decl
) == VAR_DECL
)
1014 && !DECL_EXTERNAL (decl
)
1015 && ((TREE_STATIC (decl
)
1016 && (!DECL_COMMON (decl
) || !TREE_PUBLIC (decl
)))
1017 || DECL_INITIAL (decl
)))
1020 if (TREE_CODE (decl
) == FUNCTION_DECL
)
1021 code
= (defined
? 'T' : 't');
1022 else if (TREE_CODE (decl
) == VAR_DECL
)
1023 code
= (defined
? 'D' : 'd');
1028 sym_ref
= XEXP (DECL_RTL (decl
), 0);
1029 orig_str
= XSTR (sym_ref
, 0);
1030 len
= strlen (orig_str
) + 1;
1032 if (orig_str
[0] == '!')
1034 /* Already encoded; see if we need to change it. */
1035 if (code
== orig_str
[1])
1037 /* Yes, tweak a copy of the name and put it in a new string. */
1038 new_str
= alloca (len
);
1039 memcpy (new_str
, orig_str
, len
);
1041 XSTR (sym_ref
, 0) = ggc_alloc_string (new_str
, len
);
1045 /* Add the encoding. */
1047 new_str
= alloca (new_len
);
1052 memcpy (new_str
+ 4, orig_str
, len
);
1053 XSTR (sym_ref
, 0) = ggc_alloc_string (new_str
, new_len
);
1055 /* The non-lazy pointer list may have captured references to the
1056 old encoded name, change them. */
1057 update_non_lazy_ptrs (XSTR (sym_ref
, 0));
1058 update_stubs (XSTR (sym_ref
, 0));
1061 /* Scan the list of non-lazy pointers and update any recorded names whose
1062 stripped name matches the argument. */
1065 update_non_lazy_ptrs (name
)
1068 char *name1
, *name2
;
1071 STRIP_NAME_ENCODING (name1
, name
);
1073 for (temp
= machopic_non_lazy_pointers
;
1075 temp
= TREE_CHAIN (temp
))
1077 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1079 if (*sym_name
== '!')
1081 STRIP_NAME_ENCODING (name2
, sym_name
);
1082 if (strcmp (name1
, name2
) == 0)
1084 IDENTIFIER_POINTER (TREE_VALUE (temp
)) = name
;
1092 /* Scan the list of stubs and update any recorded names whose
1093 stripped name matches the argument. */
1099 char *name1
, *name2
;
1102 STRIP_NAME_ENCODING (name1
, name
);
1104 for (temp
= machopic_stubs
;
1106 temp
= TREE_CHAIN (temp
))
1108 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1110 if (*sym_name
== '!')
1112 STRIP_NAME_ENCODING (name2
, sym_name
);
1113 if (strcmp (name1
, name2
) == 0)
1115 IDENTIFIER_POINTER (TREE_VALUE (temp
)) = name
;
1123 machopic_asm_out_constructor (symbol
, priority
)
1125 int priority ATTRIBUTE_UNUSED
;
1128 mod_init_section ();
1130 constructor_section ();
1131 assemble_align (POINTER_SIZE
);
1132 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1135 fprintf (asm_out_file
, ".reference .constructors_used\n");
1139 machopic_asm_out_destructor (symbol
, priority
)
1141 int priority ATTRIBUTE_UNUSED
;
1144 mod_term_section ();
1146 destructor_section ();
1147 assemble_align (POINTER_SIZE
);
1148 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1151 fprintf (asm_out_file
, ".reference .destructors_used\n");