Merged revisions 96681,96683-96686,96689-96692,96698-96701,96705,96708,96710,96712...
[official-gcc.git] / gcc / config / darwin.c
blob602df2f7f703a82139b82b7add4ae7d2fb14b89a
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, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, 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 "errors.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);
1051 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1052 objc_constant_string_object_section ();
1053 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1054 objc_string_object_section ();
1055 else
1056 base_function ();
1058 else if (TREE_CODE (exp) == VAR_DECL &&
1059 DECL_NAME (exp) &&
1060 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1061 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1062 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1064 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1066 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1067 objc_cls_meth_section ();
1068 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1069 objc_inst_meth_section ();
1070 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1071 objc_cat_cls_meth_section ();
1072 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1073 objc_cat_inst_meth_section ();
1074 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1075 objc_class_vars_section ();
1076 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1077 objc_instance_vars_section ();
1078 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1079 objc_cat_cls_meth_section ();
1080 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1081 objc_class_names_section ();
1082 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1083 objc_meth_var_names_section ();
1084 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1085 objc_meth_var_types_section ();
1086 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1087 objc_cls_refs_section ();
1088 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1089 objc_class_section ();
1090 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1091 objc_meta_class_section ();
1092 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1093 objc_category_section ();
1094 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1095 objc_selector_refs_section ();
1096 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1097 objc_selector_fixup_section ();
1098 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1099 objc_symbols_section ();
1100 else if (!strncmp (name, "_OBJC_MODULES", 13))
1101 objc_module_info_section ();
1102 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1103 objc_image_info_section ();
1104 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1105 objc_cat_inst_meth_section ();
1106 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1107 objc_cat_cls_meth_section ();
1108 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1109 objc_cat_cls_meth_section ();
1110 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1111 objc_protocol_section ();
1112 else
1113 base_function ();
1115 /* ::operator new and ::operator delete must be coalesced, even
1116 if not weak. There are 8 variants that we look for. */
1117 else if (TREE_CODE (exp) == FUNCTION_DECL
1118 && ! DECL_ONE_ONLY (exp))
1120 const char * name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (exp));
1121 if (name[0] == '_' && name[1] == 'Z'
1122 && ((name[2] == 'n' && (name[3] == 'a' || name[3] == 'w')
1123 && name[4] == 'm')
1124 || (name[2] == 'd' && (name[3] == 'a' || name[3] == 'l')
1125 && name[4] == 'P' && name[5] == 'v')))
1127 bool delete_p = name[2] == 'd';
1128 if (name[5 + delete_p] == 0
1129 || strcmp (name + 5 + delete_p, "KSt9nothrow_t") == 0)
1130 base_funs[reloc][1] ();
1131 else
1132 base_function ();
1134 else
1135 base_function ();
1137 else
1138 base_function ();
1141 /* This can be called with address expressions as "rtx".
1142 They must go in "const". */
1144 void
1145 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1146 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1148 if (GET_MODE_SIZE (mode) == 8
1149 && (GET_CODE (x) == CONST_INT
1150 || GET_CODE (x) == CONST_DOUBLE))
1151 literal8_section ();
1152 else if (GET_MODE_SIZE (mode) == 4
1153 && (GET_CODE (x) == CONST_INT
1154 || GET_CODE (x) == CONST_DOUBLE))
1155 literal4_section ();
1156 else if (MACHOPIC_INDIRECT
1157 && (GET_CODE (x) == SYMBOL_REF
1158 || GET_CODE (x) == CONST
1159 || GET_CODE (x) == LABEL_REF))
1160 const_data_section ();
1161 else
1162 const_section ();
1165 void
1166 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1168 if (MACHOPIC_INDIRECT)
1169 mod_init_section ();
1170 else
1171 constructor_section ();
1172 assemble_align (POINTER_SIZE);
1173 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1175 if (! MACHOPIC_INDIRECT)
1176 fprintf (asm_out_file, ".reference .constructors_used\n");
1179 void
1180 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1182 if (MACHOPIC_INDIRECT)
1183 mod_term_section ();
1184 else
1185 destructor_section ();
1186 assemble_align (POINTER_SIZE);
1187 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1189 if (! MACHOPIC_INDIRECT)
1190 fprintf (asm_out_file, ".reference .destructors_used\n");
1193 void
1194 darwin_globalize_label (FILE *stream, const char *name)
1196 if (!!strncmp (name, "_OBJC_", 6))
1197 default_globalize_label (stream, name);
1200 void
1201 darwin_asm_named_section (const char *name,
1202 unsigned int flags ATTRIBUTE_UNUSED,
1203 tree decl ATTRIBUTE_UNUSED)
1205 fprintf (asm_out_file, "\t.section %s\n", name);
1208 void
1209 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1211 /* Darwin does not use unique sections. */
1214 /* Handle a "weak_import" attribute; arguments as in
1215 struct attribute_spec.handler. */
1217 tree
1218 darwin_handle_weak_import_attribute (tree *node, tree name,
1219 tree ARG_UNUSED (args),
1220 int ARG_UNUSED (flags),
1221 bool * no_add_attrs)
1223 if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1225 warning (0, "%qs attribute ignored", IDENTIFIER_POINTER (name));
1226 *no_add_attrs = true;
1228 else
1229 declare_weak (*node);
1231 return NULL_TREE;
1234 static void
1235 no_dead_strip (FILE *file, const char *lab)
1237 fprintf (file, ".no_dead_strip %s\n", lab);
1240 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1241 The third parameter is nonzero if this is for exception handling.
1242 The fourth parameter is nonzero if this is just a placeholder for an
1243 FDE that we are omitting. */
1245 void
1246 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1248 tree id = DECL_ASSEMBLER_NAME (decl)
1249 ? DECL_ASSEMBLER_NAME (decl)
1250 : DECL_NAME (decl);
1252 const char *prefix = user_label_prefix;
1254 const char *base = IDENTIFIER_POINTER (id);
1255 unsigned int base_len = IDENTIFIER_LENGTH (id);
1257 const char *suffix = ".eh";
1259 int need_quotes = name_needs_quotes (base);
1260 int quotes_len = need_quotes ? 2 : 0;
1261 char *lab;
1263 if (! for_eh)
1264 suffix = ".eh1";
1266 lab = xmalloc (strlen (prefix)
1267 + base_len + strlen (suffix) + quotes_len + 1);
1268 lab[0] = '\0';
1270 if (need_quotes)
1271 strcat(lab, "\"");
1272 strcat(lab, prefix);
1273 strcat(lab, base);
1274 strcat(lab, suffix);
1275 if (need_quotes)
1276 strcat(lab, "\"");
1278 if (TREE_PUBLIC (decl))
1279 fprintf (file, "\t%s %s\n",
1280 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1281 ? ".globl"
1282 : ".private_extern"),
1283 lab);
1285 if (DECL_WEAK (decl))
1286 fprintf (file, "\t.weak_definition %s\n", lab);
1288 if (empty)
1290 fprintf (file, "%s = 0\n", lab);
1292 /* Mark the absolute .eh and .eh1 style labels as needed to
1293 ensure that we don't dead code strip them and keep such
1294 labels from another instantiation point until we can fix this
1295 properly with group comdat support. */
1296 no_dead_strip (file, lab);
1298 else
1299 fprintf (file, "%s:\n", lab);
1301 free (lab);
1304 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1306 void
1307 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1309 const char *nlp_name;
1311 gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1313 nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1314 fputs ("\t.long\t", file);
1315 ASM_OUTPUT_LABELREF (file, nlp_name);
1316 fputs ("-.", file);
1319 /* Emit an assembler directive to set visibility for a symbol. The
1320 only supported visibilities are VISIBILITY_DEFAULT and
1321 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1322 extern". There is no MACH-O equivalent of ELF's
1323 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1325 void
1326 darwin_assemble_visibility (tree decl, int vis)
1328 if (vis == VISIBILITY_DEFAULT)
1330 else if (vis == VISIBILITY_HIDDEN)
1332 fputs ("\t.private_extern ", asm_out_file);
1333 assemble_name (asm_out_file,
1334 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1335 fputs ("\n", asm_out_file);
1337 else
1338 warning (0, "internal and protected visibility attributes not supported "
1339 "in this configuration; ignored");
1342 /* Output a difference of two labels that will be an assembly time
1343 constant if the two labels are local. (.long lab1-lab2 will be
1344 very different if lab1 is at the boundary between two sections; it
1345 will be relocated according to the second section, not the first,
1346 so one ends up with a difference between labels in different
1347 sections, which is bad in the dwarf2 eh context for instance.) */
1349 static int darwin_dwarf_label_counter;
1351 void
1352 darwin_asm_output_dwarf_delta (FILE *file, int size,
1353 const char *lab1, const char *lab2)
1355 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1356 && lab2[0] == '*' && lab2[1] == 'L');
1357 const char *directive = (size == 8 ? ".quad" : ".long");
1359 if (islocaldiff)
1360 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1361 else
1362 fprintf (file, "\t%s\t", directive);
1363 assemble_name_raw (file, lab1);
1364 fprintf (file, "-");
1365 assemble_name_raw (file, lab2);
1366 if (islocaldiff)
1367 fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1370 void
1371 darwin_file_end (void)
1373 machopic_finish (asm_out_file);
1374 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1376 constructor_section ();
1377 destructor_section ();
1378 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1380 fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1383 #include "gt-darwin.h"