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