OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [config/] [darwin.c] - Blame information for rev 12

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.