* config/xtensa/xtensa.c (call_insn_operand): Check
[official-gcc.git] / gcc / config / darwin.c
bloba626045a9fcf2f5a335ddb2f8e3e4037da4d286d
1 /* Functions for generic Darwin as target machine for GNU C compiler.
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Apple Computer Inc.
6 This file is part of GCC.
8 GCC 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 GCC 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 GCC; 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 "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 #include "errors.h"
46 static int machopic_data_defined_p (const char *);
47 static void update_non_lazy_ptrs (const char *);
48 static void update_stubs (const char *);
49 static const char *machopic_non_lazy_ptr_name (const char*);
51 int
52 name_needs_quotes (const char *name)
54 int c;
55 while ((c = *name++) != '\0')
56 if (! ISIDNUM (c) && c != '.' && c != '$')
57 return 1;
58 return 0;
62 * flag_pic = 1 ... generate only indirections
63 * flag_pic = 2 ... generate indirections and pure code
66 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
67 reference, which will not be changed. */
69 static GTY(()) tree machopic_defined_list;
71 enum machopic_addr_class
72 machopic_classify_ident (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 /* The PIC base symbol is always defined. */
86 if (! strcmp (name, "<pic base>"))
87 return MACHOPIC_DEFINED_DATA;
89 if (name[0] != '!')
91 /* Here if no special encoding to be found. */
92 if (lprefix)
94 const char *name = IDENTIFIER_POINTER (ident);
95 int len = strlen (name);
97 if ((len > 5 && !strcmp (name + len - 5, "$stub"))
98 || (len > 6 && !strcmp (name + len - 6, "$stub\"")))
99 return MACHOPIC_DEFINED_FUNCTION;
100 return MACHOPIC_DEFINED_DATA;
103 for (temp = machopic_defined_list;
104 temp != NULL_TREE;
105 temp = TREE_CHAIN (temp))
107 if (ident == TREE_VALUE (temp))
108 return MACHOPIC_DEFINED_DATA;
111 if (TREE_ASM_WRITTEN (ident))
112 return MACHOPIC_DEFINED_DATA;
114 return MACHOPIC_UNDEFINED;
117 else if (name[1] == 'D')
118 return MACHOPIC_DEFINED_DATA;
120 else if (name[1] == 'T')
121 return MACHOPIC_DEFINED_FUNCTION;
123 /* It is possible that someone is holding a "stale" name, which has
124 since been defined. See if there is a "defined" name (i.e,
125 different from NAME only in having a '!D_' or a '!T_' instead of
126 a '!d_' or '!t_' prefix) in the identifier hash tables. If so, say
127 that this identifier is defined. */
128 else if (name[1] == 'd' || name[1] == 't')
130 char *new_name;
131 new_name = (char *)alloca (strlen (name) + 1);
132 strcpy (new_name, name);
133 new_name[1] = (name[1] == 'd') ? 'D' : 'T';
134 if (maybe_get_identifier (new_name) != NULL)
135 return (name[1] == 'd') ? MACHOPIC_DEFINED_DATA
136 : MACHOPIC_DEFINED_FUNCTION;
139 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
141 if (ident == TREE_VALUE (temp))
143 if (name[1] == 'T')
144 return MACHOPIC_DEFINED_FUNCTION;
145 else
146 return MACHOPIC_DEFINED_DATA;
150 if (name[1] == 't' || name[1] == 'T')
152 if (lprefix)
153 return MACHOPIC_DEFINED_FUNCTION;
154 else
155 return MACHOPIC_UNDEFINED_FUNCTION;
157 else
159 if (lprefix)
160 return MACHOPIC_DEFINED_DATA;
161 else
162 return MACHOPIC_UNDEFINED_DATA;
167 enum machopic_addr_class
168 machopic_classify_name (const char *name)
170 return machopic_classify_ident (get_identifier (name));
174 machopic_ident_defined_p (tree ident)
176 switch (machopic_classify_ident (ident))
178 case MACHOPIC_UNDEFINED:
179 case MACHOPIC_UNDEFINED_DATA:
180 case MACHOPIC_UNDEFINED_FUNCTION:
181 return 0;
182 default:
183 return 1;
187 static int
188 machopic_data_defined_p (const char *name)
190 switch (machopic_classify_ident (get_identifier (name)))
192 case MACHOPIC_DEFINED_DATA:
193 return 1;
194 default:
195 return 0;
200 machopic_name_defined_p (const char *name)
202 return machopic_ident_defined_p (get_identifier (name));
205 void
206 machopic_define_ident (tree ident)
208 if (!machopic_ident_defined_p (ident))
209 machopic_defined_list =
210 tree_cons (NULL_TREE, ident, machopic_defined_list);
213 void
214 machopic_define_name (const char *name)
216 machopic_define_ident (get_identifier (name));
219 static GTY(()) char * function_base;
221 const char *
222 machopic_function_base_name (void)
224 /* if dynamic-no-pic is on, we should not get here */
225 if (MACHO_DYNAMIC_NO_PIC_P)
226 abort ();
228 if (function_base == NULL)
229 function_base =
230 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
232 current_function_uses_pic_offset_table = 1;
234 return function_base;
237 static GTY(()) const char * function_base_func_name;
238 static GTY(()) int current_pic_label_num;
240 void
241 machopic_output_function_base_name (FILE *file)
243 const char *current_name;
245 /* If dynamic-no-pic is on, we should not get here. */
246 if (MACHO_DYNAMIC_NO_PIC_P)
247 abort ();
248 current_name =
249 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
250 if (function_base_func_name != current_name)
252 ++current_pic_label_num;
253 function_base_func_name = current_name;
255 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
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 static const char *
265 machopic_non_lazy_ptr_name (const char *name)
267 const char *temp_name;
268 tree temp, ident = get_identifier (name);
270 for (temp = machopic_non_lazy_pointers;
271 temp != NULL_TREE;
272 temp = TREE_CHAIN (temp))
274 if (ident == TREE_VALUE (temp))
275 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
278 name = darwin_strip_name_encoding (name);
280 /* Try again, but comparing names this time. */
281 for (temp = machopic_non_lazy_pointers;
282 temp != NULL_TREE;
283 temp = TREE_CHAIN (temp))
285 if (TREE_VALUE (temp))
287 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
288 temp_name = darwin_strip_name_encoding (temp_name);
289 if (strcmp (name, temp_name) == 0)
290 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
295 char *buffer;
296 int namelen = strlen (name);
297 int bufferlen = 0;
298 tree ptr_name;
300 buffer = alloca (namelen + strlen("$non_lazy_ptr") + 5);
302 strcpy (buffer, "&L");
303 bufferlen = 2;
304 if (name[0] == '*')
306 memcpy (buffer + bufferlen, name+1, namelen-1+1);
307 bufferlen += namelen-1;
309 else
311 buffer[bufferlen] = '_';
312 memcpy (buffer + bufferlen +1, name, namelen+1);
313 bufferlen += namelen +1;
316 memcpy (buffer + bufferlen, "$non_lazy_ptr", strlen("$non_lazy_ptr")+1);
317 bufferlen += strlen("$non_lazy_ptr");
318 ptr_name = get_identifier (buffer);
320 machopic_non_lazy_pointers
321 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
323 TREE_USED (machopic_non_lazy_pointers) = 0;
325 return IDENTIFIER_POINTER (ptr_name);
329 static GTY(()) tree machopic_stubs;
331 /* Return the name of the stub corresponding to the given name,
332 generating a new stub name if necessary. */
334 const char *
335 machopic_stub_name (const char *name)
337 tree temp, ident = get_identifier (name);
338 const char *tname;
340 for (temp = machopic_stubs;
341 temp != NULL_TREE;
342 temp = TREE_CHAIN (temp))
344 if (ident == TREE_VALUE (temp))
345 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
346 tname = IDENTIFIER_POINTER (TREE_VALUE (temp));
347 if (strcmp (name, tname) == 0)
348 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
349 /* A library call name might not be section-encoded yet, so try
350 it against a stripped name. */
351 if (name[0] != '!'
352 && tname[0] == '!'
353 && strcmp (name, tname + 4) == 0)
354 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
357 name = darwin_strip_name_encoding (name);
360 char *buffer;
361 int bufferlen = 0;
362 int namelen = strlen (name);
363 tree ptr_name;
364 int needs_quotes = name_needs_quotes (name);
366 buffer = alloca (namelen + 20);
368 if (needs_quotes)
370 strcpy (buffer, "&\"L");
371 bufferlen = strlen("&\"L");
373 else
375 strcpy (buffer, "&L");
376 bufferlen = strlen("&L");
379 if (name[0] == '*')
381 memcpy (buffer + bufferlen, name+1, namelen - 1 +1);
382 bufferlen += namelen - 1;
384 else
386 buffer[bufferlen] = '_';
387 memcpy (buffer + bufferlen +1, name, namelen+1);
388 bufferlen += namelen +1;
391 if (needs_quotes)
393 memcpy (buffer + bufferlen, "$stub\"", strlen("$stub\"")+1);
394 bufferlen += strlen("$stub\"");
396 else
398 memcpy (buffer + bufferlen, "$stub", strlen("$stub")+1);
399 bufferlen += strlen("$stub");
401 ptr_name = get_identifier (buffer);
403 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
404 TREE_USED (machopic_stubs) = 0;
406 return IDENTIFIER_POINTER (ptr_name);
410 void
411 machopic_validate_stub_or_non_lazy_ptr (const char *name, int validate_stub)
413 const char *real_name;
414 tree temp, ident = get_identifier (name), id2;
416 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
417 temp != NULL_TREE;
418 temp = TREE_CHAIN (temp))
419 if (ident == TREE_PURPOSE (temp))
421 /* Mark both the stub or non-lazy pointer as well as the
422 original symbol as being referenced. */
423 TREE_USED (temp) = 1;
424 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
425 mark_referenced (TREE_VALUE (temp));
426 real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
427 real_name = darwin_strip_name_encoding (real_name);
428 id2 = maybe_get_identifier (real_name);
429 if (id2)
430 mark_referenced (id2);
434 /* Transform ORIG, which may be any data source, to the corresponding
435 source using indirections. */
438 machopic_indirect_data_reference (rtx orig, rtx reg)
440 rtx ptr_ref = orig;
442 if (! MACHOPIC_INDIRECT)
443 return orig;
445 if (GET_CODE (orig) == SYMBOL_REF)
447 const char *name = XSTR (orig, 0);
448 int defined = machopic_data_defined_p (name);
450 if (defined && MACHO_DYNAMIC_NO_PIC_P)
452 #if defined (TARGET_TOC)
453 emit_insn (gen_macho_high (reg, orig));
454 emit_insn (gen_macho_low (reg, reg, orig));
455 #else
456 /* some other cpu -- writeme! */
457 abort ();
458 #endif
459 return reg;
461 else if (defined)
463 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
464 rtx pic_base = gen_rtx_SYMBOL_REF (Pmode,
465 machopic_function_base_name ());
466 rtx offset = gen_rtx_CONST (Pmode,
467 gen_rtx_MINUS (Pmode, orig, pic_base));
468 #endif
470 #if defined (TARGET_TOC) /* i.e., PowerPC */
471 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
473 if (reg == NULL)
474 abort ();
476 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
477 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
478 gen_rtx_HIGH (Pmode, offset))));
479 emit_insn (gen_rtx_SET (Pmode, reg,
480 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
482 orig = reg;
483 #else
484 #if defined (HAVE_lo_sum)
485 if (reg == 0) abort ();
487 emit_insn (gen_rtx_SET (VOIDmode, reg,
488 gen_rtx_HIGH (Pmode, offset)));
489 emit_insn (gen_rtx_SET (VOIDmode, reg,
490 gen_rtx_LO_SUM (Pmode, reg, offset)));
491 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
493 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
494 #endif
495 #endif
496 return orig;
499 ptr_ref = gen_rtx_SYMBOL_REF (Pmode,
500 machopic_non_lazy_ptr_name (name));
502 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
503 RTX_UNCHANGING_P (ptr_ref) = 1;
505 return ptr_ref;
507 else if (GET_CODE (orig) == CONST)
509 rtx base, result;
511 /* legitimize both operands of the PLUS */
512 if (GET_CODE (XEXP (orig, 0)) == PLUS)
514 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
515 reg);
516 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
517 (base == reg ? 0 : reg));
519 else
520 return orig;
522 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
523 result = plus_constant (base, INTVAL (orig));
524 else
525 result = gen_rtx_PLUS (Pmode, base, orig);
527 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
529 if (reg)
531 emit_move_insn (reg, result);
532 result = reg;
534 else
536 result = force_reg (GET_MODE (result), result);
540 return result;
543 else if (GET_CODE (orig) == MEM)
544 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
545 /* When the target is i386, this code prevents crashes due to the
546 compiler's ignorance on how to move the PIC base register to
547 other registers. (The reload phase sometimes introduces such
548 insns.) */
549 else if (GET_CODE (orig) == PLUS
550 && GET_CODE (XEXP (orig, 0)) == REG
551 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
552 #ifdef I386
553 /* Prevent the same register from being erroneously used
554 as both the base and index registers. */
555 && GET_CODE (XEXP (orig, 1)) == CONST
556 #endif
557 && reg)
559 emit_move_insn (reg, XEXP (orig, 0));
560 XEXP (ptr_ref, 0) = reg;
562 return ptr_ref;
565 /* Transform TARGET (a MEM), which is a function call target, to the
566 corresponding symbol_stub if necessary. Return a new MEM. */
569 machopic_indirect_call_target (rtx target)
571 if (GET_CODE (target) != MEM)
572 return target;
574 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
576 enum machine_mode mode = GET_MODE (XEXP (target, 0));
577 const char *name = XSTR (XEXP (target, 0), 0);
579 /* If the name is already defined, we need do nothing. */
580 if (name[0] == '!' && name[1] == 'T')
581 return target;
583 if (!machopic_name_defined_p (name))
585 const char *stub_name = machopic_stub_name (name);
587 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
588 RTX_UNCHANGING_P (target) = 1;
592 return target;
596 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
598 rtx pic_ref = orig;
600 if (! MACHOPIC_INDIRECT)
601 return orig;
603 /* First handle a simple SYMBOL_REF or LABEL_REF */
604 if (GET_CODE (orig) == LABEL_REF
605 || (GET_CODE (orig) == SYMBOL_REF
608 /* addr(foo) = &func+(foo-func) */
609 rtx pic_base;
611 orig = machopic_indirect_data_reference (orig, reg);
613 if (GET_CODE (orig) == PLUS
614 && GET_CODE (XEXP (orig, 0)) == REG)
616 if (reg == 0)
617 return force_reg (mode, orig);
619 emit_move_insn (reg, orig);
620 return reg;
623 /* if dynamic-no-pic then use 0 as the pic base */
624 if (MACHO_DYNAMIC_NO_PIC_P)
625 pic_base = CONST0_RTX (Pmode);
626 else
627 pic_base = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
629 if (GET_CODE (orig) == MEM)
631 if (reg == 0)
633 if (reload_in_progress)
634 abort ();
635 else
636 reg = gen_reg_rtx (Pmode);
639 #ifdef HAVE_lo_sum
640 if (MACHO_DYNAMIC_NO_PIC_P
641 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
642 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
644 #if defined (TARGET_TOC) /* ppc */
645 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
646 rtx asym = XEXP (orig, 0);
647 rtx mem;
649 emit_insn (gen_macho_high (temp_reg, asym));
650 mem = gen_rtx_MEM (GET_MODE (orig),
651 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
652 RTX_UNCHANGING_P (mem) = 1;
653 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
654 #else
655 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
656 abort ();
657 #endif
658 pic_ref = reg;
660 else
661 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
662 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
664 rtx offset = gen_rtx_CONST (Pmode,
665 gen_rtx_MINUS (Pmode,
666 XEXP (orig, 0),
667 pic_base));
668 #if defined (TARGET_TOC) /* i.e., PowerPC */
669 /* Generating a new reg may expose opportunities for
670 common subexpression elimination. */
671 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (SImode);
672 rtx mem;
673 rtx insn;
674 rtx sum;
676 sum = gen_rtx_HIGH (Pmode, offset);
677 if (! MACHO_DYNAMIC_NO_PIC_P)
678 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
680 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
682 mem = gen_rtx_MEM (GET_MODE (orig),
683 gen_rtx_LO_SUM (Pmode,
684 hi_sum_reg, offset));
685 RTX_UNCHANGING_P (mem) = 1;
686 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
687 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
688 REG_NOTES (insn));
690 pic_ref = reg;
691 #else
692 emit_insn (gen_rtx_USE (VOIDmode,
693 gen_rtx_REG (Pmode,
694 PIC_OFFSET_TABLE_REGNUM)));
696 emit_insn (gen_rtx_SET (VOIDmode, reg,
697 gen_rtx_HIGH (Pmode,
698 gen_rtx_CONST (Pmode,
699 offset))));
700 emit_insn (gen_rtx_SET (VOIDmode, reg,
701 gen_rtx_LO_SUM (Pmode, reg,
702 gen_rtx_CONST (Pmode, offset))));
703 pic_ref = gen_rtx_PLUS (Pmode,
704 pic_offset_table_rtx, reg);
705 #endif
707 else
708 #endif /* HAVE_lo_sum */
710 rtx pic = pic_offset_table_rtx;
711 if (GET_CODE (pic) != REG)
713 emit_move_insn (reg, pic);
714 pic = reg;
716 #if 0
717 emit_insn (gen_rtx_USE (VOIDmode,
718 gen_rtx_REG (Pmode,
719 PIC_OFFSET_TABLE_REGNUM)));
720 #endif
722 pic_ref = gen_rtx_PLUS (Pmode,
723 pic,
724 gen_rtx_CONST (Pmode,
725 gen_rtx_MINUS (Pmode,
726 XEXP (orig, 0),
727 pic_base)));
730 #if !defined (TARGET_TOC)
731 emit_move_insn (reg, pic_ref);
732 pic_ref = gen_rtx_MEM (GET_MODE (orig), reg);
733 #endif
734 RTX_UNCHANGING_P (pic_ref) = 1;
736 else
739 #ifdef HAVE_lo_sum
740 if (GET_CODE (orig) == SYMBOL_REF
741 || GET_CODE (orig) == LABEL_REF)
743 rtx offset = gen_rtx_CONST (Pmode,
744 gen_rtx_MINUS (Pmode,
745 orig, pic_base));
746 #if defined (TARGET_TOC) /* i.e., PowerPC */
747 rtx hi_sum_reg;
749 if (reg == 0)
751 if (reload_in_progress)
752 abort ();
753 else
754 reg = gen_reg_rtx (SImode);
757 hi_sum_reg = reg;
759 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
760 (MACHO_DYNAMIC_NO_PIC_P)
761 ? gen_rtx_HIGH (Pmode, offset)
762 : gen_rtx_PLUS (Pmode,
763 pic_offset_table_rtx,
764 gen_rtx_HIGH (Pmode,
765 offset))));
766 emit_insn (gen_rtx_SET (VOIDmode, reg,
767 gen_rtx_LO_SUM (Pmode,
768 hi_sum_reg, offset)));
769 pic_ref = reg;
770 RTX_UNCHANGING_P (pic_ref) = 1;
771 #else
772 emit_insn (gen_rtx_SET (VOIDmode, reg,
773 gen_rtx_HIGH (Pmode, offset)));
774 emit_insn (gen_rtx_SET (VOIDmode, reg,
775 gen_rtx_LO_SUM (Pmode, reg, offset)));
776 pic_ref = gen_rtx_PLUS (Pmode,
777 pic_offset_table_rtx, reg);
778 RTX_UNCHANGING_P (pic_ref) = 1;
779 #endif
781 else
782 #endif /* HAVE_lo_sum */
784 if (GET_CODE (orig) == REG)
786 return orig;
788 else
790 rtx pic = pic_offset_table_rtx;
791 if (GET_CODE (pic) != REG)
793 emit_move_insn (reg, pic);
794 pic = reg;
796 #if 0
797 emit_insn (gen_rtx_USE (VOIDmode,
798 pic_offset_table_rtx));
799 #endif
800 pic_ref = gen_rtx_PLUS (Pmode,
801 pic,
802 gen_rtx_CONST (Pmode,
803 gen_rtx_MINUS (Pmode,
804 orig, pic_base)));
809 if (GET_CODE (pic_ref) != REG)
811 if (reg != 0)
813 emit_move_insn (reg, pic_ref);
814 return reg;
816 else
818 return force_reg (mode, pic_ref);
821 else
823 return pic_ref;
827 else if (GET_CODE (orig) == SYMBOL_REF)
828 return orig;
830 else if (GET_CODE (orig) == PLUS
831 && (GET_CODE (XEXP (orig, 0)) == MEM
832 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
833 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
834 && XEXP (orig, 0) != pic_offset_table_rtx
835 && GET_CODE (XEXP (orig, 1)) != REG)
838 rtx base;
839 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
841 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
842 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
843 Pmode, (base == reg ? 0 : reg));
844 if (GET_CODE (orig) == CONST_INT)
846 pic_ref = plus_constant (base, INTVAL (orig));
847 is_complex = 1;
849 else
850 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
852 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
853 RTX_UNCHANGING_P (pic_ref) = 1;
855 if (reg && is_complex)
857 emit_move_insn (reg, pic_ref);
858 pic_ref = reg;
860 /* Likewise, should we set special REG_NOTEs here? */
863 else if (GET_CODE (orig) == CONST)
865 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
868 else if (GET_CODE (orig) == MEM
869 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
871 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
873 addr = gen_rtx_MEM (GET_MODE (orig), addr);
874 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
875 emit_move_insn (reg, addr);
876 pic_ref = reg;
879 return pic_ref;
883 void
884 machopic_finish (FILE *asm_out_file)
886 tree temp;
888 for (temp = machopic_stubs;
889 temp != NULL_TREE;
890 temp = TREE_CHAIN (temp))
892 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
893 const char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
894 char *sym;
895 char *stub;
897 if (! TREE_USED (temp))
898 continue;
900 sym_name = darwin_strip_name_encoding (sym_name);
902 sym = alloca (strlen (sym_name) + 2);
903 if (sym_name[0] == '*' || sym_name[0] == '&')
904 strcpy (sym, sym_name + 1);
905 else if (sym_name[0] == '-' || sym_name[0] == '+')
906 strcpy (sym, sym_name);
907 else
908 sym[0] = '_', strcpy (sym + 1, sym_name);
910 stub = alloca (strlen (stub_name) + 2);
911 if (stub_name[0] == '*' || stub_name[0] == '&')
912 strcpy (stub, stub_name + 1);
913 else
914 stub[0] = '_', strcpy (stub + 1, stub_name);
916 machopic_output_stub (asm_out_file, sym, stub);
919 for (temp = machopic_non_lazy_pointers;
920 temp != NULL_TREE;
921 temp = TREE_CHAIN (temp))
923 const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
924 const char *const lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
926 if (! TREE_USED (temp))
927 continue;
929 if (machopic_ident_defined_p (TREE_VALUE (temp)))
931 data_section ();
932 assemble_align (GET_MODE_ALIGNMENT (Pmode));
933 assemble_label (lazy_name);
934 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
935 GET_MODE_SIZE (Pmode),
936 GET_MODE_ALIGNMENT (Pmode), 1);
938 else
940 machopic_nl_symbol_ptr_section ();
941 assemble_name (asm_out_file, lazy_name);
942 fprintf (asm_out_file, ":\n");
944 fprintf (asm_out_file, "\t.indirect_symbol ");
945 assemble_name (asm_out_file, sym_name);
946 fprintf (asm_out_file, "\n");
948 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
949 GET_MODE_ALIGNMENT (Pmode), 1);
955 machopic_operand_p (rtx op)
957 if (MACHOPIC_JUST_INDIRECT)
959 while (GET_CODE (op) == CONST)
960 op = XEXP (op, 0);
962 if (GET_CODE (op) == SYMBOL_REF)
963 return machopic_name_defined_p (XSTR (op, 0));
964 else
965 return 0;
968 while (GET_CODE (op) == CONST)
969 op = XEXP (op, 0);
971 if (GET_CODE (op) == MINUS
972 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
973 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
974 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
975 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
976 return 1;
978 return 0;
981 /* This function records whether a given name corresponds to a defined
982 or undefined function or variable, for machopic_classify_ident to
983 use later. */
985 void
986 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
988 char code = '\0';
989 int defined = 0;
990 rtx sym_ref;
991 const char *orig_str;
992 char *new_str;
993 size_t len, new_len;
995 /* Do the standard encoding things first. */
996 default_encode_section_info (decl, rtl, first);
998 /* With the introduction of symbol_ref flags, some of the following
999 code has become redundant and should be removed at some point. */
1001 if ((TREE_CODE (decl) == FUNCTION_DECL
1002 || TREE_CODE (decl) == VAR_DECL)
1003 && !DECL_EXTERNAL (decl)
1004 && (!TREE_PUBLIC (decl) || (!DECL_ONE_ONLY (decl) && !DECL_WEAK (decl)))
1005 && ((TREE_STATIC (decl)
1006 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1007 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
1008 && DECL_INITIAL (decl) != error_mark_node)))
1009 defined = 1;
1011 if (TREE_CODE (decl) == FUNCTION_DECL)
1012 code = (defined ? 'T' : 't');
1013 else if (TREE_CODE (decl) == VAR_DECL)
1014 code = (defined ? 'D' : 'd');
1016 if (code == '\0')
1017 return;
1019 sym_ref = XEXP (rtl, 0);
1020 orig_str = XSTR (sym_ref, 0);
1021 len = strlen (orig_str) + 1;
1023 if (orig_str[0] == '!')
1025 /* Already encoded; see if we need to change it. */
1026 if (code == orig_str[1])
1027 return;
1028 /* Yes, tweak a copy of the name and put it in a new string. */
1029 new_str = alloca (len);
1030 memcpy (new_str, orig_str, len);
1031 new_str[1] = code;
1032 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
1034 else
1036 /* Add the encoding. */
1037 new_len = len + 4;
1038 new_str = alloca (new_len);
1039 new_str[0] = '!';
1040 new_str[1] = code;
1041 new_str[2] = '_';
1042 new_str[3] = '_';
1043 memcpy (new_str + 4, orig_str, len);
1044 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
1046 /* The non-lazy pointer list may have captured references to the
1047 old encoded name, change them. */
1048 if (TREE_CODE (decl) == VAR_DECL)
1049 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1050 else
1051 update_stubs (XSTR (sym_ref, 0));
1054 /* Undo the effects of the above. */
1056 const char *
1057 darwin_strip_name_encoding (const char *str)
1059 return str[0] == '!' ? str + 4 : str;
1062 /* Scan the list of non-lazy pointers and update any recorded names whose
1063 stripped name matches the argument. */
1065 static void
1066 update_non_lazy_ptrs (const char *name)
1068 const char *name1, *name2;
1069 tree temp;
1071 name1 = darwin_strip_name_encoding (name);
1073 for (temp = machopic_non_lazy_pointers;
1074 temp != NULL_TREE;
1075 temp = TREE_CHAIN (temp))
1077 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1079 if (*sym_name == '!')
1081 name2 = darwin_strip_name_encoding (sym_name);
1082 if (strcmp (name1, name2) == 0)
1084 /* FIXME: This breaks the identifier hash table. */
1085 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1086 = (unsigned char *) name;
1087 break;
1093 /* Scan the list of stubs and update any recorded names whose
1094 stripped name matches the argument. */
1096 static void
1097 update_stubs (const char *name)
1099 const char *name1, *name2;
1100 tree temp;
1102 name1 = darwin_strip_name_encoding (name);
1104 for (temp = machopic_stubs;
1105 temp != NULL_TREE;
1106 temp = TREE_CHAIN (temp))
1108 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1110 if (*sym_name == '!')
1112 name2 = darwin_strip_name_encoding (sym_name);
1113 if (strcmp (name1, name2) == 0)
1115 /* FIXME: This breaks the identifier hash table. */
1116 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1117 = (unsigned char *) name;
1118 break;
1124 void
1125 darwin_make_decl_one_only (tree decl)
1127 static const char *text_section = "__TEXT,__textcoal_nt,coalesced,no_toc";
1128 static const char *data_section = "__DATA,__datacoal_nt,coalesced,no_toc";
1130 const char *sec = TREE_CODE (decl) == FUNCTION_DECL
1131 ? text_section
1132 : data_section;
1133 TREE_PUBLIC (decl) = 1;
1134 DECL_ONE_ONLY (decl) = 1;
1135 DECL_SECTION_NAME (decl) = build_string (strlen (sec), sec);
1138 void
1139 machopic_select_section (tree exp, int reloc,
1140 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1142 void (*base_function)(void);
1144 if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1145 base_function = readonly_data_section;
1146 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1147 base_function = const_data_section;
1148 else
1149 base_function = data_section;
1151 if (TREE_CODE (exp) == STRING_CST
1152 && ((size_t) TREE_STRING_LENGTH (exp)
1153 == strlen (TREE_STRING_POINTER (exp)) + 1))
1154 cstring_section ();
1155 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1156 && flag_merge_constants)
1158 tree size = TYPE_SIZE (TREE_TYPE (exp));
1160 if (TREE_CODE (size) == INTEGER_CST &&
1161 TREE_INT_CST_LOW (size) == 4 &&
1162 TREE_INT_CST_HIGH (size) == 0)
1163 literal4_section ();
1164 else if (TREE_CODE (size) == INTEGER_CST &&
1165 TREE_INT_CST_LOW (size) == 8 &&
1166 TREE_INT_CST_HIGH (size) == 0)
1167 literal8_section ();
1168 else
1169 base_function ();
1171 else if (TREE_CODE (exp) == CONSTRUCTOR
1172 && TREE_TYPE (exp)
1173 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1174 && TYPE_NAME (TREE_TYPE (exp)))
1176 tree name = TYPE_NAME (TREE_TYPE (exp));
1177 if (TREE_CODE (name) == TYPE_DECL)
1178 name = DECL_NAME (name);
1179 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1180 objc_constant_string_object_section ();
1181 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1182 objc_string_object_section ();
1183 else
1184 base_function ();
1186 else if (TREE_CODE (exp) == VAR_DECL &&
1187 DECL_NAME (exp) &&
1188 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1189 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1190 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1192 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1194 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1195 objc_cls_meth_section ();
1196 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1197 objc_inst_meth_section ();
1198 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1199 objc_cat_cls_meth_section ();
1200 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1201 objc_cat_inst_meth_section ();
1202 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1203 objc_class_vars_section ();
1204 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1205 objc_instance_vars_section ();
1206 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1207 objc_cat_cls_meth_section ();
1208 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1209 objc_class_names_section ();
1210 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1211 objc_meth_var_names_section ();
1212 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1213 objc_meth_var_types_section ();
1214 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1215 objc_cls_refs_section ();
1216 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1217 objc_class_section ();
1218 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1219 objc_meta_class_section ();
1220 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1221 objc_category_section ();
1222 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1223 objc_selector_refs_section ();
1224 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1225 objc_selector_fixup_section ();
1226 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1227 objc_symbols_section ();
1228 else if (!strncmp (name, "_OBJC_MODULES", 13))
1229 objc_module_info_section ();
1230 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1231 objc_image_info_section ();
1232 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1233 objc_cat_inst_meth_section ();
1234 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1235 objc_cat_cls_meth_section ();
1236 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1237 objc_cat_cls_meth_section ();
1238 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1239 objc_protocol_section ();
1240 else
1241 base_function ();
1243 else
1244 base_function ();
1247 /* This can be called with address expressions as "rtx".
1248 They must go in "const". */
1250 void
1251 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1252 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1254 if (GET_MODE_SIZE (mode) == 8)
1255 literal8_section ();
1256 else if (GET_MODE_SIZE (mode) == 4
1257 && (GET_CODE (x) == CONST_INT
1258 || GET_CODE (x) == CONST_DOUBLE))
1259 literal4_section ();
1260 else if (MACHOPIC_INDIRECT
1261 && (GET_CODE (x) == SYMBOL_REF
1262 || GET_CODE (x) == CONST
1263 || GET_CODE (x) == LABEL_REF))
1264 const_data_section ();
1265 else
1266 const_section ();
1269 void
1270 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1272 if (MACHOPIC_INDIRECT)
1273 mod_init_section ();
1274 else
1275 constructor_section ();
1276 assemble_align (POINTER_SIZE);
1277 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1279 if (! MACHOPIC_INDIRECT)
1280 fprintf (asm_out_file, ".reference .constructors_used\n");
1283 void
1284 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1286 if (MACHOPIC_INDIRECT)
1287 mod_term_section ();
1288 else
1289 destructor_section ();
1290 assemble_align (POINTER_SIZE);
1291 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1293 if (! MACHOPIC_INDIRECT)
1294 fprintf (asm_out_file, ".reference .destructors_used\n");
1297 void
1298 darwin_globalize_label (FILE *stream, const char *name)
1300 if (!!strncmp (name, "_OBJC_", 6))
1301 default_globalize_label (stream, name);
1304 void
1305 darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
1307 if (flag_reorder_blocks_and_partition)
1308 fprintf (asm_out_file, SECTION_FORMAT_STRING, name);
1309 else
1310 fprintf (asm_out_file, ".section %s\n", name);
1313 unsigned int
1314 darwin_section_type_flags (tree decl, const char *name, int reloc)
1316 unsigned int flags = default_section_type_flags (decl, name, reloc);
1318 /* Weak or linkonce variables live in a writable section. */
1319 if (decl != 0 && TREE_CODE (decl) != FUNCTION_DECL
1320 && (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)))
1321 flags |= SECTION_WRITE;
1323 return flags;
1326 void
1327 darwin_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
1329 /* Darwin does not use unique sections. However, the target's
1330 unique_section hook is called for linkonce symbols. We need
1331 to set an appropriate section for such symbols. */
1332 if (DECL_ONE_ONLY (decl) && !DECL_SECTION_NAME (decl))
1333 darwin_make_decl_one_only (decl);
1336 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1337 The third parameter is nonzero if this is just a placeholder for an
1338 FDE that we are omitting. */
1339 void
1340 darwin_emit_unwind_label(FILE *file, tree decl, int empty)
1342 tree id = DECL_ASSEMBLER_NAME (decl)
1343 ? DECL_ASSEMBLER_NAME (decl)
1344 : DECL_NAME (decl);
1346 const char *prefix = "_";
1347 const int prefix_len = 1;
1349 const char *base = IDENTIFIER_POINTER (id);
1350 unsigned int base_len = IDENTIFIER_LENGTH (id);
1352 const char *suffix = ".eh";
1353 unsigned int suffix_len = 3;
1355 int need_quotes = name_needs_quotes (base);
1356 int quotes_len = need_quotes ? 2 : 0;
1358 char *lab = xmalloc (prefix_len + base_len + suffix_len + quotes_len + 1);
1359 lab[0] = '\0';
1361 if (need_quotes)
1362 strcat(lab, "\"");
1363 strcat(lab, prefix);
1364 strcat(lab, base);
1365 strcat(lab, suffix);
1366 if (need_quotes)
1367 strcat(lab, "\"");
1369 if (TREE_PUBLIC (decl))
1370 fprintf (file, "%s %s\n",
1371 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1372 ? ".globl"
1373 : ".private_extern"),
1374 lab);
1376 if (DECL_ONE_ONLY (decl) && TREE_PUBLIC (decl))
1377 fprintf (file, ".weak_definition %s\n", lab);
1379 if (empty)
1380 fprintf (file, "%s = 0\n", lab);
1381 else
1382 fprintf (file, "%s:\n", lab);
1384 free (lab);
1387 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1388 void
1389 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1391 const char *str;
1392 const char *nlp_name;
1394 if (GET_CODE (addr) != SYMBOL_REF)
1395 abort ();
1397 str = darwin_strip_name_encoding (XSTR (addr, 0));
1398 nlp_name = machopic_non_lazy_ptr_name (str);
1399 fputs ("\t.long\t", file);
1400 ASM_OUTPUT_LABELREF (file, nlp_name);
1401 fputs ("-.", file);
1404 /* Emit an assembler directive to set visibility for a symbol. The
1405 only supported visibilities are VISIBILITY_DEFAULT and
1406 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1407 extern". There is no MACH-O equivalent of ELF's
1408 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1410 void
1411 darwin_assemble_visibility (tree decl, int vis)
1413 if (vis == VISIBILITY_DEFAULT)
1415 else if (vis == VISIBILITY_HIDDEN)
1417 fputs ("\t.private_extern ", asm_out_file);
1418 assemble_name (asm_out_file,
1419 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1420 fputs ("\n", asm_out_file);
1422 else
1423 warning ("internal and protected visibility attributes not supported"
1424 "in this configuration; ignored");
1427 /* Output a difference of two labels that will be an assembly time
1428 constant if the two labels are local. (.long lab1-lab2 will be
1429 very different if lab1 is at the boundary between two sections; it
1430 will be relocated according to the second section, not the first,
1431 so one ends up with a difference between labels in different
1432 sections, which is bad in the dwarf2 eh context for instance.) */
1434 static int darwin_dwarf_label_counter;
1436 void
1437 darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
1438 const char *lab1, const char *lab2)
1440 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1441 && lab2[0] == '*' && lab2[1] == 'L');
1443 if (islocaldiff)
1444 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1445 else
1446 fprintf (file, "\t%s\t", ".long");
1447 assemble_name (file, lab1);
1448 fprintf (file, "-");
1449 assemble_name (file, lab2);
1450 if (islocaldiff)
1451 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1454 void
1455 darwin_file_end (void)
1457 machopic_finish (asm_out_file);
1458 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1460 constructor_section ();
1461 destructor_section ();
1462 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1466 #include "gt-darwin.h"