]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/darwin.c
s390.c (s390_emit_prologue): Added missing "{}" brackets.
[thirdparty/gcc.git] / gcc / config / darwin.c
CommitLineData
ee890fe2 1/* Functions for generic Darwin as target machine for GNU C compiler.
0ea5865c 2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003, 2004
ee890fe2
SS
3 Free Software Foundation, Inc.
4 Contributed by Apple Computer Inc.
5
7ec022b2 6This file is part of GCC.
ee890fe2 7
7ec022b2 8GCC is free software; you can redistribute it and/or modify
ee890fe2
SS
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
7ec022b2 13GCC is distributed in the hope that it will be useful,
ee890fe2
SS
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
7ec022b2 19along with GCC; see the file COPYING. If not, write to
ee890fe2
SS
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
22
23#include "config.h"
24#include "system.h"
4977bab6
ZW
25#include "coretypes.h"
26#include "tm.h"
ee890fe2
SS
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"
ee890fe2
SS
40#include "function.h"
41#include "ggc.h"
3ac88239 42#include "langhooks.h"
245ff137 43#include "tm_p.h"
6ce4806b 44#include "errors.h"
11abc112 45#include "hashtab.h"
ee890fe2 46
699c914a
MS
47/* Darwin supports a feature called fix-and-continue, which is used
48 for rapid turn around debugging. When code is compiled with the
49 -mfix-and-continue flag, two changes are made to the generated code
50 that allow the system to do things that it would normally not be
51 able to do easily. These changes allow gdb to load in
52 recompilation of a translation unit that has been changed into a
53 running program and replace existing functions and methods of that
54 translation unit with with versions of those functions and methods
55 from the newly compiled translation unit. The new functions access
56 the existing static data from the old translation unit, if the data
57 existed in the unit to be replaced, and from the new translation
58 unit, for new data.
59
60 The changes are to insert 4 nops at the beginning of all functions
61 and to use indirection to get at static duration data. The 4 nops
62 are required by consumers of the generated code. Currently, gdb
63 uses this to patch in a jump to the overriding function, this
64 allows all uses of the old name to forward to the replacement,
65 including existing function poiinters and virtual methods. See
66 rs6000_emit_prologue for the code that handles the nop insertions.
67
68 The added indirection allows gdb to redirect accesses to static
69 duration data from the newly loaded translation unit to the
70 existing data, if any. @code{static} data is special and is
71 handled by setting the second word in the .non_lazy_symbol_pointer
72 data structure to the address of the data. See indirect_data for
73 the code that handles the extra indirection, and
74 machopic_output_indirection and its use of MACHO_SYMBOL_STATIC for
75 the code that handles @code{static} data indirection. */
76
77
8f4220dc
MA
78/* Nonzero if the user passes the -mone-byte-bool switch, which forces
79 sizeof(bool) to be 1. */
80const char *darwin_one_byte_bool = 0;
81
ee890fe2 82int
9c808aad 83name_needs_quotes (const char *name)
ee890fe2
SS
84{
85 int c;
86 while ((c = *name++) != '\0')
6f94a68e 87 if (! ISIDNUM (c) && c != '.' && c != '$')
ee890fe2
SS
88 return 1;
89 return 0;
90}
91
9c808aad 92/*
ee890fe2
SS
93 * flag_pic = 1 ... generate only indirections
94 * flag_pic = 2 ... generate indirections and pure code
95 */
96
11abc112
MM
97static int
98machopic_symbol_defined_p (rtx sym_ref)
ee890fe2 99{
156a126c
MS
100 return (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
101 || (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref));
ee890fe2
SS
102}
103
11abc112
MM
104/* This module assumes that (const (symbol_ref "foo")) is a legal pic
105 reference, which will not be changed. */
9c808aad 106
ee890fe2 107enum machopic_addr_class
11abc112 108machopic_classify_symbol (rtx sym_ref)
ee890fe2 109{
11abc112
MM
110 int flags;
111 bool function_p;
112
113 flags = SYMBOL_REF_FLAGS (sym_ref);
114 function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
115 if (machopic_symbol_defined_p (sym_ref))
116 return (function_p
117 ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
118 else
119 return (function_p
120 ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
ee890fe2
SS
121}
122
699c914a
MS
123#ifndef TARGET_FIX_AND_CONTINUE
124#define TARGET_FIX_AND_CONTINUE 0
125#endif
126
127/* Indicate when fix-and-continue style code generation is being used
128 and when a reference to data should be indirected so that it can be
129 rebound in a new translation unit to refernce the original instance
130 of that data. Symbol names that are for code generation local to
131 the translation unit are bound to the new translation unit;
132 currently this means symbols that begin with L or _OBJC_;
133 otherwise, we indicate that an indirect reference should be made to
134 permit the runtime to rebind new instances of the translation unit
135 to the original instance of the data. */
136
137static int
138indirect_data (rtx sym_ref)
139{
140 int lprefix;
141 const char *name;
142
143 /* If we aren't generating fix-and-continue code, don't do anything special. */
144 if (TARGET_FIX_AND_CONTINUE == 0)
145 return 0;
146
147 /* Otherwise, all symbol except symbols that begin with L or _OBJC_
148 are indirected. Symbols that begin with L and _OBJC_ are always
149 bound to the current translation unit as they are used for
150 generated local data of the translation unit. */
151
152 name = XSTR (sym_ref, 0);
153
154 lprefix = (((name[0] == '*' || name[0] == '&')
155 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
156 || (strncmp (name, "_OBJC_", 6)));
157
158 return ! lprefix;
159}
160
161
ee890fe2 162static int
11abc112 163machopic_data_defined_p (rtx sym_ref)
ee890fe2 164{
699c914a
MS
165 if (indirect_data (sym_ref))
166 return 0;
167
11abc112 168 switch (machopic_classify_symbol (sym_ref))
ee890fe2
SS
169 {
170 case MACHOPIC_DEFINED_DATA:
171 return 1;
172 default:
173 return 0;
174 }
175}
176
ee890fe2 177void
11abc112 178machopic_define_symbol (rtx mem)
ee890fe2 179{
11abc112
MM
180 rtx sym_ref;
181 if (GET_CODE (mem) != MEM)
182 abort ();
183 sym_ref = XEXP (mem, 0);
184 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
ee890fe2
SS
185}
186
6788f5ca 187static GTY(()) char * function_base;
ee890fe2 188
92c1a778 189const char *
9c808aad 190machopic_function_base_name (void)
ee890fe2 191{
ab82a49f
AP
192 /* if dynamic-no-pic is on, we should not get here */
193 if (MACHO_DYNAMIC_NO_PIC_P)
194 abort ();
ee890fe2 195
1622229c 196 if (function_base == NULL)
9c808aad 197 function_base =
1622229c
AP
198 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
199
200 current_function_uses_pic_offset_table = 1;
201
202 return function_base;
203}
204
11abc112
MM
205/* Return a SYMBOL_REF for the PIC function base. */
206
207rtx
208machopic_function_base_sym (void)
209{
210 rtx sym_ref;
211
212 sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
213 SYMBOL_REF_FLAGS (sym_ref)
214 |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
215 return sym_ref;
216}
217
1622229c
AP
218static GTY(()) const char * function_base_func_name;
219static GTY(()) int current_pic_label_num;
220
221void
222machopic_output_function_base_name (FILE *file)
223{
224 const char *current_name;
225
ff482c8d 226 /* If dynamic-no-pic is on, we should not get here. */
1622229c
AP
227 if (MACHO_DYNAMIC_NO_PIC_P)
228 abort ();
9c808aad 229 current_name =
1622229c 230 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
6788f5ca 231 if (function_base_func_name != current_name)
ee890fe2 232 {
ee890fe2 233 ++current_pic_label_num;
6788f5ca 234 function_base_func_name = current_name;
ee890fe2 235 }
1622229c 236 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
ee890fe2
SS
237}
238
11abc112
MM
239/* The suffix attached to non-lazy pointer symbols. */
240#define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
241/* The suffix attached to stub symbols. */
242#define STUB_SUFFIX "$stub"
ee890fe2 243
11abc112 244typedef struct machopic_indirection GTY (())
ee890fe2 245{
11abc112
MM
246 /* The SYMBOL_REF for the entity referenced. */
247 rtx symbol;
248 /* The IDENTIFIER_NODE giving the name of the stub or non-lazy
249 pointer. */
250 tree ptr_name;
251 /* True iff this entry is for a stub (as opposed to a non-lazy
252 pointer). */
253 bool stub_p;
254 /* True iff this stub or pointer pointer has been referenced. */
255 bool used;
256} machopic_indirection;
257
258/* A table mapping stub names and non-lazy pointer names to
259 SYMBOL_REFs for the stubbed-to and pointed-to entities. */
260
261static GTY ((param_is (struct machopic_indirection))) htab_t
262 machopic_indirections;
263
264/* Return a hash value for a SLOT in the indirections hash table. */
265
266static hashval_t
267machopic_indirection_hash (const void *slot)
268{
269 const machopic_indirection *p = (const machopic_indirection *) slot;
270 return IDENTIFIER_HASH_VALUE (p->ptr_name);
271}
9c808aad 272
11abc112
MM
273/* Returns true if the KEY is the same as that associated with
274 SLOT. */
275
276static int
277machopic_indirection_eq (const void *slot, const void *key)
278{
279 return ((const machopic_indirection *) slot)->ptr_name == (tree) key;
280}
ee890fe2 281
11abc112
MM
282/* Return the name of the non-lazy pointer (if STUB_P is false) or
283 stub (if STUB_B is true) corresponding to the given name. */
df56a27f 284
11abc112
MM
285const char *
286machopic_indirection_name (rtx sym_ref, bool stub_p)
287{
288 char *buffer;
289 const char *name = XSTR (sym_ref, 0);
290 int namelen = strlen (name);
291 tree ptr_name;
292 machopic_indirection *p;
293
294 /* Construct the name of the non-lazy pointer or stub. */
295 if (stub_p)
df56a27f 296 {
11abc112
MM
297 int needs_quotes = name_needs_quotes (name);
298 buffer = alloca (strlen ("&L")
299 + namelen
300 + strlen (STUB_SUFFIX)
301 + 2 /* possible quotes */
302 + 1 /* '\0' */);
303
304 if (needs_quotes)
df56a27f 305 {
11abc112
MM
306 if (name[0] == '*')
307 sprintf (buffer, "&\"L%s" STUB_SUFFIX "\"", name + 1);
308 else
309 sprintf (buffer, "&\"L%s%s" STUB_SUFFIX "\"", user_label_prefix,
310 name);
df56a27f 311 }
11abc112
MM
312 else if (name[0] == '*')
313 sprintf (buffer, "&L%s" STUB_SUFFIX, name + 1);
314 else
315 sprintf (buffer, "&L%s%s" STUB_SUFFIX, user_label_prefix, name);
316 }
317 else
318 {
319 buffer = alloca (strlen ("&L")
320 + strlen (user_label_prefix)
321 + namelen
322 + strlen (NON_LAZY_POINTER_SUFFIX)
323 + 1 /* '\0' */);
324 if (name[0] == '*')
325 sprintf (buffer, "&L%s" NON_LAZY_POINTER_SUFFIX, name + 1);
326 else
327 sprintf (buffer, "&L%s%s" NON_LAZY_POINTER_SUFFIX,
328 user_label_prefix, name);
df56a27f
SS
329 }
330
11abc112
MM
331 /* See if we already have it. */
332 ptr_name = maybe_get_identifier (buffer);
333 /* If not, create a mapping from the non-lazy pointer to the
334 SYMBOL_REF. */
335 if (!ptr_name)
336 {
337 void **slot;
338 ptr_name = get_identifier (buffer);
339 p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
340 p->symbol = sym_ref;
341 p->ptr_name = ptr_name;
342 p->stub_p = stub_p;
343 p->used = 0;
344 if (!machopic_indirections)
345 machopic_indirections
346 = htab_create_ggc (37,
347 machopic_indirection_hash,
348 machopic_indirection_eq,
349 /*htab_del=*/NULL);
350 slot = htab_find_slot_with_hash (machopic_indirections, ptr_name,
351 IDENTIFIER_HASH_VALUE (ptr_name),
352 INSERT);
353 *((machopic_indirection **) slot) = p;
354 }
355
356 return IDENTIFIER_POINTER (ptr_name);
ee890fe2
SS
357}
358
11abc112 359/* Return the name of the stub for the mcount function. */
ee890fe2 360
11abc112
MM
361const char*
362machopic_mcount_stub_name (void)
ee890fe2 363{
11abc112 364 return "&L*mcount$stub";
ee890fe2
SS
365}
366
11abc112
MM
367/* If NAME is the name of a stub or a non-lazy pointer , mark the stub
368 or non-lazy pointer as used -- and mark the object to which the
369 pointer/stub refers as used as well, since the pointer/stub will
370 emit a reference to it. */
371
ee890fe2 372void
11abc112 373machopic_validate_stub_or_non_lazy_ptr (const char *name)
ee890fe2 374{
11abc112 375 tree ident = get_identifier (name);
ee890fe2 376
11abc112
MM
377 machopic_indirection *p;
378
379 p = ((machopic_indirection *)
380 (htab_find_with_hash (machopic_indirections, ident,
381 IDENTIFIER_HASH_VALUE (ident))));
382 if (p)
383 {
384 p->used = 1;
385 mark_referenced (ident);
386 mark_referenced (get_identifier (XSTR (p->symbol, 0)));
387 }
ee890fe2
SS
388}
389
390/* Transform ORIG, which may be any data source, to the corresponding
391 source using indirections. */
392
393rtx
9c808aad 394machopic_indirect_data_reference (rtx orig, rtx reg)
ee890fe2
SS
395{
396 rtx ptr_ref = orig;
9c808aad 397
ee890fe2
SS
398 if (! MACHOPIC_INDIRECT)
399 return orig;
400
401 if (GET_CODE (orig) == SYMBOL_REF)
402 {
11abc112 403 int defined = machopic_data_defined_p (orig);
ab82a49f
AP
404
405 if (defined && MACHO_DYNAMIC_NO_PIC_P)
406 {
407#if defined (TARGET_TOC)
ac9e2cff
AP
408 emit_insn (GET_MODE (orig) == DImode
409 ? gen_macho_high_di (reg, orig)
410 : gen_macho_high (reg, orig));
411 emit_insn (GET_MODE (orig) == DImode
412 ? gen_macho_low_di (reg, reg, orig)
413 : gen_macho_low (reg, reg, orig));
ab82a49f
AP
414#else
415 /* some other cpu -- writeme! */
416 abort ();
417#endif
418 return reg;
419 }
420 else if (defined)
ee890fe2 421 {
7ae8cf75 422#if defined (TARGET_TOC) || defined (HAVE_lo_sum)
11abc112 423 rtx pic_base = machopic_function_base_sym ();
6f94a68e
GK
424 rtx offset = gen_rtx_CONST (Pmode,
425 gen_rtx_MINUS (Pmode, orig, pic_base));
7ae8cf75 426#endif
ee890fe2
SS
427
428#if defined (TARGET_TOC) /* i.e., PowerPC */
d9b46dfb 429 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
ee890fe2
SS
430
431 if (reg == NULL)
432 abort ();
433
6f94a68e
GK
434 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
435 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
436 gen_rtx_HIGH (Pmode, offset))));
437 emit_insn (gen_rtx_SET (Pmode, reg,
438 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
ee890fe2
SS
439
440 orig = reg;
441#else
442#if defined (HAVE_lo_sum)
443 if (reg == 0) abort ();
444
6f94a68e
GK
445 emit_insn (gen_rtx_SET (VOIDmode, reg,
446 gen_rtx_HIGH (Pmode, offset)));
447 emit_insn (gen_rtx_SET (VOIDmode, reg,
448 gen_rtx_LO_SUM (Pmode, reg, offset)));
449 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
ee890fe2 450
6f94a68e 451 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
ee890fe2
SS
452#endif
453#endif
454 return orig;
455 }
456
828a4fe4 457 ptr_ref = (gen_rtx_SYMBOL_REF
11abc112
MM
458 (Pmode,
459 machopic_indirection_name (orig, /*stub_p=*/false)));
ee890fe2 460
542a8afa 461 SYMBOL_REF_DECL (ptr_ref) = SYMBOL_REF_DECL (orig);
c0d594f1 462
542a8afa 463 ptr_ref = gen_const_mem (Pmode, ptr_ref);
828a4fe4 464 machopic_define_symbol (ptr_ref);
ee890fe2
SS
465
466 return ptr_ref;
467 }
468 else if (GET_CODE (orig) == CONST)
469 {
470 rtx base, result;
471
472 /* legitimize both operands of the PLUS */
473 if (GET_CODE (XEXP (orig, 0)) == PLUS)
474 {
475 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
476 reg);
477 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
478 (base == reg ? 0 : reg));
479 }
9c808aad 480 else
ee890fe2
SS
481 return orig;
482
483 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
ed8908e7 484 result = plus_constant (base, INTVAL (orig));
ee890fe2 485 else
6f94a68e 486 result = gen_rtx_PLUS (Pmode, base, orig);
ee890fe2 487
ee890fe2
SS
488 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
489 {
490 if (reg)
491 {
492 emit_move_insn (reg, result);
493 result = reg;
494 }
495 else
496 {
497 result = force_reg (GET_MODE (result), result);
498 }
499 }
500
501 return result;
502
503 }
504 else if (GET_CODE (orig) == MEM)
505 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
506 /* When the target is i386, this code prevents crashes due to the
507 compiler's ignorance on how to move the PIC base register to
508 other registers. (The reload phase sometimes introduces such
509 insns.) */
510 else if (GET_CODE (orig) == PLUS
511 && GET_CODE (XEXP (orig, 0)) == REG
512 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
513#ifdef I386
514 /* Prevent the same register from being erroneously used
515 as both the base and index registers. */
516 && GET_CODE (XEXP (orig, 1)) == CONST
517#endif
518 && reg)
519 {
520 emit_move_insn (reg, XEXP (orig, 0));
521 XEXP (ptr_ref, 0) = reg;
522 }
523 return ptr_ref;
524}
525
ee890fe2
SS
526/* Transform TARGET (a MEM), which is a function call target, to the
527 corresponding symbol_stub if necessary. Return a new MEM. */
528
529rtx
9c808aad 530machopic_indirect_call_target (rtx target)
ee890fe2
SS
531{
532 if (GET_CODE (target) != MEM)
533 return target;
534
11abc112
MM
535 if (MACHOPIC_INDIRECT
536 && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
537 && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
538 & MACHO_SYMBOL_FLAG_DEFINED))
9c808aad 539 {
11abc112
MM
540 rtx sym_ref = XEXP (target, 0);
541 const char *stub_name = machopic_indirection_name (sym_ref,
542 /*stub_p=*/true);
543 enum machine_mode mode = GET_MODE (sym_ref);
544 tree decl = SYMBOL_REF_DECL (sym_ref);
545
546 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
547 SYMBOL_REF_DECL (XEXP (target, 0)) = decl;
389fdba0 548 MEM_READONLY_P (target) = 1;
542a8afa 549 MEM_NOTRAP_P (target) = 1;
ee890fe2
SS
550 }
551
552 return target;
553}
554
555rtx
9c808aad 556machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
ee890fe2
SS
557{
558 rtx pic_ref = orig;
559
ab82a49f 560 if (! MACHOPIC_INDIRECT)
ee890fe2
SS
561 return orig;
562
563 /* First handle a simple SYMBOL_REF or LABEL_REF */
564 if (GET_CODE (orig) == LABEL_REF
565 || (GET_CODE (orig) == SYMBOL_REF
566 ))
567 {
568 /* addr(foo) = &func+(foo-func) */
569 rtx pic_base;
570
571 orig = machopic_indirect_data_reference (orig, reg);
572
9c808aad 573 if (GET_CODE (orig) == PLUS
ee890fe2
SS
574 && GET_CODE (XEXP (orig, 0)) == REG)
575 {
576 if (reg == 0)
577 return force_reg (mode, orig);
578
579 emit_move_insn (reg, orig);
580 return reg;
9c808aad 581 }
ee890fe2 582
ab82a49f
AP
583 /* if dynamic-no-pic then use 0 as the pic base */
584 if (MACHO_DYNAMIC_NO_PIC_P)
585 pic_base = CONST0_RTX (Pmode);
586 else
11abc112 587 pic_base = machopic_function_base_sym ();
ee890fe2
SS
588
589 if (GET_CODE (orig) == MEM)
590 {
591 if (reg == 0)
592 {
593 if (reload_in_progress)
594 abort ();
595 else
596 reg = gen_reg_rtx (Pmode);
597 }
9c808aad 598
ee890fe2 599#ifdef HAVE_lo_sum
ab82a49f
AP
600 if (MACHO_DYNAMIC_NO_PIC_P
601 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
602 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
603 {
604#if defined (TARGET_TOC) /* ppc */
605 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
606 rtx asym = XEXP (orig, 0);
607 rtx mem;
608
ac9e2cff
AP
609 emit_insn (mode == DImode
610 ? gen_macho_high_di (temp_reg, asym)
611 : gen_macho_high (temp_reg, asym));
542a8afa
RH
612 mem = gen_const_mem (GET_MODE (orig),
613 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
6f94a68e 614 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
ab82a49f
AP
615#else
616 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
617 abort ();
618#endif
619 pic_ref = reg;
620 }
621 else
9c808aad 622 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
ee890fe2
SS
623 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
624 {
6f94a68e
GK
625 rtx offset = gen_rtx_CONST (Pmode,
626 gen_rtx_MINUS (Pmode,
627 XEXP (orig, 0),
628 pic_base));
ee890fe2
SS
629#if defined (TARGET_TOC) /* i.e., PowerPC */
630 /* Generating a new reg may expose opportunities for
631 common subexpression elimination. */
49bd1d27 632 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
6f94a68e
GK
633 rtx mem;
634 rtx insn;
635 rtx sum;
636
637 sum = gen_rtx_HIGH (Pmode, offset);
638 if (! MACHO_DYNAMIC_NO_PIC_P)
639 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
ee890fe2 640
6f94a68e
GK
641 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
642
542a8afa
RH
643 mem = gen_const_mem (GET_MODE (orig),
644 gen_rtx_LO_SUM (Pmode,
645 hi_sum_reg, offset));
6f94a68e
GK
646 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
647 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
648 REG_NOTES (insn));
649
650 pic_ref = reg;
ee890fe2 651#else
6f94a68e
GK
652 emit_insn (gen_rtx_USE (VOIDmode,
653 gen_rtx_REG (Pmode,
654 PIC_OFFSET_TABLE_REGNUM)));
655
656 emit_insn (gen_rtx_SET (VOIDmode, reg,
657 gen_rtx_HIGH (Pmode,
658 gen_rtx_CONST (Pmode,
659 offset))));
660 emit_insn (gen_rtx_SET (VOIDmode, reg,
661 gen_rtx_LO_SUM (Pmode, reg,
662 gen_rtx_CONST (Pmode, offset))));
663 pic_ref = gen_rtx_PLUS (Pmode,
664 pic_offset_table_rtx, reg);
ee890fe2
SS
665#endif
666 }
667 else
668#endif /* HAVE_lo_sum */
669 {
670 rtx pic = pic_offset_table_rtx;
671 if (GET_CODE (pic) != REG)
672 {
673 emit_move_insn (reg, pic);
674 pic = reg;
675 }
676#if 0
6f94a68e
GK
677 emit_insn (gen_rtx_USE (VOIDmode,
678 gen_rtx_REG (Pmode,
679 PIC_OFFSET_TABLE_REGNUM)));
ee890fe2
SS
680#endif
681
6f94a68e
GK
682 pic_ref = gen_rtx_PLUS (Pmode,
683 pic,
684 gen_rtx_CONST (Pmode,
685 gen_rtx_MINUS (Pmode,
686 XEXP (orig, 0),
687 pic_base)));
ee890fe2 688 }
9c808aad 689
ee890fe2 690#if !defined (TARGET_TOC)
ee890fe2 691 emit_move_insn (reg, pic_ref);
542a8afa 692 pic_ref = gen_const_mem (GET_MODE (orig), reg);
f9b0ac3b 693#endif
ee890fe2
SS
694 }
695 else
696 {
697
698#ifdef HAVE_lo_sum
9c808aad 699 if (GET_CODE (orig) == SYMBOL_REF
ee890fe2
SS
700 || GET_CODE (orig) == LABEL_REF)
701 {
6f94a68e
GK
702 rtx offset = gen_rtx_CONST (Pmode,
703 gen_rtx_MINUS (Pmode,
704 orig, pic_base));
ee890fe2
SS
705#if defined (TARGET_TOC) /* i.e., PowerPC */
706 rtx hi_sum_reg;
707
708 if (reg == 0)
709 {
710 if (reload_in_progress)
711 abort ();
712 else
49bd1d27 713 reg = gen_reg_rtx (Pmode);
ee890fe2 714 }
9c808aad 715
ee890fe2
SS
716 hi_sum_reg = reg;
717
6f94a68e
GK
718 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
719 (MACHO_DYNAMIC_NO_PIC_P)
720 ? gen_rtx_HIGH (Pmode, offset)
721 : gen_rtx_PLUS (Pmode,
722 pic_offset_table_rtx,
723 gen_rtx_HIGH (Pmode,
724 offset))));
725 emit_insn (gen_rtx_SET (VOIDmode, reg,
726 gen_rtx_LO_SUM (Pmode,
727 hi_sum_reg, offset)));
ee890fe2
SS
728 pic_ref = reg;
729#else
6f94a68e
GK
730 emit_insn (gen_rtx_SET (VOIDmode, reg,
731 gen_rtx_HIGH (Pmode, offset)));
732 emit_insn (gen_rtx_SET (VOIDmode, reg,
733 gen_rtx_LO_SUM (Pmode, reg, offset)));
734 pic_ref = gen_rtx_PLUS (Pmode,
735 pic_offset_table_rtx, reg);
ee890fe2
SS
736#endif
737 }
738 else
739#endif /* HAVE_lo_sum */
740 {
741 if (GET_CODE (orig) == REG)
742 {
743 return orig;
744 }
745 else
746 {
747 rtx pic = pic_offset_table_rtx;
748 if (GET_CODE (pic) != REG)
749 {
750 emit_move_insn (reg, pic);
751 pic = reg;
752 }
753#if 0
6f94a68e
GK
754 emit_insn (gen_rtx_USE (VOIDmode,
755 pic_offset_table_rtx));
ee890fe2 756#endif
6f94a68e
GK
757 pic_ref = gen_rtx_PLUS (Pmode,
758 pic,
759 gen_rtx_CONST (Pmode,
760 gen_rtx_MINUS (Pmode,
761 orig, pic_base)));
ee890fe2
SS
762 }
763 }
764 }
765
ee890fe2
SS
766 if (GET_CODE (pic_ref) != REG)
767 {
768 if (reg != 0)
769 {
770 emit_move_insn (reg, pic_ref);
771 return reg;
772 }
773 else
774 {
775 return force_reg (mode, pic_ref);
776 }
777 }
778 else
779 {
780 return pic_ref;
781 }
782 }
783
784 else if (GET_CODE (orig) == SYMBOL_REF)
785 return orig;
786
787 else if (GET_CODE (orig) == PLUS
788 && (GET_CODE (XEXP (orig, 0)) == MEM
789 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
790 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
791 && XEXP (orig, 0) != pic_offset_table_rtx
792 && GET_CODE (XEXP (orig, 1)) != REG)
9c808aad 793
ee890fe2
SS
794 {
795 rtx base;
796 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
797
798 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
799 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
800 Pmode, (base == reg ? 0 : reg));
801 if (GET_CODE (orig) == CONST_INT)
802 {
ed8908e7 803 pic_ref = plus_constant (base, INTVAL (orig));
ee890fe2
SS
804 is_complex = 1;
805 }
806 else
6f94a68e 807 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
ee890fe2 808
ee890fe2
SS
809 if (reg && is_complex)
810 {
811 emit_move_insn (reg, pic_ref);
812 pic_ref = reg;
813 }
814 /* Likewise, should we set special REG_NOTEs here? */
815 }
816
817 else if (GET_CODE (orig) == CONST)
818 {
819 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
820 }
821
822 else if (GET_CODE (orig) == MEM
823 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
824 {
825 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
389fdba0 826 addr = replace_equiv_address (orig, addr);
ee890fe2
SS
827 emit_move_insn (reg, addr);
828 pic_ref = reg;
829 }
830
831 return pic_ref;
832}
833
11abc112
MM
834/* Output the stub or non-lazy pointer in *SLOT, if it has been used.
835 DATA is the FILE* for assembly output. Called from
836 htab_traverse. */
ee890fe2 837
11abc112
MM
838static int
839machopic_output_indirection (void **slot, void *data)
ee890fe2 840{
11abc112
MM
841 machopic_indirection *p = *((machopic_indirection **) slot);
842 FILE *asm_out_file = (FILE *) data;
843 rtx symbol;
844 const char *sym_name;
845 const char *ptr_name;
846
847 if (!p->used)
848 return 1;
ee890fe2 849
11abc112
MM
850 symbol = p->symbol;
851 sym_name = XSTR (symbol, 0);
852 ptr_name = IDENTIFIER_POINTER (p->ptr_name);
853
854 if (p->stub_p)
ee890fe2 855 {
ee890fe2
SS
856 char *sym;
857 char *stub;
ee890fe2 858
ee890fe2
SS
859 sym = alloca (strlen (sym_name) + 2);
860 if (sym_name[0] == '*' || sym_name[0] == '&')
861 strcpy (sym, sym_name + 1);
862 else if (sym_name[0] == '-' || sym_name[0] == '+')
9c808aad 863 strcpy (sym, sym_name);
ee890fe2 864 else
789a4ea3 865 sprintf (sym, "%s%s", user_label_prefix, sym_name);
ee890fe2 866
11abc112
MM
867 stub = alloca (strlen (ptr_name) + 2);
868 if (ptr_name[0] == '*' || ptr_name[0] == '&')
869 strcpy (stub, ptr_name + 1);
ee890fe2 870 else
11abc112 871 sprintf (stub, "%s%s", user_label_prefix, ptr_name);
ee890fe2 872
11abc112 873 machopic_output_stub (asm_out_file, sym, stub);
ee890fe2 874 }
699c914a 875 else if (! indirect_data (symbol)
156a126c
MS
876 && (machopic_symbol_defined_p (symbol)
877 || SYMBOL_REF_LOCAL_P (symbol)))
ee890fe2 878 {
11abc112
MM
879 data_section ();
880 assemble_align (GET_MODE_ALIGNMENT (Pmode));
881 assemble_label (ptr_name);
882 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
883 GET_MODE_SIZE (Pmode),
884 GET_MODE_ALIGNMENT (Pmode), 1);
ee890fe2 885 }
11abc112
MM
886 else
887 {
699c914a
MS
888 rtx init = const0_rtx;
889
11abc112
MM
890 machopic_nl_symbol_ptr_section ();
891 assemble_name (asm_out_file, ptr_name);
892 fprintf (asm_out_file, ":\n");
893
894 fprintf (asm_out_file, "\t.indirect_symbol ");
895 assemble_name (asm_out_file, sym_name);
896 fprintf (asm_out_file, "\n");
897
699c914a
MS
898 /* Variables that are marked with MACHO_SYMBOL_STATIC need to
899 have their symbol name instead of 0 in the second entry of
900 the non-lazy symbol pointer data structure when they are
901 defined. This allows the runtime to rebind newer instances
902 of the translation unit with the original instance of the
903 data. */
904
905 if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
906 && machopic_symbol_defined_p (symbol))
907 init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
908
909 assemble_integer (init, GET_MODE_SIZE (Pmode),
11abc112
MM
910 GET_MODE_ALIGNMENT (Pmode), 1);
911 }
912
913 return 1;
914}
915
916void
917machopic_finish (FILE *asm_out_file)
918{
919 if (machopic_indirections)
699c914a 920 htab_traverse_noresize (machopic_indirections,
11abc112
MM
921 machopic_output_indirection,
922 asm_out_file);
ee890fe2
SS
923}
924
9c808aad
AJ
925int
926machopic_operand_p (rtx op)
ee890fe2
SS
927{
928 if (MACHOPIC_JUST_INDIRECT)
929 {
930 while (GET_CODE (op) == CONST)
931 op = XEXP (op, 0);
932
933 if (GET_CODE (op) == SYMBOL_REF)
11abc112 934 return machopic_symbol_defined_p (op);
ee890fe2
SS
935 else
936 return 0;
937 }
938
939 while (GET_CODE (op) == CONST)
940 op = XEXP (op, 0);
941
942 if (GET_CODE (op) == MINUS
943 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
944 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
11abc112
MM
945 && machopic_symbol_defined_p (XEXP (op, 0))
946 && machopic_symbol_defined_p (XEXP (op, 1)))
ee890fe2
SS
947 return 1;
948
ee890fe2
SS
949 return 0;
950}
df56a27f
SS
951
952/* This function records whether a given name corresponds to a defined
953 or undefined function or variable, for machopic_classify_ident to
954 use later. */
955
956void
9c808aad 957darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
df56a27f 958{
353e51f8 959 rtx sym_ref;
df56a27f 960
e1a4211d
SS
961 /* Do the standard encoding things first. */
962 default_encode_section_info (decl, rtl, first);
963
11abc112
MM
964 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
965 return;
e1a4211d 966
11abc112
MM
967 sym_ref = XEXP (rtl, 0);
968 if (TREE_CODE (decl) == VAR_DECL)
969 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
970
971 if (!DECL_EXTERNAL (decl)
4746cf84 972 && (!TREE_PUBLIC (decl) || (!DECL_ONE_ONLY (decl) && !DECL_WEAK (decl)))
df56a27f
SS
973 && ((TREE_STATIC (decl)
974 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
bfbdca0b 975 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
abe72dd8 976 && DECL_INITIAL (decl) != error_mark_node)))
11abc112 977 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
699c914a
MS
978
979 if (TREE_CODE (decl) == VAR_DECL
980 && indirect_data (sym_ref)
981 && ! TREE_PUBLIC (decl))
982 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
4e08ba6c 983}
2cc07db4 984
c61eceeb
MA
985static GTY(()) tree textcoal_section = 0;
986static GTY(()) tree datacoal_section = 0;
987
4746cf84
MA
988void
989darwin_make_decl_one_only (tree decl)
990{
c61eceeb
MA
991 tree sec = 0;
992 if (textcoal_section == 0)
993 {
994 static const char *ts = "__TEXT,__textcoal_nt,coalesced,no_toc";
995 static const char *ds = "__DATA,__datacoal_nt,coalesced,no_toc";
996 textcoal_section = build_string (strlen (ts), ts);
997 datacoal_section = build_string (strlen (ds), ds);
998 }
4746cf84 999
c61eceeb
MA
1000 sec = TREE_CODE (decl) == FUNCTION_DECL
1001 ? textcoal_section
1002 : datacoal_section;
4746cf84
MA
1003 TREE_PUBLIC (decl) = 1;
1004 DECL_ONE_ONLY (decl) = 1;
c61eceeb 1005 DECL_SECTION_NAME (decl) = sec;
4746cf84
MA
1006}
1007
8e3e233b
DP
1008void
1009darwin_mark_decl_preserved (const char *name)
1010{
1011 fprintf (asm_out_file, ".no_dead_strip ");
1012 assemble_name (asm_out_file, name);
1013 fputc ('\n', asm_out_file);
1014}
1015
ae46c4e0 1016void
9c808aad
AJ
1017machopic_select_section (tree exp, int reloc,
1018 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
ae46c4e0 1019{
3d7964d5 1020 void (*base_function)(void);
9c808aad 1021
3d7964d5
GK
1022 if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1023 base_function = readonly_data_section;
1024 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1025 base_function = const_data_section;
1026 else
1027 base_function = data_section;
9c808aad 1028
3d7964d5 1029 if (TREE_CODE (exp) == STRING_CST
9c808aad 1030 && ((size_t) TREE_STRING_LENGTH (exp)
3521b33c 1031 == strlen (TREE_STRING_POINTER (exp)) + 1))
3d7964d5
GK
1032 cstring_section ();
1033 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1034 && flag_merge_constants)
ae46c4e0
RH
1035 {
1036 tree size = TYPE_SIZE (TREE_TYPE (exp));
1037
1038 if (TREE_CODE (size) == INTEGER_CST &&
1039 TREE_INT_CST_LOW (size) == 4 &&
1040 TREE_INT_CST_HIGH (size) == 0)
1041 literal4_section ();
1042 else if (TREE_CODE (size) == INTEGER_CST &&
1043 TREE_INT_CST_LOW (size) == 8 &&
1044 TREE_INT_CST_HIGH (size) == 0)
1045 literal8_section ();
1046 else
3d7964d5 1047 base_function ();
ae46c4e0
RH
1048 }
1049 else if (TREE_CODE (exp) == CONSTRUCTOR
1050 && TREE_TYPE (exp)
1051 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1052 && TYPE_NAME (TREE_TYPE (exp)))
1053 {
1054 tree name = TYPE_NAME (TREE_TYPE (exp));
1055 if (TREE_CODE (name) == TYPE_DECL)
1056 name = DECL_NAME (name);
1057 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1058 objc_constant_string_object_section ();
1059 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1060 objc_string_object_section ();
ae46c4e0 1061 else
3d7964d5 1062 base_function ();
ae46c4e0
RH
1063 }
1064 else if (TREE_CODE (exp) == VAR_DECL &&
1065 DECL_NAME (exp) &&
1066 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1067 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1068 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1069 {
1070 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1071
1072 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1073 objc_cls_meth_section ();
1074 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1075 objc_inst_meth_section ();
1076 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1077 objc_cat_cls_meth_section ();
1078 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1079 objc_cat_inst_meth_section ();
1080 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1081 objc_class_vars_section ();
1082 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1083 objc_instance_vars_section ();
1084 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1085 objc_cat_cls_meth_section ();
1086 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1087 objc_class_names_section ();
1088 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1089 objc_meth_var_names_section ();
1090 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1091 objc_meth_var_types_section ();
1092 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1093 objc_cls_refs_section ();
1094 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1095 objc_class_section ();
1096 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1097 objc_meta_class_section ();
1098 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1099 objc_category_section ();
1100 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1101 objc_selector_refs_section ();
1102 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1103 objc_selector_fixup_section ();
1104 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1105 objc_symbols_section ();
1106 else if (!strncmp (name, "_OBJC_MODULES", 13))
1107 objc_module_info_section ();
264fa2db
ZL
1108 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1109 objc_image_info_section ();
ae46c4e0
RH
1110 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1111 objc_cat_inst_meth_section ();
1112 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1113 objc_cat_cls_meth_section ();
1114 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1115 objc_cat_cls_meth_section ();
1116 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1117 objc_protocol_section ();
ae46c4e0 1118 else
3d7964d5 1119 base_function ();
ae46c4e0
RH
1120 }
1121 else
3d7964d5 1122 base_function ();
ae46c4e0
RH
1123}
1124
b64a1b53 1125/* This can be called with address expressions as "rtx".
991b6592 1126 They must go in "const". */
b64a1b53
RH
1127
1128void
9c808aad
AJ
1129machopic_select_rtx_section (enum machine_mode mode, rtx x,
1130 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
b64a1b53
RH
1131{
1132 if (GET_MODE_SIZE (mode) == 8)
1133 literal8_section ();
1134 else if (GET_MODE_SIZE (mode) == 4
1135 && (GET_CODE (x) == CONST_INT
1136 || GET_CODE (x) == CONST_DOUBLE))
1137 literal4_section ();
86b0a4f3 1138 else if (MACHOPIC_INDIRECT
2e53734e
GK
1139 && (GET_CODE (x) == SYMBOL_REF
1140 || GET_CODE (x) == CONST
1141 || GET_CODE (x) == LABEL_REF))
1142 const_data_section ();
b64a1b53
RH
1143 else
1144 const_section ();
1145}
1146
2cc07db4 1147void
9c808aad 1148machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
2cc07db4 1149{
ab82a49f 1150 if (MACHOPIC_INDIRECT)
2cc07db4
RH
1151 mod_init_section ();
1152 else
1153 constructor_section ();
c8af3574
RH
1154 assemble_align (POINTER_SIZE);
1155 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2cc07db4 1156
ab82a49f 1157 if (! MACHOPIC_INDIRECT)
2cc07db4
RH
1158 fprintf (asm_out_file, ".reference .constructors_used\n");
1159}
1160
1161void
9c808aad 1162machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
2cc07db4 1163{
ab82a49f 1164 if (MACHOPIC_INDIRECT)
2cc07db4
RH
1165 mod_term_section ();
1166 else
1167 destructor_section ();
c8af3574
RH
1168 assemble_align (POINTER_SIZE);
1169 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2cc07db4 1170
ab82a49f 1171 if (! MACHOPIC_INDIRECT)
2cc07db4
RH
1172 fprintf (asm_out_file, ".reference .destructors_used\n");
1173}
e2500fed 1174
5eb99654 1175void
9c808aad 1176darwin_globalize_label (FILE *stream, const char *name)
5eb99654
KG
1177{
1178 if (!!strncmp (name, "_OBJC_", 6))
1179 default_globalize_label (stream, name);
1180}
1181
4746cf84
MA
1182void
1183darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
1184{
9fb32434 1185 fprintf (asm_out_file, ".section %s\n", name);
4746cf84
MA
1186}
1187
1188unsigned int
1189darwin_section_type_flags (tree decl, const char *name, int reloc)
1190{
1191 unsigned int flags = default_section_type_flags (decl, name, reloc);
1192
1193 /* Weak or linkonce variables live in a writable section. */
1194 if (decl != 0 && TREE_CODE (decl) != FUNCTION_DECL
1195 && (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)))
1196 flags |= SECTION_WRITE;
1197
1198 return flags;
1199}
1200
1201void
1202darwin_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
1203{
1204 /* Darwin does not use unique sections. However, the target's
1205 unique_section hook is called for linkonce symbols. We need
1206 to set an appropriate section for such symbols. */
1207 if (DECL_ONE_ONLY (decl) && !DECL_SECTION_NAME (decl))
1208 darwin_make_decl_one_only (decl);
1209}
1210
45cc4783
MS
1211#define HAVE_DEAD_STRIP 0
1212
1213static void
1214no_dead_strip (FILE *file, const char *lab)
1215{
1216 if (HAVE_DEAD_STRIP)
1217 fprintf (file, ".no_dead_strip %s\n", lab);
1218}
1219
4746cf84 1220/* Emit a label for an FDE, making it global and/or weak if appropriate.
eeab4d81
MS
1221 The third parameter is nonzero if this is for exception handling.
1222 The fourth parameter is nonzero if this is just a placeholder for an
4746cf84 1223 FDE that we are omitting. */
eeab4d81 1224
4746cf84 1225void
eeab4d81 1226darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
4746cf84
MA
1227{
1228 tree id = DECL_ASSEMBLER_NAME (decl)
1229 ? DECL_ASSEMBLER_NAME (decl)
1230 : DECL_NAME (decl);
1231
1232 const char *prefix = "_";
1233 const int prefix_len = 1;
1234
1235 const char *base = IDENTIFIER_POINTER (id);
1236 unsigned int base_len = IDENTIFIER_LENGTH (id);
1237
1238 const char *suffix = ".eh";
4746cf84
MA
1239
1240 int need_quotes = name_needs_quotes (base);
1241 int quotes_len = need_quotes ? 2 : 0;
eeab4d81
MS
1242 char *lab;
1243
1244 if (! for_eh)
1245 suffix = ".eh1";
4746cf84 1246
eeab4d81 1247 lab = xmalloc (prefix_len + base_len + strlen (suffix) + quotes_len + 1);
4746cf84
MA
1248 lab[0] = '\0';
1249
1250 if (need_quotes)
1251 strcat(lab, "\"");
1252 strcat(lab, prefix);
1253 strcat(lab, base);
1254 strcat(lab, suffix);
1255 if (need_quotes)
1256 strcat(lab, "\"");
1257
1258 if (TREE_PUBLIC (decl))
1259 fprintf (file, "%s %s\n",
1260 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1261 ? ".globl"
1262 : ".private_extern"),
1263 lab);
1264
1265 if (DECL_ONE_ONLY (decl) && TREE_PUBLIC (decl))
1266 fprintf (file, ".weak_definition %s\n", lab);
1267
1268 if (empty)
45cc4783
MS
1269 {
1270 fprintf (file, "%s = 0\n", lab);
1271
1272 /* Mark the absolute .eh and .eh1 style labels as needed to
1273 ensure that we don't dead code strip them and keep such
1274 labels from another instantiation point until we can fix this
1275 properly with group comdat support. */
1276 no_dead_strip (file, lab);
1277 }
4746cf84
MA
1278 else
1279 fprintf (file, "%s:\n", lab);
1280
1281 free (lab);
1282}
1283
1284/* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
eeab4d81 1285
4746cf84
MA
1286void
1287darwin_non_lazy_pcrel (FILE *file, rtx addr)
1288{
4746cf84
MA
1289 const char *nlp_name;
1290
1291 if (GET_CODE (addr) != SYMBOL_REF)
1292 abort ();
1293
11abc112 1294 nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
4746cf84
MA
1295 fputs ("\t.long\t", file);
1296 ASM_OUTPUT_LABELREF (file, nlp_name);
1297 fputs ("-.", file);
1298}
1299
6ce4806b
MA
1300/* Emit an assembler directive to set visibility for a symbol. The
1301 only supported visibilities are VISIBILITY_DEFAULT and
1302 VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1303 extern". There is no MACH-O equivalent of ELF's
1304 VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1305
1306void
1307darwin_assemble_visibility (tree decl, int vis)
1308{
1309 if (vis == VISIBILITY_DEFAULT)
1310 ;
1311 else if (vis == VISIBILITY_HIDDEN)
1312 {
1313 fputs ("\t.private_extern ", asm_out_file);
1314 assemble_name (asm_out_file,
1315 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1316 fputs ("\n", asm_out_file);
1317 }
1318 else
1319 warning ("internal and protected visibility attributes not supported"
1320 "in this configuration; ignored");
1321}
1322
7606e68f
SS
1323/* Output a difference of two labels that will be an assembly time
1324 constant if the two labels are local. (.long lab1-lab2 will be
1325 very different if lab1 is at the boundary between two sections; it
1326 will be relocated according to the second section, not the first,
1327 so one ends up with a difference between labels in different
1328 sections, which is bad in the dwarf2 eh context for instance.) */
1329
1330static int darwin_dwarf_label_counter;
1331
1332void
9c808aad
AJ
1333darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
1334 const char *lab1, const char *lab2)
7606e68f 1335{
4746cf84
MA
1336 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1337 && lab2[0] == '*' && lab2[1] == 'L');
7606e68f
SS
1338
1339 if (islocaldiff)
1340 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1341 else
1342 fprintf (file, "\t%s\t", ".long");
1343 assemble_name (file, lab1);
1344 fprintf (file, "-");
1345 assemble_name (file, lab2);
1346 if (islocaldiff)
1347 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1348}
1349
a5fe455b 1350void
9c808aad 1351darwin_file_end (void)
a5fe455b
ZW
1352{
1353 machopic_finish (asm_out_file);
1354 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1355 {
1356 constructor_section ();
1357 destructor_section ();
1358 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1359 }
92b9a671 1360 fprintf (asm_out_file, "\t.subsections_via_symbols\n");
a5fe455b
ZW
1361}
1362
699c914a
MS
1363/* True, iff we're generating fast turn around debugging code. When
1364 true, we arrange for function prologues to start with 4 nops so
1365 that gdb may insert code to redirect them, and for data to accessed
1366 indirectly. The runtime uses this indirection to forward
1367 references for data to the original instance of that data. */
1368
1369int darwin_fix_and_continue;
1370const char *darwin_fix_and_continue_switch;
1371
e2500fed 1372#include "gt-darwin.h"