* dwarf2out.c, fold-const.c, ipa-type-escape.c,
[official-gcc.git] / gcc / config / darwin.c
blobcac61e403c9ac12b5e022d3517eaeaf82cac775f
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 2005
4 Free Software Foundation, Inc.
5 Contributed by Apple Computer Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to
21 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "real.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "insn-flags.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "tree.h"
39 #include "expr.h"
40 #include "reload.h"
41 #include "function.h"
42 #include "ggc.h"
43 #include "langhooks.h"
44 #include "target.h"
45 #include "tm_p.h"
46 #include "toplev.h"
47 #include "hashtab.h"
49 /* Darwin supports a feature called fix-and-continue, which is used
50 for rapid turn around debugging. When code is compiled with the
51 -mfix-and-continue flag, two changes are made to the generated code
52 that allow the system to do things that it would normally not be
53 able to do easily. These changes allow gdb to load in
54 recompilation of a translation unit that has been changed into a
55 running program and replace existing functions and methods of that
56 translation unit with with versions of those functions and methods
57 from the newly compiled translation unit. The new functions access
58 the existing static symbols from the old translation unit, if the
59 symbol existed in the unit to be replaced, and from the new
60 translation unit, otherwise.
62 The changes are to insert 5 nops at the beginning of all functions
63 and to use indirection to get at static symbols. The 5 nops
64 are required by consumers of the generated code. Currently, gdb
65 uses this to patch in a jump to the overriding function, this
66 allows all uses of the old name to forward to the replacement,
67 including existing function pointers and virtual methods. See
68 rs6000_emit_prologue for the code that handles the nop insertions.
70 The added indirection allows gdb to redirect accesses to static
71 symbols from the newly loaded translation unit to the existing
72 symbol, if any. @code{static} symbols are special and are handled by
73 setting the second word in the .non_lazy_symbol_pointer data
74 structure to symbol. See indirect_data for the code that handles
75 the extra indirection, and machopic_output_indirection and its use
76 of MACHO_SYMBOL_STATIC for the code that handles @code{static}
77 symbol indirection. */
80 int
81 name_needs_quotes (const char *name)
83 int c;
84 while ((c = *name++) != '\0')
85 if (! ISIDNUM (c) && c != '.' && c != '$')
86 return 1;
87 return 0;
90 /* Return true if SYM_REF can be used without an indirection. */
91 static int
92 machopic_symbol_defined_p (rtx sym_ref)
94 if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
95 return true;
97 /* If a symbol references local and is not an extern to this
98 file, then the symbol might be able to declared as defined. */
99 if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
101 /* If the symbol references a variable and the variable is a
102 common symbol, then this symbol is not defined. */
103 if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_VARIABLE)
105 tree decl = SYMBOL_REF_DECL (sym_ref);
106 if (!decl)
107 return true;
108 if (DECL_COMMON (decl))
109 return false;
111 return true;
113 return false;
116 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
117 reference, which will not be changed. */
119 enum machopic_addr_class
120 machopic_classify_symbol (rtx sym_ref)
122 int flags;
123 bool function_p;
125 flags = SYMBOL_REF_FLAGS (sym_ref);
126 function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
127 if (machopic_symbol_defined_p (sym_ref))
128 return (function_p
129 ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
130 else
131 return (function_p
132 ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
135 #ifndef TARGET_FIX_AND_CONTINUE
136 #define TARGET_FIX_AND_CONTINUE 0
137 #endif
139 /* Indicate when fix-and-continue style code generation is being used
140 and when a reference to data should be indirected so that it can be
141 rebound in a new translation unit to reference the original instance
142 of that data. Symbol names that are for code generation local to
143 the translation unit are bound to the new translation unit;
144 currently this means symbols that begin with L or _OBJC_;
145 otherwise, we indicate that an indirect reference should be made to
146 permit the runtime to rebind new instances of the translation unit
147 to the original instance of the data. */
149 static int
150 indirect_data (rtx sym_ref)
152 int lprefix;
153 const char *name;
155 /* If we aren't generating fix-and-continue code, don't do anything special. */
156 if (TARGET_FIX_AND_CONTINUE == 0)
157 return 0;
159 /* Otherwise, all symbol except symbols that begin with L or _OBJC_
160 are indirected. Symbols that begin with L and _OBJC_ are always
161 bound to the current translation unit as they are used for
162 generated local data of the translation unit. */
164 name = XSTR (sym_ref, 0);
166 lprefix = (((name[0] == '*' || name[0] == '&')
167 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
168 || (strncmp (name, "_OBJC_", 6) == 0));
170 return ! lprefix;
174 static int
175 machopic_data_defined_p (rtx sym_ref)
177 if (indirect_data (sym_ref))
178 return 0;
180 switch (machopic_classify_symbol (sym_ref))
182 case MACHOPIC_DEFINED_DATA:
183 case MACHOPIC_DEFINED_FUNCTION:
184 return 1;
185 default:
186 return 0;
190 void
191 machopic_define_symbol (rtx mem)
193 rtx sym_ref;
195 gcc_assert (GET_CODE (mem) == MEM);
196 sym_ref = XEXP (mem, 0);
197 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
200 static GTY(()) char * function_base;
202 const char *
203 machopic_function_base_name (void)
205 /* if dynamic-no-pic is on, we should not get here */
206 gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
208 if (function_base == NULL)
209 function_base =
210 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
212 current_function_uses_pic_offset_table = 1;
214 return function_base;
217 /* Return a SYMBOL_REF for the PIC function base. */
220 machopic_function_base_sym (void)
222 rtx sym_ref;
224 sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
225 SYMBOL_REF_FLAGS (sym_ref)
226 |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
227 return sym_ref;
230 static GTY(()) const char * function_base_func_name;
231 static GTY(()) int current_pic_label_num;
233 void
234 machopic_output_function_base_name (FILE *file)
236 const char *current_name;
238 /* If dynamic-no-pic is on, we should not get here. */
239 gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
240 current_name =
241 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
242 if (function_base_func_name != current_name)
244 ++current_pic_label_num;
245 function_base_func_name = current_name;
247 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
250 /* The suffix attached to non-lazy pointer symbols. */
251 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
252 /* The suffix attached to stub symbols. */
253 #define STUB_SUFFIX "$stub"
255 typedef struct machopic_indirection GTY (())
257 /* The SYMBOL_REF for the entity referenced. */
258 rtx symbol;
259 /* The name of the stub or non-lazy pointer. */
260 const char * ptr_name;
261 /* True iff this entry is for a stub (as opposed to a non-lazy
262 pointer). */
263 bool stub_p;
264 /* True iff this stub or pointer pointer has been referenced. */
265 bool used;
266 } machopic_indirection;
268 /* A table mapping stub names and non-lazy pointer names to
269 SYMBOL_REFs for the stubbed-to and pointed-to entities. */
271 static GTY ((param_is (struct machopic_indirection))) htab_t
272 machopic_indirections;
274 /* Return a hash value for a SLOT in the indirections hash table. */
276 static hashval_t
277 machopic_indirection_hash (const void *slot)
279 const machopic_indirection *p = (const machopic_indirection *) slot;
280 return htab_hash_string (p->ptr_name);
283 /* Returns true if the KEY is the same as that associated with
284 SLOT. */
286 static int
287 machopic_indirection_eq (const void *slot, const void *key)
289 return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0;
292 /* Return the name of the non-lazy pointer (if STUB_P is false) or
293 stub (if STUB_B is true) corresponding to the given name. */
295 const char *
296 machopic_indirection_name (rtx sym_ref, bool stub_p)
298 char *buffer;
299 const char *name = XSTR (sym_ref, 0);
300 size_t namelen = strlen (name);
301 machopic_indirection *p;
302 void ** slot;
303 bool saw_star = false;
304 bool needs_quotes;
305 const char *suffix;
306 const char *prefix = user_label_prefix;
307 const char *quote = "";
309 if (name[0] == '*')
311 saw_star = true;
312 prefix = "";
313 ++name;
314 --namelen;
317 needs_quotes = name_needs_quotes (name);
318 if (needs_quotes)
320 quote = "\"";
323 if (stub_p)
324 suffix = STUB_SUFFIX;
325 else
326 suffix = NON_LAZY_POINTER_SUFFIX;
328 buffer = alloca (strlen ("&L")
329 + strlen (prefix)
330 + namelen
331 + strlen (suffix)
332 + 2 * strlen (quote)
333 + 1 /* '\0' */);
335 /* Construct the name of the non-lazy pointer or stub. */
336 sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
338 if (!machopic_indirections)
339 machopic_indirections = htab_create_ggc (37,
340 machopic_indirection_hash,
341 machopic_indirection_eq,
342 /*htab_del=*/NULL);
344 slot = htab_find_slot_with_hash (machopic_indirections, buffer,
345 htab_hash_string (buffer), INSERT);
346 if (*slot)
348 p = (machopic_indirection *) *slot;
350 else
352 p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
353 p->symbol = sym_ref;
354 p->ptr_name = xstrdup (buffer);
355 p->stub_p = stub_p;
356 p->used = false;
357 *slot = p;
360 return p->ptr_name;
363 /* Return the name of the stub for the mcount function. */
365 const char*
366 machopic_mcount_stub_name (void)
368 rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
369 return machopic_indirection_name (symbol, /*stub_p=*/true);
372 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
373 or non-lazy pointer as used -- and mark the object to which the
374 pointer/stub refers as used as well, since the pointer/stub will
375 emit a reference to it. */
377 void
378 machopic_validate_stub_or_non_lazy_ptr (const char *name)
380 machopic_indirection *p;
382 p = ((machopic_indirection *)
383 (htab_find_with_hash (machopic_indirections, name,
384 htab_hash_string (name))));
385 if (p && ! p->used)
387 const char *real_name;
388 tree id;
390 p->used = true;
392 /* Do what output_addr_const will do when we actually call it. */
393 if (SYMBOL_REF_DECL (p->symbol))
394 mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
396 real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
398 id = maybe_get_identifier (real_name);
399 if (id)
400 mark_referenced (id);
404 /* Transform ORIG, which may be any data source, to the corresponding
405 source using indirections. */
408 machopic_indirect_data_reference (rtx orig, rtx reg)
410 rtx ptr_ref = orig;
412 if (! MACHOPIC_INDIRECT)
413 return orig;
415 if (GET_CODE (orig) == SYMBOL_REF)
417 int defined = machopic_data_defined_p (orig);
419 if (defined && MACHO_DYNAMIC_NO_PIC_P)
421 #if defined (TARGET_TOC)
422 emit_insn (gen_macho_high (reg, orig));
423 emit_insn (gen_macho_low (reg, reg, orig));
424 #else
425 /* some other cpu -- writeme! */
426 gcc_unreachable ();
427 #endif
428 return reg;
430 else if (defined)
432 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
433 rtx pic_base = machopic_function_base_sym ();
434 rtx offset = gen_rtx_CONST (Pmode,
435 gen_rtx_MINUS (Pmode, orig, pic_base));
436 #endif
438 #if defined (TARGET_TOC) /* i.e., PowerPC */
439 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
441 gcc_assert (reg);
443 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
444 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
445 gen_rtx_HIGH (Pmode, offset))));
446 emit_insn (gen_rtx_SET (Pmode, reg,
447 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
449 orig = reg;
450 #else
451 #if defined (HAVE_lo_sum)
452 gcc_assert (reg);
454 emit_insn (gen_rtx_SET (VOIDmode, reg,
455 gen_rtx_HIGH (Pmode, offset)));
456 emit_insn (gen_rtx_SET (VOIDmode, reg,
457 gen_rtx_LO_SUM (Pmode, reg, offset)));
458 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
460 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
461 #endif
462 #endif
463 return orig;
466 ptr_ref = (gen_rtx_SYMBOL_REF
467 (Pmode,
468 machopic_indirection_name (orig, /*stub_p=*/false)));
470 SYMBOL_REF_DECL (ptr_ref) = SYMBOL_REF_DECL (orig);
472 ptr_ref = gen_const_mem (Pmode, ptr_ref);
473 machopic_define_symbol (ptr_ref);
475 return ptr_ref;
477 else if (GET_CODE (orig) == CONST)
479 rtx base, result;
481 /* legitimize both operands of the PLUS */
482 if (GET_CODE (XEXP (orig, 0)) == PLUS)
484 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
485 reg);
486 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
487 (base == reg ? 0 : reg));
489 else
490 return orig;
492 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
493 result = plus_constant (base, INTVAL (orig));
494 else
495 result = gen_rtx_PLUS (Pmode, base, orig);
497 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
499 if (reg)
501 emit_move_insn (reg, result);
502 result = reg;
504 else
506 result = force_reg (GET_MODE (result), result);
510 return result;
513 else if (GET_CODE (orig) == MEM)
514 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
515 /* When the target is i386, this code prevents crashes due to the
516 compiler's ignorance on how to move the PIC base register to
517 other registers. (The reload phase sometimes introduces such
518 insns.) */
519 else if (GET_CODE (orig) == PLUS
520 && GET_CODE (XEXP (orig, 0)) == REG
521 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
522 #ifdef I386
523 /* Prevent the same register from being erroneously used
524 as both the base and index registers. */
525 && GET_CODE (XEXP (orig, 1)) == CONST
526 #endif
527 && reg)
529 emit_move_insn (reg, XEXP (orig, 0));
530 XEXP (ptr_ref, 0) = reg;
532 return ptr_ref;
535 /* Transform TARGET (a MEM), which is a function call target, to the
536 corresponding symbol_stub if necessary. Return a new MEM. */
539 machopic_indirect_call_target (rtx target)
541 if (GET_CODE (target) != MEM)
542 return target;
544 if (MACHOPIC_INDIRECT
545 && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
546 && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
547 & MACHO_SYMBOL_FLAG_DEFINED))
549 rtx sym_ref = XEXP (target, 0);
550 const char *stub_name = machopic_indirection_name (sym_ref,
551 /*stub_p=*/true);
552 enum machine_mode mode = GET_MODE (sym_ref);
553 tree decl = SYMBOL_REF_DECL (sym_ref);
555 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
556 SYMBOL_REF_DECL (XEXP (target, 0)) = decl;
557 MEM_READONLY_P (target) = 1;
558 MEM_NOTRAP_P (target) = 1;
561 return target;
565 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
567 rtx pic_ref = orig;
569 if (! MACHOPIC_INDIRECT)
570 return orig;
572 /* First handle a simple SYMBOL_REF or LABEL_REF */
573 if (GET_CODE (orig) == LABEL_REF
574 || (GET_CODE (orig) == SYMBOL_REF
577 /* addr(foo) = &func+(foo-func) */
578 rtx pic_base;
580 orig = machopic_indirect_data_reference (orig, reg);
582 if (GET_CODE (orig) == PLUS
583 && GET_CODE (XEXP (orig, 0)) == REG)
585 if (reg == 0)
586 return force_reg (mode, orig);
588 emit_move_insn (reg, orig);
589 return reg;
592 /* if dynamic-no-pic then use 0 as the pic base */
593 if (MACHO_DYNAMIC_NO_PIC_P)
594 pic_base = CONST0_RTX (Pmode);
595 else
596 pic_base = machopic_function_base_sym ();
598 if (GET_CODE (orig) == MEM)
600 if (reg == 0)
602 gcc_assert (!reload_in_progress);
603 reg = gen_reg_rtx (Pmode);
606 #ifdef HAVE_lo_sum
607 if (MACHO_DYNAMIC_NO_PIC_P
608 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
609 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
611 #if defined (TARGET_TOC) /* ppc */
612 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
613 rtx asym = XEXP (orig, 0);
614 rtx mem;
616 emit_insn (gen_macho_high (temp_reg, asym));
617 mem = gen_const_mem (GET_MODE (orig),
618 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
619 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
620 #else
621 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
622 gcc_unreachable ();
623 #endif
624 pic_ref = reg;
626 else
627 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
628 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
630 rtx offset = gen_rtx_CONST (Pmode,
631 gen_rtx_MINUS (Pmode,
632 XEXP (orig, 0),
633 pic_base));
634 #if defined (TARGET_TOC) /* i.e., PowerPC */
635 /* Generating a new reg may expose opportunities for
636 common subexpression elimination. */
637 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
638 rtx mem;
639 rtx insn;
640 rtx sum;
642 sum = gen_rtx_HIGH (Pmode, offset);
643 if (! MACHO_DYNAMIC_NO_PIC_P)
644 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
646 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
648 mem = gen_const_mem (GET_MODE (orig),
649 gen_rtx_LO_SUM (Pmode,
650 hi_sum_reg, offset));
651 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
652 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
653 REG_NOTES (insn));
655 pic_ref = reg;
656 #else
657 emit_insn (gen_rtx_USE (VOIDmode,
658 gen_rtx_REG (Pmode,
659 PIC_OFFSET_TABLE_REGNUM)));
661 emit_insn (gen_rtx_SET (VOIDmode, reg,
662 gen_rtx_HIGH (Pmode,
663 gen_rtx_CONST (Pmode,
664 offset))));
665 emit_insn (gen_rtx_SET (VOIDmode, reg,
666 gen_rtx_LO_SUM (Pmode, reg,
667 gen_rtx_CONST (Pmode, offset))));
668 pic_ref = gen_rtx_PLUS (Pmode,
669 pic_offset_table_rtx, reg);
670 #endif
672 else
673 #endif /* HAVE_lo_sum */
675 rtx pic = pic_offset_table_rtx;
676 if (GET_CODE (pic) != REG)
678 emit_move_insn (reg, pic);
679 pic = reg;
681 #if 0
682 emit_insn (gen_rtx_USE (VOIDmode,
683 gen_rtx_REG (Pmode,
684 PIC_OFFSET_TABLE_REGNUM)));
685 #endif
687 pic_ref = gen_rtx_PLUS (Pmode,
688 pic,
689 gen_rtx_CONST (Pmode,
690 gen_rtx_MINUS (Pmode,
691 XEXP (orig, 0),
692 pic_base)));
695 #if !defined (TARGET_TOC)
696 emit_move_insn (reg, pic_ref);
697 pic_ref = gen_const_mem (GET_MODE (orig), reg);
698 #endif
700 else
703 #ifdef HAVE_lo_sum
704 if (GET_CODE (orig) == SYMBOL_REF
705 || GET_CODE (orig) == LABEL_REF)
707 rtx offset = gen_rtx_CONST (Pmode,
708 gen_rtx_MINUS (Pmode,
709 orig, pic_base));
710 #if defined (TARGET_TOC) /* i.e., PowerPC */
711 rtx hi_sum_reg;
713 if (reg == 0)
715 gcc_assert (!reload_in_progress);
716 reg = gen_reg_rtx (Pmode);
719 hi_sum_reg = reg;
721 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
722 (MACHO_DYNAMIC_NO_PIC_P)
723 ? gen_rtx_HIGH (Pmode, offset)
724 : gen_rtx_PLUS (Pmode,
725 pic_offset_table_rtx,
726 gen_rtx_HIGH (Pmode,
727 offset))));
728 emit_insn (gen_rtx_SET (VOIDmode, reg,
729 gen_rtx_LO_SUM (Pmode,
730 hi_sum_reg, offset)));
731 pic_ref = reg;
732 #else
733 emit_insn (gen_rtx_SET (VOIDmode, reg,
734 gen_rtx_HIGH (Pmode, offset)));
735 emit_insn (gen_rtx_SET (VOIDmode, reg,
736 gen_rtx_LO_SUM (Pmode, reg, offset)));
737 pic_ref = gen_rtx_PLUS (Pmode,
738 pic_offset_table_rtx, reg);
739 #endif
741 else
742 #endif /* HAVE_lo_sum */
744 if (REG_P (orig)
745 || GET_CODE (orig) == SUBREG)
747 return orig;
749 else
751 rtx pic = pic_offset_table_rtx;
752 if (GET_CODE (pic) != REG)
754 emit_move_insn (reg, pic);
755 pic = reg;
757 #if 0
758 emit_insn (gen_rtx_USE (VOIDmode,
759 pic_offset_table_rtx));
760 #endif
761 pic_ref = gen_rtx_PLUS (Pmode,
762 pic,
763 gen_rtx_CONST (Pmode,
764 gen_rtx_MINUS (Pmode,
765 orig, pic_base)));
770 if (GET_CODE (pic_ref) != REG)
772 if (reg != 0)
774 emit_move_insn (reg, pic_ref);
775 return reg;
777 else
779 return force_reg (mode, pic_ref);
782 else
784 return pic_ref;
788 else if (GET_CODE (orig) == SYMBOL_REF)
789 return orig;
791 else if (GET_CODE (orig) == PLUS
792 && (GET_CODE (XEXP (orig, 0)) == MEM
793 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
794 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
795 && XEXP (orig, 0) != pic_offset_table_rtx
796 && GET_CODE (XEXP (orig, 1)) != REG)
799 rtx base;
800 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
802 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
803 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
804 Pmode, (base == reg ? 0 : reg));
805 if (GET_CODE (orig) == CONST_INT)
807 pic_ref = plus_constant (base, INTVAL (orig));
808 is_complex = 1;
810 else
811 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
813 if (reg && is_complex)
815 emit_move_insn (reg, pic_ref);
816 pic_ref = reg;
818 /* Likewise, should we set special REG_NOTEs here? */
821 else if (GET_CODE (orig) == CONST)
823 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
826 else if (GET_CODE (orig) == MEM
827 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
829 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
830 addr = replace_equiv_address (orig, addr);
831 emit_move_insn (reg, addr);
832 pic_ref = reg;
835 return pic_ref;
838 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
839 DATA is the FILE* for assembly output. Called from
840 htab_traverse. */
842 static int
843 machopic_output_indirection (void **slot, void *data)
845 machopic_indirection *p = *((machopic_indirection **) slot);
846 FILE *asm_out_file = (FILE *) data;
847 rtx symbol;
848 const char *sym_name;
849 const char *ptr_name;
851 if (!p->used)
852 return 1;
854 symbol = p->symbol;
855 sym_name = XSTR (symbol, 0);
856 ptr_name = p->ptr_name;
858 if (p->stub_p)
860 char *sym;
861 char *stub;
863 sym = alloca (strlen (sym_name) + 2);
864 if (sym_name[0] == '*' || sym_name[0] == '&')
865 strcpy (sym, sym_name + 1);
866 else if (sym_name[0] == '-' || sym_name[0] == '+')
867 strcpy (sym, sym_name);
868 else
869 sprintf (sym, "%s%s", user_label_prefix, sym_name);
871 stub = alloca (strlen (ptr_name) + 2);
872 if (ptr_name[0] == '*' || ptr_name[0] == '&')
873 strcpy (stub, ptr_name + 1);
874 else
875 sprintf (stub, "%s%s", user_label_prefix, ptr_name);
877 machopic_output_stub (asm_out_file, sym, stub);
879 else if (! indirect_data (symbol)
880 && (machopic_symbol_defined_p (symbol)
881 || SYMBOL_REF_LOCAL_P (symbol)))
883 data_section ();
884 assemble_align (GET_MODE_ALIGNMENT (Pmode));
885 assemble_label (ptr_name);
886 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
887 GET_MODE_SIZE (Pmode),
888 GET_MODE_ALIGNMENT (Pmode), 1);
890 else
892 rtx init = const0_rtx;
894 machopic_nl_symbol_ptr_section ();
895 assemble_name (asm_out_file, ptr_name);
896 fprintf (asm_out_file, ":\n");
898 fprintf (asm_out_file, "\t.indirect_symbol ");
899 assemble_name (asm_out_file, sym_name);
900 fprintf (asm_out_file, "\n");
902 /* Variables that are marked with MACHO_SYMBOL_STATIC need to
903 have their symbol name instead of 0 in the second entry of
904 the non-lazy symbol pointer data structure when they are
905 defined. This allows the runtime to rebind newer instances
906 of the translation unit with the original instance of the
907 symbol. */
909 if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
910 && machopic_symbol_defined_p (symbol))
911 init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
913 assemble_integer (init, GET_MODE_SIZE (Pmode),
914 GET_MODE_ALIGNMENT (Pmode), 1);
917 return 1;
920 void
921 machopic_finish (FILE *asm_out_file)
923 if (machopic_indirections)
924 htab_traverse_noresize (machopic_indirections,
925 machopic_output_indirection,
926 asm_out_file);
930 machopic_operand_p (rtx op)
932 if (MACHOPIC_JUST_INDIRECT)
934 while (GET_CODE (op) == CONST)
935 op = XEXP (op, 0);
937 if (GET_CODE (op) == SYMBOL_REF)
938 return machopic_symbol_defined_p (op);
939 else
940 return 0;
943 while (GET_CODE (op) == CONST)
944 op = XEXP (op, 0);
946 if (GET_CODE (op) == MINUS
947 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
948 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
949 && machopic_symbol_defined_p (XEXP (op, 0))
950 && machopic_symbol_defined_p (XEXP (op, 1)))
951 return 1;
953 return 0;
956 /* This function records whether a given name corresponds to a defined
957 or undefined function or variable, for machopic_classify_ident to
958 use later. */
960 void
961 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
963 rtx sym_ref;
965 /* Do the standard encoding things first. */
966 default_encode_section_info (decl, rtl, first);
968 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
969 return;
971 sym_ref = XEXP (rtl, 0);
972 if (TREE_CODE (decl) == VAR_DECL)
973 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
975 if (!DECL_EXTERNAL (decl)
976 && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
977 && ((TREE_STATIC (decl)
978 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
979 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
980 && DECL_INITIAL (decl) != error_mark_node)))
981 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
983 if (! TREE_PUBLIC (decl))
984 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
987 void
988 darwin_mark_decl_preserved (const char *name)
990 fprintf (asm_out_file, ".no_dead_strip ");
991 assemble_name (asm_out_file, name);
992 fputc ('\n', asm_out_file);
995 void
996 machopic_select_section (tree exp, int reloc,
997 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
999 void (*base_function)(void);
1000 bool weak_p = DECL_P (exp) && DECL_WEAK (exp);
1001 static void (* const base_funs[][2])(void) = {
1002 { text_section, text_coal_section },
1003 { unlikely_text_section, text_unlikely_coal_section },
1004 { readonly_data_section, const_coal_section },
1005 { const_data_section, const_data_coal_section },
1006 { data_section, data_coal_section }
1009 if (reloc == 0
1010 && (last_text_section == in_text_unlikely
1011 || last_text_section == in_text_unlikely_coal))
1012 reloc = 1;
1014 if (TREE_CODE (exp) == FUNCTION_DECL)
1015 base_function = base_funs[reloc][weak_p];
1016 else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1017 base_function = base_funs[2][weak_p];
1018 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1019 base_function = base_funs[3][weak_p];
1020 else
1021 base_function = base_funs[4][weak_p];
1023 if (TREE_CODE (exp) == STRING_CST
1024 && ((size_t) TREE_STRING_LENGTH (exp)
1025 == strlen (TREE_STRING_POINTER (exp)) + 1))
1026 cstring_section ();
1027 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1028 && flag_merge_constants)
1030 tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1032 if (TREE_CODE (size) == INTEGER_CST &&
1033 TREE_INT_CST_LOW (size) == 4 &&
1034 TREE_INT_CST_HIGH (size) == 0)
1035 literal4_section ();
1036 else if (TREE_CODE (size) == INTEGER_CST &&
1037 TREE_INT_CST_LOW (size) == 8 &&
1038 TREE_INT_CST_HIGH (size) == 0)
1039 literal8_section ();
1040 else
1041 base_function ();
1043 else if (TREE_CODE (exp) == CONSTRUCTOR
1044 && TREE_TYPE (exp)
1045 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1046 && TYPE_NAME (TREE_TYPE (exp)))
1048 tree name = TYPE_NAME (TREE_TYPE (exp));
1049 if (TREE_CODE (name) == TYPE_DECL)
1050 name = DECL_NAME (name);
1052 if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1054 if (flag_next_runtime)
1055 objc_constant_string_object_section ();
1056 else
1057 objc_string_object_section ();
1059 else
1060 base_function ();
1062 else if (TREE_CODE (exp) == VAR_DECL &&
1063 DECL_NAME (exp) &&
1064 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1065 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1066 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1068 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1070 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1071 objc_cls_meth_section ();
1072 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1073 objc_inst_meth_section ();
1074 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1075 objc_cat_cls_meth_section ();
1076 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1077 objc_cat_inst_meth_section ();
1078 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1079 objc_class_vars_section ();
1080 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1081 objc_instance_vars_section ();
1082 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1083 objc_cat_cls_meth_section ();
1084 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1085 objc_class_names_section ();
1086 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1087 objc_meth_var_names_section ();
1088 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1089 objc_meth_var_types_section ();
1090 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1091 objc_cls_refs_section ();
1092 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1093 objc_class_section ();
1094 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1095 objc_meta_class_section ();
1096 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1097 objc_category_section ();
1098 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1099 objc_selector_refs_section ();
1100 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1101 objc_selector_fixup_section ();
1102 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1103 objc_symbols_section ();
1104 else if (!strncmp (name, "_OBJC_MODULES", 13))
1105 objc_module_info_section ();
1106 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1107 objc_image_info_section ();
1108 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1109 objc_cat_inst_meth_section ();
1110 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1111 objc_cat_cls_meth_section ();
1112 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1113 objc_cat_cls_meth_section ();
1114 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1115 objc_protocol_section ();
1116 else
1117 base_function ();
1119 /* ::operator new and ::operator delete must be coalesced, even
1120 if not weak. There are 8 variants that we look for. */
1121 else if (TREE_CODE (exp) == FUNCTION_DECL
1122 && ! DECL_ONE_ONLY (exp))
1124 const char * name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (exp));
1125 if (name[0] == '_' && name[1] == 'Z'
1126 && ((name[2] == 'n' && (name[3] == 'a' || name[3] == 'w')
1127 && name[4] == 'm')
1128 || (name[2] == 'd' && (name[3] == 'a' || name[3] == 'l')
1129 && name[4] == 'P' && name[5] == 'v')))
1131 bool delete_p = name[2] == 'd';
1132 if (name[5 + delete_p] == 0
1133 || strcmp (name + 5 + delete_p, "KSt9nothrow_t") == 0)
1134 base_funs[reloc][1] ();
1135 else
1136 base_function ();
1138 else
1139 base_function ();
1141 else
1142 base_function ();
1145 /* This can be called with address expressions as "rtx".
1146 They must go in "const". */
1148 void
1149 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1150 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1152 if (GET_MODE_SIZE (mode) == 8
1153 && (GET_CODE (x) == CONST_INT
1154 || GET_CODE (x) == CONST_DOUBLE))
1155 literal8_section ();
1156 else if (GET_MODE_SIZE (mode) == 4
1157 && (GET_CODE (x) == CONST_INT
1158 || GET_CODE (x) == CONST_DOUBLE))
1159 literal4_section ();
1160 else if (MACHOPIC_INDIRECT
1161 && (GET_CODE (x) == SYMBOL_REF
1162 || GET_CODE (x) == CONST
1163 || GET_CODE (x) == LABEL_REF))
1164 const_data_section ();
1165 else
1166 const_section ();
1169 void
1170 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1172 if (MACHOPIC_INDIRECT)
1173 mod_init_section ();
1174 else
1175 constructor_section ();
1176 assemble_align (POINTER_SIZE);
1177 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1179 if (! MACHOPIC_INDIRECT)
1180 fprintf (asm_out_file, ".reference .constructors_used\n");
1183 void
1184 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1186 if (MACHOPIC_INDIRECT)
1187 mod_term_section ();
1188 else
1189 destructor_section ();
1190 assemble_align (POINTER_SIZE);
1191 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1193 if (! MACHOPIC_INDIRECT)
1194 fprintf (asm_out_file, ".reference .destructors_used\n");
1197 void
1198 darwin_globalize_label (FILE *stream, const char *name)
1200 if (!!strncmp (name, "_OBJC_", 6))
1201 default_globalize_label (stream, name);
1204 void
1205 darwin_asm_named_section (const char *name,
1206 unsigned int flags ATTRIBUTE_UNUSED,
1207 tree decl ATTRIBUTE_UNUSED)
1209 fprintf (asm_out_file, "\t.section %s\n", name);
1212 void
1213 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1215 /* Darwin does not use unique sections. */
1218 /* Handle a "weak_import" attribute; arguments as in
1219 struct attribute_spec.handler. */
1221 tree
1222 darwin_handle_weak_import_attribute (tree *node, tree name,
1223 tree ARG_UNUSED (args),
1224 int ARG_UNUSED (flags),
1225 bool * no_add_attrs)
1227 if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1229 warning (OPT_Wattributes, "%qs attribute ignored",
1230 IDENTIFIER_POINTER (name));
1231 *no_add_attrs = true;
1233 else
1234 declare_weak (*node);
1236 return NULL_TREE;
1239 static void
1240 no_dead_strip (FILE *file, const char *lab)
1242 fprintf (file, ".no_dead_strip %s\n", lab);
1245 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1246 The third parameter is nonzero if this is for exception handling.
1247 The fourth parameter is nonzero if this is just a placeholder for an
1248 FDE that we are omitting. */
1250 void
1251 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1253 tree id = DECL_ASSEMBLER_NAME (decl)
1254 ? DECL_ASSEMBLER_NAME (decl)
1255 : DECL_NAME (decl);
1257 const char *prefix = user_label_prefix;
1259 const char *base = IDENTIFIER_POINTER (id);
1260 unsigned int base_len = IDENTIFIER_LENGTH (id);
1262 const char *suffix = ".eh";
1264 int need_quotes = name_needs_quotes (base);
1265 int quotes_len = need_quotes ? 2 : 0;
1266 char *lab;
1268 if (! for_eh)
1269 suffix = ".eh1";
1271 lab = xmalloc (strlen (prefix)
1272 + base_len + strlen (suffix) + quotes_len + 1);
1273 lab[0] = '\0';
1275 if (need_quotes)
1276 strcat(lab, "\"");
1277 strcat(lab, prefix);
1278 strcat(lab, base);
1279 strcat(lab, suffix);
1280 if (need_quotes)
1281 strcat(lab, "\"");
1283 if (TREE_PUBLIC (decl))
1284 fprintf (file, "\t%s %s\n",
1285 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1286 ? ".globl"
1287 : ".private_extern"),
1288 lab);
1290 if (DECL_WEAK (decl))
1291 fprintf (file, "\t.weak_definition %s\n", lab);
1293 if (empty)
1295 fprintf (file, "%s = 0\n", lab);
1297 /* Mark the absolute .eh and .eh1 style labels as needed to
1298 ensure that we don't dead code strip them and keep such
1299 labels from another instantiation point until we can fix this
1300 properly with group comdat support. */
1301 no_dead_strip (file, lab);
1303 else
1304 fprintf (file, "%s:\n", lab);
1306 free (lab);
1309 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1311 void
1312 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1314 const char *nlp_name;
1316 gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1318 nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1319 fputs ("\t.long\t", file);
1320 ASM_OUTPUT_LABELREF (file, nlp_name);
1321 fputs ("-.", file);
1324 /* Emit an assembler directive to set visibility for a symbol. The
1325 only supported visibilities are VISIBILITY_DEFAULT and
1326 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1327 extern". There is no MACH-O equivalent of ELF's
1328 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1330 void
1331 darwin_assemble_visibility (tree decl, int vis)
1333 if (vis == VISIBILITY_DEFAULT)
1335 else if (vis == VISIBILITY_HIDDEN)
1337 fputs ("\t.private_extern ", asm_out_file);
1338 assemble_name (asm_out_file,
1339 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1340 fputs ("\n", asm_out_file);
1342 else
1343 warning (OPT_Wattributes, "internal and protected visibility attributes "
1344 "not supported in this configuration; ignored");
1347 /* Output a difference of two labels that will be an assembly time
1348 constant if the two labels are local. (.long lab1-lab2 will be
1349 very different if lab1 is at the boundary between two sections; it
1350 will be relocated according to the second section, not the first,
1351 so one ends up with a difference between labels in different
1352 sections, which is bad in the dwarf2 eh context for instance.) */
1354 static int darwin_dwarf_label_counter;
1356 void
1357 darwin_asm_output_dwarf_delta (FILE *file, int size,
1358 const char *lab1, const char *lab2)
1360 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1361 && lab2[0] == '*' && lab2[1] == 'L');
1362 const char *directive = (size == 8 ? ".quad" : ".long");
1364 if (islocaldiff)
1365 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1366 else
1367 fprintf (file, "\t%s\t", directive);
1368 assemble_name_raw (file, lab1);
1369 fprintf (file, "-");
1370 assemble_name_raw (file, lab2);
1371 if (islocaldiff)
1372 fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1375 void
1376 darwin_file_end (void)
1378 machopic_finish (asm_out_file);
1379 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1381 constructor_section ();
1382 destructor_section ();
1383 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1385 fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1388 /* Cross-module name binding. Darwin does not support overriding
1389 functions at dynamic-link time. */
1391 bool
1392 darwin_binds_local_p (tree decl)
1394 return default_binds_local_p_1 (decl, 0);
1397 #include "gt-darwin.h"