rs6000.md: Remove warning.
[gcc.git] / gcc / config / darwin.c
1 /* Functions for generic Darwin as target machine for GNU C compiler.
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by Apple Computer Inc.
5
6 This file is part of GNU CC.
7
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.
12
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.
17
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. */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-flags.h"
34 #include "output.h"
35 #include "insn-attr.h"
36 #include "flags.h"
37 #include "tree.h"
38 #include "expr.h"
39 #include "reload.h"
40 #include "function.h"
41 #include "ggc.h"
42 #include "langhooks.h"
43 #include "tm_p.h"
44
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 *));
48
49 int
50 name_needs_quotes (name)
51 const char *name;
52 {
53 int c;
54 while ((c = *name++) != '\0')
55 if (! ISIDNUM (c))
56 return 1;
57 return 0;
58 }
59
60 /*
61 * flag_pic = 1 ... generate only indirections
62 * flag_pic = 2 ... generate indirections and pure code
63 */
64
65 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
66 reference, which will not be changed. */
67
68 static GTY(()) tree machopic_defined_list;
69
70 enum machopic_addr_class
71 machopic_classify_ident (ident)
72 tree ident;
73 {
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;
84
85 if (name[0] != '!')
86 {
87 /* Here if no special encoding to be found. */
88 if (lprefix)
89 {
90 const char *name = IDENTIFIER_POINTER (ident);
91 int len = strlen (name);
92
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;
97 }
98
99 for (temp = machopic_defined_list;
100 temp != NULL_TREE;
101 temp = TREE_CHAIN (temp))
102 {
103 if (ident == TREE_VALUE (temp))
104 return MACHOPIC_DEFINED_DATA;
105 }
106
107 if (TREE_ASM_WRITTEN (ident))
108 return MACHOPIC_DEFINED_DATA;
109
110 return MACHOPIC_UNDEFINED;
111 }
112
113 else if (name[1] == 'D')
114 return MACHOPIC_DEFINED_DATA;
115
116 else if (name[1] == 'T')
117 return MACHOPIC_DEFINED_FUNCTION;
118
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')
125 {
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;
133 }
134
135 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
136 {
137 if (ident == TREE_VALUE (temp))
138 {
139 if (name[1] == 'T')
140 return MACHOPIC_DEFINED_FUNCTION;
141 else
142 return MACHOPIC_DEFINED_DATA;
143 }
144 }
145
146 if (name[1] == 't' || name[1] == 'T')
147 {
148 if (lprefix)
149 return MACHOPIC_DEFINED_FUNCTION;
150 else
151 return MACHOPIC_UNDEFINED_FUNCTION;
152 }
153 else
154 {
155 if (lprefix)
156 return MACHOPIC_DEFINED_DATA;
157 else
158 return MACHOPIC_UNDEFINED_DATA;
159 }
160 }
161
162
163 enum machopic_addr_class
164 machopic_classify_name (name)
165 const char *name;
166 {
167 return machopic_classify_ident (get_identifier (name));
168 }
169
170 int
171 machopic_ident_defined_p (ident)
172 tree ident;
173 {
174 switch (machopic_classify_ident (ident))
175 {
176 case MACHOPIC_UNDEFINED:
177 case MACHOPIC_UNDEFINED_DATA:
178 case MACHOPIC_UNDEFINED_FUNCTION:
179 return 0;
180 default:
181 return 1;
182 }
183 }
184
185 static int
186 machopic_data_defined_p (name)
187 const char *name;
188 {
189 switch (machopic_classify_ident (get_identifier (name)))
190 {
191 case MACHOPIC_DEFINED_DATA:
192 return 1;
193 default:
194 return 0;
195 }
196 }
197
198 int
199 machopic_name_defined_p (name)
200 const char *name;
201 {
202 return machopic_ident_defined_p (get_identifier (name));
203 }
204
205 void
206 machopic_define_ident (ident)
207 tree ident;
208 {
209 if (!machopic_ident_defined_p (ident))
210 machopic_defined_list =
211 tree_cons (NULL_TREE, ident, machopic_defined_list);
212 }
213
214 void
215 machopic_define_name (name)
216 const char *name;
217 {
218 machopic_define_ident (get_identifier (name));
219 }
220
221 /* This is a static to make inline functions work. The rtx
222 representing the PIC base symbol always points to here. */
223
224 static char function_base[32];
225
226 static GTY(()) int current_pic_label_num;
227
228 const char *
229 machopic_function_base_name ()
230 {
231 static const char *name = NULL;
232 static const char *current_name;
233
234 current_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
235
236 if (name != current_name)
237 {
238 current_function_uses_pic_offset_table = 1;
239
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. */
245
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);
251
252 name = current_name;
253 }
254
255 return function_base;
256 }
257
258 static GTY(()) tree machopic_non_lazy_pointers;
259
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. */
263
264 const char *
265 machopic_non_lazy_ptr_name (name)
266 const char *name;
267 {
268 const char *temp_name;
269 tree temp, ident = get_identifier (name);
270
271 for (temp = machopic_non_lazy_pointers;
272 temp != NULL_TREE;
273 temp = TREE_CHAIN (temp))
274 {
275 if (ident == TREE_VALUE (temp))
276 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
277 }
278
279 name = darwin_strip_name_encoding (name);
280
281 /* Try again, but comparing names this time. */
282 for (temp = machopic_non_lazy_pointers;
283 temp != NULL_TREE;
284 temp = TREE_CHAIN (temp))
285 {
286 if (TREE_VALUE (temp))
287 {
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));
292 }
293 }
294
295 {
296 char *buffer;
297 tree ptr_name;
298
299 buffer = alloca (strlen (name) + 20);
300
301 strcpy (buffer, "&L");
302 if (name[0] == '*')
303 strcat (buffer, name+1);
304 else
305 {
306 strcat (buffer, "_");
307 strcat (buffer, name);
308 }
309
310 strcat (buffer, "$non_lazy_ptr");
311 ptr_name = get_identifier (buffer);
312
313 machopic_non_lazy_pointers
314 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
315
316 TREE_USED (machopic_non_lazy_pointers) = 0;
317
318 return IDENTIFIER_POINTER (ptr_name);
319 }
320 }
321
322 static GTY(()) tree machopic_stubs;
323
324 /* Return the name of the stub corresponding to the given name,
325 generating a new stub name if necessary. */
326
327 const char *
328 machopic_stub_name (name)
329 const char *name;
330 {
331 tree temp, ident = get_identifier (name);
332 const char *tname;
333
334 for (temp = machopic_stubs;
335 temp != NULL_TREE;
336 temp = TREE_CHAIN (temp))
337 {
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));
349 }
350
351 name = darwin_strip_name_encoding (name);
352
353 {
354 char *buffer;
355 tree ptr_name;
356 int needs_quotes = name_needs_quotes (name);
357
358 buffer = alloca (strlen (name) + 20);
359
360 if (needs_quotes)
361 strcpy (buffer, "&\"L");
362 else
363 strcpy (buffer, "&L");
364 if (name[0] == '*')
365 {
366 strcat (buffer, name+1);
367 }
368 else
369 {
370 strcat (buffer, "_");
371 strcat (buffer, name);
372 }
373
374 if (needs_quotes)
375 strcat (buffer, "$stub\"");
376 else
377 strcat (buffer, "$stub");
378 ptr_name = get_identifier (buffer);
379
380 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
381 TREE_USED (machopic_stubs) = 0;
382
383 return IDENTIFIER_POINTER (ptr_name);
384 }
385 }
386
387 void
388 machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
389 const char *name;
390 int validate_stub;
391 {
392 const char *real_name;
393 tree temp, ident = get_identifier (name), id2;
394
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))
399 {
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;
410 }
411 }
412
413 /* Transform ORIG, which may be any data source, to the corresponding
414 source using indirections. */
415
416 rtx
417 machopic_indirect_data_reference (orig, reg)
418 rtx orig, reg;
419 {
420 rtx ptr_ref = orig;
421
422 if (! MACHOPIC_INDIRECT)
423 return orig;
424
425 if (GET_CODE (orig) == SYMBOL_REF)
426 {
427 const char *name = XSTR (orig, 0);
428
429 if (machopic_data_defined_p (name))
430 {
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
437
438 #if defined (TARGET_TOC) /* i.e., PowerPC */
439 rtx hi_sum_reg = reg;
440
441 if (reg == NULL)
442 abort ();
443
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)));
449
450 orig = reg;
451 #else
452 #if defined (HAVE_lo_sum)
453 if (reg == 0) abort ();
454
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)));
461
462 orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
463 #endif
464 #endif
465 return orig;
466 }
467
468 ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
469 machopic_non_lazy_ptr_name (name));
470
471 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
472 RTX_UNCHANGING_P (ptr_ref) = 1;
473
474 return ptr_ref;
475 }
476 else if (GET_CODE (orig) == CONST)
477 {
478 rtx base, result;
479
480 /* legitimize both operands of the PLUS */
481 if (GET_CODE (XEXP (orig, 0)) == PLUS)
482 {
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));
487 }
488 else
489 return orig;
490
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);
495
496 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
497 {
498 if (reg)
499 {
500 emit_move_insn (reg, result);
501 result = reg;
502 }
503 else
504 {
505 result = force_reg (GET_MODE (result), result);
506 }
507 }
508
509 return result;
510
511 }
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)
527 {
528 emit_move_insn (reg, XEXP (orig, 0));
529 XEXP (ptr_ref, 0) = reg;
530 }
531 return ptr_ref;
532 }
533
534 /* Transform TARGET (a MEM), which is a function call target, to the
535 corresponding symbol_stub if necessary. Return a new MEM. */
536
537 rtx
538 machopic_indirect_call_target (target)
539 rtx target;
540 {
541 if (GET_CODE (target) != MEM)
542 return target;
543
544 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
545 {
546 enum machine_mode mode = GET_MODE (XEXP (target, 0));
547 const char *name = XSTR (XEXP (target, 0), 0);
548
549 /* If the name is already defined, we need do nothing. */
550 if (name[0] == '!' && name[1] == 'T')
551 return target;
552
553 if (!machopic_name_defined_p (name))
554 {
555 const char *stub_name = machopic_stub_name (name);
556
557 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
558 RTX_UNCHANGING_P (target) = 1;
559 }
560 }
561
562 return target;
563 }
564
565 rtx
566 machopic_legitimize_pic_address (orig, mode, reg)
567 rtx orig, reg;
568 enum machine_mode mode;
569 {
570 rtx pic_ref = orig;
571
572 if (! MACHOPIC_PURE)
573 return orig;
574
575 /* First handle a simple SYMBOL_REF or LABEL_REF */
576 if (GET_CODE (orig) == LABEL_REF
577 || (GET_CODE (orig) == SYMBOL_REF
578 ))
579 {
580 /* addr(foo) = &func+(foo-func) */
581 rtx pic_base;
582
583 orig = machopic_indirect_data_reference (orig, reg);
584
585 if (GET_CODE (orig) == PLUS
586 && GET_CODE (XEXP (orig, 0)) == REG)
587 {
588 if (reg == 0)
589 return force_reg (mode, orig);
590
591 emit_move_insn (reg, orig);
592 return reg;
593 }
594
595 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
596
597 if (GET_CODE (orig) == MEM)
598 {
599 if (reg == 0)
600 {
601 if (reload_in_progress)
602 abort ();
603 else
604 reg = gen_reg_rtx (Pmode);
605 }
606
607 #ifdef HAVE_lo_sum
608 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
609 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
610 {
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));
619
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;
629
630 #else
631 emit_insn (gen_rtx (USE, VOIDmode,
632 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
633
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
643 }
644 else
645 #endif /* HAVE_lo_sum */
646 {
647 rtx pic = pic_offset_table_rtx;
648 if (GET_CODE (pic) != REG)
649 {
650 emit_move_insn (reg, pic);
651 pic = reg;
652 }
653 #if 0
654 emit_insn (gen_rtx (USE, VOIDmode,
655 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
656 #endif
657
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)));
664 }
665
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;
671 }
672 else
673 {
674
675 #ifdef HAVE_lo_sum
676 if (GET_CODE (orig) == SYMBOL_REF
677 || GET_CODE (orig) == LABEL_REF)
678 {
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;
683
684 if (reg == 0)
685 {
686 if (reload_in_progress)
687 abort ();
688 else
689 reg = gen_reg_rtx (SImode);
690 }
691
692 hi_sum_reg = reg;
693
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
712 }
713 else
714 #endif /* HAVE_lo_sum */
715 {
716 if (GET_CODE (orig) == REG)
717 {
718 return orig;
719 }
720 else
721 {
722 rtx pic = pic_offset_table_rtx;
723 if (GET_CODE (pic) != REG)
724 {
725 emit_move_insn (reg, pic);
726 pic = reg;
727 }
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)));
737 }
738 }
739 }
740
741 if (GET_CODE (pic_ref) != REG)
742 {
743 if (reg != 0)
744 {
745 emit_move_insn (reg, pic_ref);
746 return reg;
747 }
748 else
749 {
750 return force_reg (mode, pic_ref);
751 }
752 }
753 else
754 {
755 return pic_ref;
756 }
757 }
758
759 else if (GET_CODE (orig) == SYMBOL_REF)
760 return orig;
761
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)
768
769 {
770 rtx base;
771 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
772
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)
777 {
778 pic_ref = plus_constant (base, INTVAL (orig));
779 is_complex = 1;
780 }
781 else
782 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
783
784 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
785 RTX_UNCHANGING_P (pic_ref) = 1;
786
787 if (reg && is_complex)
788 {
789 emit_move_insn (reg, pic_ref);
790 pic_ref = reg;
791 }
792 /* Likewise, should we set special REG_NOTEs here? */
793 }
794
795 else if (GET_CODE (orig) == CONST)
796 {
797 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
798 }
799
800 else if (GET_CODE (orig) == MEM
801 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
802 {
803 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
804
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;
809 }
810
811 return pic_ref;
812 }
813
814
815 void
816 machopic_finish (asm_out_file)
817 FILE *asm_out_file;
818 {
819 tree temp;
820
821 for (temp = machopic_stubs;
822 temp != NULL_TREE;
823 temp = TREE_CHAIN (temp))
824 {
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;
829
830 if (! TREE_USED (temp))
831 continue;
832
833 /* If the symbol is actually defined, we don't need a stub. */
834 if (sym_name[0] == '!' && sym_name[1] == 'T')
835 continue;
836
837 sym_name = darwin_strip_name_encoding (sym_name);
838
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);
846
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);
852
853 machopic_output_stub (asm_out_file, sym, stub);
854 }
855
856 for (temp = machopic_non_lazy_pointers;
857 temp != NULL_TREE;
858 temp = TREE_CHAIN (temp))
859 {
860 const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
861 const char *const lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
862
863 if (! TREE_USED (temp))
864 continue;
865
866 if (machopic_ident_defined_p (TREE_VALUE (temp)))
867 {
868 data_section ();
869 assemble_align (GET_MODE_ALIGNMENT (Pmode));
870 assemble_label (lazy_name);
871 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
872 GET_MODE_SIZE (Pmode),
873 GET_MODE_ALIGNMENT (Pmode), 1);
874 }
875 else
876 {
877 machopic_nl_symbol_ptr_section ();
878 assemble_name (asm_out_file, lazy_name);
879 fprintf (asm_out_file, ":\n");
880
881 fprintf (asm_out_file, "\t.indirect_symbol ");
882 assemble_name (asm_out_file, sym_name);
883 fprintf (asm_out_file, "\n");
884
885 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
886 GET_MODE_ALIGNMENT (Pmode), 1);
887 }
888 }
889 }
890
891 int
892 machopic_operand_p (op)
893 rtx op;
894 {
895 if (MACHOPIC_JUST_INDIRECT)
896 {
897 while (GET_CODE (op) == CONST)
898 op = XEXP (op, 0);
899
900 if (GET_CODE (op) == SYMBOL_REF)
901 return machopic_name_defined_p (XSTR (op, 0));
902 else
903 return 0;
904 }
905
906 while (GET_CODE (op) == CONST)
907 op = XEXP (op, 0);
908
909 if (GET_CODE (op) == MINUS
910 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
911 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
912 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
913 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
914 return 1;
915
916 return 0;
917 }
918
919 /* This function records whether a given name corresponds to a defined
920 or undefined function or variable, for machopic_classify_ident to
921 use later. */
922
923 void
924 darwin_encode_section_info (decl, first)
925 tree decl;
926 int first ATTRIBUTE_UNUSED;
927 {
928 char code = '\0';
929 int defined = 0;
930 rtx sym_ref;
931 const char *orig_str;
932 char *new_str;
933 size_t len, new_len;
934
935 if ((TREE_CODE (decl) == FUNCTION_DECL
936 || TREE_CODE (decl) == VAR_DECL)
937 && !DECL_EXTERNAL (decl)
938 && ((TREE_STATIC (decl)
939 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
940 || (DECL_INITIAL (decl)
941 && DECL_INITIAL (decl) != error_mark_node)))
942 defined = 1;
943
944 if (TREE_CODE (decl) == FUNCTION_DECL)
945 code = (defined ? 'T' : 't');
946 else if (TREE_CODE (decl) == VAR_DECL)
947 code = (defined ? 'D' : 'd');
948
949 if (code == '\0')
950 return;
951
952 sym_ref = XEXP (DECL_RTL (decl), 0);
953 orig_str = XSTR (sym_ref, 0);
954 len = strlen (orig_str) + 1;
955
956 if (orig_str[0] == '!')
957 {
958 /* Already encoded; see if we need to change it. */
959 if (code == orig_str[1])
960 return;
961 /* Yes, tweak a copy of the name and put it in a new string. */
962 new_str = alloca (len);
963 memcpy (new_str, orig_str, len);
964 new_str[1] = code;
965 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
966 }
967 else
968 {
969 /* Add the encoding. */
970 new_len = len + 4;
971 new_str = alloca (new_len);
972 new_str[0] = '!';
973 new_str[1] = code;
974 new_str[2] = '_';
975 new_str[3] = '_';
976 memcpy (new_str + 4, orig_str, len);
977 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
978 }
979 /* The non-lazy pointer list may have captured references to the
980 old encoded name, change them. */
981 if (TREE_CODE (decl) == VAR_DECL)
982 update_non_lazy_ptrs (XSTR (sym_ref, 0));
983 else
984 update_stubs (XSTR (sym_ref, 0));
985 }
986
987 /* Undo the effects of the above. */
988
989 const char *
990 darwin_strip_name_encoding (str)
991 const char *str;
992 {
993 return str[0] == '!' ? str + 4 : str;
994 }
995
996 /* Scan the list of non-lazy pointers and update any recorded names whose
997 stripped name matches the argument. */
998
999 static void
1000 update_non_lazy_ptrs (name)
1001 const char *name;
1002 {
1003 const char *name1, *name2;
1004 tree temp;
1005
1006 name1 = darwin_strip_name_encoding (name);
1007
1008 for (temp = machopic_non_lazy_pointers;
1009 temp != NULL_TREE;
1010 temp = TREE_CHAIN (temp))
1011 {
1012 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1013
1014 if (*sym_name == '!')
1015 {
1016 name2 = darwin_strip_name_encoding (sym_name);
1017 if (strcmp (name1, name2) == 0)
1018 {
1019 /* FIXME: This breaks the identifier hash table. */
1020 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1021 = (unsigned char *) name;
1022 break;
1023 }
1024 }
1025 }
1026 }
1027
1028 /* Function NAME is being defined, and its label has just been output.
1029 If there's already a reference to a stub for this function, we can
1030 just emit the stub label now and we don't bother emitting the stub later. */
1031
1032 void
1033 machopic_output_possible_stub_label (file, name)
1034 FILE *file;
1035 const char *name;
1036 {
1037 tree temp;
1038
1039
1040 /* Ensure we're looking at a section-encoded name. */
1041 if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
1042 return;
1043
1044 for (temp = machopic_stubs;
1045 temp != NULL_TREE;
1046 temp = TREE_CHAIN (temp))
1047 {
1048 const char *sym_name;
1049
1050 sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1051 if (sym_name[0] == '!' && sym_name[1] == 'T'
1052 && ! strcmp (name+2, sym_name+2))
1053 {
1054 ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
1055 /* Avoid generating a stub for this. */
1056 TREE_USED (temp) = 0;
1057 break;
1058 }
1059 }
1060 }
1061
1062 /* Scan the list of stubs and update any recorded names whose
1063 stripped name matches the argument. */
1064
1065 static void
1066 update_stubs (name)
1067 const char *name;
1068 {
1069 const char *name1, *name2;
1070 tree temp;
1071
1072 name1 = darwin_strip_name_encoding (name);
1073
1074 for (temp = machopic_stubs;
1075 temp != NULL_TREE;
1076 temp = TREE_CHAIN (temp))
1077 {
1078 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1079
1080 if (*sym_name == '!')
1081 {
1082 name2 = darwin_strip_name_encoding (sym_name);
1083 if (strcmp (name1, name2) == 0)
1084 {
1085 /* FIXME: This breaks the identifier hash table. */
1086 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1087 = (unsigned char *) name;
1088 break;
1089 }
1090 }
1091 }
1092 }
1093
1094 void
1095 machopic_select_section (exp, reloc, align)
1096 tree exp;
1097 int reloc;
1098 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1099 {
1100 if (TREE_CODE (exp) == STRING_CST)
1101 {
1102 if (flag_writable_strings)
1103 data_section ();
1104 else if ((size_t) TREE_STRING_LENGTH (exp) !=
1105 strlen (TREE_STRING_POINTER (exp)) + 1)
1106 readonly_data_section ();
1107 else
1108 cstring_section ();
1109 }
1110 else if (TREE_CODE (exp) == INTEGER_CST
1111 || TREE_CODE (exp) == REAL_CST)
1112 {
1113 tree size = TYPE_SIZE (TREE_TYPE (exp));
1114
1115 if (TREE_CODE (size) == INTEGER_CST &&
1116 TREE_INT_CST_LOW (size) == 4 &&
1117 TREE_INT_CST_HIGH (size) == 0)
1118 literal4_section ();
1119 else if (TREE_CODE (size) == INTEGER_CST &&
1120 TREE_INT_CST_LOW (size) == 8 &&
1121 TREE_INT_CST_HIGH (size) == 0)
1122 literal8_section ();
1123 else
1124 readonly_data_section ();
1125 }
1126 else if (TREE_CODE (exp) == CONSTRUCTOR
1127 && TREE_TYPE (exp)
1128 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1129 && TYPE_NAME (TREE_TYPE (exp)))
1130 {
1131 tree name = TYPE_NAME (TREE_TYPE (exp));
1132 if (TREE_CODE (name) == TYPE_DECL)
1133 name = DECL_NAME (name);
1134 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1135 objc_constant_string_object_section ();
1136 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1137 objc_string_object_section ();
1138 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1139 {
1140 if (TREE_SIDE_EFFECTS (exp) || (flag_pic && reloc))
1141 const_data_section ();
1142 else
1143 readonly_data_section ();
1144 }
1145 else
1146 data_section ();
1147 }
1148 else if (TREE_CODE (exp) == VAR_DECL &&
1149 DECL_NAME (exp) &&
1150 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1151 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1152 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1153 {
1154 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1155
1156 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1157 objc_cls_meth_section ();
1158 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1159 objc_inst_meth_section ();
1160 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1161 objc_cat_cls_meth_section ();
1162 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1163 objc_cat_inst_meth_section ();
1164 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1165 objc_class_vars_section ();
1166 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1167 objc_instance_vars_section ();
1168 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1169 objc_cat_cls_meth_section ();
1170 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1171 objc_class_names_section ();
1172 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1173 objc_meth_var_names_section ();
1174 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1175 objc_meth_var_types_section ();
1176 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1177 objc_cls_refs_section ();
1178 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1179 objc_class_section ();
1180 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1181 objc_meta_class_section ();
1182 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1183 objc_category_section ();
1184 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1185 objc_selector_refs_section ();
1186 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1187 objc_selector_fixup_section ();
1188 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1189 objc_symbols_section ();
1190 else if (!strncmp (name, "_OBJC_MODULES", 13))
1191 objc_module_info_section ();
1192 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1193 objc_cat_inst_meth_section ();
1194 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1195 objc_cat_cls_meth_section ();
1196 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1197 objc_cat_cls_meth_section ();
1198 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1199 objc_protocol_section ();
1200 else if ((TREE_READONLY (exp) || TREE_CONSTANT (exp))
1201 && !TREE_SIDE_EFFECTS (exp))
1202 {
1203 if (flag_pic && reloc)
1204 const_data_section ();
1205 else
1206 readonly_data_section ();
1207 }
1208 else
1209 data_section ();
1210 }
1211 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1212 {
1213 if (TREE_SIDE_EFFECTS (exp) || (flag_pic && reloc))
1214 const_data_section ();
1215 else
1216 readonly_data_section ();
1217 }
1218 else
1219 data_section ();
1220 }
1221
1222 /* This can be called with address expressions as "rtx".
1223 They must go in "const". */
1224
1225 void
1226 machopic_select_rtx_section (mode, x, align)
1227 enum machine_mode mode;
1228 rtx x;
1229 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1230 {
1231 if (GET_MODE_SIZE (mode) == 8)
1232 literal8_section ();
1233 else if (GET_MODE_SIZE (mode) == 4
1234 && (GET_CODE (x) == CONST_INT
1235 || GET_CODE (x) == CONST_DOUBLE))
1236 literal4_section ();
1237 else
1238 const_section ();
1239 }
1240
1241 void
1242 machopic_asm_out_constructor (symbol, priority)
1243 rtx symbol;
1244 int priority ATTRIBUTE_UNUSED;
1245 {
1246 if (flag_pic)
1247 mod_init_section ();
1248 else
1249 constructor_section ();
1250 assemble_align (POINTER_SIZE);
1251 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1252
1253 if (!flag_pic)
1254 fprintf (asm_out_file, ".reference .constructors_used\n");
1255 }
1256
1257 void
1258 machopic_asm_out_destructor (symbol, priority)
1259 rtx symbol;
1260 int priority ATTRIBUTE_UNUSED;
1261 {
1262 if (flag_pic)
1263 mod_term_section ();
1264 else
1265 destructor_section ();
1266 assemble_align (POINTER_SIZE);
1267 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1268
1269 if (!flag_pic)
1270 fprintf (asm_out_file, ".reference .destructors_used\n");
1271 }
1272
1273 void
1274 darwin_globalize_label (stream, name)
1275 FILE *stream;
1276 const char *name;
1277 {
1278 if (!!strncmp (name, "_OBJC_", 6))
1279 default_globalize_label (stream, name);
1280 }
1281
1282 /* Output a difference of two labels that will be an assembly time
1283 constant if the two labels are local. (.long lab1-lab2 will be
1284 very different if lab1 is at the boundary between two sections; it
1285 will be relocated according to the second section, not the first,
1286 so one ends up with a difference between labels in different
1287 sections, which is bad in the dwarf2 eh context for instance.) */
1288
1289 static int darwin_dwarf_label_counter;
1290
1291 void
1292 darwin_asm_output_dwarf_delta (file, size, lab1, lab2)
1293 FILE *file;
1294 int size ATTRIBUTE_UNUSED;
1295 const char *lab1, *lab2;
1296 {
1297 const char *p = lab1 + (lab1[0] == '*');
1298 int islocaldiff = (p[0] == 'L');
1299
1300 if (islocaldiff)
1301 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1302 else
1303 fprintf (file, "\t%s\t", ".long");
1304 assemble_name (file, lab1);
1305 fprintf (file, "-");
1306 assemble_name (file, lab2);
1307 if (islocaldiff)
1308 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1309 }
1310
1311 #include "gt-darwin.h"
1312