* real.c: Avoid parse error if FLOAT_WORDS_BIG_ENDIAN is
[official-gcc.git] / gcc / config / darwin.c
blobfc162d07ffff9b3c5ee8af856afa422c971d6f26
1 /* Functions for generic Darwin as target machine for GNU C compiler.
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Apple Computer Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
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. */
23 #include "config.h"
24 #include "system.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "real.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
32 #include "output.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "tree.h"
36 #include "expr.h"
37 #include "reload.h"
38 #include "function.h"
39 #include "ggc.h"
40 #include "langhooks.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 void update_non_lazy_ptrs PARAMS ((const char *));
47 static void update_stubs PARAMS ((const char *));
49 int
50 name_needs_quotes (name)
51 const char *name;
53 int c;
54 while ((c = *name++) != '\0')
55 if (! ISIDNUM (c))
56 return 1;
57 return 0;
60 /*
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)
72 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')))
77 || ( name[0] == '_'
78 && name[1] == 'O'
79 && name[2] == 'B'
80 && name[3] == 'J'
81 && name[4] == 'C'
82 && name[5] == '_'));
83 tree temp;
85 if (name[0] != '!')
87 /* Here if no special encoding to be found. */
88 if (lprefix)
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;
100 temp != NULL_TREE;
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')
126 char *new_name;
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))
139 if (name[1] == 'T')
140 return MACHOPIC_DEFINED_FUNCTION;
141 else
142 return MACHOPIC_DEFINED_DATA;
146 if (name[1] == 't' || name[1] == 'T')
148 if (lprefix)
149 return MACHOPIC_DEFINED_FUNCTION;
150 else
151 return MACHOPIC_UNDEFINED_FUNCTION;
153 else
155 if (lprefix)
156 return MACHOPIC_DEFINED_DATA;
157 else
158 return MACHOPIC_UNDEFINED_DATA;
163 enum machopic_addr_class
164 machopic_classify_name (name)
165 const char *name;
167 return machopic_classify_ident (get_identifier (name));
171 machopic_ident_defined_p (ident)
172 tree ident;
174 switch (machopic_classify_ident (ident))
176 case MACHOPIC_UNDEFINED:
177 case MACHOPIC_UNDEFINED_DATA:
178 case MACHOPIC_UNDEFINED_FUNCTION:
179 return 0;
180 default:
181 return 1;
185 static int
186 machopic_data_defined_p (name)
187 const char *name;
189 switch (machopic_classify_ident (get_identifier (name)))
191 case MACHOPIC_DEFINED_DATA:
192 return 1;
193 default:
194 return 0;
199 machopic_name_defined_p (name)
200 const char *name;
202 return machopic_ident_defined_p (get_identifier (name));
205 void
206 machopic_define_ident (ident)
207 tree ident;
209 if (!machopic_ident_defined_p (ident))
210 machopic_defined_list =
211 tree_cons (NULL_TREE, ident, machopic_defined_list);
214 void
215 machopic_define_name (name)
216 const char *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 static char function_base[32];
226 static int current_pic_label_num;
228 const char *
229 machopic_function_base_name ()
231 static const char *name = NULL;
232 static const char *current_name;
234 current_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
236 if (name != current_name)
238 current_function_uses_pic_offset_table = 1;
240 /* Save mucho space and time. Some of the C++ mangled names are over
241 700 characters long! Note that we produce a label containing a '-'
242 if the function we're compiling is an Objective-C method, as evinced
243 by the incredibly scientific test below. This is because code in
244 rs6000.c makes the same ugly test when loading the PIC reg. */
246 ++current_pic_label_num;
247 if (*current_name == '+' || *current_name == '-')
248 sprintf (function_base, "*\"L-%d$pb\"", current_pic_label_num);
249 else
250 sprintf (function_base, "*L%d$pb", current_pic_label_num);
252 name = current_name;
255 return function_base;
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
262 a new one. */
264 const char *
265 machopic_non_lazy_ptr_name (name)
266 const char *name;
268 const char *temp_name;
269 tree temp, ident = get_identifier (name);
271 for (temp = machopic_non_lazy_pointers;
272 temp != NULL_TREE;
273 temp = TREE_CHAIN (temp))
275 if (ident == TREE_VALUE (temp))
276 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
279 name = darwin_strip_name_encoding (name);
281 /* Try again, but comparing names this time. */
282 for (temp = machopic_non_lazy_pointers;
283 temp != NULL_TREE;
284 temp = TREE_CHAIN (temp))
286 if (TREE_VALUE (temp))
288 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
289 temp_name = darwin_strip_name_encoding (temp_name);
290 if (strcmp (name, temp_name) == 0)
291 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
296 char *buffer;
297 tree ptr_name;
299 buffer = alloca (strlen (name) + 20);
301 strcpy (buffer, "&L");
302 if (name[0] == '*')
303 strcat (buffer, name+1);
304 else
306 strcat (buffer, "_");
307 strcat (buffer, name);
310 strcat (buffer, "$non_lazy_ptr");
311 ptr_name = get_identifier (buffer);
313 machopic_non_lazy_pointers
314 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
316 TREE_USED (machopic_non_lazy_pointers) = 0;
318 return IDENTIFIER_POINTER (ptr_name);
322 static GTY(()) tree machopic_stubs;
324 /* Return the name of the stub corresponding to the given name,
325 generating a new stub name if necessary. */
327 const char *
328 machopic_stub_name (name)
329 const char *name;
331 tree temp, ident = get_identifier (name);
332 const char *tname;
334 for (temp = machopic_stubs;
335 temp != NULL_TREE;
336 temp = TREE_CHAIN (temp))
338 if (ident == TREE_VALUE (temp))
339 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
340 tname = IDENTIFIER_POINTER (TREE_VALUE (temp));
341 if (strcmp (name, tname) == 0)
342 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
343 /* A library call name might not be section-encoded yet, so try
344 it against a stripped name. */
345 if (name[0] != '!'
346 && tname[0] == '!'
347 && strcmp (name, tname + 4) == 0)
348 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
351 name = darwin_strip_name_encoding (name);
354 char *buffer;
355 tree ptr_name;
356 int needs_quotes = name_needs_quotes (name);
358 buffer = alloca (strlen (name) + 20);
360 if (needs_quotes)
361 strcpy (buffer, "&\"L");
362 else
363 strcpy (buffer, "&L");
364 if (name[0] == '*')
366 strcat (buffer, name+1);
368 else
370 strcat (buffer, "_");
371 strcat (buffer, name);
374 if (needs_quotes)
375 strcat (buffer, "$stub\"");
376 else
377 strcat (buffer, "$stub");
378 ptr_name = get_identifier (buffer);
380 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
381 TREE_USED (machopic_stubs) = 0;
383 return IDENTIFIER_POINTER (ptr_name);
387 void
388 machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
389 const char *name;
390 int validate_stub;
392 const char *real_name;
393 tree temp, ident = get_identifier (name), id2;
395 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
396 temp != NULL_TREE;
397 temp = TREE_CHAIN (temp))
398 if (ident == TREE_PURPOSE (temp))
400 /* Mark both the stub or non-lazy pointer as well as the
401 original symbol as being referenced. */
402 TREE_USED (temp) = 1;
403 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
404 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
405 real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
406 real_name = darwin_strip_name_encoding (real_name);
407 id2 = maybe_get_identifier (real_name);
408 if (id2)
409 TREE_SYMBOL_REFERENCED (id2) = 1;
413 /* Transform ORIG, which may be any data source, to the corresponding
414 source using indirections. */
417 machopic_indirect_data_reference (orig, reg)
418 rtx orig, reg;
420 rtx ptr_ref = orig;
422 if (! MACHOPIC_INDIRECT)
423 return orig;
425 if (GET_CODE (orig) == SYMBOL_REF)
427 const char *name = XSTR (orig, 0);
429 if (machopic_data_defined_p (name))
431 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
432 rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
433 machopic_function_base_name ());
434 rtx offset = gen_rtx (CONST, Pmode,
435 gen_rtx (MINUS, Pmode, orig, pic_base));
436 #endif
438 #if defined (TARGET_TOC) /* i.e., PowerPC */
439 rtx hi_sum_reg = reg;
441 if (reg == NULL)
442 abort ();
444 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
445 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
446 gen_rtx (HIGH, Pmode, offset))));
447 emit_insn (gen_rtx (SET, Pmode, reg,
448 gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
450 orig = reg;
451 #else
452 #if defined (HAVE_lo_sum)
453 if (reg == 0) abort ();
455 emit_insn (gen_rtx (SET, VOIDmode, reg,
456 gen_rtx (HIGH, Pmode, offset)));
457 emit_insn (gen_rtx (SET, VOIDmode, reg,
458 gen_rtx (LO_SUM, Pmode, reg, offset)));
459 emit_insn (gen_rtx (USE, VOIDmode,
460 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
462 orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
463 #endif
464 #endif
465 return orig;
468 ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
469 machopic_non_lazy_ptr_name (name));
471 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
472 RTX_UNCHANGING_P (ptr_ref) = 1;
474 return ptr_ref;
476 else if (GET_CODE (orig) == CONST)
478 rtx base, result;
480 /* legitimize both operands of the PLUS */
481 if (GET_CODE (XEXP (orig, 0)) == PLUS)
483 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
484 reg);
485 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
486 (base == reg ? 0 : reg));
488 else
489 return orig;
491 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
492 result = plus_constant (base, INTVAL (orig));
493 else
494 result = gen_rtx (PLUS, Pmode, base, orig);
496 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
498 if (reg)
500 emit_move_insn (reg, result);
501 result = reg;
503 else
505 result = force_reg (GET_MODE (result), result);
509 return result;
512 else if (GET_CODE (orig) == MEM)
513 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
514 /* When the target is i386, this code prevents crashes due to the
515 compiler's ignorance on how to move the PIC base register to
516 other registers. (The reload phase sometimes introduces such
517 insns.) */
518 else if (GET_CODE (orig) == PLUS
519 && GET_CODE (XEXP (orig, 0)) == REG
520 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
521 #ifdef I386
522 /* Prevent the same register from being erroneously used
523 as both the base and index registers. */
524 && GET_CODE (XEXP (orig, 1)) == CONST
525 #endif
526 && reg)
528 emit_move_insn (reg, XEXP (orig, 0));
529 XEXP (ptr_ref, 0) = reg;
531 return ptr_ref;
534 /* Transform TARGET (a MEM), which is a function call target, to the
535 corresponding symbol_stub if necessary. Return a new MEM. */
538 machopic_indirect_call_target (target)
539 rtx target;
541 if (GET_CODE (target) != MEM)
542 return target;
544 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
546 enum machine_mode mode = GET_MODE (XEXP (target, 0));
547 const char *name = XSTR (XEXP (target, 0), 0);
549 /* If the name is already defined, we need do nothing. */
550 if (name[0] == '!' && name[1] == 'T')
551 return target;
553 if (!machopic_name_defined_p (name))
555 const char *stub_name = machopic_stub_name (name);
557 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
558 RTX_UNCHANGING_P (target) = 1;
562 return target;
566 machopic_legitimize_pic_address (orig, mode, reg)
567 rtx orig, reg;
568 enum machine_mode mode;
570 rtx pic_ref = orig;
572 if (! MACHOPIC_PURE)
573 return orig;
575 /* First handle a simple SYMBOL_REF or LABEL_REF */
576 if (GET_CODE (orig) == LABEL_REF
577 || (GET_CODE (orig) == SYMBOL_REF
580 /* addr(foo) = &func+(foo-func) */
581 rtx pic_base;
583 orig = machopic_indirect_data_reference (orig, reg);
585 if (GET_CODE (orig) == PLUS
586 && GET_CODE (XEXP (orig, 0)) == REG)
588 if (reg == 0)
589 return force_reg (mode, orig);
591 emit_move_insn (reg, orig);
592 return reg;
595 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
597 if (GET_CODE (orig) == MEM)
599 if (reg == 0)
601 if (reload_in_progress)
602 abort ();
603 else
604 reg = gen_reg_rtx (Pmode);
607 #ifdef HAVE_lo_sum
608 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
609 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
611 rtx offset = gen_rtx (CONST, Pmode,
612 gen_rtx (MINUS, Pmode,
613 XEXP (orig, 0), pic_base));
614 #if defined (TARGET_TOC) /* i.e., PowerPC */
615 /* Generating a new reg may expose opportunities for
616 common subexpression elimination. */
617 rtx hi_sum_reg =
618 (reload_in_progress ? reg : gen_reg_rtx (SImode));
620 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
621 gen_rtx (PLUS, Pmode,
622 pic_offset_table_rtx,
623 gen_rtx (HIGH, Pmode, offset))));
624 emit_insn (gen_rtx (SET, VOIDmode, reg,
625 gen_rtx (MEM, GET_MODE (orig),
626 gen_rtx (LO_SUM, Pmode,
627 hi_sum_reg, offset))));
628 pic_ref = reg;
630 #else
631 emit_insn (gen_rtx (USE, VOIDmode,
632 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
634 emit_insn (gen_rtx (SET, VOIDmode, reg,
635 gen_rtx (HIGH, Pmode,
636 gen_rtx (CONST, Pmode, offset))));
637 emit_insn (gen_rtx (SET, VOIDmode, reg,
638 gen_rtx (LO_SUM, Pmode, reg,
639 gen_rtx (CONST, Pmode, offset))));
640 pic_ref = gen_rtx (PLUS, Pmode,
641 pic_offset_table_rtx, reg);
642 #endif
644 else
645 #endif /* HAVE_lo_sum */
647 rtx pic = pic_offset_table_rtx;
648 if (GET_CODE (pic) != REG)
650 emit_move_insn (reg, pic);
651 pic = reg;
653 #if 0
654 emit_insn (gen_rtx (USE, VOIDmode,
655 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
656 #endif
658 pic_ref = gen_rtx (PLUS, Pmode,
659 pic,
660 gen_rtx (CONST, Pmode,
661 gen_rtx (MINUS, Pmode,
662 XEXP (orig, 0),
663 pic_base)));
666 #if !defined (TARGET_TOC)
667 emit_move_insn (reg, pic_ref);
668 pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
669 #endif
670 RTX_UNCHANGING_P (pic_ref) = 1;
672 else
675 #ifdef HAVE_lo_sum
676 if (GET_CODE (orig) == SYMBOL_REF
677 || GET_CODE (orig) == LABEL_REF)
679 rtx offset = gen_rtx (CONST, Pmode,
680 gen_rtx (MINUS, Pmode, orig, pic_base));
681 #if defined (TARGET_TOC) /* i.e., PowerPC */
682 rtx hi_sum_reg;
684 if (reg == 0)
686 if (reload_in_progress)
687 abort ();
688 else
689 reg = gen_reg_rtx (SImode);
692 hi_sum_reg = reg;
694 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
695 gen_rtx (PLUS, Pmode,
696 pic_offset_table_rtx,
697 gen_rtx (HIGH, Pmode, offset))));
698 emit_insn (gen_rtx (SET, VOIDmode, reg,
699 gen_rtx (LO_SUM, Pmode,
700 hi_sum_reg, offset)));
701 pic_ref = reg;
702 RTX_UNCHANGING_P (pic_ref) = 1;
703 #else
704 emit_insn (gen_rtx (SET, VOIDmode, reg,
705 gen_rtx (HIGH, Pmode, offset)));
706 emit_insn (gen_rtx (SET, VOIDmode, reg,
707 gen_rtx (LO_SUM, Pmode, reg, offset)));
708 pic_ref = gen_rtx (PLUS, Pmode,
709 pic_offset_table_rtx, reg);
710 RTX_UNCHANGING_P (pic_ref) = 1;
711 #endif
713 else
714 #endif /* HAVE_lo_sum */
716 if (GET_CODE (orig) == REG)
718 return orig;
720 else
722 rtx pic = pic_offset_table_rtx;
723 if (GET_CODE (pic) != REG)
725 emit_move_insn (reg, pic);
726 pic = reg;
728 #if 0
729 emit_insn (gen_rtx (USE, VOIDmode,
730 pic_offset_table_rtx));
731 #endif
732 pic_ref = gen_rtx (PLUS, Pmode,
733 pic,
734 gen_rtx (CONST, Pmode,
735 gen_rtx (MINUS, Pmode,
736 orig, pic_base)));
741 if (GET_CODE (pic_ref) != REG)
743 if (reg != 0)
745 emit_move_insn (reg, pic_ref);
746 return reg;
748 else
750 return force_reg (mode, pic_ref);
753 else
755 return pic_ref;
759 else if (GET_CODE (orig) == SYMBOL_REF)
760 return orig;
762 else if (GET_CODE (orig) == PLUS
763 && (GET_CODE (XEXP (orig, 0)) == MEM
764 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
765 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
766 && XEXP (orig, 0) != pic_offset_table_rtx
767 && GET_CODE (XEXP (orig, 1)) != REG)
770 rtx base;
771 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
773 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
774 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
775 Pmode, (base == reg ? 0 : reg));
776 if (GET_CODE (orig) == CONST_INT)
778 pic_ref = plus_constant (base, INTVAL (orig));
779 is_complex = 1;
781 else
782 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
784 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
785 RTX_UNCHANGING_P (pic_ref) = 1;
787 if (reg && is_complex)
789 emit_move_insn (reg, pic_ref);
790 pic_ref = reg;
792 /* Likewise, should we set special REG_NOTEs here? */
795 else if (GET_CODE (orig) == CONST)
797 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
800 else if (GET_CODE (orig) == MEM
801 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
803 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
805 addr = gen_rtx (MEM, GET_MODE (orig), addr);
806 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
807 emit_move_insn (reg, addr);
808 pic_ref = reg;
811 return pic_ref;
815 void
816 machopic_finish (asm_out_file)
817 FILE *asm_out_file;
819 tree temp;
821 for (temp = machopic_stubs;
822 temp != NULL_TREE;
823 temp = TREE_CHAIN (temp))
825 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
826 const char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
827 char *sym;
828 char *stub;
830 if (! TREE_USED (temp))
831 continue;
833 /* If the symbol is actually defined, we don't need a stub. */
834 if (sym_name[0] == '!' && sym_name[1] == 'T')
835 continue;
837 sym_name = darwin_strip_name_encoding (sym_name);
839 sym = alloca (strlen (sym_name) + 2);
840 if (sym_name[0] == '*' || sym_name[0] == '&')
841 strcpy (sym, sym_name + 1);
842 else if (sym_name[0] == '-' || sym_name[0] == '+')
843 strcpy (sym, sym_name);
844 else
845 sym[0] = '_', strcpy (sym + 1, sym_name);
847 stub = alloca (strlen (stub_name) + 2);
848 if (stub_name[0] == '*' || stub_name[0] == '&')
849 strcpy (stub, stub_name + 1);
850 else
851 stub[0] = '_', strcpy (stub + 1, stub_name);
853 machopic_output_stub (asm_out_file, sym, stub);
856 for (temp = machopic_non_lazy_pointers;
857 temp != NULL_TREE;
858 temp = TREE_CHAIN (temp))
860 const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
861 const char *const lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
862 #if 0
863 tree decl = lookup_name_darwin (TREE_VALUE (temp));
864 #endif
866 if (! TREE_USED (temp))
867 continue;
869 if (machopic_ident_defined_p (TREE_VALUE (temp))
870 #if 0 /* add back when we have private externs */
871 || (decl && DECL_PRIVATE_EXTERN (decl))
872 #endif
875 data_section ();
876 assemble_align (GET_MODE_ALIGNMENT (Pmode));
877 assemble_label (lazy_name);
878 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
879 GET_MODE_SIZE (Pmode),
880 GET_MODE_ALIGNMENT (Pmode), 1);
882 else
884 machopic_nl_symbol_ptr_section ();
885 assemble_name (asm_out_file, lazy_name);
886 fprintf (asm_out_file, ":\n");
888 fprintf (asm_out_file, "\t.indirect_symbol ");
889 assemble_name (asm_out_file, sym_name);
890 fprintf (asm_out_file, "\n");
892 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
893 GET_MODE_ALIGNMENT (Pmode), 1);
898 int
899 machopic_operand_p (op)
900 rtx op;
902 if (MACHOPIC_JUST_INDIRECT)
904 while (GET_CODE (op) == CONST)
905 op = XEXP (op, 0);
907 if (GET_CODE (op) == SYMBOL_REF)
908 return machopic_name_defined_p (XSTR (op, 0));
909 else
910 return 0;
913 while (GET_CODE (op) == CONST)
914 op = XEXP (op, 0);
916 if (GET_CODE (op) == MINUS
917 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
918 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
919 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
920 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
921 return 1;
923 #if 0 /*def TARGET_TOC*/ /* i.e., PowerPC */
924 /* Without this statement, the compiler crashes while compiling enquire.c
925 when targetting PowerPC. It is not known why this code is not needed
926 when targetting other processors. */
927 else if (GET_CODE (op) == SYMBOL_REF
928 && (machopic_classify_name (XSTR (op, 0))
929 == MACHOPIC_DEFINED_FUNCTION))
931 return 1;
933 #endif
935 return 0;
938 /* This function records whether a given name corresponds to a defined
939 or undefined function or variable, for machopic_classify_ident to
940 use later. */
942 void
943 darwin_encode_section_info (decl, first)
944 tree decl;
945 int first ATTRIBUTE_UNUSED;
947 char code = '\0';
948 int defined = 0;
949 rtx sym_ref;
950 const char *orig_str;
951 char *new_str;
952 size_t len, new_len;
954 if ((TREE_CODE (decl) == FUNCTION_DECL
955 || TREE_CODE (decl) == VAR_DECL)
956 && !DECL_EXTERNAL (decl)
957 && ((TREE_STATIC (decl)
958 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
959 || (DECL_INITIAL (decl)
960 && DECL_INITIAL (decl) != error_mark_node)))
961 defined = 1;
963 if (TREE_CODE (decl) == FUNCTION_DECL)
964 code = (defined ? 'T' : 't');
965 else if (TREE_CODE (decl) == VAR_DECL)
966 code = (defined ? 'D' : 'd');
968 if (code == '\0')
969 return;
971 sym_ref = XEXP (DECL_RTL (decl), 0);
972 orig_str = XSTR (sym_ref, 0);
973 len = strlen (orig_str) + 1;
975 if (orig_str[0] == '!')
977 /* Already encoded; see if we need to change it. */
978 if (code == orig_str[1])
979 return;
980 /* Yes, tweak a copy of the name and put it in a new string. */
981 new_str = alloca (len);
982 memcpy (new_str, orig_str, len);
983 new_str[1] = code;
984 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
986 else
988 /* Add the encoding. */
989 new_len = len + 4;
990 new_str = alloca (new_len);
991 new_str[0] = '!';
992 new_str[1] = code;
993 new_str[2] = '_';
994 new_str[3] = '_';
995 memcpy (new_str + 4, orig_str, len);
996 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
998 /* The non-lazy pointer list may have captured references to the
999 old encoded name, change them. */
1000 if (TREE_CODE (decl) == VAR_DECL)
1001 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1002 else
1003 update_stubs (XSTR (sym_ref, 0));
1006 /* Undo the effects of the above. */
1008 const char *
1009 darwin_strip_name_encoding (str)
1010 const char *str;
1012 return str[0] == '!' ? str + 4 : str;
1015 /* Scan the list of non-lazy pointers and update any recorded names whose
1016 stripped name matches the argument. */
1018 static void
1019 update_non_lazy_ptrs (name)
1020 const char *name;
1022 const char *name1, *name2;
1023 tree temp;
1025 name1 = darwin_strip_name_encoding (name);
1027 for (temp = machopic_non_lazy_pointers;
1028 temp != NULL_TREE;
1029 temp = TREE_CHAIN (temp))
1031 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1033 if (*sym_name == '!')
1035 name2 = darwin_strip_name_encoding (sym_name);
1036 if (strcmp (name1, name2) == 0)
1038 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1039 break;
1045 /* Function NAME is being defined, and its label has just been output.
1046 If there's already a reference to a stub for this function, we can
1047 just emit the stub label now and we don't bother emitting the stub later. */
1049 void
1050 machopic_output_possible_stub_label (file, name)
1051 FILE *file;
1052 const char *name;
1054 tree temp;
1057 /* Ensure we're looking at a section-encoded name. */
1058 if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
1059 return;
1061 for (temp = machopic_stubs;
1062 temp != NULL_TREE;
1063 temp = TREE_CHAIN (temp))
1065 const char *sym_name;
1067 sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1068 if (sym_name[0] == '!' && sym_name[1] == 'T'
1069 && ! strcmp (name+2, sym_name+2))
1071 ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
1072 /* Avoid generating a stub for this. */
1073 TREE_USED (temp) = 0;
1074 break;
1079 /* Scan the list of stubs and update any recorded names whose
1080 stripped name matches the argument. */
1082 static void
1083 update_stubs (name)
1084 const char *name;
1086 const char *name1, *name2;
1087 tree temp;
1089 name1 = darwin_strip_name_encoding (name);
1091 for (temp = machopic_stubs;
1092 temp != NULL_TREE;
1093 temp = TREE_CHAIN (temp))
1095 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1097 if (*sym_name == '!')
1099 name2 = darwin_strip_name_encoding (sym_name);
1100 if (strcmp (name1, name2) == 0)
1102 IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
1103 break;
1109 void
1110 machopic_select_section (exp, reloc, align)
1111 tree exp;
1112 int reloc;
1113 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1115 if (TREE_CODE (exp) == STRING_CST)
1117 if (flag_writable_strings)
1118 data_section ();
1119 else if (TREE_STRING_LENGTH (exp) !=
1120 strlen (TREE_STRING_POINTER (exp)) + 1)
1121 readonly_data_section ();
1122 else
1123 cstring_section ();
1125 else if (TREE_CODE (exp) == INTEGER_CST
1126 || TREE_CODE (exp) == REAL_CST)
1128 tree size = TYPE_SIZE (TREE_TYPE (exp));
1130 if (TREE_CODE (size) == INTEGER_CST &&
1131 TREE_INT_CST_LOW (size) == 4 &&
1132 TREE_INT_CST_HIGH (size) == 0)
1133 literal4_section ();
1134 else if (TREE_CODE (size) == INTEGER_CST &&
1135 TREE_INT_CST_LOW (size) == 8 &&
1136 TREE_INT_CST_HIGH (size) == 0)
1137 literal8_section ();
1138 else
1139 readonly_data_section ();
1141 else if (TREE_CODE (exp) == CONSTRUCTOR
1142 && TREE_TYPE (exp)
1143 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1144 && TYPE_NAME (TREE_TYPE (exp)))
1146 tree name = TYPE_NAME (TREE_TYPE (exp));
1147 if (TREE_CODE (name) == TYPE_DECL)
1148 name = DECL_NAME (name);
1149 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1150 objc_constant_string_object_section ();
1151 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1152 objc_string_object_section ();
1153 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1155 if (TREE_SIDE_EFFECTS (exp) || (flag_pic && reloc))
1156 const_data_section ();
1157 else
1158 readonly_data_section ();
1160 else
1161 data_section ();
1163 else if (TREE_CODE (exp) == VAR_DECL &&
1164 DECL_NAME (exp) &&
1165 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1166 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1167 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1169 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1171 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1172 objc_cls_meth_section ();
1173 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1174 objc_inst_meth_section ();
1175 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1176 objc_cat_cls_meth_section ();
1177 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1178 objc_cat_inst_meth_section ();
1179 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1180 objc_class_vars_section ();
1181 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1182 objc_instance_vars_section ();
1183 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1184 objc_cat_cls_meth_section ();
1185 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1186 objc_class_names_section ();
1187 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1188 objc_meth_var_names_section ();
1189 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1190 objc_meth_var_types_section ();
1191 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1192 objc_cls_refs_section ();
1193 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1194 objc_class_section ();
1195 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1196 objc_meta_class_section ();
1197 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1198 objc_category_section ();
1199 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1200 objc_selector_refs_section ();
1201 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1202 objc_selector_fixup_section ();
1203 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1204 objc_symbols_section ();
1205 else if (!strncmp (name, "_OBJC_MODULES", 13))
1206 objc_module_info_section ();
1207 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1208 objc_cat_inst_meth_section ();
1209 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1210 objc_cat_cls_meth_section ();
1211 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1212 objc_cat_cls_meth_section ();
1213 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1214 objc_protocol_section ();
1215 else if ((TREE_READONLY (exp) || TREE_CONSTANT (exp))
1216 && !TREE_SIDE_EFFECTS (exp))
1218 if (flag_pic && reloc)
1219 const_data_section ();
1220 else
1221 readonly_data_section ();
1223 else
1224 data_section ();
1226 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1228 if (TREE_SIDE_EFFECTS (exp) || (flag_pic && reloc))
1229 const_data_section ();
1230 else
1231 readonly_data_section ();
1233 else
1234 data_section ();
1237 /* This can be called with address expressions as "rtx".
1238 They must go in "const". */
1240 void
1241 machopic_select_rtx_section (mode, x, align)
1242 enum machine_mode mode;
1243 rtx x;
1244 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1246 if (GET_MODE_SIZE (mode) == 8)
1247 literal8_section ();
1248 else if (GET_MODE_SIZE (mode) == 4
1249 && (GET_CODE (x) == CONST_INT
1250 || GET_CODE (x) == CONST_DOUBLE))
1251 literal4_section ();
1252 else
1253 const_section ();
1256 void
1257 machopic_asm_out_constructor (symbol, priority)
1258 rtx symbol;
1259 int priority ATTRIBUTE_UNUSED;
1261 if (flag_pic)
1262 mod_init_section ();
1263 else
1264 constructor_section ();
1265 assemble_align (POINTER_SIZE);
1266 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1268 if (!flag_pic)
1269 fprintf (asm_out_file, ".reference .constructors_used\n");
1272 void
1273 machopic_asm_out_destructor (symbol, priority)
1274 rtx symbol;
1275 int priority ATTRIBUTE_UNUSED;
1277 if (flag_pic)
1278 mod_term_section ();
1279 else
1280 destructor_section ();
1281 assemble_align (POINTER_SIZE);
1282 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1284 if (!flag_pic)
1285 fprintf (asm_out_file, ".reference .destructors_used\n");
1288 void
1289 darwin_globalize_label (stream, name)
1290 FILE *stream;
1291 const char *name;
1293 if (!!strncmp (name, "_OBJC_", 6))
1294 default_globalize_label (stream, name);
1297 #include "gt-darwin.h"