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