]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/darwin.c
i386.h (OPTION_DEFAULT_SPECS): Avoid -mcpu default when -march is specified.
[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
c6a2438a 977darwin_encode_section_info (decl, rtl, first)
df56a27f 978 tree decl;
c6a2438a 979 rtx rtl;
b2003250 980 int first ATTRIBUTE_UNUSED;
df56a27f
SS
981{
982 char code = '\0';
983 int defined = 0;
353e51f8 984 rtx sym_ref;
c0cbc013
DJ
985 const char *orig_str;
986 char *new_str;
353e51f8 987 size_t len, new_len;
df56a27f 988
e1a4211d
SS
989 /* Do the standard encoding things first. */
990 default_encode_section_info (decl, rtl, first);
991
992 /* With the introduction of symbol_ref flags, some of the following
993 code has become redundant and should be removed at some point. */
994
df56a27f
SS
995 if ((TREE_CODE (decl) == FUNCTION_DECL
996 || TREE_CODE (decl) == VAR_DECL)
70bdc2ff 997 && !DECL_EXTERNAL (decl)
df56a27f
SS
998 && ((TREE_STATIC (decl)
999 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
abe72dd8
SS
1000 || (DECL_INITIAL (decl)
1001 && DECL_INITIAL (decl) != error_mark_node)))
df56a27f
SS
1002 defined = 1;
1003
1004 if (TREE_CODE (decl) == FUNCTION_DECL)
1005 code = (defined ? 'T' : 't');
1006 else if (TREE_CODE (decl) == VAR_DECL)
1007 code = (defined ? 'D' : 'd');
1008
353e51f8
SS
1009 if (code == '\0')
1010 return;
df56a27f 1011
c6a2438a 1012 sym_ref = XEXP (rtl, 0);
353e51f8
SS
1013 orig_str = XSTR (sym_ref, 0);
1014 len = strlen (orig_str) + 1;
df56a27f 1015
353e51f8
SS
1016 if (orig_str[0] == '!')
1017 {
1018 /* Already encoded; see if we need to change it. */
1019 if (code == orig_str[1])
1020 return;
1021 /* Yes, tweak a copy of the name and put it in a new string. */
1022 new_str = alloca (len);
1023 memcpy (new_str, orig_str, len);
1024 new_str[1] = code;
1025 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, len);
353e51f8
SS
1026 }
1027 else
1028 {
1029 /* Add the encoding. */
1030 new_len = len + 4;
1031 new_str = alloca (new_len);
1032 new_str[0] = '!';
1033 new_str[1] = code;
1034 new_str[2] = '_';
1035 new_str[3] = '_';
1036 memcpy (new_str + 4, orig_str, len);
1037 XSTR (sym_ref, 0) = ggc_alloc_string (new_str, new_len);
df56a27f 1038 }
4e08ba6c
SS
1039 /* The non-lazy pointer list may have captured references to the
1040 old encoded name, change them. */
b7fb9feb
TC
1041 if (TREE_CODE (decl) == VAR_DECL)
1042 update_non_lazy_ptrs (XSTR (sym_ref, 0));
1043 else
1044 update_stubs (XSTR (sym_ref, 0));
df56a27f
SS
1045}
1046
772c5265
RH
1047/* Undo the effects of the above. */
1048
1049const char *
1050darwin_strip_name_encoding (str)
1051 const char *str;
1052{
1053 return str[0] == '!' ? str + 4 : str;
1054}
1055
df56a27f
SS
1056/* Scan the list of non-lazy pointers and update any recorded names whose
1057 stripped name matches the argument. */
1058
1059static void
1060update_non_lazy_ptrs (name)
1061 const char *name;
1062{
91dc3130 1063 const char *name1, *name2;
df56a27f
SS
1064 tree temp;
1065
772c5265 1066 name1 = darwin_strip_name_encoding (name);
df56a27f
SS
1067
1068 for (temp = machopic_non_lazy_pointers;
1069 temp != NULL_TREE;
1070 temp = TREE_CHAIN (temp))
1071 {
7ae8cf75 1072 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
df56a27f
SS
1073
1074 if (*sym_name == '!')
1075 {
772c5265 1076 name2 = darwin_strip_name_encoding (sym_name);
df56a27f
SS
1077 if (strcmp (name1, name2) == 0)
1078 {
d24652ee
GK
1079 /* FIXME: This breaks the identifier hash table. */
1080 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1081 = (unsigned char *) name;
df56a27f
SS
1082 break;
1083 }
1084 }
1085 }
1086}
4e08ba6c 1087
b7fb9feb
TC
1088/* Function NAME is being defined, and its label has just been output.
1089 If there's already a reference to a stub for this function, we can
991b6592 1090 just emit the stub label now and we don't bother emitting the stub later. */
b7fb9feb
TC
1091
1092void
1093machopic_output_possible_stub_label (file, name)
1094 FILE *file;
1095 const char *name;
1096{
1097 tree temp;
1098
1099
1100 /* Ensure we're looking at a section-encoded name. */
1101 if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
1102 return;
1103
1104 for (temp = machopic_stubs;
1105 temp != NULL_TREE;
1106 temp = TREE_CHAIN (temp))
1107 {
1108 const char *sym_name;
1109
1110 sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
1111 if (sym_name[0] == '!' && sym_name[1] == 'T'
1112 && ! strcmp (name+2, sym_name+2))
1113 {
1114 ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
61d951df
TC
1115 /* Avoid generating a stub for this. */
1116 TREE_USED (temp) = 0;
b7fb9feb
TC
1117 break;
1118 }
1119 }
1120}
4e08ba6c
SS
1121
1122/* Scan the list of stubs and update any recorded names whose
1123 stripped name matches the argument. */
1124
1125static void
1126update_stubs (name)
1127 const char *name;
1128{
91dc3130 1129 const char *name1, *name2;
4e08ba6c
SS
1130 tree temp;
1131
772c5265 1132 name1 = darwin_strip_name_encoding (name);
4e08ba6c
SS
1133
1134 for (temp = machopic_stubs;
1135 temp != NULL_TREE;
1136 temp = TREE_CHAIN (temp))
1137 {
7ae8cf75 1138 const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
4e08ba6c
SS
1139
1140 if (*sym_name == '!')
1141 {
772c5265 1142 name2 = darwin_strip_name_encoding (sym_name);
4e08ba6c
SS
1143 if (strcmp (name1, name2) == 0)
1144 {
d24652ee
GK
1145 /* FIXME: This breaks the identifier hash table. */
1146 IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
1147 = (unsigned char *) name;
4e08ba6c
SS
1148 break;
1149 }
1150 }
1151 }
1152}
2cc07db4 1153
ae46c4e0
RH
1154void
1155machopic_select_section (exp, reloc, align)
1156 tree exp;
1157 int reloc;
1158 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1159{
1160 if (TREE_CODE (exp) == STRING_CST)
1161 {
1162 if (flag_writable_strings)
1163 data_section ();
d24652ee 1164 else if ((size_t) TREE_STRING_LENGTH (exp) !=
ae46c4e0
RH
1165 strlen (TREE_STRING_POINTER (exp)) + 1)
1166 readonly_data_section ();
1167 else
1168 cstring_section ();
1169 }
1170 else if (TREE_CODE (exp) == INTEGER_CST
1171 || TREE_CODE (exp) == REAL_CST)
1172 {
1173 tree size = TYPE_SIZE (TREE_TYPE (exp));
1174
1175 if (TREE_CODE (size) == INTEGER_CST &&
1176 TREE_INT_CST_LOW (size) == 4 &&
1177 TREE_INT_CST_HIGH (size) == 0)
1178 literal4_section ();
1179 else if (TREE_CODE (size) == INTEGER_CST &&
1180 TREE_INT_CST_LOW (size) == 8 &&
1181 TREE_INT_CST_HIGH (size) == 0)
1182 literal8_section ();
1183 else
1184 readonly_data_section ();
1185 }
1186 else if (TREE_CODE (exp) == CONSTRUCTOR
1187 && TREE_TYPE (exp)
1188 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1189 && TYPE_NAME (TREE_TYPE (exp)))
1190 {
1191 tree name = TYPE_NAME (TREE_TYPE (exp));
1192 if (TREE_CODE (name) == TYPE_DECL)
1193 name = DECL_NAME (name);
1194 if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString"))
1195 objc_constant_string_object_section ();
1196 else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
1197 objc_string_object_section ();
1198 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1199 {
ab82a49f
AP
1200
1201 if (TREE_SIDE_EFFECTS (exp) || (MACHOPIC_INDIRECT && reloc))
ae46c4e0
RH
1202 const_data_section ();
1203 else
1204 readonly_data_section ();
1205 }
1206 else
1207 data_section ();
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 ();
1253 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1254 objc_cat_inst_meth_section ();
1255 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1256 objc_cat_cls_meth_section ();
1257 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1258 objc_cat_cls_meth_section ();
1259 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1260 objc_protocol_section ();
1261 else if ((TREE_READONLY (exp) || TREE_CONSTANT (exp))
1262 && !TREE_SIDE_EFFECTS (exp))
1263 {
ab82a49f
AP
1264
1265 if (MACHOPIC_INDIRECT && reloc)
ae46c4e0
RH
1266 const_data_section ();
1267 else
1268 readonly_data_section ();
1269 }
1270 else
1271 data_section ();
1272 }
1273 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1274 {
ab82a49f
AP
1275
1276 if (TREE_SIDE_EFFECTS (exp) || (MACHOPIC_INDIRECT && reloc))
ae46c4e0
RH
1277 const_data_section ();
1278 else
1279 readonly_data_section ();
1280 }
1281 else
1282 data_section ();
1283}
1284
b64a1b53 1285/* This can be called with address expressions as "rtx".
991b6592 1286 They must go in "const". */
b64a1b53
RH
1287
1288void
1289machopic_select_rtx_section (mode, x, align)
1290 enum machine_mode mode;
1291 rtx x;
1292 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
1293{
1294 if (GET_MODE_SIZE (mode) == 8)
1295 literal8_section ();
1296 else if (GET_MODE_SIZE (mode) == 4
1297 && (GET_CODE (x) == CONST_INT
1298 || GET_CODE (x) == CONST_DOUBLE))
1299 literal4_section ();
1300 else
1301 const_section ();
1302}
1303
2cc07db4
RH
1304void
1305machopic_asm_out_constructor (symbol, priority)
1306 rtx symbol;
1307 int priority ATTRIBUTE_UNUSED;
1308{
ab82a49f
AP
1309
1310 if (MACHOPIC_INDIRECT)
2cc07db4
RH
1311 mod_init_section ();
1312 else
1313 constructor_section ();
c8af3574
RH
1314 assemble_align (POINTER_SIZE);
1315 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2cc07db4 1316
ab82a49f
AP
1317
1318 if (! MACHOPIC_INDIRECT)
2cc07db4
RH
1319 fprintf (asm_out_file, ".reference .constructors_used\n");
1320}
1321
1322void
1323machopic_asm_out_destructor (symbol, priority)
1324 rtx symbol;
1325 int priority ATTRIBUTE_UNUSED;
1326{
ab82a49f
AP
1327
1328 if (MACHOPIC_INDIRECT)
2cc07db4
RH
1329 mod_term_section ();
1330 else
1331 destructor_section ();
c8af3574
RH
1332 assemble_align (POINTER_SIZE);
1333 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2cc07db4 1334
ab82a49f 1335 if (! MACHOPIC_INDIRECT)
2cc07db4
RH
1336 fprintf (asm_out_file, ".reference .destructors_used\n");
1337}
e2500fed 1338
5eb99654
KG
1339void
1340darwin_globalize_label (stream, name)
1341 FILE *stream;
1342 const char *name;
1343{
1344 if (!!strncmp (name, "_OBJC_", 6))
1345 default_globalize_label (stream, name);
1346}
1347
7606e68f
SS
1348/* Output a difference of two labels that will be an assembly time
1349 constant if the two labels are local. (.long lab1-lab2 will be
1350 very different if lab1 is at the boundary between two sections; it
1351 will be relocated according to the second section, not the first,
1352 so one ends up with a difference between labels in different
1353 sections, which is bad in the dwarf2 eh context for instance.) */
1354
1355static int darwin_dwarf_label_counter;
1356
1357void
1358darwin_asm_output_dwarf_delta (file, size, lab1, lab2)
1359 FILE *file;
1360 int size ATTRIBUTE_UNUSED;
1361 const char *lab1, *lab2;
1362{
1363 const char *p = lab1 + (lab1[0] == '*');
1364 int islocaldiff = (p[0] == 'L');
1365
1366 if (islocaldiff)
1367 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1368 else
1369 fprintf (file, "\t%s\t", ".long");
1370 assemble_name (file, lab1);
1371 fprintf (file, "-");
1372 assemble_name (file, lab2);
1373 if (islocaldiff)
1374 fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
1375}
1376
e2500fed
GK
1377#include "gt-darwin.h"
1378