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"
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 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 for (temp
= machopic_defined_list
; temp
!= NULL_TREE
; temp
= TREE_CHAIN (temp
))
123 if (ident
== TREE_VALUE (temp
))
126 return MACHOPIC_DEFINED_FUNCTION
;
128 return MACHOPIC_DEFINED_DATA
;
132 if (name
[1] == 't' || name
[1] == 'T')
135 return MACHOPIC_DEFINED_FUNCTION
;
137 return MACHOPIC_UNDEFINED_FUNCTION
;
142 return MACHOPIC_DEFINED_DATA
;
144 return MACHOPIC_UNDEFINED_DATA
;
149 enum machopic_addr_class
150 machopic_classify_name (name
)
153 return machopic_classify_ident (get_identifier (name
));
157 machopic_ident_defined_p (ident
)
160 switch (machopic_classify_ident (ident
))
162 case MACHOPIC_UNDEFINED
:
163 case MACHOPIC_UNDEFINED_DATA
:
164 case MACHOPIC_UNDEFINED_FUNCTION
:
172 machopic_data_defined_p (name
)
175 switch (machopic_classify_ident (get_identifier (name
)))
177 case MACHOPIC_DEFINED_DATA
:
185 machopic_name_defined_p (name
)
188 return machopic_ident_defined_p (get_identifier (name
));
192 machopic_define_ident (ident
)
195 if (!machopic_ident_defined_p (ident
))
196 machopic_defined_list
=
197 tree_cons (NULL_TREE
, ident
, machopic_defined_list
);
201 machopic_define_name (name
)
204 machopic_define_ident (get_identifier (name
));
207 /* This is a static to make inline functions work. The rtx
208 representing the PIC base symbol always points to here. */
210 static char function_base
[32];
212 static int current_pic_label_num
;
215 machopic_function_base_name ()
217 static const char *name
= NULL
;
218 static const char *current_name
;
220 current_name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
));
222 if (name
!= current_name
)
224 current_function_uses_pic_offset_table
= 1;
226 /* Save mucho space and time. Some of the C++ mangled names are over
227 700 characters long! Note that we produce a label containing a '-'
228 if the function we're compiling is an Objective-C method, as evinced
229 by the incredibly scientific test below. This is because code in
230 rs6000.c makes the same ugly test when loading the PIC reg. */
232 ++current_pic_label_num
;
233 if (*current_name
== '+' || *current_name
== '-')
234 sprintf (function_base
, "*\"L-%d$pb\"", current_pic_label_num
);
236 sprintf (function_base
, "*L%d$pb", current_pic_label_num
);
241 return function_base
;
244 static tree machopic_non_lazy_pointers
= NULL
;
246 /* Return a non-lazy pointer name corresponding to the given name,
247 either by finding it in our list of pointer names, or by generating
251 machopic_non_lazy_ptr_name (name
)
255 tree temp
, ident
= get_identifier (name
);
257 for (temp
= machopic_non_lazy_pointers
;
259 temp
= TREE_CHAIN (temp
))
261 if (ident
== TREE_VALUE (temp
))
262 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
265 STRIP_NAME_ENCODING (name
, name
);
267 /* Try again, but comparing names this time. */
268 for (temp
= machopic_non_lazy_pointers
;
270 temp
= TREE_CHAIN (temp
))
272 if (TREE_VALUE (temp
))
274 temp_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
275 STRIP_NAME_ENCODING (temp_name
, temp_name
);
276 if (strcmp (name
, temp_name
) == 0)
277 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
285 buffer
= alloca (strlen (name
) + 20);
287 strcpy (buffer
, "&L");
289 strcat (buffer
, name
+1);
292 strcat (buffer
, "_");
293 strcat (buffer
, name
);
296 strcat (buffer
, "$non_lazy_ptr");
297 ptr_name
= get_identifier (buffer
);
299 machopic_non_lazy_pointers
300 = tree_cons (ptr_name
, ident
, machopic_non_lazy_pointers
);
302 TREE_USED (machopic_non_lazy_pointers
) = 0;
304 return IDENTIFIER_POINTER (ptr_name
);
308 static tree machopic_stubs
= 0;
310 /* Make sure the GC knows about our homemade lists. */
313 machopic_add_gc_roots ()
315 ggc_add_tree_root (&machopic_defined_list
, 1);
316 ggc_add_tree_root (&machopic_non_lazy_pointers
, 1);
317 ggc_add_tree_root (&machopic_stubs
, 1);
320 /* Return the name of the stub corresponding to the given name,
321 generating a new stub name if necessary. */
324 machopic_stub_name (name
)
327 tree temp
, ident
= get_identifier (name
);
330 for (temp
= machopic_stubs
;
332 temp
= TREE_CHAIN (temp
))
334 if (ident
== TREE_VALUE (temp
))
335 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
336 tname
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
337 if (strcmp (name
, tname
) == 0)
338 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
339 /* A library call name might not be section-encoded yet, so try
340 it against a stripped name. */
343 && strcmp (name
, tname
+ 4) == 0)
344 return IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
347 STRIP_NAME_ENCODING (name
, name
);
352 int needs_quotes
= name_needs_quotes (name
);
354 buffer
= alloca (strlen (name
) + 20);
357 strcpy (buffer
, "&\"L");
359 strcpy (buffer
, "&L");
362 strcat (buffer
, name
+1);
366 strcat (buffer
, "_");
367 strcat (buffer
, name
);
371 strcat (buffer
, "$stub\"");
373 strcat (buffer
, "$stub");
374 ptr_name
= get_identifier (buffer
);
376 machopic_stubs
= tree_cons (ptr_name
, ident
, machopic_stubs
);
377 TREE_USED (machopic_stubs
) = 0;
379 return IDENTIFIER_POINTER (ptr_name
);
384 machopic_validate_stub_or_non_lazy_ptr (name
, validate_stub
)
389 tree temp
, ident
= get_identifier (name
), id2
;
391 for (temp
= (validate_stub
? machopic_stubs
: machopic_non_lazy_pointers
);
393 temp
= TREE_CHAIN (temp
))
394 if (ident
== TREE_PURPOSE (temp
))
396 /* Mark both the stub or non-lazy pointer as well as the
397 original symbol as being referenced. */
398 TREE_USED (temp
) = 1;
399 if (TREE_CODE (TREE_VALUE (temp
)) == IDENTIFIER_NODE
)
400 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp
)) = 1;
401 STRIP_NAME_ENCODING (real_name
, IDENTIFIER_POINTER (TREE_VALUE (temp
)));
402 id2
= maybe_get_identifier (real_name
);
404 TREE_SYMBOL_REFERENCED (id2
) = 1;
408 /* Transform ORIG, which may be any data source, to the corresponding
409 source using indirections. */
412 machopic_indirect_data_reference (orig
, reg
)
417 if (! MACHOPIC_INDIRECT
)
420 if (GET_CODE (orig
) == SYMBOL_REF
)
422 const char *name
= XSTR (orig
, 0);
424 if (machopic_data_defined_p (name
))
426 rtx pic_base
= gen_rtx (SYMBOL_REF
, Pmode
,
427 machopic_function_base_name ());
428 rtx offset
= gen_rtx (CONST
, Pmode
,
429 gen_rtx (MINUS
, Pmode
, orig
, pic_base
));
431 #if defined (TARGET_TOC) /* i.e., PowerPC */
432 rtx hi_sum_reg
= reg
;
437 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
438 gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
,
439 gen_rtx (HIGH
, Pmode
, offset
))));
440 emit_insn (gen_rtx (SET
, Pmode
, reg
,
441 gen_rtx (LO_SUM
, Pmode
, hi_sum_reg
, offset
)));
445 #if defined (HAVE_lo_sum)
446 if (reg
== 0) abort ();
448 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
449 gen_rtx (HIGH
, Pmode
, offset
)));
450 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
451 gen_rtx (LO_SUM
, Pmode
, reg
, offset
)));
452 emit_insn (gen_rtx (USE
, VOIDmode
,
453 gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
455 orig
= gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
, reg
);
461 ptr_ref
= gen_rtx (SYMBOL_REF
, Pmode
,
462 machopic_non_lazy_ptr_name (name
));
464 ptr_ref
= gen_rtx_MEM (Pmode
, ptr_ref
);
465 RTX_UNCHANGING_P (ptr_ref
) = 1;
469 else if (GET_CODE (orig
) == CONST
)
473 /* legitimize both operands of the PLUS */
474 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
476 base
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 0),
478 orig
= machopic_indirect_data_reference (XEXP (XEXP (orig
, 0), 1),
479 (base
== reg
? 0 : reg
));
484 if (MACHOPIC_PURE
&& GET_CODE (orig
) == CONST_INT
)
485 result
= plus_constant (base
, INTVAL (orig
));
487 result
= gen_rtx (PLUS
, Pmode
, base
, orig
);
489 if (RTX_UNCHANGING_P (base
) && RTX_UNCHANGING_P (orig
))
490 RTX_UNCHANGING_P (result
) = 1;
492 if (MACHOPIC_JUST_INDIRECT
&& GET_CODE (base
) == MEM
)
496 emit_move_insn (reg
, result
);
501 result
= force_reg (GET_MODE (result
), result
);
508 else if (GET_CODE (orig
) == MEM
)
509 XEXP (ptr_ref
, 0) = machopic_indirect_data_reference (XEXP (orig
, 0), reg
);
510 /* When the target is i386, this code prevents crashes due to the
511 compiler's ignorance on how to move the PIC base register to
512 other registers. (The reload phase sometimes introduces such
514 else if (GET_CODE (orig
) == PLUS
515 && GET_CODE (XEXP (orig
, 0)) == REG
516 && REGNO (XEXP (orig
, 0)) == PIC_OFFSET_TABLE_REGNUM
518 /* Prevent the same register from being erroneously used
519 as both the base and index registers. */
520 && GET_CODE (XEXP (orig
, 1)) == CONST
524 emit_move_insn (reg
, XEXP (orig
, 0));
525 XEXP (ptr_ref
, 0) = reg
;
530 /* For MACHOPIC_INDIRECT_CALL_TARGET below, we need to beware of:
532 extern "C" { int f(); }
533 struct X { int f(); int g(); };
534 int X::f() { ::f(); }
535 int X::g() { ::f(); f();}
537 This is hairy. Both calls to "::f()" need to be indirect (i.e., to
538 appropriate symbol stubs), but since MACHOPIC_NAME_DEFINED_P calls
539 GET_IDENTIFIER which treats "f" as "X::f", and "X::f" is indeed (being)
540 defined somewhere in "X"'s inheritance hierarchy, MACHOPIC_NAME_DEFINED_P
541 returns TRUE when called with "f", which means that
542 MACHOPIC_INDIRECT_CALL_TARGET uses an "internal" call instead of an
543 indirect one as it should.
545 Our quick-n-dirty solution to this is to call the following
546 FUNC_NAME_MAYBE_SCOPED routine which (only for C++) checks whether
547 FNAME -- the name of the function which we're calling -- is NOT a
548 mangled C++ name, AND if the current function being compiled is a
549 method, and if so, use an "external" or "indirect" call.
551 Note that this function will be called ONLY when MACHOPIC_INDIRECT_TARGET_P
552 has already indicated that the target is NOT indirect.
554 This conservative solution will sometimes make indirect calls where
555 it might have been possible to make direct ones.
557 FUNC_NAME_MAYBE_SCOPED returns 1 to indicate a "C" name (not scoped),
558 which in turns means we should create a stub for an indirect call.
561 static int is_cplusplus
= -1;
564 func_name_maybe_scoped (fname
)
568 if (is_cplusplus
< 0)
569 is_cplusplus
= (strcmp (lang_hooks
.name
, "GNU C++") == 0);
573 /* If we have a method, then check whether the function we're trying to
574 call is a "C" function. If so, we should use an indirect call.
576 It turns out to be hard to tell whether "we have a method", since
577 static member functions have a TREE_CODE of FUNCTION_TYPE, as do
578 namespace-level non-member functions. So here, we always look for
579 an extern-"C"-like name, and make stubs for them no matter the
580 calling context. This is temporary, and leaves nagging suspicion
581 that improvements should be possible here. (I.e., I suspect that
582 it can still sometimes make stubs where it needn't.) */
584 /* if (1 || TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE) */
586 /* If fname is of the form "f__1X" or "f__Fv", it's C++. */
587 while (*fname
== '_') ++fname
; /* skip leading underscores */
590 if (fname
[0] == '_' && fname
[1] == '_'
591 && (fname
[2] == 'F' || ISDIGIT (fname
[2])))
595 /* Not a C++ mangled name: must be "C", in which case play safe. */
602 /* Transform TARGET (a MEM), which is a function call target, to the
603 corresponding symbol_stub if necessary. Return a new MEM. */
606 machopic_indirect_call_target (target
)
609 if (GET_CODE (target
) != MEM
)
612 if (MACHOPIC_INDIRECT
&& GET_CODE (XEXP (target
, 0)) == SYMBOL_REF
)
614 enum machine_mode mode
= GET_MODE (XEXP (target
, 0));
615 const char *name
= XSTR (XEXP (target
, 0), 0);
617 if (!machopic_name_defined_p (name
) || func_name_maybe_scoped (name
))
619 const char *stub_name
= machopic_stub_name (name
);
621 XEXP (target
, 0) = gen_rtx (SYMBOL_REF
, mode
, stub_name
);
622 RTX_UNCHANGING_P (target
) = 1;
630 machopic_legitimize_pic_address (orig
, mode
, reg
)
632 enum machine_mode mode
;
639 /* First handle a simple SYMBOL_REF or LABEL_REF */
640 if (GET_CODE (orig
) == LABEL_REF
641 || (GET_CODE (orig
) == SYMBOL_REF
644 /* addr(foo) = &func+(foo-func) */
647 orig
= machopic_indirect_data_reference (orig
, reg
);
649 if (GET_CODE (orig
) == PLUS
650 && GET_CODE (XEXP (orig
, 0)) == REG
)
653 return force_reg (mode
, orig
);
655 emit_move_insn (reg
, orig
);
659 pic_base
= gen_rtx (SYMBOL_REF
, Pmode
, machopic_function_base_name ());
661 if (GET_CODE (orig
) == MEM
)
665 if (reload_in_progress
)
668 reg
= gen_reg_rtx (Pmode
);
672 if (GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
673 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
675 rtx offset
= gen_rtx (CONST
, Pmode
,
676 gen_rtx (MINUS
, Pmode
,
677 XEXP (orig
, 0), pic_base
));
678 #if defined (TARGET_TOC) /* i.e., PowerPC */
679 /* Generating a new reg may expose opportunities for
680 common subexpression elimination. */
682 (reload_in_progress
? reg
: gen_reg_rtx (SImode
));
684 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
685 gen_rtx (PLUS
, Pmode
,
686 pic_offset_table_rtx
,
687 gen_rtx (HIGH
, Pmode
, offset
))));
688 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
689 gen_rtx (MEM
, GET_MODE (orig
),
690 gen_rtx (LO_SUM
, Pmode
,
691 hi_sum_reg
, offset
))));
695 emit_insn (gen_rtx (USE
, VOIDmode
,
696 gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
698 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
699 gen_rtx (HIGH
, Pmode
,
700 gen_rtx (CONST
, Pmode
, offset
))));
701 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
702 gen_rtx (LO_SUM
, Pmode
, reg
,
703 gen_rtx (CONST
, Pmode
, offset
))));
704 pic_ref
= gen_rtx (PLUS
, Pmode
,
705 pic_offset_table_rtx
, reg
);
709 #endif /* HAVE_lo_sum */
711 rtx pic
= pic_offset_table_rtx
;
712 if (GET_CODE (pic
) != REG
)
714 emit_move_insn (reg
, pic
);
718 emit_insn (gen_rtx (USE
, VOIDmode
,
719 gen_rtx (REG
, Pmode
, PIC_OFFSET_TABLE_REGNUM
)));
722 pic_ref
= gen_rtx (PLUS
, Pmode
,
724 gen_rtx (CONST
, Pmode
,
725 gen_rtx (MINUS
, Pmode
,
730 #if !defined (TARGET_TOC)
731 RTX_UNCHANGING_P (pic_ref
) = 1;
732 emit_move_insn (reg
, pic_ref
);
733 pic_ref
= gen_rtx (MEM
, GET_MODE (orig
), reg
);
740 if (GET_CODE (orig
) == SYMBOL_REF
741 || GET_CODE (orig
) == LABEL_REF
)
743 rtx offset
= gen_rtx (CONST
, Pmode
,
744 gen_rtx (MINUS
, Pmode
, orig
, pic_base
));
745 #if defined (TARGET_TOC) /* i.e., PowerPC */
750 if (reload_in_progress
)
753 reg
= gen_reg_rtx (SImode
);
758 emit_insn (gen_rtx (SET
, Pmode
, hi_sum_reg
,
759 gen_rtx (PLUS
, Pmode
,
760 pic_offset_table_rtx
,
761 gen_rtx (HIGH
, Pmode
, offset
))));
762 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
763 gen_rtx (LO_SUM
, Pmode
,
764 hi_sum_reg
, offset
)));
767 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
768 gen_rtx (HIGH
, Pmode
, offset
)));
769 emit_insn (gen_rtx (SET
, VOIDmode
, reg
,
770 gen_rtx (LO_SUM
, Pmode
, reg
, offset
)));
771 pic_ref
= gen_rtx (PLUS
, Pmode
,
772 pic_offset_table_rtx
, reg
);
776 #endif /* HAVE_lo_sum */
778 if (GET_CODE (orig
) == REG
)
784 rtx pic
= pic_offset_table_rtx
;
785 if (GET_CODE (pic
) != REG
)
787 emit_move_insn (reg
, pic
);
791 emit_insn (gen_rtx (USE
, VOIDmode
,
792 pic_offset_table_rtx
));
794 pic_ref
= gen_rtx (PLUS
, Pmode
,
796 gen_rtx (CONST
, Pmode
,
797 gen_rtx (MINUS
, Pmode
,
803 RTX_UNCHANGING_P (pic_ref
) = 1;
805 if (GET_CODE (pic_ref
) != REG
)
809 emit_move_insn (reg
, pic_ref
);
814 return force_reg (mode
, pic_ref
);
823 else if (GET_CODE (orig
) == SYMBOL_REF
)
826 else if (GET_CODE (orig
) == PLUS
827 && (GET_CODE (XEXP (orig
, 0)) == MEM
828 || GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
829 || GET_CODE (XEXP (orig
, 0)) == LABEL_REF
)
830 && XEXP (orig
, 0) != pic_offset_table_rtx
831 && GET_CODE (XEXP (orig
, 1)) != REG
)
835 int is_complex
= (GET_CODE (XEXP (orig
, 0)) == MEM
);
837 base
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
838 orig
= machopic_legitimize_pic_address (XEXP (orig
, 1),
839 Pmode
, (base
== reg
? 0 : reg
));
840 if (GET_CODE (orig
) == CONST_INT
)
842 pic_ref
= plus_constant (base
, INTVAL (orig
));
846 pic_ref
= gen_rtx (PLUS
, Pmode
, base
, orig
);
848 if (RTX_UNCHANGING_P (base
) && RTX_UNCHANGING_P (orig
))
849 RTX_UNCHANGING_P (pic_ref
) = 1;
851 if (reg
&& is_complex
)
853 emit_move_insn (reg
, pic_ref
);
856 /* Likewise, should we set special REG_NOTEs here? */
859 else if (GET_CODE (orig
) == CONST
)
861 return machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
864 else if (GET_CODE (orig
) == MEM
865 && GET_CODE (XEXP (orig
, 0)) == SYMBOL_REF
)
867 rtx addr
= machopic_legitimize_pic_address (XEXP (orig
, 0), Pmode
, reg
);
869 addr
= gen_rtx (MEM
, GET_MODE (orig
), addr
);
870 RTX_UNCHANGING_P (addr
) = RTX_UNCHANGING_P (orig
);
871 emit_move_insn (reg
, addr
);
880 machopic_finish (asm_out_file
)
885 for (temp
= machopic_stubs
;
887 temp
= TREE_CHAIN (temp
))
889 const char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
890 const char *stub_name
= IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
894 if (! TREE_USED (temp
))
897 STRIP_NAME_ENCODING (sym_name
, sym_name
);
899 sym
= alloca (strlen (sym_name
) + 2);
900 if (sym_name
[0] == '*' || sym_name
[0] == '&')
901 strcpy (sym
, sym_name
+ 1);
902 else if (sym_name
[0] == '-' || sym_name
[0] == '+')
903 strcpy (sym
, sym_name
);
905 sym
[0] = '_', strcpy (sym
+ 1, sym_name
);
907 stub
= alloca (strlen (stub_name
) + 2);
908 if (stub_name
[0] == '*' || stub_name
[0] == '&')
909 strcpy (stub
, stub_name
+ 1);
911 stub
[0] = '_', strcpy (stub
+ 1, stub_name
);
913 machopic_output_stub (asm_out_file
, sym
, stub
);
916 for (temp
= machopic_non_lazy_pointers
;
918 temp
= TREE_CHAIN (temp
))
920 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
921 char *lazy_name
= IDENTIFIER_POINTER (TREE_PURPOSE (temp
));
923 tree decl
= lookup_name_darwin (TREE_VALUE (temp
));
926 if (! TREE_USED (temp
))
929 if (machopic_ident_defined_p (TREE_VALUE (temp
))
930 #if 0 /* add back when we have private externs */
931 || (decl
&& DECL_PRIVATE_EXTERN (decl
))
936 assemble_align (GET_MODE_ALIGNMENT (Pmode
));
937 assemble_label (lazy_name
);
938 assemble_integer (gen_rtx (SYMBOL_REF
, Pmode
, sym_name
),
939 GET_MODE_SIZE (Pmode
),
940 GET_MODE_ALIGNMENT (Pmode
), 1);
944 machopic_nl_symbol_ptr_section ();
945 assemble_name (asm_out_file
, lazy_name
);
946 fprintf (asm_out_file
, ":\n");
948 fprintf (asm_out_file
, "\t.indirect_symbol ");
949 assemble_name (asm_out_file
, sym_name
);
950 fprintf (asm_out_file
, "\n");
952 assemble_integer (const0_rtx
, GET_MODE_SIZE (Pmode
),
953 GET_MODE_ALIGNMENT (Pmode
), 1);
959 machopic_operand_p (op
)
962 if (MACHOPIC_JUST_INDIRECT
)
964 while (GET_CODE (op
) == CONST
)
967 if (GET_CODE (op
) == SYMBOL_REF
)
968 return machopic_name_defined_p (XSTR (op
, 0));
973 while (GET_CODE (op
) == CONST
)
976 if (GET_CODE (op
) == MINUS
977 && GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
978 && GET_CODE (XEXP (op
, 1)) == SYMBOL_REF
979 && machopic_name_defined_p (XSTR (XEXP (op
, 0), 0))
980 && machopic_name_defined_p (XSTR (XEXP (op
, 1), 0)))
983 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
984 /* Without this statement, the compiler crashes while compiling enquire.c
985 when targetting PowerPC. It is not known why this code is not needed
986 when targetting other processors. */
987 else if (GET_CODE (op
) == SYMBOL_REF
988 && (machopic_classify_name (XSTR (op
, 0))
989 == MACHOPIC_DEFINED_FUNCTION
))
998 /* This function records whether a given name corresponds to a defined
999 or undefined function or variable, for machopic_classify_ident to
1003 darwin_encode_section_info (decl
)
1009 const char *orig_str
;
1011 size_t len
, new_len
;
1013 if ((TREE_CODE (decl
) == FUNCTION_DECL
1014 || TREE_CODE (decl
) == VAR_DECL
)
1015 && !DECL_EXTERNAL (decl
)
1016 && ((TREE_STATIC (decl
)
1017 && (!DECL_COMMON (decl
) || !TREE_PUBLIC (decl
)))
1018 || (DECL_INITIAL (decl
)
1019 && DECL_INITIAL (decl
) != error_mark_node
)))
1022 if (TREE_CODE (decl
) == FUNCTION_DECL
)
1023 code
= (defined
? 'T' : 't');
1024 else if (TREE_CODE (decl
) == VAR_DECL
)
1025 code
= (defined
? 'D' : 'd');
1030 sym_ref
= XEXP (DECL_RTL (decl
), 0);
1031 orig_str
= XSTR (sym_ref
, 0);
1032 len
= strlen (orig_str
) + 1;
1034 if (orig_str
[0] == '!')
1036 /* Already encoded; see if we need to change it. */
1037 if (code
== orig_str
[1])
1039 /* Yes, tweak a copy of the name and put it in a new string. */
1040 new_str
= alloca (len
);
1041 memcpy (new_str
, orig_str
, len
);
1043 XSTR (sym_ref
, 0) = ggc_alloc_string (new_str
, len
);
1047 /* Add the encoding. */
1049 new_str
= alloca (new_len
);
1054 memcpy (new_str
+ 4, orig_str
, len
);
1055 XSTR (sym_ref
, 0) = ggc_alloc_string (new_str
, new_len
);
1057 /* The non-lazy pointer list may have captured references to the
1058 old encoded name, change them. */
1059 update_non_lazy_ptrs (XSTR (sym_ref
, 0));
1060 update_stubs (XSTR (sym_ref
, 0));
1063 /* Scan the list of non-lazy pointers and update any recorded names whose
1064 stripped name matches the argument. */
1067 update_non_lazy_ptrs (name
)
1070 const char *name1
, *name2
;
1073 STRIP_NAME_ENCODING (name1
, name
);
1075 for (temp
= machopic_non_lazy_pointers
;
1077 temp
= TREE_CHAIN (temp
))
1079 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1081 if (*sym_name
== '!')
1083 STRIP_NAME_ENCODING (name2
, sym_name
);
1084 if (strcmp (name1
, name2
) == 0)
1086 IDENTIFIER_POINTER (TREE_VALUE (temp
)) = name
;
1094 /* Scan the list of stubs and update any recorded names whose
1095 stripped name matches the argument. */
1101 const char *name1
, *name2
;
1104 STRIP_NAME_ENCODING (name1
, name
);
1106 for (temp
= machopic_stubs
;
1108 temp
= TREE_CHAIN (temp
))
1110 char *sym_name
= IDENTIFIER_POINTER (TREE_VALUE (temp
));
1112 if (*sym_name
== '!')
1114 STRIP_NAME_ENCODING (name2
, sym_name
);
1115 if (strcmp (name1
, name2
) == 0)
1117 IDENTIFIER_POINTER (TREE_VALUE (temp
)) = name
;
1125 machopic_asm_out_constructor (symbol
, priority
)
1127 int priority ATTRIBUTE_UNUSED
;
1130 mod_init_section ();
1132 constructor_section ();
1133 assemble_align (POINTER_SIZE
);
1134 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1137 fprintf (asm_out_file
, ".reference .constructors_used\n");
1141 machopic_asm_out_destructor (symbol
, priority
)
1143 int priority ATTRIBUTE_UNUSED
;
1146 mod_term_section ();
1148 destructor_section ();
1149 assemble_align (POINTER_SIZE
);
1150 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
1153 fprintf (asm_out_file
, ".reference .destructors_used\n");