]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/darwin.c
jcf-parse.c (classify_zip_file): Correctly compare filename_length against length...
[thirdparty/gcc.git] / gcc / config / darwin.c
CommitLineData
ee890fe2 1/* Functions for generic Darwin as target machine for GNU C compiler.
d24652ee 2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003
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"
ee890fe2 44
9c808aad
AJ
45static int machopic_data_defined_p (const char *);
46static void update_non_lazy_ptrs (const char *);
47static void update_stubs (const char *);
6f94a68e 48static const char *machopic_non_lazy_ptr_name (const char*);
ee890fe2 49
ee890fe2 50int
9c808aad 51name_needs_quotes (const char *name)
ee890fe2
SS
52{
53 int c;
54 while ((c = *name++) != '\0')
6f94a68e 55 if (! ISIDNUM (c) && c != '.' && c != '$')
ee890fe2
SS
56 return 1;
57 return 0;
58}
59
9c808aad 60/*
ee890fe2
SS
61 * flag_pic = 1 ... generate only indirections
62 * flag_pic = 2 ... generate indirections and pure code
63 */
64
65/* This module assumes that (const (symbol_ref "foo")) is a legal pic
66 reference, which will not be changed. */
67
e2500fed 68static GTY(()) tree machopic_defined_list;
ee890fe2
SS
69
70enum machopic_addr_class
9c808aad 71machopic_classify_ident (tree ident)
ee890fe2
SS
72{
73 const char *name = IDENTIFIER_POINTER (ident);
74 int lprefix = (((name[0] == '*' || name[0] == '&')
75 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
9c808aad
AJ
76 || ( name[0] == '_'
77 && name[1] == 'O'
78 && name[2] == 'B'
ee890fe2
SS
79 && name[3] == 'J'
80 && name[4] == 'C'
81 && name[5] == '_'));
df56a27f 82 tree temp;
9c808aad 83
1622229c
AP
84 /* The PIC base symbol is always defined. */
85 if (! strcmp (name, "<pic base>"))
86 return MACHOPIC_DEFINED_DATA;
ee890fe2 87
df56a27f 88 if (name[0] != '!')
ee890fe2 89 {
df56a27f 90 /* Here if no special encoding to be found. */
ee890fe2
SS
91 if (lprefix)
92 {
93 const char *name = IDENTIFIER_POINTER (ident);
94 int len = strlen (name);
95
96 if ((len > 5 && !strcmp (name + len - 5, "$stub"))
97 || (len > 6 && !strcmp (name + len - 6, "$stub\"")))
98 return MACHOPIC_DEFINED_FUNCTION;
99 return MACHOPIC_DEFINED_DATA;
100 }
101
102 for (temp = machopic_defined_list;
103 temp != NULL_TREE;
104 temp = TREE_CHAIN (temp))
105 {
106 if (ident == TREE_VALUE (temp))
107 return MACHOPIC_DEFINED_DATA;
108 }
109
110 if (TREE_ASM_WRITTEN (ident))
111 return MACHOPIC_DEFINED_DATA;
112
113 return MACHOPIC_UNDEFINED;
114 }
115
df56a27f
SS
116 else if (name[1] == 'D')
117 return MACHOPIC_DEFINED_DATA;
ee890fe2 118
df56a27f
SS
119 else if (name[1] == 'T')
120 return MACHOPIC_DEFINED_FUNCTION;
ee890fe2 121
b7fb9feb
TC
122 /* It is possible that someone is holding a "stale" name, which has
123 since been defined. See if there is a "defined" name (i.e,
124 different from NAME only in having a '!D_' or a '!T_' instead of
125 a '!d_' or '!t_' prefix) in the identifier hash tables. If so, say
126 that this identifier is defined. */
127 else if (name[1] == 'd' || name[1] == 't')
128 {
129 char *new_name;
130 new_name = (char *)alloca (strlen (name) + 1);
131 strcpy (new_name, name);
132 new_name[1] = (name[1] == 'd') ? 'D' : 'T';
133 if (maybe_get_identifier (new_name) != NULL)
134 return (name[1] == 'd') ? MACHOPIC_DEFINED_DATA
135 : MACHOPIC_DEFINED_FUNCTION;
136 }
137
ee890fe2
SS
138 for (temp = machopic_defined_list; temp != NULL_TREE; temp = TREE_CHAIN (temp))
139 {
140 if (ident == TREE_VALUE (temp))
141 {
df56a27f 142 if (name[1] == 'T')
ee890fe2
SS
143 return MACHOPIC_DEFINED_FUNCTION;
144 else
145 return MACHOPIC_DEFINED_DATA;
146 }
147 }
9c808aad 148
df56a27f 149 if (name[1] == 't' || name[1] == 'T')
ee890fe2
SS
150 {
151 if (lprefix)
152 return MACHOPIC_DEFINED_FUNCTION;
153 else
154 return MACHOPIC_UNDEFINED_FUNCTION;
155 }
156 else
157 {
158 if (lprefix)
159 return MACHOPIC_DEFINED_DATA;
160 else
161 return MACHOPIC_UNDEFINED_DATA;
162 }
163}
164
9c808aad 165
ee890fe2 166enum machopic_addr_class
9c808aad 167machopic_classify_name (const char *name)
ee890fe2
SS
168{
169 return machopic_classify_ident (get_identifier (name));
170}
171
172int
9c808aad 173machopic_ident_defined_p (tree ident)
ee890fe2
SS
174{
175 switch (machopic_classify_ident (ident))
176 {
177 case MACHOPIC_UNDEFINED:
178 case MACHOPIC_UNDEFINED_DATA:
179 case MACHOPIC_UNDEFINED_FUNCTION:
180 return 0;
181 default:
182 return 1;
183 }
184}
185
186static int
9c808aad 187machopic_data_defined_p (const char *name)
ee890fe2
SS
188{
189 switch (machopic_classify_ident (get_identifier (name)))
190 {
191 case MACHOPIC_DEFINED_DATA:
192 return 1;
193 default:
194 return 0;
195 }
196}
197
198int
9c808aad 199machopic_name_defined_p (const char *name)
ee890fe2
SS
200{
201 return machopic_ident_defined_p (get_identifier (name));
202}
203
204void
9c808aad 205machopic_define_ident (tree ident)
ee890fe2
SS
206{
207 if (!machopic_ident_defined_p (ident))
9c808aad 208 machopic_defined_list =
ee890fe2
SS
209 tree_cons (NULL_TREE, ident, machopic_defined_list);
210}
211
212void
9c808aad 213machopic_define_name (const char *name)
ee890fe2
SS
214{
215 machopic_define_ident (get_identifier (name));
216}
217
6788f5ca 218static GTY(()) char * function_base;
ee890fe2 219
92c1a778 220const char *
9c808aad 221machopic_function_base_name (void)
ee890fe2 222{
6788f5ca 223 const char *current_name;
ab82a49f
AP
224 /* if dynamic-no-pic is on, we should not get here */
225 if (MACHO_DYNAMIC_NO_PIC_P)
226 abort ();
9c808aad 227 current_name =
6788f5ca 228 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
ee890fe2 229
1622229c 230 if (function_base == NULL)
9c808aad 231 function_base =
1622229c
AP
232 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
233
234 current_function_uses_pic_offset_table = 1;
235
236 return function_base;
237}
238
239static GTY(()) const char * function_base_func_name;
240static GTY(()) int current_pic_label_num;
241
242void
243machopic_output_function_base_name (FILE *file)
244{
245 const char *current_name;
246
247 /* If dynamic-no-pic is on, we should not get here. */
248 if (MACHO_DYNAMIC_NO_PIC_P)
249 abort ();
9c808aad 250 current_name =
1622229c 251 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
6788f5ca 252 if (function_base_func_name != current_name)
ee890fe2 253 {
ee890fe2 254 ++current_pic_label_num;
6788f5ca 255 function_base_func_name = current_name;
ee890fe2 256 }
1622229c 257 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
ee890fe2
SS
258}
259
e2500fed 260static GTY(()) tree machopic_non_lazy_pointers;
ee890fe2
SS
261
262/* Return a non-lazy pointer name corresponding to the given name,
263 either by finding it in our list of pointer names, or by generating
264 a new one. */
265
6f94a68e 266static const char *
9c808aad 267machopic_non_lazy_ptr_name (const char *name)
ee890fe2 268{
7ae8cf75 269 const char *temp_name;
ee890fe2 270 tree temp, ident = get_identifier (name);
9c808aad 271
ee890fe2 272 for (temp = machopic_non_lazy_pointers;
9c808aad 273 temp != NULL_TREE;
ee890fe2
SS
274 temp = TREE_CHAIN (temp))
275 {
276 if (ident == TREE_VALUE (temp))
277 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
278 }
279
772c5265 280 name = darwin_strip_name_encoding (name);
df56a27f
SS
281
282 /* Try again, but comparing names this time. */
283 for (temp = machopic_non_lazy_pointers;
9c808aad 284 temp != NULL_TREE;
df56a27f
SS
285 temp = TREE_CHAIN (temp))
286 {
287 if (TREE_VALUE (temp))
288 {
289 temp_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
772c5265 290 temp_name = darwin_strip_name_encoding (temp_name);
df56a27f
SS
291 if (strcmp (name, temp_name) == 0)
292 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
293 }
294 }
295
ee890fe2
SS
296 {
297 char *buffer;
6e08ecd1
AP
298 int namelen = strlen (name);
299 int bufferlen = 0;
ee890fe2
SS
300 tree ptr_name;
301
6e08ecd1 302 buffer = alloca (namelen + strlen("$non_lazy_ptr") + 5);
ee890fe2
SS
303
304 strcpy (buffer, "&L");
6e08ecd1 305 bufferlen = 2;
ee890fe2 306 if (name[0] == '*')
6e08ecd1 307 {
77a7ed60 308 memcpy (buffer + bufferlen, name+1, namelen-1+1);
6e08ecd1
AP
309 bufferlen += namelen-1;
310 }
ee890fe2
SS
311 else
312 {
6e08ecd1 313 buffer[bufferlen] = '_';
77a7ed60 314 memcpy (buffer + bufferlen +1, name, namelen+1);
75f60443 315 bufferlen += namelen +1;
ee890fe2 316 }
9c808aad 317
77a7ed60 318 memcpy (buffer + bufferlen, "$non_lazy_ptr", strlen("$non_lazy_ptr")+1);
6e08ecd1 319 bufferlen += strlen("$non_lazy_ptr");
ee890fe2
SS
320 ptr_name = get_identifier (buffer);
321
9c808aad 322 machopic_non_lazy_pointers
ee890fe2
SS
323 = tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
324
325 TREE_USED (machopic_non_lazy_pointers) = 0;
326
327 return IDENTIFIER_POINTER (ptr_name);
328 }
329}
330
e2500fed 331static GTY(()) tree machopic_stubs;
ee890fe2
SS
332
333/* Return the name of the stub corresponding to the given name,
334 generating a new stub name if necessary. */
335
9c808aad
AJ
336const char *
337machopic_stub_name (const char *name)
ee890fe2
SS
338{
339 tree temp, ident = get_identifier (name);
93913281
SS
340 const char *tname;
341
ee890fe2 342 for (temp = machopic_stubs;
9c808aad 343 temp != NULL_TREE;
ee890fe2
SS
344 temp = TREE_CHAIN (temp))
345 {
346 if (ident == TREE_VALUE (temp))
347 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
93913281
SS
348 tname = IDENTIFIER_POINTER (TREE_VALUE (temp));
349 if (strcmp (name, tname) == 0)
350 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
351 /* A library call name might not be section-encoded yet, so try
352 it against a stripped name. */
353 if (name[0] != '!'
354 && tname[0] == '!'
355 && strcmp (name, tname + 4) == 0)
4e08ba6c 356 return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
ee890fe2
SS
357 }
358
772c5265 359 name = darwin_strip_name_encoding (name);
df56a27f 360
ee890fe2
SS
361 {
362 char *buffer;
6e08ecd1
AP
363 int bufferlen = 0;
364 int namelen = strlen (name);
ee890fe2
SS
365 tree ptr_name;
366 int needs_quotes = name_needs_quotes (name);
367
6e08ecd1 368 buffer = alloca (namelen + 20);
ee890fe2
SS
369
370 if (needs_quotes)
6e08ecd1
AP
371 {
372 strcpy (buffer, "&\"L");
373 bufferlen = strlen("&\"L");
374 }
ee890fe2 375 else
6e08ecd1
AP
376 {
377 strcpy (buffer, "&L");
378 bufferlen = strlen("&L");
379 }
380
ee890fe2
SS
381 if (name[0] == '*')
382 {
77a7ed60 383 memcpy (buffer + bufferlen, name+1, namelen - 1 +1);
6e08ecd1 384 bufferlen += namelen - 1;
ee890fe2
SS
385 }
386 else
387 {
6e08ecd1 388 buffer[bufferlen] = '_';
77a7ed60 389 memcpy (buffer + bufferlen +1, name, namelen+1);
75f60443 390 bufferlen += namelen +1;
ee890fe2
SS
391 }
392
393 if (needs_quotes)
6e08ecd1 394 {
77a7ed60 395 memcpy (buffer + bufferlen, "$stub\"", strlen("$stub\"")+1);
6e08ecd1
AP
396 bufferlen += strlen("$stub\"");
397 }
ee890fe2 398 else
6e08ecd1 399 {
77a7ed60 400 memcpy (buffer + bufferlen, "$stub", strlen("$stub")+1);
6e08ecd1
AP
401 bufferlen += strlen("$stub");
402 }
ee890fe2
SS
403 ptr_name = get_identifier (buffer);
404
405 machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
406 TREE_USED (machopic_stubs) = 0;
407
408 return IDENTIFIER_POINTER (ptr_name);
409 }
410}
411
412void
9c808aad 413machopic_validate_stub_or_non_lazy_ptr (const char *name, int validate_stub)
ee890fe2 414{
7ae8cf75 415 const char *real_name;
df56a27f 416 tree temp, ident = get_identifier (name), id2;
ee890fe2
SS
417
418 for (temp = (validate_stub ? machopic_stubs : machopic_non_lazy_pointers);
419 temp != NULL_TREE;
420 temp = TREE_CHAIN (temp))
421 if (ident == TREE_PURPOSE (temp))
422 {
423 /* Mark both the stub or non-lazy pointer as well as the
424 original symbol as being referenced. */
425 TREE_USED (temp) = 1;
426 if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
af0f185b 427 mark_referenced (TREE_VALUE (temp));
772c5265
RH
428 real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
429 real_name = darwin_strip_name_encoding (real_name);
df56a27f
SS
430 id2 = maybe_get_identifier (real_name);
431 if (id2)
af0f185b 432 mark_referenced (id2);
ee890fe2
SS
433 }
434}
435
436/* Transform ORIG, which may be any data source, to the corresponding
437 source using indirections. */
438
439rtx
9c808aad 440machopic_indirect_data_reference (rtx orig, rtx reg)
ee890fe2
SS
441{
442 rtx ptr_ref = orig;
9c808aad 443
ee890fe2
SS
444 if (! MACHOPIC_INDIRECT)
445 return orig;
446
447 if (GET_CODE (orig) == SYMBOL_REF)
448 {
449 const char *name = XSTR (orig, 0);
ab82a49f
AP
450 int defined = machopic_data_defined_p (name);
451
452 if (defined && MACHO_DYNAMIC_NO_PIC_P)
453 {
454#if defined (TARGET_TOC)
9c808aad 455 emit_insn (gen_macho_high (reg, orig));
ab82a49f
AP
456 emit_insn (gen_macho_low (reg, reg, orig));
457#else
458 /* some other cpu -- writeme! */
459 abort ();
460#endif
461 return reg;
462 }
463 else if (defined)
ee890fe2 464 {
7ae8cf75 465#if defined (TARGET_TOC) || defined (HAVE_lo_sum)
6f94a68e
GK
466 rtx pic_base = gen_rtx_SYMBOL_REF (Pmode,
467 machopic_function_base_name ());
468 rtx offset = gen_rtx_CONST (Pmode,
469 gen_rtx_MINUS (Pmode, orig, pic_base));
7ae8cf75 470#endif
ee890fe2
SS
471
472#if defined (TARGET_TOC) /* i.e., PowerPC */
d9b46dfb 473 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
ee890fe2
SS
474
475 if (reg == NULL)
476 abort ();
477
6f94a68e
GK
478 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
479 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
480 gen_rtx_HIGH (Pmode, offset))));
481 emit_insn (gen_rtx_SET (Pmode, reg,
482 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
ee890fe2
SS
483
484 orig = reg;
485#else
486#if defined (HAVE_lo_sum)
487 if (reg == 0) abort ();
488
6f94a68e
GK
489 emit_insn (gen_rtx_SET (VOIDmode, reg,
490 gen_rtx_HIGH (Pmode, offset)));
491 emit_insn (gen_rtx_SET (VOIDmode, reg,
492 gen_rtx_LO_SUM (Pmode, reg, offset)));
493 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
ee890fe2 494
6f94a68e 495 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
ee890fe2
SS
496#endif
497#endif
498 return orig;
499 }
500
6f94a68e
GK
501 ptr_ref = gen_rtx_SYMBOL_REF (Pmode,
502 machopic_non_lazy_ptr_name (name));
ee890fe2
SS
503
504 ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
505 RTX_UNCHANGING_P (ptr_ref) = 1;
506
507 return ptr_ref;
508 }
509 else if (GET_CODE (orig) == CONST)
510 {
511 rtx base, result;
512
513 /* legitimize both operands of the PLUS */
514 if (GET_CODE (XEXP (orig, 0)) == PLUS)
515 {
516 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
517 reg);
518 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
519 (base == reg ? 0 : reg));
520 }
9c808aad 521 else
ee890fe2
SS
522 return orig;
523
524 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
ed8908e7 525 result = plus_constant (base, INTVAL (orig));
ee890fe2 526 else
6f94a68e 527 result = gen_rtx_PLUS (Pmode, base, orig);
ee890fe2 528
ee890fe2
SS
529 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
530 {
531 if (reg)
532 {
533 emit_move_insn (reg, result);
534 result = reg;
535 }
536 else
537 {
538 result = force_reg (GET_MODE (result), result);
539 }
540 }
541
542 return result;
543
544 }
545 else if (GET_CODE (orig) == MEM)
546 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
547 /* When the target is i386, this code prevents crashes due to the
548 compiler's ignorance on how to move the PIC base register to
549 other registers. (The reload phase sometimes introduces such
550 insns.) */
551 else if (GET_CODE (orig) == PLUS
552 && GET_CODE (XEXP (orig, 0)) == REG
553 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
554#ifdef I386
555 /* Prevent the same register from being erroneously used
556 as both the base and index registers. */
557 && GET_CODE (XEXP (orig, 1)) == CONST
558#endif
559 && reg)
560 {
561 emit_move_insn (reg, XEXP (orig, 0));
562 XEXP (ptr_ref, 0) = reg;
563 }
564 return ptr_ref;
565}
566
ee890fe2
SS
567/* Transform TARGET (a MEM), which is a function call target, to the
568 corresponding symbol_stub if necessary. Return a new MEM. */
569
570rtx
9c808aad 571machopic_indirect_call_target (rtx target)
ee890fe2
SS
572{
573 if (GET_CODE (target) != MEM)
574 return target;
575
576 if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
9c808aad 577 {
ee890fe2
SS
578 enum machine_mode mode = GET_MODE (XEXP (target, 0));
579 const char *name = XSTR (XEXP (target, 0), 0);
580
b7fb9feb
TC
581 /* If the name is already defined, we need do nothing. */
582 if (name[0] == '!' && name[1] == 'T')
583 return target;
584
585 if (!machopic_name_defined_p (name))
ee890fe2
SS
586 {
587 const char *stub_name = machopic_stub_name (name);
588
6f94a68e 589 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
ee890fe2 590 RTX_UNCHANGING_P (target) = 1;
9c808aad 591 }
ee890fe2
SS
592 }
593
594 return target;
595}
596
597rtx
9c808aad 598machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
ee890fe2
SS
599{
600 rtx pic_ref = orig;
601
ab82a49f 602 if (! MACHOPIC_INDIRECT)
ee890fe2
SS
603 return orig;
604
605 /* First handle a simple SYMBOL_REF or LABEL_REF */
606 if (GET_CODE (orig) == LABEL_REF
607 || (GET_CODE (orig) == SYMBOL_REF
608 ))
609 {
610 /* addr(foo) = &func+(foo-func) */
611 rtx pic_base;
612
613 orig = machopic_indirect_data_reference (orig, reg);
614
9c808aad 615 if (GET_CODE (orig) == PLUS
ee890fe2
SS
616 && GET_CODE (XEXP (orig, 0)) == REG)
617 {
618 if (reg == 0)
619 return force_reg (mode, orig);
620
621 emit_move_insn (reg, orig);
622 return reg;
9c808aad 623 }
ee890fe2 624
ab82a49f
AP
625 /* if dynamic-no-pic then use 0 as the pic base */
626 if (MACHO_DYNAMIC_NO_PIC_P)
627 pic_base = CONST0_RTX (Pmode);
628 else
6f94a68e 629 pic_base = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
ee890fe2
SS
630
631 if (GET_CODE (orig) == MEM)
632 {
633 if (reg == 0)
634 {
635 if (reload_in_progress)
636 abort ();
637 else
638 reg = gen_reg_rtx (Pmode);
639 }
9c808aad 640
ee890fe2 641#ifdef HAVE_lo_sum
ab82a49f
AP
642 if (MACHO_DYNAMIC_NO_PIC_P
643 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
644 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
645 {
646#if defined (TARGET_TOC) /* ppc */
647 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
648 rtx asym = XEXP (orig, 0);
649 rtx mem;
650
651 emit_insn (gen_macho_high (temp_reg, asym));
652 mem = gen_rtx_MEM (GET_MODE (orig),
6f94a68e 653 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
ab82a49f 654 RTX_UNCHANGING_P (mem) = 1;
6f94a68e 655 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
ab82a49f
AP
656#else
657 /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
658 abort ();
659#endif
660 pic_ref = reg;
661 }
662 else
9c808aad 663 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
ee890fe2
SS
664 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
665 {
6f94a68e
GK
666 rtx offset = gen_rtx_CONST (Pmode,
667 gen_rtx_MINUS (Pmode,
668 XEXP (orig, 0),
669 pic_base));
ee890fe2
SS
670#if defined (TARGET_TOC) /* i.e., PowerPC */
671 /* Generating a new reg may expose opportunities for
672 common subexpression elimination. */
6f94a68e
GK
673 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (SImode);
674 rtx mem;
675 rtx insn;
676 rtx sum;
677
678 sum = gen_rtx_HIGH (Pmode, offset);
679 if (! MACHO_DYNAMIC_NO_PIC_P)
680 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
ee890fe2 681
6f94a68e
GK
682 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
683
684 mem = gen_rtx_MEM (GET_MODE (orig),
685 gen_rtx_LO_SUM (Pmode,
686 hi_sum_reg, offset));
687 RTX_UNCHANGING_P (mem) = 1;
688 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
689 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
690 REG_NOTES (insn));
691
692 pic_ref = reg;
ee890fe2 693#else
6f94a68e
GK
694 emit_insn (gen_rtx_USE (VOIDmode,
695 gen_rtx_REG (Pmode,
696 PIC_OFFSET_TABLE_REGNUM)));
697
698 emit_insn (gen_rtx_SET (VOIDmode, reg,
699 gen_rtx_HIGH (Pmode,
700 gen_rtx_CONST (Pmode,
701 offset))));
702 emit_insn (gen_rtx_SET (VOIDmode, reg,
703 gen_rtx_LO_SUM (Pmode, reg,
704 gen_rtx_CONST (Pmode, offset))));
705 pic_ref = gen_rtx_PLUS (Pmode,
706 pic_offset_table_rtx, reg);
ee890fe2
SS
707#endif
708 }
709 else
710#endif /* HAVE_lo_sum */
711 {
712 rtx pic = pic_offset_table_rtx;
713 if (GET_CODE (pic) != REG)
714 {
715 emit_move_insn (reg, pic);
716 pic = reg;
717 }
718#if 0
6f94a68e
GK
719 emit_insn (gen_rtx_USE (VOIDmode,
720 gen_rtx_REG (Pmode,
721 PIC_OFFSET_TABLE_REGNUM)));
ee890fe2
SS
722#endif
723
6f94a68e
GK
724 pic_ref = gen_rtx_PLUS (Pmode,
725 pic,
726 gen_rtx_CONST (Pmode,
727 gen_rtx_MINUS (Pmode,
728 XEXP (orig, 0),
729 pic_base)));
ee890fe2 730 }
9c808aad 731
ee890fe2 732#if !defined (TARGET_TOC)
ee890fe2 733 emit_move_insn (reg, pic_ref);
6f94a68e 734 pic_ref = gen_rtx_MEM (GET_MODE (orig), reg);
ee890fe2 735#endif
b069de3b 736 RTX_UNCHANGING_P (pic_ref) = 1;
ee890fe2
SS
737 }
738 else
739 {
740
741#ifdef HAVE_lo_sum
9c808aad 742 if (GET_CODE (orig) == SYMBOL_REF
ee890fe2
SS
743 || GET_CODE (orig) == LABEL_REF)
744 {
6f94a68e
GK
745 rtx offset = gen_rtx_CONST (Pmode,
746 gen_rtx_MINUS (Pmode,
747 orig, pic_base));
ee890fe2
SS
748#if defined (TARGET_TOC) /* i.e., PowerPC */
749 rtx hi_sum_reg;
750
751 if (reg == 0)
752 {
753 if (reload_in_progress)
754 abort ();
755 else
756 reg = gen_reg_rtx (SImode);
757 }
9c808aad 758
ee890fe2
SS
759 hi_sum_reg = reg;
760
6f94a68e
GK
761 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
762 (MACHO_DYNAMIC_NO_PIC_P)
763 ? gen_rtx_HIGH (Pmode, offset)
764 : gen_rtx_PLUS (Pmode,
765 pic_offset_table_rtx,
766 gen_rtx_HIGH (Pmode,
767 offset))));
768 emit_insn (gen_rtx_SET (VOIDmode, reg,
769 gen_rtx_LO_SUM (Pmode,
770 hi_sum_reg, offset)));
ee890fe2 771 pic_ref = reg;
b069de3b 772 RTX_UNCHANGING_P (pic_ref) = 1;
ee890fe2 773#else
6f94a68e
GK
774 emit_insn (gen_rtx_SET (VOIDmode, reg,
775 gen_rtx_HIGH (Pmode, offset)));
776 emit_insn (gen_rtx_SET (VOIDmode, reg,
777 gen_rtx_LO_SUM (Pmode, reg, offset)));
778 pic_ref = gen_rtx_PLUS (Pmode,
779 pic_offset_table_rtx, reg);
b069de3b 780 RTX_UNCHANGING_P (pic_ref) = 1;
ee890fe2
SS
781#endif
782 }
783 else
784#endif /* HAVE_lo_sum */
785 {
786 if (GET_CODE (orig) == REG)
787 {
788 return orig;
789 }
790 else
791 {
792 rtx pic = pic_offset_table_rtx;
793 if (GET_CODE (pic) != REG)
794 {
795 emit_move_insn (reg, pic);
796 pic = reg;
797 }
798#if 0
6f94a68e
GK
799 emit_insn (gen_rtx_USE (VOIDmode,
800 pic_offset_table_rtx));
ee890fe2 801#endif
6f94a68e
GK
802 pic_ref = gen_rtx_PLUS (Pmode,
803 pic,
804 gen_rtx_CONST (Pmode,
805 gen_rtx_MINUS (Pmode,
806 orig, pic_base)));
ee890fe2
SS
807 }
808 }
809 }
810
ee890fe2
SS
811 if (GET_CODE (pic_ref) != REG)
812 {
813 if (reg != 0)
814 {
815 emit_move_insn (reg, pic_ref);
816 return reg;
817 }
818 else
819 {
820 return force_reg (mode, pic_ref);
821 }
822 }
823 else
824 {
825 return pic_ref;
826 }
827 }
828
829 else if (GET_CODE (orig) == SYMBOL_REF)
830 return orig;
831
832 else if (GET_CODE (orig) == PLUS
833 && (GET_CODE (XEXP (orig, 0)) == MEM
834 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
835 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
836 && XEXP (orig, 0) != pic_offset_table_rtx
837 && GET_CODE (XEXP (orig, 1)) != REG)
9c808aad 838
ee890fe2
SS
839 {
840 rtx base;
841 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
842
843 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
844 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
845 Pmode, (base == reg ? 0 : reg));
846 if (GET_CODE (orig) == CONST_INT)
847 {
ed8908e7 848 pic_ref = plus_constant (base, INTVAL (orig));
ee890fe2
SS
849 is_complex = 1;
850 }
851 else
6f94a68e 852 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
ee890fe2
SS
853
854 if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
855 RTX_UNCHANGING_P (pic_ref) = 1;
856
857 if (reg && is_complex)
858 {
859 emit_move_insn (reg, pic_ref);
860 pic_ref = reg;
861 }
862 /* Likewise, should we set special REG_NOTEs here? */
863 }
864
865 else if (GET_CODE (orig) == CONST)
866 {
867 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
868 }
869
870 else if (GET_CODE (orig) == MEM
871 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
872 {
873 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
874
6f94a68e 875 addr = gen_rtx_MEM (GET_MODE (orig), addr);
ee890fe2
SS
876 RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
877 emit_move_insn (reg, addr);
878 pic_ref = reg;
879 }
880
881 return pic_ref;
882}
883
884
885void
9c808aad 886machopic_finish (FILE *asm_out_file)
ee890fe2
SS
887{
888 tree temp;
889
890 for (temp = machopic_stubs;
891 temp != NULL_TREE;
892 temp = TREE_CHAIN (temp))
893 {
91dc3130
KG
894 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
895 const char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
ee890fe2
SS
896 char *sym;
897 char *stub;
ee890fe2
SS
898
899 if (! TREE_USED (temp))
900 continue;
901
b7fb9feb
TC
902 /* If the symbol is actually defined, we don't need a stub. */
903 if (sym_name[0] == '!' && sym_name[1] == 'T')
904 continue;
905
772c5265 906 sym_name = darwin_strip_name_encoding (sym_name);
ee890fe2
SS
907
908 sym = alloca (strlen (sym_name) + 2);
909 if (sym_name[0] == '*' || sym_name[0] == '&')
910 strcpy (sym, sym_name + 1);
911 else if (sym_name[0] == '-' || sym_name[0] == '+')
9c808aad 912 strcpy (sym, sym_name);
ee890fe2
SS
913 else
914 sym[0] = '_', strcpy (sym + 1, sym_name);
915
916 stub = alloca (strlen (stub_name) + 2);
917 if (stub_name[0] == '*' || stub_name[0] == '&')
918 strcpy (stub, stub_name + 1);
919 else
920 stub[0] = '_', strcpy (stub + 1, stub_name);
921
922 machopic_output_stub (asm_out_file, sym, stub);
923 }
924
925 for (temp = machopic_non_lazy_pointers;
9c808aad 926 temp != NULL_TREE;
ee890fe2
SS
927 temp = TREE_CHAIN (temp))
928 {
7ae8cf75
KG
929 const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
930 const char *const lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
ee890fe2
SS
931
932 if (! TREE_USED (temp))
933 continue;
934
3f64e543 935 if (machopic_ident_defined_p (TREE_VALUE (temp)))
ee890fe2
SS
936 {
937 data_section ();
c8af3574 938 assemble_align (GET_MODE_ALIGNMENT (Pmode));
ee890fe2 939 assemble_label (lazy_name);
6f94a68e 940 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
c8af3574
RH
941 GET_MODE_SIZE (Pmode),
942 GET_MODE_ALIGNMENT (Pmode), 1);
ee890fe2
SS
943 }
944 else
945 {
946 machopic_nl_symbol_ptr_section ();
9c808aad 947 assemble_name (asm_out_file, lazy_name);
ee890fe2
SS
948 fprintf (asm_out_file, ":\n");
949
950 fprintf (asm_out_file, "\t.indirect_symbol ");
9c808aad 951 assemble_name (asm_out_file, sym_name);
ee890fe2
SS
952 fprintf (asm_out_file, "\n");
953
c8af3574
RH
954 assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
955 GET_MODE_ALIGNMENT (Pmode), 1);
ee890fe2
SS
956 }
957 }
958}
959
9c808aad
AJ
960int
961machopic_operand_p (rtx op)
ee890fe2
SS
962{
963 if (MACHOPIC_JUST_INDIRECT)
964 {
965 while (GET_CODE (op) == CONST)
966 op = XEXP (op, 0);
967
968 if (GET_CODE (op) == SYMBOL_REF)
969 return machopic_name_defined_p (XSTR (op, 0));
970 else
971 return 0;
972 }
973
974 while (GET_CODE (op) == CONST)
975 op = XEXP (op, 0);
976
977 if (GET_CODE (op) == MINUS
978 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
979 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
980 && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
981 && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
982 return 1;
983
ee890fe2
SS
984 return 0;
985}
df56a27f
SS
986
987/* This function records whether a given name corresponds to a defined
988 or undefined function or variable, for machopic_classify_ident to
989 use later. */
990
991void
9c808aad 992darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
df56a27f
SS
993{
994 char code = '\0';
995 int defined = 0;
353e51f8 996 rtx sym_ref;
c0cbc013
DJ
997 const char *orig_str;
998 char *new_str;
353e51f8 999 size_t len, new_len;
df56a27f 1000
e1a4211d
SS
1001 /* Do the standard encoding things first. */
1002 default_encode_section_info (decl, rtl, first);
1003
1004 /* With the introduction of symbol_ref flags, some of the following
1005 code has become redundant and should be removed at some point. */
1006
df56a27f
SS
1007 if ((TREE_CODE (decl) == FUNCTION_DECL
1008 || TREE_CODE (decl) == VAR_DECL)
70bdc2ff 1009 && !DECL_EXTERNAL (decl)
df56a27f
SS
1010 && ((TREE_STATIC (decl)
1011 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
abe72dd8
SS
1012 || (DECL_INITIAL (decl)
1013 && DECL_INITIAL (decl) != error_mark_node)))
df56a27f
SS
1014 defined = 1;
1015
1016 if (TREE_CODE (decl) == FUNCTION_DECL)
1017 code = (defined ? 'T' : 't');
1018 else if (TREE_CODE (decl) == VAR_DECL)
1019 code = (defined ? 'D' : 'd');
1020
353e51f8
SS
1021 if (code == '\0')
1022 return;
df56a27f 1023
c6a2438a 1024 sym_ref = XEXP (rtl, 0);
353e51f8
SS
1025 orig_str = XSTR (sym_ref, 0);
1026 len = strlen (orig_str) + 1;
df56a27f 1027
353e51f8
SS
1028 if (orig_str[0] == '!')
1029 {
1030 /* Already encoded; see if we need to change it. */
1031 if (code == orig_str[1])
1032 return;
1033 /* Yes, tweak a copy of the name and put it in a new string. */
1034 new_str = alloca (len);
1035 memcpy (new_str, orig_str, len);
1036 new_str[1] = code;
1037 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
353e51f8
SS
1038 }
1039 else
1040 {
1041 /* Add the encoding. */
1042 new_len = len + 4;
1043 new_str = alloca (new_len);
1044 new_str[0] = '!';
1045 new_str[1] = code;
1046 new_str[2] = '_';
1047 new_str[3] = '_';
1048 memcpy (new_str + 4, orig_str, len);
1049 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
df56a27f 1050 }
4e08ba6c
SS
1051 /* The non-lazy pointer list may have captured references to the
1052 old encoded name, change them. */
b7fb9feb
TC
1053 if (TREE_CODE (decl) == VAR_DECL)
1054 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1055 else
1056 update_stubs (XSTR (sym_ref, 0));
df56a27f
SS
1057}
1058
772c5265
RH
1059/* Undo the effects of the above. */
1060
1061const char *
9c808aad 1062darwin_strip_name_encoding (const char *str)
772c5265
RH
1063{
1064 return str[0] == '!' ? str + 4 : str;
1065}
1066
df56a27f
SS
1067/* Scan the list of non-lazy pointers and update any recorded names whose
1068 stripped name matches the argument. */
1069
1070static void
9c808aad 1071update_non_lazy_ptrs (const char *name)
df56a27f 1072{
91dc3130 1073 const char *name1, *name2;
df56a27f
SS
1074 tree temp;
1075
772c5265 1076 name1 = darwin_strip_name_encoding (name);
df56a27f
SS
1077
1078 for (temp = machopic_non_lazy_pointers;
9c808aad 1079 temp != NULL_TREE;
df56a27f
SS
1080 temp = TREE_CHAIN (temp))
1081 {
7ae8cf75 1082 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
df56a27f
SS
1083
1084 if (*sym_name == '!')
1085 {
772c5265 1086 name2 = darwin_strip_name_encoding (sym_name);
df56a27f
SS
1087 if (strcmp (name1, name2) == 0)
1088 {
d24652ee 1089 /* FIXME: This breaks the identifier hash table. */
9c808aad 1090 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
d24652ee 1091 = (unsigned char *) name;
df56a27f
SS
1092 break;
1093 }
1094 }
1095 }
1096}
4e08ba6c 1097
b7fb9feb
TC
1098/* Function NAME is being defined, and its label has just been output.
1099 If there's already a reference to a stub for this function, we can
991b6592 1100 just emit the stub label now and we don't bother emitting the stub later. */
b7fb9feb
TC
1101
1102void
9c808aad 1103machopic_output_possible_stub_label (FILE *file, const char *name)
b7fb9feb
TC
1104{
1105 tree temp;
1106
b7fb9feb
TC
1107 /* Ensure we're looking at a section-encoded name. */
1108 if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
1109 return;
1110
1111 for (temp = machopic_stubs;
1112 temp != NULL_TREE;
1113 temp = TREE_CHAIN (temp))
1114 {
1115 const char *sym_name;
1116
1117 sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1118 if (sym_name[0] == '!' && sym_name[1] == 'T'
1119 && ! strcmp (name+2, sym_name+2))
1120 {
1121 ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
61d951df
TC
1122 /* Avoid generating a stub for this. */
1123 TREE_USED (temp) = 0;
b7fb9feb
TC
1124 break;
1125 }
1126 }
1127}
4e08ba6c
SS
1128
1129/* Scan the list of stubs and update any recorded names whose
1130 stripped name matches the argument. */
1131
1132static void
9c808aad 1133update_stubs (const char *name)
4e08ba6c 1134{
91dc3130 1135 const char *name1, *name2;
4e08ba6c
SS
1136 tree temp;
1137
772c5265 1138 name1 = darwin_strip_name_encoding (name);
4e08ba6c
SS
1139
1140 for (temp = machopic_stubs;
9c808aad 1141 temp != NULL_TREE;
4e08ba6c
SS
1142 temp = TREE_CHAIN (temp))
1143 {
7ae8cf75 1144 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
4e08ba6c
SS
1145
1146 if (*sym_name == '!')
1147 {
772c5265 1148 name2 = darwin_strip_name_encoding (sym_name);
4e08ba6c
SS
1149 if (strcmp (name1, name2) == 0)
1150 {
d24652ee 1151 /* FIXME: This breaks the identifier hash table. */
9c808aad 1152 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
d24652ee 1153 = (unsigned char *) name;
4e08ba6c
SS
1154 break;
1155 }
1156 }
1157 }
1158}
2cc07db4 1159
ae46c4e0 1160void
9c808aad
AJ
1161machopic_select_section (tree exp, int reloc,
1162 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
ae46c4e0 1163{
3d7964d5 1164 void (*base_function)(void);
9c808aad 1165
3d7964d5
GK
1166 if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1167 base_function = readonly_data_section;
1168 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1169 base_function = const_data_section;
1170 else
1171 base_function = data_section;
9c808aad 1172
3d7964d5 1173 if (TREE_CODE (exp) == STRING_CST
9c808aad 1174 && ((size_t) TREE_STRING_LENGTH (exp)
3d7964d5
GK
1175 == strlen (TREE_STRING_POINTER (exp)) + 1)
1176 && ! flag_writable_strings)
1177 cstring_section ();
1178 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1179 && flag_merge_constants)
ae46c4e0
RH
1180 {
1181 tree size = TYPE_SIZE (TREE_TYPE (exp));
1182
1183 if (TREE_CODE (size) == INTEGER_CST &&
1184 TREE_INT_CST_LOW (size) == 4 &&
1185 TREE_INT_CST_HIGH (size) == 0)
1186 literal4_section ();
1187 else if (TREE_CODE (size) == INTEGER_CST &&
1188 TREE_INT_CST_LOW (size) == 8 &&
1189 TREE_INT_CST_HIGH (size) == 0)
1190 literal8_section ();
1191 else
3d7964d5 1192 base_function ();
ae46c4e0
RH
1193 }
1194 else if (TREE_CODE (exp) == CONSTRUCTOR
1195 && TREE_TYPE (exp)
1196 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1197 && TYPE_NAME (TREE_TYPE (exp)))
1198 {
1199 tree name = TYPE_NAME (TREE_TYPE (exp));
1200 if (TREE_CODE (name) == TYPE_DECL)
1201 name = DECL_NAME (name);
1202 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1203 objc_constant_string_object_section ();
1204 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1205 objc_string_object_section ();
ae46c4e0 1206 else
3d7964d5 1207 base_function ();
ae46c4e0
RH
1208 }
1209 else if (TREE_CODE (exp) == VAR_DECL &&
1210 DECL_NAME (exp) &&
1211 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1212 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1213 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1214 {
1215 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1216
1217 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1218 objc_cls_meth_section ();
1219 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1220 objc_inst_meth_section ();
1221 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1222 objc_cat_cls_meth_section ();
1223 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1224 objc_cat_inst_meth_section ();
1225 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1226 objc_class_vars_section ();
1227 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1228 objc_instance_vars_section ();
1229 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1230 objc_cat_cls_meth_section ();
1231 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1232 objc_class_names_section ();
1233 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1234 objc_meth_var_names_section ();
1235 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1236 objc_meth_var_types_section ();
1237 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1238 objc_cls_refs_section ();
1239 else if (!strncmp (name, "_OBJC_CLASS_", 12))
1240 objc_class_section ();
1241 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1242 objc_meta_class_section ();
1243 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1244 objc_category_section ();
1245 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1246 objc_selector_refs_section ();
1247 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1248 objc_selector_fixup_section ();
1249 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1250 objc_symbols_section ();
1251 else if (!strncmp (name, "_OBJC_MODULES", 13))
1252 objc_module_info_section ();
264fa2db
ZL
1253 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1254 objc_image_info_section ();
ae46c4e0
RH
1255 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1256 objc_cat_inst_meth_section ();
1257 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1258 objc_cat_cls_meth_section ();
1259 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1260 objc_cat_cls_meth_section ();
1261 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1262 objc_protocol_section ();
ae46c4e0 1263 else
3d7964d5 1264 base_function ();
ae46c4e0
RH
1265 }
1266 else
3d7964d5 1267 base_function ();
ae46c4e0
RH
1268}
1269
b64a1b53 1270/* This can be called with address expressions as "rtx".
991b6592 1271 They must go in "const". */
b64a1b53
RH
1272
1273void
9c808aad
AJ
1274machopic_select_rtx_section (enum machine_mode mode, rtx x,
1275 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
b64a1b53
RH
1276{
1277 if (GET_MODE_SIZE (mode) == 8)
1278 literal8_section ();
1279 else if (GET_MODE_SIZE (mode) == 4
1280 && (GET_CODE (x) == CONST_INT
1281 || GET_CODE (x) == CONST_DOUBLE))
1282 literal4_section ();
86b0a4f3 1283 else if (MACHOPIC_INDIRECT
2e53734e
GK
1284 && (GET_CODE (x) == SYMBOL_REF
1285 || GET_CODE (x) == CONST
1286 || GET_CODE (x) == LABEL_REF))
1287 const_data_section ();
b64a1b53
RH
1288 else
1289 const_section ();
1290}
1291
2cc07db4 1292void
9c808aad 1293machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
2cc07db4 1294{
ab82a49f 1295 if (MACHOPIC_INDIRECT)
2cc07db4
RH
1296 mod_init_section ();
1297 else
1298 constructor_section ();
c8af3574
RH
1299 assemble_align (POINTER_SIZE);
1300 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2cc07db4 1301
ab82a49f 1302 if (! MACHOPIC_INDIRECT)
2cc07db4
RH
1303 fprintf (asm_out_file, ".reference .constructors_used\n");
1304}
1305
1306void
9c808aad 1307machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
2cc07db4 1308{
ab82a49f 1309 if (MACHOPIC_INDIRECT)
2cc07db4
RH
1310 mod_term_section ();
1311 else
1312 destructor_section ();
c8af3574
RH
1313 assemble_align (POINTER_SIZE);
1314 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2cc07db4 1315
ab82a49f 1316 if (! MACHOPIC_INDIRECT)
2cc07db4
RH
1317 fprintf (asm_out_file, ".reference .destructors_used\n");
1318}
e2500fed 1319
5eb99654 1320void
9c808aad 1321darwin_globalize_label (FILE *stream, const char *name)
5eb99654
KG
1322{
1323 if (!!strncmp (name, "_OBJC_", 6))
1324 default_globalize_label (stream, name);
1325}
1326
7606e68f
SS
1327/* Output a difference of two labels that will be an assembly time
1328 constant if the two labels are local. (.long lab1-lab2 will be
1329 very different if lab1 is at the boundary between two sections; it
1330 will be relocated according to the second section, not the first,
1331 so one ends up with a difference between labels in different
1332 sections, which is bad in the dwarf2 eh context for instance.) */
1333
1334static int darwin_dwarf_label_counter;
1335
1336void
9c808aad
AJ
1337darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
1338 const char *lab1, const char *lab2)
7606e68f
SS
1339{
1340 const char *p = lab1 + (lab1[0] == '*');
1341 int islocaldiff = (p[0] == 'L');
1342
1343 if (islocaldiff)
1344 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1345 else
1346 fprintf (file, "\t%s\t", ".long");
1347 assemble_name (file, lab1);
1348 fprintf (file, "-");
1349 assemble_name (file, lab2);
1350 if (islocaldiff)
1351 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1352}
1353
a5fe455b 1354void
9c808aad 1355darwin_file_end (void)
a5fe455b
ZW
1356{
1357 machopic_finish (asm_out_file);
1358 if (strcmp (lang_hooks.name, "GNU C++") == 0)
1359 {
1360 constructor_section ();
1361 destructor_section ();
1362 ASM_OUTPUT_ALIGN (asm_out_file, 1);
1363 }
1364}
1365
e2500fed 1366#include "gt-darwin.h"