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