* emit-rtl.c (gen_const_mem): New.
[official-gcc.git] / gcc / config / darwin.c
blob579daf876fac51b719fce1adf989bbe659236c46
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"
45 #include "hashtab.h"
47 /* Nonzero if the user passes the -mone-byte-bool switch, which forces
48 sizeof(bool) to be 1. */
49 const char *darwin_one_byte_bool = 0;
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 static int
67 machopic_symbol_defined_p (rtx sym_ref)
69 return ((SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
70 /* Local symbols must always be defined. */
71 || SYMBOL_REF_LOCAL_P (sym_ref));
74 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
75 reference, which will not be changed. */
77 enum machopic_addr_class
78 machopic_classify_symbol (rtx sym_ref)
80 int flags;
81 bool function_p;
83 flags = SYMBOL_REF_FLAGS (sym_ref);
84 function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
85 if (machopic_symbol_defined_p (sym_ref))
86 return (function_p
87 ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
88 else
89 return (function_p
90 ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
93 static int
94 machopic_data_defined_p (rtx sym_ref)
96 switch (machopic_classify_symbol (sym_ref))
98 case MACHOPIC_DEFINED_DATA:
99 return 1;
100 default:
101 return 0;
105 void
106 machopic_define_symbol (rtx mem)
108 rtx sym_ref;
109 if (GET_CODE (mem) != MEM)
110 abort ();
111 sym_ref = XEXP (mem, 0);
112 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
115 static GTY(()) char * function_base;
117 const char *
118 machopic_function_base_name (void)
120 /* if dynamic-no-pic is on, we should not get here */
121 if (MACHO_DYNAMIC_NO_PIC_P)
122 abort ();
124 if (function_base == NULL)
125 function_base =
126 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
128 current_function_uses_pic_offset_table = 1;
130 return function_base;
133 /* Return a SYMBOL_REF for the PIC function base. */
136 machopic_function_base_sym (void)
138 rtx sym_ref;
140 sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
141 SYMBOL_REF_FLAGS (sym_ref)
142 |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
143 return sym_ref;
146 static GTY(()) const char * function_base_func_name;
147 static GTY(()) int current_pic_label_num;
149 void
150 machopic_output_function_base_name (FILE *file)
152 const char *current_name;
154 /* If dynamic-no-pic is on, we should not get here. */
155 if (MACHO_DYNAMIC_NO_PIC_P)
156 abort ();
157 current_name =
158 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
159 if (function_base_func_name != current_name)
161 ++current_pic_label_num;
162 function_base_func_name = current_name;
164 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
167 /* The suffix attached to non-lazy pointer symbols. */
168 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
169 /* The suffix attached to stub symbols. */
170 #define STUB_SUFFIX "$stub"
172 typedef struct machopic_indirection GTY (())
174 /* The SYMBOL_REF for the entity referenced. */
175 rtx symbol;
176 /* The IDENTIFIER_NODE giving the name of the stub or non-lazy
177 pointer. */
178 tree ptr_name;
179 /* True iff this entry is for a stub (as opposed to a non-lazy
180 pointer). */
181 bool stub_p;
182 /* True iff this stub or pointer pointer has been referenced. */
183 bool used;
184 } machopic_indirection;
186 /* A table mapping stub names and non-lazy pointer names to
187 SYMBOL_REFs for the stubbed-to and pointed-to entities. */
189 static GTY ((param_is (struct machopic_indirection))) htab_t
190 machopic_indirections;
192 /* Return a hash value for a SLOT in the indirections hash table. */
194 static hashval_t
195 machopic_indirection_hash (const void *slot)
197 const machopic_indirection *p = (const machopic_indirection *) slot;
198 return IDENTIFIER_HASH_VALUE (p->ptr_name);
201 /* Returns true if the KEY is the same as that associated with
202 SLOT. */
204 static int
205 machopic_indirection_eq (const void *slot, const void *key)
207 return ((const machopic_indirection *) slot)->ptr_name == (tree) key;
210 /* Return the name of the non-lazy pointer (if STUB_P is false) or
211 stub (if STUB_B is true) corresponding to the given name. */
213 const char *
214 machopic_indirection_name (rtx sym_ref, bool stub_p)
216 char *buffer;
217 const char *name = XSTR (sym_ref, 0);
218 int namelen = strlen (name);
219 tree ptr_name;
220 machopic_indirection *p;
222 /* Construct the name of the non-lazy pointer or stub. */
223 if (stub_p)
225 int needs_quotes = name_needs_quotes (name);
226 buffer = alloca (strlen ("&L")
227 + namelen
228 + strlen (STUB_SUFFIX)
229 + 2 /* possible quotes */
230 + 1 /* '\0' */);
232 if (needs_quotes)
234 if (name[0] == '*')
235 sprintf (buffer, "&\"L%s" STUB_SUFFIX "\"", name + 1);
236 else
237 sprintf (buffer, "&\"L%s%s" STUB_SUFFIX "\"", user_label_prefix,
238 name);
240 else if (name[0] == '*')
241 sprintf (buffer, "&L%s" STUB_SUFFIX, name + 1);
242 else
243 sprintf (buffer, "&L%s%s" STUB_SUFFIX, user_label_prefix, name);
245 else
247 buffer = alloca (strlen ("&L")
248 + strlen (user_label_prefix)
249 + namelen
250 + strlen (NON_LAZY_POINTER_SUFFIX)
251 + 1 /* '\0' */);
252 if (name[0] == '*')
253 sprintf (buffer, "&L%s" NON_LAZY_POINTER_SUFFIX, name + 1);
254 else
255 sprintf (buffer, "&L%s%s" NON_LAZY_POINTER_SUFFIX,
256 user_label_prefix, name);
259 /* See if we already have it. */
260 ptr_name = maybe_get_identifier (buffer);
261 /* If not, create a mapping from the non-lazy pointer to the
262 SYMBOL_REF. */
263 if (!ptr_name)
265 void **slot;
266 ptr_name = get_identifier (buffer);
267 p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
268 p->symbol = sym_ref;
269 p->ptr_name = ptr_name;
270 p->stub_p = stub_p;
271 p->used = 0;
272 if (!machopic_indirections)
273 machopic_indirections
274 = htab_create_ggc (37,
275 machopic_indirection_hash,
276 machopic_indirection_eq,
277 /*htab_del=*/NULL);
278 slot = htab_find_slot_with_hash (machopic_indirections, ptr_name,
279 IDENTIFIER_HASH_VALUE (ptr_name),
280 INSERT);
281 *((machopic_indirection **) slot) = p;
284 return IDENTIFIER_POINTER (ptr_name);
287 /* Return the name of the stub for the mcount function. */
289 const char*
290 machopic_mcount_stub_name (void)
292 return "&L*mcount$stub";
295 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
296 or non-lazy pointer as used -- and mark the object to which the
297 pointer/stub refers as used as well, since the pointer/stub will
298 emit a reference to it. */
300 void
301 machopic_validate_stub_or_non_lazy_ptr (const char *name)
303 tree ident = get_identifier (name);
305 machopic_indirection *p;
307 p = ((machopic_indirection *)
308 (htab_find_with_hash (machopic_indirections, ident,
309 IDENTIFIER_HASH_VALUE (ident))));
310 if (p)
312 p->used = 1;
313 mark_referenced (ident);
314 mark_referenced (get_identifier (XSTR (p->symbol, 0)));
318 /* Transform ORIG, which may be any data source, to the corresponding
319 source using indirections. */
322 machopic_indirect_data_reference (rtx orig, rtx reg)
324 rtx ptr_ref = orig;
326 if (! MACHOPIC_INDIRECT)
327 return orig;
329 if (GET_CODE (orig) == SYMBOL_REF)
331 int defined = machopic_data_defined_p (orig);
333 if (defined && MACHO_DYNAMIC_NO_PIC_P)
335 #if defined (TARGET_TOC)
336 emit_insn (GET_MODE (orig) == DImode
337 ? gen_macho_high_di (reg, orig)
338 : gen_macho_high (reg, orig));
339 emit_insn (GET_MODE (orig) == DImode
340 ? gen_macho_low_di (reg, reg, orig)
341 : gen_macho_low (reg, reg, orig));
342 #else
343 /* some other cpu -- writeme! */
344 abort ();
345 #endif
346 return reg;
348 else if (defined)
350 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
351 rtx pic_base = machopic_function_base_sym ();
352 rtx offset = gen_rtx_CONST (Pmode,
353 gen_rtx_MINUS (Pmode, orig, pic_base));
354 #endif
356 #if defined (TARGET_TOC) /* i.e., PowerPC */
357 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
359 if (reg == NULL)
360 abort ();
362 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
363 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
364 gen_rtx_HIGH (Pmode, offset))));
365 emit_insn (gen_rtx_SET (Pmode, reg,
366 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
368 orig = reg;
369 #else
370 #if defined (HAVE_lo_sum)
371 if (reg == 0) abort ();
373 emit_insn (gen_rtx_SET (VOIDmode, reg,
374 gen_rtx_HIGH (Pmode, offset)));
375 emit_insn (gen_rtx_SET (VOIDmode, reg,
376 gen_rtx_LO_SUM (Pmode, reg, offset)));
377 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
379 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
380 #endif
381 #endif
382 return orig;
385 ptr_ref = (gen_rtx_SYMBOL_REF
386 (Pmode,
387 machopic_indirection_name (orig, /*stub_p=*/false)));
389 SYMBOL_REF_DECL (ptr_ref) = SYMBOL_REF_DECL (orig);
391 ptr_ref = gen_const_mem (Pmode, ptr_ref);
393 return ptr_ref;
395 else if (GET_CODE (orig) == CONST)
397 rtx base, result;
399 /* legitimize both operands of the PLUS */
400 if (GET_CODE (XEXP (orig, 0)) == PLUS)
402 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
403 reg);
404 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
405 (base == reg ? 0 : reg));
407 else
408 return orig;
410 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
411 result = plus_constant (base, INTVAL (orig));
412 else
413 result = gen_rtx_PLUS (Pmode, base, orig);
415 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
417 if (reg)
419 emit_move_insn (reg, result);
420 result = reg;
422 else
424 result = force_reg (GET_MODE (result), result);
428 return result;
431 else if (GET_CODE (orig) == MEM)
432 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
433 /* When the target is i386, this code prevents crashes due to the
434 compiler's ignorance on how to move the PIC base register to
435 other registers. (The reload phase sometimes introduces such
436 insns.) */
437 else if (GET_CODE (orig) == PLUS
438 && GET_CODE (XEXP (orig, 0)) == REG
439 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
440 #ifdef I386
441 /* Prevent the same register from being erroneously used
442 as both the base and index registers. */
443 && GET_CODE (XEXP (orig, 1)) == CONST
444 #endif
445 && reg)
447 emit_move_insn (reg, XEXP (orig, 0));
448 XEXP (ptr_ref, 0) = reg;
450 return ptr_ref;
453 /* Transform TARGET (a MEM), which is a function call target, to the
454 corresponding symbol_stub if necessary. Return a new MEM. */
457 machopic_indirect_call_target (rtx target)
459 if (GET_CODE (target) != MEM)
460 return target;
462 if (MACHOPIC_INDIRECT
463 && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
464 && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
465 & MACHO_SYMBOL_FLAG_DEFINED))
467 rtx sym_ref = XEXP (target, 0);
468 const char *stub_name = machopic_indirection_name (sym_ref,
469 /*stub_p=*/true);
470 enum machine_mode mode = GET_MODE (sym_ref);
471 tree decl = SYMBOL_REF_DECL (sym_ref);
473 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
474 SYMBOL_REF_DECL (XEXP (target, 0)) = decl;
475 MEM_READONLY_P (target) = 1;
476 MEM_NOTRAP_P (target) = 1;
479 return target;
483 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
485 rtx pic_ref = orig;
487 if (! MACHOPIC_INDIRECT)
488 return orig;
490 /* First handle a simple SYMBOL_REF or LABEL_REF */
491 if (GET_CODE (orig) == LABEL_REF
492 || (GET_CODE (orig) == SYMBOL_REF
495 /* addr(foo) = &func+(foo-func) */
496 rtx pic_base;
498 orig = machopic_indirect_data_reference (orig, reg);
500 if (GET_CODE (orig) == PLUS
501 && GET_CODE (XEXP (orig, 0)) == REG)
503 if (reg == 0)
504 return force_reg (mode, orig);
506 emit_move_insn (reg, orig);
507 return reg;
510 /* if dynamic-no-pic then use 0 as the pic base */
511 if (MACHO_DYNAMIC_NO_PIC_P)
512 pic_base = CONST0_RTX (Pmode);
513 else
514 pic_base = machopic_function_base_sym ();
516 if (GET_CODE (orig) == MEM)
518 if (reg == 0)
520 if (reload_in_progress)
521 abort ();
522 else
523 reg = gen_reg_rtx (Pmode);
526 #ifdef HAVE_lo_sum
527 if (MACHO_DYNAMIC_NO_PIC_P
528 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
529 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
531 #if defined (TARGET_TOC) /* ppc */
532 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
533 rtx asym = XEXP (orig, 0);
534 rtx mem;
536 emit_insn (mode == DImode
537 ? gen_macho_high_di (temp_reg, asym)
538 : gen_macho_high (temp_reg, asym));
539 mem = gen_const_mem (GET_MODE (orig),
540 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
541 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
542 #else
543 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
544 abort ();
545 #endif
546 pic_ref = reg;
548 else
549 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
550 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
552 rtx offset = gen_rtx_CONST (Pmode,
553 gen_rtx_MINUS (Pmode,
554 XEXP (orig, 0),
555 pic_base));
556 #if defined (TARGET_TOC) /* i.e., PowerPC */
557 /* Generating a new reg may expose opportunities for
558 common subexpression elimination. */
559 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
560 rtx mem;
561 rtx insn;
562 rtx sum;
564 sum = gen_rtx_HIGH (Pmode, offset);
565 if (! MACHO_DYNAMIC_NO_PIC_P)
566 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
568 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
570 mem = gen_const_mem (GET_MODE (orig),
571 gen_rtx_LO_SUM (Pmode,
572 hi_sum_reg, offset));
573 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
574 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
575 REG_NOTES (insn));
577 pic_ref = reg;
578 #else
579 emit_insn (gen_rtx_USE (VOIDmode,
580 gen_rtx_REG (Pmode,
581 PIC_OFFSET_TABLE_REGNUM)));
583 emit_insn (gen_rtx_SET (VOIDmode, reg,
584 gen_rtx_HIGH (Pmode,
585 gen_rtx_CONST (Pmode,
586 offset))));
587 emit_insn (gen_rtx_SET (VOIDmode, reg,
588 gen_rtx_LO_SUM (Pmode, reg,
589 gen_rtx_CONST (Pmode, offset))));
590 pic_ref = gen_rtx_PLUS (Pmode,
591 pic_offset_table_rtx, reg);
592 #endif
594 else
595 #endif /* HAVE_lo_sum */
597 rtx pic = pic_offset_table_rtx;
598 if (GET_CODE (pic) != REG)
600 emit_move_insn (reg, pic);
601 pic = reg;
603 #if 0
604 emit_insn (gen_rtx_USE (VOIDmode,
605 gen_rtx_REG (Pmode,
606 PIC_OFFSET_TABLE_REGNUM)));
607 #endif
609 pic_ref = gen_rtx_PLUS (Pmode,
610 pic,
611 gen_rtx_CONST (Pmode,
612 gen_rtx_MINUS (Pmode,
613 XEXP (orig, 0),
614 pic_base)));
617 #if !defined (TARGET_TOC)
618 emit_move_insn (reg, pic_ref);
619 pic_ref = gen_const_mem (GET_MODE (orig), reg);
620 #endif
622 else
625 #ifdef HAVE_lo_sum
626 if (GET_CODE (orig) == SYMBOL_REF
627 || GET_CODE (orig) == LABEL_REF)
629 rtx offset = gen_rtx_CONST (Pmode,
630 gen_rtx_MINUS (Pmode,
631 orig, pic_base));
632 #if defined (TARGET_TOC) /* i.e., PowerPC */
633 rtx hi_sum_reg;
635 if (reg == 0)
637 if (reload_in_progress)
638 abort ();
639 else
640 reg = gen_reg_rtx (Pmode);
643 hi_sum_reg = reg;
645 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
646 (MACHO_DYNAMIC_NO_PIC_P)
647 ? gen_rtx_HIGH (Pmode, offset)
648 : gen_rtx_PLUS (Pmode,
649 pic_offset_table_rtx,
650 gen_rtx_HIGH (Pmode,
651 offset))));
652 emit_insn (gen_rtx_SET (VOIDmode, reg,
653 gen_rtx_LO_SUM (Pmode,
654 hi_sum_reg, offset)));
655 pic_ref = reg;
656 #else
657 emit_insn (gen_rtx_SET (VOIDmode, reg,
658 gen_rtx_HIGH (Pmode, offset)));
659 emit_insn (gen_rtx_SET (VOIDmode, reg,
660 gen_rtx_LO_SUM (Pmode, reg, offset)));
661 pic_ref = gen_rtx_PLUS (Pmode,
662 pic_offset_table_rtx, reg);
663 #endif
665 else
666 #endif /* HAVE_lo_sum */
668 if (GET_CODE (orig) == REG)
670 return orig;
672 else
674 rtx pic = pic_offset_table_rtx;
675 if (GET_CODE (pic) != REG)
677 emit_move_insn (reg, pic);
678 pic = reg;
680 #if 0
681 emit_insn (gen_rtx_USE (VOIDmode,
682 pic_offset_table_rtx));
683 #endif
684 pic_ref = gen_rtx_PLUS (Pmode,
685 pic,
686 gen_rtx_CONST (Pmode,
687 gen_rtx_MINUS (Pmode,
688 orig, pic_base)));
693 if (GET_CODE (pic_ref) != REG)
695 if (reg != 0)
697 emit_move_insn (reg, pic_ref);
698 return reg;
700 else
702 return force_reg (mode, pic_ref);
705 else
707 return pic_ref;
711 else if (GET_CODE (orig) == SYMBOL_REF)
712 return orig;
714 else if (GET_CODE (orig) == PLUS
715 && (GET_CODE (XEXP (orig, 0)) == MEM
716 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
717 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
718 && XEXP (orig, 0) != pic_offset_table_rtx
719 && GET_CODE (XEXP (orig, 1)) != REG)
722 rtx base;
723 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
725 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
726 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
727 Pmode, (base == reg ? 0 : reg));
728 if (GET_CODE (orig) == CONST_INT)
730 pic_ref = plus_constant (base, INTVAL (orig));
731 is_complex = 1;
733 else
734 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
736 if (reg && is_complex)
738 emit_move_insn (reg, pic_ref);
739 pic_ref = reg;
741 /* Likewise, should we set special REG_NOTEs here? */
744 else if (GET_CODE (orig) == CONST)
746 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
749 else if (GET_CODE (orig) == MEM
750 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
752 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
753 addr = replace_equiv_address (orig, addr);
754 emit_move_insn (reg, addr);
755 pic_ref = reg;
758 return pic_ref;
761 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
762 DATA is the FILE* for assembly output. Called from
763 htab_traverse. */
765 static int
766 machopic_output_indirection (void **slot, void *data)
768 machopic_indirection *p = *((machopic_indirection **) slot);
769 FILE *asm_out_file = (FILE *) data;
770 rtx symbol;
771 const char *sym_name;
772 const char *ptr_name;
774 if (!p->used)
775 return 1;
777 symbol = p->symbol;
778 sym_name = XSTR (symbol, 0);
779 ptr_name = IDENTIFIER_POINTER (p->ptr_name);
781 if (p->stub_p)
783 char *sym;
784 char *stub;
786 sym = alloca (strlen (sym_name) + 2);
787 if (sym_name[0] == '*' || sym_name[0] == '&')
788 strcpy (sym, sym_name + 1);
789 else if (sym_name[0] == '-' || sym_name[0] == '+')
790 strcpy (sym, sym_name);
791 else
792 sprintf (sym, "%s%s", user_label_prefix, sym_name);
794 stub = alloca (strlen (ptr_name) + 2);
795 if (ptr_name[0] == '*' || ptr_name[0] == '&')
796 strcpy (stub, ptr_name + 1);
797 else
798 sprintf (stub, "%s%s", user_label_prefix, ptr_name);
800 machopic_output_stub (asm_out_file, sym, stub);
802 else if (machopic_symbol_defined_p (symbol))
804 data_section ();
805 assemble_align (GET_MODE_ALIGNMENT (Pmode));
806 assemble_label (ptr_name);
807 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
808 GET_MODE_SIZE (Pmode),
809 GET_MODE_ALIGNMENT (Pmode), 1);
811 else
813 machopic_nl_symbol_ptr_section ();
814 assemble_name (asm_out_file, ptr_name);
815 fprintf (asm_out_file, ":\n");
817 fprintf (asm_out_file, "\t.indirect_symbol ");
818 assemble_name (asm_out_file, sym_name);
819 fprintf (asm_out_file, "\n");
821 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
822 GET_MODE_ALIGNMENT (Pmode), 1);
825 return 1;
828 void
829 machopic_finish (FILE *asm_out_file)
831 if (machopic_indirections)
832 htab_traverse_noresize (machopic_indirections,
833 machopic_output_indirection,
834 asm_out_file);
838 machopic_operand_p (rtx op)
840 if (MACHOPIC_JUST_INDIRECT)
842 while (GET_CODE (op) == CONST)
843 op = XEXP (op, 0);
845 if (GET_CODE (op) == SYMBOL_REF)
846 return machopic_symbol_defined_p (op);
847 else
848 return 0;
851 while (GET_CODE (op) == CONST)
852 op = XEXP (op, 0);
854 if (GET_CODE (op) == MINUS
855 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
856 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
857 && machopic_symbol_defined_p (XEXP (op, 0))
858 && machopic_symbol_defined_p (XEXP (op, 1)))
859 return 1;
861 return 0;
864 /* This function records whether a given name corresponds to a defined
865 or undefined function or variable, for machopic_classify_ident to
866 use later. */
868 void
869 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
871 rtx sym_ref;
873 /* Do the standard encoding things first. */
874 default_encode_section_info (decl, rtl, first);
876 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
877 return;
879 sym_ref = XEXP (rtl, 0);
880 if (TREE_CODE (decl) == VAR_DECL)
881 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
883 if (!DECL_EXTERNAL (decl)
884 && (!TREE_PUBLIC (decl) || (!DECL_ONE_ONLY (decl) && !DECL_WEAK (decl)))
885 && ((TREE_STATIC (decl)
886 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
887 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
888 && DECL_INITIAL (decl) != error_mark_node)))
889 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
892 void
893 darwin_make_decl_one_only (tree decl)
895 static const char *text_section = "__TEXT,__textcoal_nt,coalesced,no_toc";
896 static const char *data_section = "__DATA,__datacoal_nt,coalesced,no_toc";
898 const char *sec = TREE_CODE (decl) == FUNCTION_DECL
899 ? text_section
900 : data_section;
901 TREE_PUBLIC (decl) = 1;
902 DECL_ONE_ONLY (decl) = 1;
903 DECL_SECTION_NAME (decl) = build_string (strlen (sec), sec);
906 void
907 darwin_mark_decl_preserved (const char *name)
909 fprintf (asm_out_file, ".no_dead_strip ");
910 assemble_name (asm_out_file, name);
911 fputc ('\n', asm_out_file);
914 void
915 machopic_select_section (tree exp, int reloc,
916 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
918 void (*base_function)(void);
920 if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
921 base_function = readonly_data_section;
922 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
923 base_function = const_data_section;
924 else
925 base_function = data_section;
927 if (TREE_CODE (exp) == STRING_CST
928 && ((size_t) TREE_STRING_LENGTH (exp)
929 == strlen (TREE_STRING_POINTER (exp)) + 1))
930 cstring_section ();
931 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
932 && flag_merge_constants)
934 tree size = TYPE_SIZE (TREE_TYPE (exp));
936 if (TREE_CODE (size) == INTEGER_CST &&
937 TREE_INT_CST_LOW (size) == 4 &&
938 TREE_INT_CST_HIGH (size) == 0)
939 literal4_section ();
940 else if (TREE_CODE (size) == INTEGER_CST &&
941 TREE_INT_CST_LOW (size) == 8 &&
942 TREE_INT_CST_HIGH (size) == 0)
943 literal8_section ();
944 else
945 base_function ();
947 else if (TREE_CODE (exp) == CONSTRUCTOR
948 && TREE_TYPE (exp)
949 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
950 && TYPE_NAME (TREE_TYPE (exp)))
952 tree name = TYPE_NAME (TREE_TYPE (exp));
953 if (TREE_CODE (name) == TYPE_DECL)
954 name = DECL_NAME (name);
955 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
956 objc_constant_string_object_section ();
957 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
958 objc_string_object_section ();
959 else
960 base_function ();
962 else if (TREE_CODE (exp) == VAR_DECL &&
963 DECL_NAME (exp) &&
964 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
965 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
966 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
968 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
970 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
971 objc_cls_meth_section ();
972 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
973 objc_inst_meth_section ();
974 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
975 objc_cat_cls_meth_section ();
976 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
977 objc_cat_inst_meth_section ();
978 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
979 objc_class_vars_section ();
980 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
981 objc_instance_vars_section ();
982 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
983 objc_cat_cls_meth_section ();
984 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
985 objc_class_names_section ();
986 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
987 objc_meth_var_names_section ();
988 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
989 objc_meth_var_types_section ();
990 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
991 objc_cls_refs_section ();
992 else if (!strncmp (name, "_OBJC_CLASS_", 12))
993 objc_class_section ();
994 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
995 objc_meta_class_section ();
996 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
997 objc_category_section ();
998 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
999 objc_selector_refs_section ();
1000 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1001 objc_selector_fixup_section ();
1002 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1003 objc_symbols_section ();
1004 else if (!strncmp (name, "_OBJC_MODULES", 13))
1005 objc_module_info_section ();
1006 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1007 objc_image_info_section ();
1008 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1009 objc_cat_inst_meth_section ();
1010 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1011 objc_cat_cls_meth_section ();
1012 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1013 objc_cat_cls_meth_section ();
1014 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1015 objc_protocol_section ();
1016 else
1017 base_function ();
1019 else
1020 base_function ();
1023 /* This can be called with address expressions as "rtx".
1024 They must go in "const". */
1026 void
1027 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1028 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1030 if (GET_MODE_SIZE (mode) == 8)
1031 literal8_section ();
1032 else if (GET_MODE_SIZE (mode) == 4
1033 && (GET_CODE (x) == CONST_INT
1034 || GET_CODE (x) == CONST_DOUBLE))
1035 literal4_section ();
1036 else if (MACHOPIC_INDIRECT
1037 && (GET_CODE (x) == SYMBOL_REF
1038 || GET_CODE (x) == CONST
1039 || GET_CODE (x) == LABEL_REF))
1040 const_data_section ();
1041 else
1042 const_section ();
1045 void
1046 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1048 if (MACHOPIC_INDIRECT)
1049 mod_init_section ();
1050 else
1051 constructor_section ();
1052 assemble_align (POINTER_SIZE);
1053 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1055 if (! MACHOPIC_INDIRECT)
1056 fprintf (asm_out_file, ".reference .constructors_used\n");
1059 void
1060 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1062 if (MACHOPIC_INDIRECT)
1063 mod_term_section ();
1064 else
1065 destructor_section ();
1066 assemble_align (POINTER_SIZE);
1067 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1069 if (! MACHOPIC_INDIRECT)
1070 fprintf (asm_out_file, ".reference .destructors_used\n");
1073 void
1074 darwin_globalize_label (FILE *stream, const char *name)
1076 if (!!strncmp (name, "_OBJC_", 6))
1077 default_globalize_label (stream, name);
1080 void
1081 darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
1083 fprintf (asm_out_file, ".section %s\n", name);
1086 unsigned int
1087 darwin_section_type_flags (tree decl, const char *name, int reloc)
1089 unsigned int flags = default_section_type_flags (decl, name, reloc);
1091 /* Weak or linkonce variables live in a writable section. */
1092 if (decl != 0 && TREE_CODE (decl) != FUNCTION_DECL
1093 && (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)))
1094 flags |= SECTION_WRITE;
1096 return flags;
1099 void
1100 darwin_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
1102 /* Darwin does not use unique sections. However, the target's
1103 unique_section hook is called for linkonce symbols. We need
1104 to set an appropriate section for such symbols. */
1105 if (DECL_ONE_ONLY (decl) && !DECL_SECTION_NAME (decl))
1106 darwin_make_decl_one_only (decl);
1109 #define HAVE_DEAD_STRIP 0
1111 static void
1112 no_dead_strip (FILE *file, const char *lab)
1114 if (HAVE_DEAD_STRIP)
1115 fprintf (file, ".no_dead_strip %s\n", lab);
1118 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1119 The third parameter is nonzero if this is for exception handling.
1120 The fourth parameter is nonzero if this is just a placeholder for an
1121 FDE that we are omitting. */
1123 void
1124 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1126 tree id = DECL_ASSEMBLER_NAME (decl)
1127 ? DECL_ASSEMBLER_NAME (decl)
1128 : DECL_NAME (decl);
1130 const char *prefix = "_";
1131 const int prefix_len = 1;
1133 const char *base = IDENTIFIER_POINTER (id);
1134 unsigned int base_len = IDENTIFIER_LENGTH (id);
1136 const char *suffix = ".eh";
1138 int need_quotes = name_needs_quotes (base);
1139 int quotes_len = need_quotes ? 2 : 0;
1140 char *lab;
1142 if (! for_eh)
1143 suffix = ".eh1";
1145 lab = xmalloc (prefix_len + base_len + strlen (suffix) + quotes_len + 1);
1146 lab[0] = '\0';
1148 if (need_quotes)
1149 strcat(lab, "\"");
1150 strcat(lab, prefix);
1151 strcat(lab, base);
1152 strcat(lab, suffix);
1153 if (need_quotes)
1154 strcat(lab, "\"");
1156 if (TREE_PUBLIC (decl))
1157 fprintf (file, "%s %s\n",
1158 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1159 ? ".globl"
1160 : ".private_extern"),
1161 lab);
1163 if (DECL_ONE_ONLY (decl) && TREE_PUBLIC (decl))
1164 fprintf (file, ".weak_definition %s\n", lab);
1166 if (empty)
1168 fprintf (file, "%s = 0\n", lab);
1170 /* Mark the absolute .eh and .eh1 style labels as needed to
1171 ensure that we don't dead code strip them and keep such
1172 labels from another instantiation point until we can fix this
1173 properly with group comdat support. */
1174 no_dead_strip (file, lab);
1176 else
1177 fprintf (file, "%s:\n", lab);
1179 free (lab);
1182 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
1184 void
1185 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1187 const char *nlp_name;
1189 if (GET_CODE (addr) != SYMBOL_REF)
1190 abort ();
1192 nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1193 fputs ("\t.long\t", file);
1194 ASM_OUTPUT_LABELREF (file, nlp_name);
1195 fputs ("-.", file);
1198 /* Emit an assembler directive to set visibility for a symbol. The
1199 only supported visibilities are VISIBILITY_DEFAULT and
1200 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1201 extern". There is no MACH-O equivalent of ELF's
1202 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1204 void
1205 darwin_assemble_visibility (tree decl, int vis)
1207 if (vis == VISIBILITY_DEFAULT)
1209 else if (vis == VISIBILITY_HIDDEN)
1211 fputs ("\t.private_extern ", asm_out_file);
1212 assemble_name (asm_out_file,
1213 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1214 fputs ("\n", asm_out_file);
1216 else
1217 warning ("internal and protected visibility attributes not supported"
1218 "in this configuration; ignored");
1221 /* Output a difference of two labels that will be an assembly time
1222 constant if the two labels are local. (.long lab1-lab2 will be
1223 very different if lab1 is at the boundary between two sections; it
1224 will be relocated according to the second section, not the first,
1225 so one ends up with a difference between labels in different
1226 sections, which is bad in the dwarf2 eh context for instance.) */
1228 static int darwin_dwarf_label_counter;
1230 void
1231 darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
1232 const char *lab1, const char *lab2)
1234 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1235 && lab2[0] == '*' && lab2[1] == 'L');
1237 if (islocaldiff)
1238 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1239 else
1240 fprintf (file, "\t%s\t", ".long");
1241 assemble_name (file, lab1);
1242 fprintf (file, "-");
1243 assemble_name (file, lab2);
1244 if (islocaldiff)
1245 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1248 void
1249 darwin_file_end (void)
1251 machopic_finish (asm_out_file);
1252 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1254 constructor_section ();
1255 destructor_section ();
1256 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1258 fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1261 #include "gt-darwin.h"