darwin.c (machopic_select_rtx_section): Use const_data_section for things that might...
[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 (const char *);
46 static void update_non_lazy_ptrs (const char *);
47 static void update_stubs (const char *);
48
49 int
50 name_needs_quotes (const char *name)
51 {
52 int c;
53 while ((c = *name++) != '\0')
54 if (! ISIDNUM (c))
55 return 1;
56 return 0;
57 }
58
59 /*
60 * flag_pic = 1 ... generate only indirections
61 * flag_pic = 2 ... generate indirections and pure code
62 */
63
64 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
65 reference, which will not be changed. */
66
67 static GTY(()) tree machopic_defined_list;
68
69 enum machopic_addr_class
70 machopic_classify_ident (tree ident)
71 {
72 const char *name = IDENTIFIER_POINTER (ident);
73 int lprefix = (((name[0] == '*' || name[0] == '&')
74 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
75 || ( name[0] == '_'
76 && name[1] == 'O'
77 && name[2] == 'B'
78 && name[3] == 'J'
79 && name[4] == 'C'
80 && name[5] == '_'));
81 tree temp;
82
83 /* The PIC base symbol is always defined. */
84 if (! strcmp (name, "<pic base>"))
85 return MACHOPIC_DEFINED_DATA;
86
87 if (name[0] != '!')
88 {
89 /* Here if no special encoding to be found. */
90 if (lprefix)
91 {
92 const char *name = IDENTIFIER_POINTER (ident);
93 int len = strlen (name);
94
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;
99 }
100
101 for (temp = machopic_defined_list;
102 temp != NULL_TREE;
103 temp = TREE_CHAIN (temp))
104 {
105 if (ident == TREE_VALUE (temp))
106 return MACHOPIC_DEFINED_DATA;
107 }
108
109 if (TREE_ASM_WRITTEN (ident))
110 return MACHOPIC_DEFINED_DATA;
111
112 return MACHOPIC_UNDEFINED;
113 }
114
115 else if (name[1] == 'D')
116 return MACHOPIC_DEFINED_DATA;
117
118 else if (name[1] == 'T')
119 return MACHOPIC_DEFINED_FUNCTION;
120
121 /* It is possible that someone is holding a "stale" name, which has
122 since been defined. See if there is a "defined" name (i.e,
123 different from NAME only in having a '!D_' or a '!T_' instead of
124 a '!d_' or '!t_' prefix) in the identifier hash tables. If so, say
125 that this identifier is defined. */
126 else if (name[1] == 'd' || name[1] == 't')
127 {
128 char *new_name;
129 new_name = (char *)alloca (strlen (name) + 1);
130 strcpy (new_name, name);
131 new_name[1] = (name[1] == 'd') ? 'D' : 'T';
132 if (maybe_get_identifier (new_name) != NULL)
133 return (name[1] == 'd') ? MACHOPIC_DEFINED_DATA
134 : MACHOPIC_DEFINED_FUNCTION;
135 }
136
137 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
138 {
139 if (ident == TREE_VALUE (temp))
140 {
141 if (name[1] == 'T')
142 return MACHOPIC_DEFINED_FUNCTION;
143 else
144 return MACHOPIC_DEFINED_DATA;
145 }
146 }
147
148 if (name[1] == 't' || name[1] == 'T')
149 {
150 if (lprefix)
151 return MACHOPIC_DEFINED_FUNCTION;
152 else
153 return MACHOPIC_UNDEFINED_FUNCTION;
154 }
155 else
156 {
157 if (lprefix)
158 return MACHOPIC_DEFINED_DATA;
159 else
160 return MACHOPIC_UNDEFINED_DATA;
161 }
162 }
163
164
165 enum machopic_addr_class
166 machopic_classify_name (const char *name)
167 {
168 return machopic_classify_ident (get_identifier (name));
169 }
170
171 int
172 machopic_ident_defined_p (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 (const char *name)
187 {
188 switch (machopic_classify_ident (get_identifier (name)))
189 {
190 case MACHOPIC_DEFINED_DATA:
191 return 1;
192 default:
193 return 0;
194 }
195 }
196
197 int
198 machopic_name_defined_p (const char *name)
199 {
200 return machopic_ident_defined_p (get_identifier (name));
201 }
202
203 void
204 machopic_define_ident (tree ident)
205 {
206 if (!machopic_ident_defined_p (ident))
207 machopic_defined_list =
208 tree_cons (NULL_TREE, ident, machopic_defined_list);
209 }
210
211 void
212 machopic_define_name (const char *name)
213 {
214 machopic_define_ident (get_identifier (name));
215 }
216
217 static GTY(()) char * function_base;
218
219 const char *
220 machopic_function_base_name (void)
221 {
222 const char *current_name;
223 /* if dynamic-no-pic is on, we should not get here */
224 if (MACHO_DYNAMIC_NO_PIC_P)
225 abort ();
226 current_name =
227 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
228
229 if (function_base == NULL)
230 function_base =
231 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
232
233 current_function_uses_pic_offset_table = 1;
234
235 return function_base;
236 }
237
238 static GTY(()) const char * function_base_func_name;
239 static GTY(()) int current_pic_label_num;
240
241 void
242 machopic_output_function_base_name (FILE *file)
243 {
244 const char *current_name;
245
246 /* If dynamic-no-pic is on, we should not get here. */
247 if (MACHO_DYNAMIC_NO_PIC_P)
248 abort ();
249 current_name =
250 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
251 if (function_base_func_name != current_name)
252 {
253 ++current_pic_label_num;
254 function_base_func_name = current_name;
255 }
256 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
257 }
258
259 static GTY(()) tree machopic_non_lazy_pointers;
260
261 /* Return a non-lazy pointer name corresponding to the given name,
262 either by finding it in our list of pointer names, or by generating
263 a new one. */
264
265 const char *
266 machopic_non_lazy_ptr_name (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 (const char *name)
329 {
330 tree temp, ident = get_identifier (name);
331 const char *tname;
332
333 for (temp = machopic_stubs;
334 temp != NULL_TREE;
335 temp = TREE_CHAIN (temp))
336 {
337 if (ident == TREE_VALUE (temp))
338 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
339 tname = IDENTIFIER_POINTER (TREE_VALUE (temp));
340 if (strcmp (name, tname) == 0)
341 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
342 /* A library call name might not be section-encoded yet, so try
343 it against a stripped name. */
344 if (name[0] != '!'
345 && tname[0] == '!'
346 && strcmp (name, tname + 4) == 0)
347 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
348 }
349
350 name = darwin_strip_name_encoding (name);
351
352 {
353 char *buffer;
354 tree ptr_name;
355 int needs_quotes = name_needs_quotes (name);
356
357 buffer = alloca (strlen (name) + 20);
358
359 if (needs_quotes)
360 strcpy (buffer, "&\"L");
361 else
362 strcpy (buffer, "&L");
363 if (name[0] == '*')
364 {
365 strcat (buffer, name+1);
366 }
367 else
368 {
369 strcat (buffer, "_");
370 strcat (buffer, name);
371 }
372
373 if (needs_quotes)
374 strcat (buffer, "$stub\"");
375 else
376 strcat (buffer, "$stub");
377 ptr_name = get_identifier (buffer);
378
379 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
380 TREE_USED (machopic_stubs) = 0;
381
382 return IDENTIFIER_POINTER (ptr_name);
383 }
384 }
385
386 void
387 machopic_validate_stub_or_non_lazy_ptr (const char *name, int validate_stub)
388 {
389 const char *real_name;
390 tree temp, ident = get_identifier (name), id2;
391
392 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
393 temp != NULL_TREE;
394 temp = TREE_CHAIN (temp))
395 if (ident == TREE_PURPOSE (temp))
396 {
397 /* Mark both the stub or non-lazy pointer as well as the
398 original symbol as being referenced. */
399 TREE_USED (temp) = 1;
400 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
401 TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
402 real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
403 real_name = darwin_strip_name_encoding (real_name);
404 id2 = maybe_get_identifier (real_name);
405 if (id2)
406 TREE_SYMBOL_REFERENCED (id2) = 1;
407 }
408 }
409
410 /* Transform ORIG, which may be any data source, to the corresponding
411 source using indirections. */
412
413 rtx
414 machopic_indirect_data_reference (rtx orig, rtx reg)
415 {
416 rtx ptr_ref = orig;
417
418 if (! MACHOPIC_INDIRECT)
419 return orig;
420
421 if (GET_CODE (orig) == SYMBOL_REF)
422 {
423 const char *name = XSTR (orig, 0);
424
425 int defined = machopic_data_defined_p (name);
426
427 if (defined && MACHO_DYNAMIC_NO_PIC_P)
428 {
429 #if defined (TARGET_TOC)
430 emit_insn (gen_macho_high (reg, orig));
431 emit_insn (gen_macho_low (reg, reg, orig));
432 #else
433 /* some other cpu -- writeme! */
434 abort ();
435 #endif
436 return reg;
437 }
438 else if (defined)
439 {
440 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
441 rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
442 machopic_function_base_name ());
443 rtx offset = gen_rtx (CONST, Pmode,
444 gen_rtx (MINUS, Pmode, orig, pic_base));
445 #endif
446
447 #if defined (TARGET_TOC) /* i.e., PowerPC */
448 rtx hi_sum_reg = reg;
449
450 if (reg == NULL)
451 abort ();
452
453 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
454 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
455 gen_rtx (HIGH, Pmode, offset))));
456 emit_insn (gen_rtx (SET, Pmode, reg,
457 gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
458
459 orig = reg;
460 #else
461 #if defined (HAVE_lo_sum)
462 if (reg == 0) abort ();
463
464 emit_insn (gen_rtx (SET, VOIDmode, reg,
465 gen_rtx (HIGH, Pmode, offset)));
466 emit_insn (gen_rtx (SET, VOIDmode, reg,
467 gen_rtx (LO_SUM, Pmode, reg, offset)));
468 emit_insn (gen_rtx (USE, VOIDmode,
469 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
470
471 orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
472 #endif
473 #endif
474 return orig;
475 }
476
477 ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
478 machopic_non_lazy_ptr_name (name));
479
480 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
481 RTX_UNCHANGING_P (ptr_ref) = 1;
482
483 return ptr_ref;
484 }
485 else if (GET_CODE (orig) == CONST)
486 {
487 rtx base, result;
488
489 /* legitimize both operands of the PLUS */
490 if (GET_CODE (XEXP (orig, 0)) == PLUS)
491 {
492 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
493 reg);
494 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
495 (base == reg ? 0 : reg));
496 }
497 else
498 return orig;
499
500 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
501 result = plus_constant (base, INTVAL (orig));
502 else
503 result = gen_rtx (PLUS, Pmode, base, orig);
504
505 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
506 {
507 if (reg)
508 {
509 emit_move_insn (reg, result);
510 result = reg;
511 }
512 else
513 {
514 result = force_reg (GET_MODE (result), result);
515 }
516 }
517
518 return result;
519
520 }
521 else if (GET_CODE (orig) == MEM)
522 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
523 /* When the target is i386, this code prevents crashes due to the
524 compiler's ignorance on how to move the PIC base register to
525 other registers. (The reload phase sometimes introduces such
526 insns.) */
527 else if (GET_CODE (orig) == PLUS
528 && GET_CODE (XEXP (orig, 0)) == REG
529 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
530 #ifdef I386
531 /* Prevent the same register from being erroneously used
532 as both the base and index registers. */
533 && GET_CODE (XEXP (orig, 1)) == CONST
534 #endif
535 && reg)
536 {
537 emit_move_insn (reg, XEXP (orig, 0));
538 XEXP (ptr_ref, 0) = reg;
539 }
540 return ptr_ref;
541 }
542
543 /* Transform TARGET (a MEM), which is a function call target, to the
544 corresponding symbol_stub if necessary. Return a new MEM. */
545
546 rtx
547 machopic_indirect_call_target (rtx target)
548 {
549 if (GET_CODE (target) != MEM)
550 return target;
551
552 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
553 {
554 enum machine_mode mode = GET_MODE (XEXP (target, 0));
555 const char *name = XSTR (XEXP (target, 0), 0);
556
557 /* If the name is already defined, we need do nothing. */
558 if (name[0] == '!' && name[1] == 'T')
559 return target;
560
561 if (!machopic_name_defined_p (name))
562 {
563 const char *stub_name = machopic_stub_name (name);
564
565 XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
566 RTX_UNCHANGING_P (target) = 1;
567 }
568 }
569
570 return target;
571 }
572
573 rtx
574 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
575 {
576 rtx pic_ref = orig;
577
578 if (! MACHOPIC_INDIRECT)
579 return orig;
580
581 /* First handle a simple SYMBOL_REF or LABEL_REF */
582 if (GET_CODE (orig) == LABEL_REF
583 || (GET_CODE (orig) == SYMBOL_REF
584 ))
585 {
586 /* addr(foo) = &func+(foo-func) */
587 rtx pic_base;
588
589 orig = machopic_indirect_data_reference (orig, reg);
590
591 if (GET_CODE (orig) == PLUS
592 && GET_CODE (XEXP (orig, 0)) == REG)
593 {
594 if (reg == 0)
595 return force_reg (mode, orig);
596
597 emit_move_insn (reg, orig);
598 return reg;
599 }
600
601 /* if dynamic-no-pic then use 0 as the pic base */
602 if (MACHO_DYNAMIC_NO_PIC_P)
603 pic_base = CONST0_RTX (Pmode);
604 else
605 pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
606
607 if (GET_CODE (orig) == MEM)
608 {
609 if (reg == 0)
610 {
611 if (reload_in_progress)
612 abort ();
613 else
614 reg = gen_reg_rtx (Pmode);
615 }
616
617 #ifdef HAVE_lo_sum
618 if (MACHO_DYNAMIC_NO_PIC_P
619 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
620 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
621 {
622 #if defined (TARGET_TOC) /* ppc */
623 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
624 rtx asym = XEXP (orig, 0);
625 rtx mem;
626
627 emit_insn (gen_macho_high (temp_reg, asym));
628 mem = gen_rtx_MEM (GET_MODE (orig),
629 gen_rtx (LO_SUM, Pmode, temp_reg, asym));
630 RTX_UNCHANGING_P (mem) = 1;
631 emit_insn (gen_rtx (SET, VOIDmode, reg, mem));
632 #else
633 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
634 abort ();
635 #endif
636 pic_ref = reg;
637 }
638 else
639 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
640 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
641 {
642 rtx offset = gen_rtx (CONST, Pmode,
643 gen_rtx (MINUS, Pmode,
644 XEXP (orig, 0), pic_base));
645 #if defined (TARGET_TOC) /* i.e., PowerPC */
646 /* Generating a new reg may expose opportunities for
647 common subexpression elimination. */
648 rtx hi_sum_reg =
649 (reload_in_progress ? reg : gen_reg_rtx (SImode));
650
651 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
652 gen_rtx (PLUS, Pmode,
653 pic_offset_table_rtx,
654 gen_rtx (HIGH, Pmode, offset))));
655 emit_insn (gen_rtx (SET, VOIDmode, reg,
656 gen_rtx (MEM, GET_MODE (orig),
657 gen_rtx (LO_SUM, Pmode,
658 hi_sum_reg, offset))));
659 pic_ref = reg;
660
661 #else
662 emit_insn (gen_rtx (USE, VOIDmode,
663 gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
664
665 emit_insn (gen_rtx (SET, VOIDmode, reg,
666 gen_rtx (HIGH, Pmode,
667 gen_rtx (CONST, Pmode, offset))));
668 emit_insn (gen_rtx (SET, VOIDmode, reg,
669 gen_rtx (LO_SUM, Pmode, reg,
670 gen_rtx (CONST, Pmode, offset))));
671 pic_ref = gen_rtx (PLUS, Pmode,
672 pic_offset_table_rtx, reg);
673 #endif
674 }
675 else
676 #endif /* HAVE_lo_sum */
677 {
678 rtx pic = pic_offset_table_rtx;
679 if (GET_CODE (pic) != REG)
680 {
681 emit_move_insn (reg, pic);
682 pic = reg;
683 }
684 #if 0
685 emit_insn (gen_rtx (USE, VOIDmode,
686 gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
687 #endif
688
689 pic_ref = gen_rtx (PLUS, Pmode,
690 pic,
691 gen_rtx (CONST, Pmode,
692 gen_rtx (MINUS, Pmode,
693 XEXP (orig, 0),
694 pic_base)));
695 }
696
697 #if !defined (TARGET_TOC)
698 emit_move_insn (reg, pic_ref);
699 pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
700 #endif
701 RTX_UNCHANGING_P (pic_ref) = 1;
702 }
703 else
704 {
705
706 #ifdef HAVE_lo_sum
707 if (GET_CODE (orig) == SYMBOL_REF
708 || GET_CODE (orig) == LABEL_REF)
709 {
710 rtx offset = gen_rtx (CONST, Pmode,
711 gen_rtx (MINUS, Pmode, orig, pic_base));
712 #if defined (TARGET_TOC) /* i.e., PowerPC */
713 rtx hi_sum_reg;
714
715 if (reg == 0)
716 {
717 if (reload_in_progress)
718 abort ();
719 else
720 reg = gen_reg_rtx (SImode);
721 }
722
723 hi_sum_reg = reg;
724
725 emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
726 (MACHO_DYNAMIC_NO_PIC_P)
727 ? gen_rtx (HIGH, Pmode, offset)
728 : gen_rtx (PLUS, Pmode,
729 pic_offset_table_rtx,
730 gen_rtx (HIGH, Pmode, offset))));
731 emit_insn (gen_rtx (SET, VOIDmode, reg,
732 gen_rtx (LO_SUM, Pmode,
733 hi_sum_reg, offset)));
734 pic_ref = reg;
735 RTX_UNCHANGING_P (pic_ref) = 1;
736 #else
737 emit_insn (gen_rtx (SET, VOIDmode, reg,
738 gen_rtx (HIGH, Pmode, offset)));
739 emit_insn (gen_rtx (SET, VOIDmode, reg,
740 gen_rtx (LO_SUM, Pmode, reg, offset)));
741 pic_ref = gen_rtx (PLUS, Pmode,
742 pic_offset_table_rtx, reg);
743 RTX_UNCHANGING_P (pic_ref) = 1;
744 #endif
745 }
746 else
747 #endif /* HAVE_lo_sum */
748 {
749 if (GET_CODE (orig) == REG)
750 {
751 return orig;
752 }
753 else
754 {
755 rtx pic = pic_offset_table_rtx;
756 if (GET_CODE (pic) != REG)
757 {
758 emit_move_insn (reg, pic);
759 pic = reg;
760 }
761 #if 0
762 emit_insn (gen_rtx (USE, VOIDmode,
763 pic_offset_table_rtx));
764 #endif
765 pic_ref = gen_rtx (PLUS, Pmode,
766 pic,
767 gen_rtx (CONST, Pmode,
768 gen_rtx (MINUS, Pmode,
769 orig, pic_base)));
770 }
771 }
772 }
773
774 if (GET_CODE (pic_ref) != REG)
775 {
776 if (reg != 0)
777 {
778 emit_move_insn (reg, pic_ref);
779 return reg;
780 }
781 else
782 {
783 return force_reg (mode, pic_ref);
784 }
785 }
786 else
787 {
788 return pic_ref;
789 }
790 }
791
792 else if (GET_CODE (orig) == SYMBOL_REF)
793 return orig;
794
795 else if (GET_CODE (orig) == PLUS
796 && (GET_CODE (XEXP (orig, 0)) == MEM
797 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
798 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
799 && XEXP (orig, 0) != pic_offset_table_rtx
800 && GET_CODE (XEXP (orig, 1)) != REG)
801
802 {
803 rtx base;
804 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
805
806 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
807 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
808 Pmode, (base == reg ? 0 : reg));
809 if (GET_CODE (orig) == CONST_INT)
810 {
811 pic_ref = plus_constant (base, INTVAL (orig));
812 is_complex = 1;
813 }
814 else
815 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
816
817 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
818 RTX_UNCHANGING_P (pic_ref) = 1;
819
820 if (reg && is_complex)
821 {
822 emit_move_insn (reg, pic_ref);
823 pic_ref = reg;
824 }
825 /* Likewise, should we set special REG_NOTEs here? */
826 }
827
828 else if (GET_CODE (orig) == CONST)
829 {
830 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
831 }
832
833 else if (GET_CODE (orig) == MEM
834 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
835 {
836 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
837
838 addr = gen_rtx (MEM, GET_MODE (orig), addr);
839 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
840 emit_move_insn (reg, addr);
841 pic_ref = reg;
842 }
843
844 return pic_ref;
845 }
846
847
848 void
849 machopic_finish (FILE *asm_out_file)
850 {
851 tree temp;
852
853 for (temp = machopic_stubs;
854 temp != NULL_TREE;
855 temp = TREE_CHAIN (temp))
856 {
857 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
858 const char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
859 char *sym;
860 char *stub;
861
862 if (! TREE_USED (temp))
863 continue;
864
865 /* If the symbol is actually defined, we don't need a stub. */
866 if (sym_name[0] == '!' && sym_name[1] == 'T')
867 continue;
868
869 sym_name = darwin_strip_name_encoding (sym_name);
870
871 sym = alloca (strlen (sym_name) + 2);
872 if (sym_name[0] == '*' || sym_name[0] == '&')
873 strcpy (sym, sym_name + 1);
874 else if (sym_name[0] == '-' || sym_name[0] == '+')
875 strcpy (sym, sym_name);
876 else
877 sym[0] = '_', strcpy (sym + 1, sym_name);
878
879 stub = alloca (strlen (stub_name) + 2);
880 if (stub_name[0] == '*' || stub_name[0] == '&')
881 strcpy (stub, stub_name + 1);
882 else
883 stub[0] = '_', strcpy (stub + 1, stub_name);
884
885 machopic_output_stub (asm_out_file, sym, stub);
886 }
887
888 for (temp = machopic_non_lazy_pointers;
889 temp != NULL_TREE;
890 temp = TREE_CHAIN (temp))
891 {
892 const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
893 const char *const lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
894
895 if (! TREE_USED (temp))
896 continue;
897
898 if (machopic_ident_defined_p (TREE_VALUE (temp)))
899 {
900 data_section ();
901 assemble_align (GET_MODE_ALIGNMENT (Pmode));
902 assemble_label (lazy_name);
903 assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
904 GET_MODE_SIZE (Pmode),
905 GET_MODE_ALIGNMENT (Pmode), 1);
906 }
907 else
908 {
909 machopic_nl_symbol_ptr_section ();
910 assemble_name (asm_out_file, lazy_name);
911 fprintf (asm_out_file, ":\n");
912
913 fprintf (asm_out_file, "\t.indirect_symbol ");
914 assemble_name (asm_out_file, sym_name);
915 fprintf (asm_out_file, "\n");
916
917 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
918 GET_MODE_ALIGNMENT (Pmode), 1);
919 }
920 }
921 }
922
923 int
924 machopic_operand_p (rtx op)
925 {
926 if (MACHOPIC_JUST_INDIRECT)
927 {
928 while (GET_CODE (op) == CONST)
929 op = XEXP (op, 0);
930
931 if (GET_CODE (op) == SYMBOL_REF)
932 return machopic_name_defined_p (XSTR (op, 0));
933 else
934 return 0;
935 }
936
937 while (GET_CODE (op) == CONST)
938 op = XEXP (op, 0);
939
940 if (GET_CODE (op) == MINUS
941 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
942 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
943 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
944 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
945 return 1;
946
947 return 0;
948 }
949
950 /* This function records whether a given name corresponds to a defined
951 or undefined function or variable, for machopic_classify_ident to
952 use later. */
953
954 void
955 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
956 {
957 char code = '\0';
958 int defined = 0;
959 rtx sym_ref;
960 const char *orig_str;
961 char *new_str;
962 size_t len, new_len;
963
964 /* Do the standard encoding things first. */
965 default_encode_section_info (decl, rtl, first);
966
967 /* With the introduction of symbol_ref flags, some of the following
968 code has become redundant and should be removed at some point. */
969
970 if ((TREE_CODE (decl) == FUNCTION_DECL
971 || TREE_CODE (decl) == VAR_DECL)
972 && !DECL_EXTERNAL (decl)
973 && ((TREE_STATIC (decl)
974 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
975 || (DECL_INITIAL (decl)
976 && DECL_INITIAL (decl) != error_mark_node)))
977 defined = 1;
978
979 if (TREE_CODE (decl) == FUNCTION_DECL)
980 code = (defined ? 'T' : 't');
981 else if (TREE_CODE (decl) == VAR_DECL)
982 code = (defined ? 'D' : 'd');
983
984 if (code == '\0')
985 return;
986
987 sym_ref = XEXP (rtl, 0);
988 orig_str = XSTR (sym_ref, 0);
989 len = strlen (orig_str) + 1;
990
991 if (orig_str[0] == '!')
992 {
993 /* Already encoded; see if we need to change it. */
994 if (code == orig_str[1])
995 return;
996 /* Yes, tweak a copy of the name and put it in a new string. */
997 new_str = alloca (len);
998 memcpy (new_str, orig_str, len);
999 new_str[1] = code;
1000 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
1001 }
1002 else
1003 {
1004 /* Add the encoding. */
1005 new_len = len + 4;
1006 new_str = alloca (new_len);
1007 new_str[0] = '!';
1008 new_str[1] = code;
1009 new_str[2] = '_';
1010 new_str[3] = '_';
1011 memcpy (new_str + 4, orig_str, len);
1012 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
1013 }
1014 /* The non-lazy pointer list may have captured references to the
1015 old encoded name, change them. */
1016 if (TREE_CODE (decl) == VAR_DECL)
1017 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1018 else
1019 update_stubs (XSTR (sym_ref, 0));
1020 }
1021
1022 /* Undo the effects of the above. */
1023
1024 const char *
1025 darwin_strip_name_encoding (const char *str)
1026 {
1027 return str[0] == '!' ? str + 4 : str;
1028 }
1029
1030 /* Scan the list of non-lazy pointers and update any recorded names whose
1031 stripped name matches the argument. */
1032
1033 static void
1034 update_non_lazy_ptrs (const char *name)
1035 {
1036 const char *name1, *name2;
1037 tree temp;
1038
1039 name1 = darwin_strip_name_encoding (name);
1040
1041 for (temp = machopic_non_lazy_pointers;
1042 temp != NULL_TREE;
1043 temp = TREE_CHAIN (temp))
1044 {
1045 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1046
1047 if (*sym_name == '!')
1048 {
1049 name2 = darwin_strip_name_encoding (sym_name);
1050 if (strcmp (name1, name2) == 0)
1051 {
1052 /* FIXME: This breaks the identifier hash table. */
1053 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1054 = (unsigned char *) name;
1055 break;
1056 }
1057 }
1058 }
1059 }
1060
1061 /* Function NAME is being defined, and its label has just been output.
1062 If there's already a reference to a stub for this function, we can
1063 just emit the stub label now and we don't bother emitting the stub later. */
1064
1065 void
1066 machopic_output_possible_stub_label (FILE *file, const char *name)
1067 {
1068 tree temp;
1069
1070
1071 /* Ensure we're looking at a section-encoded name. */
1072 if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
1073 return;
1074
1075 for (temp = machopic_stubs;
1076 temp != NULL_TREE;
1077 temp = TREE_CHAIN (temp))
1078 {
1079 const char *sym_name;
1080
1081 sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1082 if (sym_name[0] == '!' && sym_name[1] == 'T'
1083 && ! strcmp (name+2, sym_name+2))
1084 {
1085 ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
1086 /* Avoid generating a stub for this. */
1087 TREE_USED (temp) = 0;
1088 break;
1089 }
1090 }
1091 }
1092
1093 /* Scan the list of stubs and update any recorded names whose
1094 stripped name matches the argument. */
1095
1096 static void
1097 update_stubs (const char *name)
1098 {
1099 const char *name1, *name2;
1100 tree temp;
1101
1102 name1 = darwin_strip_name_encoding (name);
1103
1104 for (temp = machopic_stubs;
1105 temp != NULL_TREE;
1106 temp = TREE_CHAIN (temp))
1107 {
1108 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1109
1110 if (*sym_name == '!')
1111 {
1112 name2 = darwin_strip_name_encoding (sym_name);
1113 if (strcmp (name1, name2) == 0)
1114 {
1115 /* FIXME: This breaks the identifier hash table. */
1116 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1117 = (unsigned char *) name;
1118 break;
1119 }
1120 }
1121 }
1122 }
1123
1124 void
1125 machopic_select_section (tree exp, int reloc,
1126 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1127 {
1128 void (*base_function)(void);
1129
1130 if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1131 base_function = readonly_data_section;
1132 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1133 base_function = const_data_section;
1134 else
1135 base_function = data_section;
1136
1137 if (TREE_CODE (exp) == STRING_CST
1138 && ((size_t) TREE_STRING_LENGTH (exp)
1139 == strlen (TREE_STRING_POINTER (exp)) + 1)
1140 && ! flag_writable_strings)
1141 cstring_section ();
1142 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1143 && flag_merge_constants)
1144 {
1145 tree size = TYPE_SIZE (TREE_TYPE (exp));
1146
1147 if (TREE_CODE (size) == INTEGER_CST &&
1148 TREE_INT_CST_LOW (size) == 4 &&
1149 TREE_INT_CST_HIGH (size) == 0)
1150 literal4_section ();
1151 else if (TREE_CODE (size) == INTEGER_CST &&
1152 TREE_INT_CST_LOW (size) == 8 &&
1153 TREE_INT_CST_HIGH (size) == 0)
1154 literal8_section ();
1155 else
1156 base_function ();
1157 }
1158 else if (TREE_CODE (exp) == CONSTRUCTOR
1159 && TREE_TYPE (exp)
1160 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1161 && TYPE_NAME (TREE_TYPE (exp)))
1162 {
1163 tree name = TYPE_NAME (TREE_TYPE (exp));
1164 if (TREE_CODE (name) == TYPE_DECL)
1165 name = DECL_NAME (name);
1166 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1167 objc_constant_string_object_section ();
1168 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1169 objc_string_object_section ();
1170 else
1171 base_function ();
1172 }
1173 else if (TREE_CODE (exp) == VAR_DECL &&
1174 DECL_NAME (exp) &&
1175 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1176 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1177 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1178 {
1179 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1180
1181 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1182 objc_cls_meth_section ();
1183 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1184 objc_inst_meth_section ();
1185 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1186 objc_cat_cls_meth_section ();
1187 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1188 objc_cat_inst_meth_section ();
1189 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1190 objc_class_vars_section ();
1191 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1192 objc_instance_vars_section ();
1193 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1194 objc_cat_cls_meth_section ();
1195 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1196 objc_class_names_section ();
1197 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1198 objc_meth_var_names_section ();
1199 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1200 objc_meth_var_types_section ();
1201 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1202 objc_cls_refs_section ();
1203 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1204 objc_class_section ();
1205 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1206 objc_meta_class_section ();
1207 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1208 objc_category_section ();
1209 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1210 objc_selector_refs_section ();
1211 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1212 objc_selector_fixup_section ();
1213 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1214 objc_symbols_section ();
1215 else if (!strncmp (name, "_OBJC_MODULES", 13))
1216 objc_module_info_section ();
1217 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1218 objc_cat_inst_meth_section ();
1219 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1220 objc_cat_cls_meth_section ();
1221 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1222 objc_cat_cls_meth_section ();
1223 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1224 objc_protocol_section ();
1225 else
1226 base_function ();
1227 }
1228 else
1229 base_function ();
1230 }
1231
1232 /* This can be called with address expressions as "rtx".
1233 They must go in "const". */
1234
1235 void
1236 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1237 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1238 {
1239 if (GET_MODE_SIZE (mode) == 8)
1240 literal8_section ();
1241 else if (GET_MODE_SIZE (mode) == 4
1242 && (GET_CODE (x) == CONST_INT
1243 || GET_CODE (x) == CONST_DOUBLE))
1244 literal4_section ();
1245 else if (! MACHO_DYNAMIC_NO_PIC_P
1246 && (GET_CODE (x) == SYMBOL_REF
1247 || GET_CODE (x) == CONST
1248 || GET_CODE (x) == LABEL_REF))
1249 const_data_section ();
1250 else
1251 const_section ();
1252 }
1253
1254 void
1255 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1256 {
1257
1258 if (MACHOPIC_INDIRECT)
1259 mod_init_section ();
1260 else
1261 constructor_section ();
1262 assemble_align (POINTER_SIZE);
1263 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1264
1265
1266 if (! MACHOPIC_INDIRECT)
1267 fprintf (asm_out_file, ".reference .constructors_used\n");
1268 }
1269
1270 void
1271 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1272 {
1273
1274 if (MACHOPIC_INDIRECT)
1275 mod_term_section ();
1276 else
1277 destructor_section ();
1278 assemble_align (POINTER_SIZE);
1279 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1280
1281 if (! MACHOPIC_INDIRECT)
1282 fprintf (asm_out_file, ".reference .destructors_used\n");
1283 }
1284
1285 void
1286 darwin_globalize_label (FILE *stream, const char *name)
1287 {
1288 if (!!strncmp (name, "_OBJC_", 6))
1289 default_globalize_label (stream, name);
1290 }
1291
1292 /* Output a difference of two labels that will be an assembly time
1293 constant if the two labels are local. (.long lab1-lab2 will be
1294 very different if lab1 is at the boundary between two sections; it
1295 will be relocated according to the second section, not the first,
1296 so one ends up with a difference between labels in different
1297 sections, which is bad in the dwarf2 eh context for instance.) */
1298
1299 static int darwin_dwarf_label_counter;
1300
1301 void
1302 darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
1303 const char *lab1, const char *lab2)
1304 {
1305 const char *p = lab1 + (lab1[0] == '*');
1306 int islocaldiff = (p[0] == 'L');
1307
1308 if (islocaldiff)
1309 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1310 else
1311 fprintf (file, "\t%s\t", ".long");
1312 assemble_name (file, lab1);
1313 fprintf (file, "-");
1314 assemble_name (file, lab2);
1315 if (islocaldiff)
1316 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1317 }
1318
1319 void
1320 darwin_file_end (void)
1321 {
1322 machopic_finish (asm_out_file);
1323 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1324 {
1325 constructor_section ();
1326 destructor_section ();
1327 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1328 }
1329 }
1330
1331 #include "gt-darwin.h"