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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [config/] [darwin.c] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
/* 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, 2006, 2007, 2008, 2009, 2010
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 3, 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 COPYING3.  If not see
21
<http://www.gnu.org/licenses/>.  */
22
 
23
#include "config.h"
24
#include "system.h"
25
#include "coretypes.h"
26
#include "tm.h"
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"
40
#include "function.h"
41
#include "ggc.h"
42
#include "langhooks.h"
43
#include "target.h"
44
#include "tm_p.h"
45
#include "toplev.h"
46
#include "hashtab.h"
47
#include "df.h"
48
#include "debug.h"
49
#include "obstack.h"
50
#include "lto-streamer.h"
51
 
52
/* Darwin supports a feature called fix-and-continue, which is used
53
   for rapid turn around debugging.  When code is compiled with the
54
   -mfix-and-continue flag, two changes are made to the generated code
55
   that allow the system to do things that it would normally not be
56
   able to do easily.  These changes allow gdb to load in
57
   recompilation of a translation unit that has been changed into a
58
   running program and replace existing functions and methods of that
59
   translation unit with versions of those functions and methods
60
   from the newly compiled translation unit.  The new functions access
61
   the existing static symbols from the old translation unit, if the
62
   symbol existed in the unit to be replaced, and from the new
63
   translation unit, otherwise.
64
 
65
   The changes are to insert 5 nops at the beginning of all functions
66
   and to use indirection to get at static symbols.  The 5 nops
67
   are required by consumers of the generated code.  Currently, gdb
68
   uses this to patch in a jump to the overriding function, this
69
   allows all uses of the old name to forward to the replacement,
70
   including existing function pointers and virtual methods.  See
71
   rs6000_emit_prologue for the code that handles the nop insertions.
72
 
73
   The added indirection allows gdb to redirect accesses to static
74
   symbols from the newly loaded translation unit to the existing
75
   symbol, if any.  @code{static} symbols are special and are handled by
76
   setting the second word in the .non_lazy_symbol_pointer data
77
   structure to symbol.  See indirect_data for the code that handles
78
   the extra indirection, and machopic_output_indirection and its use
79
   of MACHO_SYMBOL_STATIC for the code that handles @code{static}
80
   symbol indirection.  */
81
 
82
/* Section names.  */
83
section * darwin_sections[NUM_DARWIN_SECTIONS];
84
 
85
/* True if we're setting __attribute__ ((ms_struct)).  */
86
int darwin_ms_struct = false;
87
 
88
/* A get_unnamed_section callback used to switch to an ObjC section.
89
   DIRECTIVE is as for output_section_asm_op.  */
90
 
91
static void
92
output_objc_section_asm_op (const void *directive)
93
{
94
  static bool been_here = false;
95
 
96
  if (! been_here)
97
    {
98
      static const enum darwin_section_enum tomark[] =
99
        {
100
          /* written, cold -> hot */
101
          objc_cat_cls_meth_section,
102
          objc_cat_inst_meth_section,
103
          objc_string_object_section,
104
          objc_constant_string_object_section,
105
          objc_selector_refs_section,
106
          objc_selector_fixup_section,
107
          objc_cls_refs_section,
108
          objc_class_section,
109
          objc_meta_class_section,
110
          /* shared, hot -> cold */
111
          objc_cls_meth_section,
112
          objc_inst_meth_section,
113
          objc_protocol_section,
114
          objc_class_names_section,
115
          objc_meth_var_types_section,
116
          objc_meth_var_names_section,
117
          objc_category_section,
118
          objc_class_vars_section,
119
          objc_instance_vars_section,
120
          objc_module_info_section,
121
          objc_symbols_section
122
        };
123
      size_t i;
124
 
125
      been_here = true;
126
      for (i = 0; i < ARRAY_SIZE (tomark); i++)
127
        switch_to_section (darwin_sections[tomark[i]]);
128
    }
129
  output_section_asm_op (directive);
130
}
131
 
132
/* Implement TARGET_ASM_INIT_SECTIONS.  */
133
 
134
void
135
darwin_init_sections (void)
136
{
137
#define DEF_SECTION(NAME, FLAGS, DIRECTIVE, OBJC)               \
138
  darwin_sections[NAME] =                                       \
139
    get_unnamed_section (FLAGS, (OBJC                           \
140
                                 ? output_objc_section_asm_op   \
141
                                 : output_section_asm_op),      \
142
                         "\t" DIRECTIVE);
143
#include "config/darwin-sections.def"
144
#undef DEF_SECTION
145
 
146
  readonly_data_section = darwin_sections[const_section];
147
  exception_section = darwin_sections[darwin_exception_section];
148
  eh_frame_section = darwin_sections[darwin_eh_frame_section];
149
}
150
 
151
int
152
name_needs_quotes (const char *name)
153
{
154
  int c;
155
  while ((c = *name++) != '\0')
156
    if (! ISIDNUM (c) && c != '.' && c != '$')
157
      return 1;
158
  return 0;
159
}
160
 
161
/* Return true if SYM_REF can be used without an indirection.  */
162
static int
163
machopic_symbol_defined_p (rtx sym_ref)
164
{
165
  if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
166
    return true;
167
 
168
  /* If a symbol references local and is not an extern to this
169
     file, then the symbol might be able to declared as defined.  */
170
  if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
171
    {
172
      /* If the symbol references a variable and the variable is a
173
         common symbol, then this symbol is not defined.  */
174
      if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_VARIABLE)
175
        {
176
          tree decl = SYMBOL_REF_DECL (sym_ref);
177
          if (!decl)
178
            return true;
179
          if (DECL_COMMON (decl))
180
            return false;
181
        }
182
      return true;
183
    }
184
  return false;
185
}
186
 
187
/* This module assumes that (const (symbol_ref "foo")) is a legal pic
188
   reference, which will not be changed.  */
189
 
190
enum machopic_addr_class
191
machopic_classify_symbol (rtx sym_ref)
192
{
193
  int flags;
194
  bool function_p;
195
 
196
  flags = SYMBOL_REF_FLAGS (sym_ref);
197
  function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
198
  if (machopic_symbol_defined_p (sym_ref))
199
    return (function_p
200
            ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
201
  else
202
    return (function_p
203
            ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
204
}
205
 
206
#ifndef TARGET_FIX_AND_CONTINUE
207
#define TARGET_FIX_AND_CONTINUE 0
208
#endif
209
 
210
/* Indicate when fix-and-continue style code generation is being used
211
   and when a reference to data should be indirected so that it can be
212
   rebound in a new translation unit to reference the original instance
213
   of that data.  Symbol names that are for code generation local to
214
   the translation unit are bound to the new translation unit;
215
   currently this means symbols that begin with L or _OBJC_;
216
   otherwise, we indicate that an indirect reference should be made to
217
   permit the runtime to rebind new instances of the translation unit
218
   to the original instance of the data.  */
219
 
220
static int
221
indirect_data (rtx sym_ref)
222
{
223
  int lprefix;
224
  const char *name;
225
 
226
  /* If we aren't generating fix-and-continue code, don't do anything
227
     special.  */
228
  if (TARGET_FIX_AND_CONTINUE == 0)
229
    return 0;
230
 
231
  /* Otherwise, all symbol except symbols that begin with L or _OBJC_
232
     are indirected.  Symbols that begin with L and _OBJC_ are always
233
     bound to the current translation unit as they are used for
234
     generated local data of the translation unit.  */
235
 
236
  name = XSTR (sym_ref, 0);
237
 
238
  lprefix = (((name[0] == '*' || name[0] == '&')
239
              && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
240
             || (strncmp (name, "_OBJC_", 6) == 0));
241
 
242
  return ! lprefix;
243
}
244
 
245
 
246
static int
247
machopic_data_defined_p (rtx sym_ref)
248
{
249
  if (indirect_data (sym_ref))
250
    return 0;
251
 
252
  switch (machopic_classify_symbol (sym_ref))
253
    {
254
    case MACHOPIC_DEFINED_DATA:
255
    case MACHOPIC_DEFINED_FUNCTION:
256
      return 1;
257
    default:
258
      return 0;
259
    }
260
}
261
 
262
void
263
machopic_define_symbol (rtx mem)
264
{
265
  rtx sym_ref;
266
 
267
  gcc_assert (GET_CODE (mem) == MEM);
268
  sym_ref = XEXP (mem, 0);
269
  SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
270
}
271
 
272
/* Return either ORIG or:
273
 
274
     (const:P (unspec:P [ORIG] UNSPEC_MACHOPIC_OFFSET))
275
 
276
   depending on MACHO_DYNAMIC_NO_PIC_P.  */
277
rtx
278
machopic_gen_offset (rtx orig)
279
{
280
  if (MACHO_DYNAMIC_NO_PIC_P)
281
    return orig;
282
  else
283
    {
284
      /* Play games to avoid marking the function as needing pic if we
285
         are being called as part of the cost-estimation process.  */
286
      if (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl)
287
        crtl->uses_pic_offset_table = 1;
288
      orig = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
289
                             UNSPEC_MACHOPIC_OFFSET);
290
      return gen_rtx_CONST (Pmode, orig);
291
    }
292
}
293
 
294
static GTY(()) const char * function_base_func_name;
295
static GTY(()) int current_pic_label_num;
296
 
297
void
298
machopic_output_function_base_name (FILE *file)
299
{
300
  const char *current_name;
301
 
302
  /* If dynamic-no-pic is on, we should not get here.  */
303
  gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
304
  current_name =
305
    IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
306
  if (function_base_func_name != current_name)
307
    {
308
      ++current_pic_label_num;
309
      function_base_func_name = current_name;
310
    }
311
  fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
312
}
313
 
314
/* The suffix attached to non-lazy pointer symbols.  */
315
#define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
316
/* The suffix attached to stub symbols.  */
317
#define STUB_SUFFIX "$stub"
318
 
319
typedef struct GTY (()) machopic_indirection
320
{
321
  /* The SYMBOL_REF for the entity referenced.  */
322
  rtx symbol;
323
  /* The name of the stub or non-lazy pointer.  */
324
  const char * ptr_name;
325
  /* True iff this entry is for a stub (as opposed to a non-lazy
326
     pointer).  */
327
  bool stub_p;
328
  /* True iff this stub or pointer pointer has been referenced.  */
329
  bool used;
330
} machopic_indirection;
331
 
332
/* A table mapping stub names and non-lazy pointer names to
333
   SYMBOL_REFs for the stubbed-to and pointed-to entities.  */
334
 
335
static GTY ((param_is (struct machopic_indirection))) htab_t
336
  machopic_indirections;
337
 
338
/* Return a hash value for a SLOT in the indirections hash table.  */
339
 
340
static hashval_t
341
machopic_indirection_hash (const void *slot)
342
{
343
  const machopic_indirection *p = (const machopic_indirection *) slot;
344
  return htab_hash_string (p->ptr_name);
345
}
346
 
347
/* Returns true if the KEY is the same as that associated with
348
   SLOT.  */
349
 
350
static int
351
machopic_indirection_eq (const void *slot, const void *key)
352
{
353
  return strcmp (((const machopic_indirection *) slot)->ptr_name,
354
                 (const char *) key) == 0;
355
}
356
 
357
/* Return the name of the non-lazy pointer (if STUB_P is false) or
358
   stub (if STUB_B is true) corresponding to the given name.  */
359
 
360
const char *
361
machopic_indirection_name (rtx sym_ref, bool stub_p)
362
{
363
  char *buffer;
364
  const char *name = XSTR (sym_ref, 0);
365
  size_t namelen = strlen (name);
366
  machopic_indirection *p;
367
  void ** slot;
368
  bool saw_star = false;
369
  bool needs_quotes;
370
  const char *suffix;
371
  const char *prefix = user_label_prefix;
372
  const char *quote = "";
373
  tree id;
374
 
375
  id = maybe_get_identifier (name);
376
  if (id)
377
    {
378
      tree id_orig = id;
379
 
380
      while (IDENTIFIER_TRANSPARENT_ALIAS (id))
381
        id = TREE_CHAIN (id);
382
      if (id != id_orig)
383
        {
384
          name = IDENTIFIER_POINTER (id);
385
          namelen = strlen (name);
386
        }
387
    }
388
 
389
  if (name[0] == '*')
390
    {
391
      saw_star = true;
392
      prefix = "";
393
      ++name;
394
      --namelen;
395
    }
396
 
397
  needs_quotes = name_needs_quotes (name);
398
  if (needs_quotes)
399
    {
400
      quote = "\"";
401
    }
402
 
403
  if (stub_p)
404
    suffix = STUB_SUFFIX;
405
  else
406
    suffix = NON_LAZY_POINTER_SUFFIX;
407
 
408
  buffer = XALLOCAVEC (char, strlen ("&L")
409
                   + strlen (prefix)
410
                   + namelen
411
                   + strlen (suffix)
412
                   + 2 * strlen (quote)
413
                   + 1 /* '\0' */);
414
 
415
  /* Construct the name of the non-lazy pointer or stub.  */
416
  sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
417
 
418
  if (!machopic_indirections)
419
    machopic_indirections = htab_create_ggc (37,
420
                                             machopic_indirection_hash,
421
                                             machopic_indirection_eq,
422
                                             /*htab_del=*/NULL);
423
 
424
  slot = htab_find_slot_with_hash (machopic_indirections, buffer,
425
                                   htab_hash_string (buffer), INSERT);
426
  if (*slot)
427
    {
428
      p = (machopic_indirection *) *slot;
429
    }
430
  else
431
    {
432
      p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
433
      p->symbol = sym_ref;
434
      p->ptr_name = xstrdup (buffer);
435
      p->stub_p = stub_p;
436
      p->used = false;
437
      *slot = p;
438
    }
439
 
440
  return p->ptr_name;
441
}
442
 
443
/* Return the name of the stub for the mcount function.  */
444
 
445
const char*
446
machopic_mcount_stub_name (void)
447
{
448
  rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
449
  return machopic_indirection_name (symbol, /*stub_p=*/true);
450
}
451
 
452
/* If NAME is the name of a stub or a non-lazy pointer , mark the stub
453
   or non-lazy pointer as used -- and mark the object to which the
454
   pointer/stub refers as used as well, since the pointer/stub will
455
   emit a reference to it.  */
456
 
457
void
458
machopic_validate_stub_or_non_lazy_ptr (const char *name)
459
{
460
  machopic_indirection *p;
461
 
462
  p = ((machopic_indirection *)
463
       (htab_find_with_hash (machopic_indirections, name,
464
                             htab_hash_string (name))));
465
  if (p && ! p->used)
466
    {
467
      const char *real_name;
468
      tree id;
469
 
470
      p->used = true;
471
 
472
      /* Do what output_addr_const will do when we actually call it.  */
473
      if (SYMBOL_REF_DECL (p->symbol))
474
        mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
475
 
476
      real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
477
 
478
      id = maybe_get_identifier (real_name);
479
      if (id)
480
        mark_referenced (id);
481
    }
482
}
483
 
484
/* Transform ORIG, which may be any data source, to the corresponding
485
   source using indirections.  */
486
 
487
rtx
488
machopic_indirect_data_reference (rtx orig, rtx reg)
489
{
490
  rtx ptr_ref = orig;
491
 
492
  if (! MACHOPIC_INDIRECT)
493
    return orig;
494
 
495
  if (GET_CODE (orig) == SYMBOL_REF)
496
    {
497
      int defined = machopic_data_defined_p (orig);
498
 
499
      if (defined && MACHO_DYNAMIC_NO_PIC_P)
500
        {
501
#if defined (TARGET_TOC)
502
          /* Create a new register for CSE opportunities.  */
503
          rtx hi_reg = (!can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode));
504
          emit_insn (gen_macho_high (hi_reg, orig));
505
          emit_insn (gen_macho_low (reg, hi_reg, orig));
506
#else
507
           /* some other cpu -- writeme!  */
508
           gcc_unreachable ();
509
#endif
510
           return reg;
511
        }
512
      else if (defined)
513
        {
514
#if defined (TARGET_TOC) || defined (HAVE_lo_sum)
515
          rtx offset = machopic_gen_offset (orig);
516
#endif
517
 
518
#if defined (TARGET_TOC) /* i.e., PowerPC */
519
          rtx hi_sum_reg = (!can_create_pseudo_p ()
520
                            ? reg
521
                            : gen_reg_rtx (Pmode));
522
 
523
          gcc_assert (reg);
524
 
525
          emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
526
                              gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
527
                                       gen_rtx_HIGH (Pmode, offset))));
528
          emit_insn (gen_rtx_SET (Pmode, reg,
529
                                  gen_rtx_LO_SUM (Pmode, hi_sum_reg,
530
                                                  copy_rtx (offset))));
531
 
532
          orig = reg;
533
#else
534
#if defined (HAVE_lo_sum)
535
          gcc_assert (reg);
536
 
537
          emit_insn (gen_rtx_SET (VOIDmode, reg,
538
                                  gen_rtx_HIGH (Pmode, offset)));
539
          emit_insn (gen_rtx_SET (VOIDmode, reg,
540
                                  gen_rtx_LO_SUM (Pmode, reg,
541
                                                  copy_rtx (offset))));
542
          emit_use (pic_offset_table_rtx);
543
 
544
          orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
545
#endif
546
#endif
547
          return orig;
548
        }
549
 
550
      ptr_ref = (gen_rtx_SYMBOL_REF
551
                 (Pmode,
552
                  machopic_indirection_name (orig, /*stub_p=*/false)));
553
 
554
      SYMBOL_REF_DATA (ptr_ref) = SYMBOL_REF_DATA (orig);
555
 
556
      ptr_ref = gen_const_mem (Pmode, ptr_ref);
557
      machopic_define_symbol (ptr_ref);
558
 
559
      return ptr_ref;
560
    }
561
  else if (GET_CODE (orig) == CONST)
562
    {
563
      rtx base, result;
564
 
565
      /* legitimize both operands of the PLUS */
566
      if (GET_CODE (XEXP (orig, 0)) == PLUS)
567
        {
568
          base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
569
                                                   reg);
570
          orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
571
                                                   (base == reg ? 0 : reg));
572
        }
573
      else
574
        return orig;
575
 
576
      if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
577
        result = plus_constant (base, INTVAL (orig));
578
      else
579
        result = gen_rtx_PLUS (Pmode, base, orig);
580
 
581
      if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
582
        {
583
          if (reg)
584
            {
585
              emit_move_insn (reg, result);
586
              result = reg;
587
            }
588
          else
589
            {
590
              result = force_reg (GET_MODE (result), result);
591
            }
592
        }
593
 
594
      return result;
595
 
596
    }
597
  else if (GET_CODE (orig) == MEM)
598
    XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
599
  /* When the target is i386, this code prevents crashes due to the
600
     compiler's ignorance on how to move the PIC base register to
601
     other registers.  (The reload phase sometimes introduces such
602
     insns.)  */
603
  else if (GET_CODE (orig) == PLUS
604
           && GET_CODE (XEXP (orig, 0)) == REG
605
           && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
606
#ifdef I386
607
           /* Prevent the same register from being erroneously used
608
              as both the base and index registers.  */
609
           && GET_CODE (XEXP (orig, 1)) == CONST
610
#endif
611
           && reg)
612
    {
613
      emit_move_insn (reg, XEXP (orig, 0));
614
      XEXP (ptr_ref, 0) = reg;
615
    }
616
  return ptr_ref;
617
}
618
 
619
/* Transform TARGET (a MEM), which is a function call target, to the
620
   corresponding symbol_stub if necessary.  Return a new MEM.  */
621
 
622
rtx
623
machopic_indirect_call_target (rtx target)
624
{
625
  if (GET_CODE (target) != MEM)
626
    return target;
627
 
628
  if (MACHOPIC_INDIRECT
629
      && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
630
      && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
631
           & MACHO_SYMBOL_FLAG_DEFINED))
632
    {
633
      rtx sym_ref = XEXP (target, 0);
634
      const char *stub_name = machopic_indirection_name (sym_ref,
635
                                                         /*stub_p=*/true);
636
      enum machine_mode mode = GET_MODE (sym_ref);
637
 
638
      XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
639
      SYMBOL_REF_DATA (XEXP (target, 0)) = SYMBOL_REF_DATA (sym_ref);
640
      MEM_READONLY_P (target) = 1;
641
      MEM_NOTRAP_P (target) = 1;
642
    }
643
 
644
  return target;
645
}
646
 
647
rtx
648
machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
649
{
650
  rtx pic_ref = orig;
651
 
652
  if (! MACHOPIC_INDIRECT)
653
    return orig;
654
 
655
  /* First handle a simple SYMBOL_REF or LABEL_REF */
656
  if (GET_CODE (orig) == LABEL_REF
657
      || (GET_CODE (orig) == SYMBOL_REF
658
          ))
659
    {
660
      /* addr(foo) = &func+(foo-func) */
661
      orig = machopic_indirect_data_reference (orig, reg);
662
 
663
      if (GET_CODE (orig) == PLUS
664
          && GET_CODE (XEXP (orig, 0)) == REG)
665
        {
666
          if (reg == 0)
667
            return force_reg (mode, orig);
668
 
669
          emit_move_insn (reg, orig);
670
          return reg;
671
        }
672
 
673
      if (GET_CODE (orig) == MEM)
674
        {
675
          if (reg == 0)
676
            {
677
              gcc_assert (!reload_in_progress);
678
              reg = gen_reg_rtx (Pmode);
679
            }
680
 
681
#ifdef HAVE_lo_sum
682
          if (MACHO_DYNAMIC_NO_PIC_P
683
              && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
684
                  || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
685
            {
686
#if defined (TARGET_TOC)        /* ppc  */
687
              rtx temp_reg = (!can_create_pseudo_p ()
688
                              ? reg :
689
                              gen_reg_rtx (Pmode));
690
              rtx asym = XEXP (orig, 0);
691
              rtx mem;
692
 
693
              emit_insn (gen_macho_high (temp_reg, asym));
694
              mem = gen_const_mem (GET_MODE (orig),
695
                                   gen_rtx_LO_SUM (Pmode, temp_reg,
696
                                                   copy_rtx (asym)));
697
              emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
698
#else
699
              /* Some other CPU -- WriteMe! but right now there are no other
700
                 platforms that can use dynamic-no-pic  */
701
              gcc_unreachable ();
702
#endif
703
              pic_ref = reg;
704
            }
705
          else
706
          if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
707
              || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
708
            {
709
              rtx offset = machopic_gen_offset (XEXP (orig, 0));
710
#if defined (TARGET_TOC) /* i.e., PowerPC */
711
              /* Generating a new reg may expose opportunities for
712
                 common subexpression elimination.  */
713
              rtx hi_sum_reg = (!can_create_pseudo_p ()
714
                                ? reg
715
                                : gen_reg_rtx (Pmode));
716
              rtx mem;
717
              rtx insn;
718
              rtx sum;
719
 
720
              sum = gen_rtx_HIGH (Pmode, offset);
721
              if (! MACHO_DYNAMIC_NO_PIC_P)
722
                sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
723
 
724
              emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
725
 
726
              mem = gen_const_mem (GET_MODE (orig),
727
                                  gen_rtx_LO_SUM (Pmode,
728
                                                  hi_sum_reg,
729
                                                  copy_rtx (offset)));
730
              insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
731
              set_unique_reg_note (insn, REG_EQUAL, pic_ref);
732
 
733
              pic_ref = reg;
734
#else
735
              emit_use (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
736
 
737
              emit_insn (gen_rtx_SET (VOIDmode, reg,
738
                                      gen_rtx_HIGH (Pmode,
739
                                                    gen_rtx_CONST (Pmode,
740
                                                                   offset))));
741
              emit_insn (gen_rtx_SET (VOIDmode, reg,
742
                                  gen_rtx_LO_SUM (Pmode, reg,
743
                                           gen_rtx_CONST (Pmode,
744
                                                          copy_rtx (offset)))));
745
              pic_ref = gen_rtx_PLUS (Pmode,
746
                                      pic_offset_table_rtx, reg);
747
#endif
748
            }
749
          else
750
#endif  /* HAVE_lo_sum */
751
            {
752
              rtx pic = pic_offset_table_rtx;
753
              if (GET_CODE (pic) != REG)
754
                {
755
                  emit_move_insn (reg, pic);
756
                  pic = reg;
757
                }
758
#if 0
759
              emit_use (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
760
#endif
761
 
762
              if (reload_in_progress)
763
                df_set_regs_ever_live (REGNO (pic), true);
764
              pic_ref = gen_rtx_PLUS (Pmode, pic,
765
                                      machopic_gen_offset (XEXP (orig, 0)));
766
            }
767
 
768
#if !defined (TARGET_TOC)
769
          emit_move_insn (reg, pic_ref);
770
          pic_ref = gen_const_mem (GET_MODE (orig), reg);
771
#endif
772
        }
773
      else
774
        {
775
 
776
#ifdef HAVE_lo_sum
777
          if (GET_CODE (orig) == SYMBOL_REF
778
              || GET_CODE (orig) == LABEL_REF)
779
            {
780
              rtx offset = machopic_gen_offset (orig);
781
#if defined (TARGET_TOC) /* i.e., PowerPC */
782
              rtx hi_sum_reg;
783
 
784
              if (reg == 0)
785
                {
786
                  gcc_assert (!reload_in_progress);
787
                  reg = gen_reg_rtx (Pmode);
788
                }
789
 
790
              hi_sum_reg = reg;
791
 
792
              emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
793
                                      (MACHO_DYNAMIC_NO_PIC_P)
794
                                      ? gen_rtx_HIGH (Pmode, offset)
795
                                      : gen_rtx_PLUS (Pmode,
796
                                                      pic_offset_table_rtx,
797
                                                      gen_rtx_HIGH (Pmode,
798
                                                                    offset))));
799
              emit_insn (gen_rtx_SET (VOIDmode, reg,
800
                                      gen_rtx_LO_SUM (Pmode,
801
                                                      hi_sum_reg,
802
                                                      copy_rtx (offset))));
803
              pic_ref = reg;
804
#else
805
              emit_insn (gen_rtx_SET (VOIDmode, reg,
806
                                      gen_rtx_HIGH (Pmode, offset)));
807
              emit_insn (gen_rtx_SET (VOIDmode, reg,
808
                                      gen_rtx_LO_SUM (Pmode, reg,
809
                                                      copy_rtx (offset))));
810
              pic_ref = gen_rtx_PLUS (Pmode,
811
                                      pic_offset_table_rtx, reg);
812
#endif
813
            }
814
          else
815
#endif  /*  HAVE_lo_sum  */
816
            {
817
              if (REG_P (orig)
818
                  || GET_CODE (orig) == SUBREG)
819
                {
820
                  return orig;
821
                }
822
              else
823
                {
824
                  rtx pic = pic_offset_table_rtx;
825
                  if (GET_CODE (pic) != REG)
826
                    {
827
                      emit_move_insn (reg, pic);
828
                      pic = reg;
829
                    }
830
#if 0
831
                  emit_use (pic_offset_table_rtx);
832
#endif
833
                  if (reload_in_progress)
834
                    df_set_regs_ever_live (REGNO (pic), true);
835
                  pic_ref = gen_rtx_PLUS (Pmode,
836
                                          pic,
837
                                          machopic_gen_offset (orig));
838
                }
839
            }
840
        }
841
 
842
      if (GET_CODE (pic_ref) != REG)
843
        {
844
          if (reg != 0)
845
            {
846
              emit_move_insn (reg, pic_ref);
847
              return reg;
848
            }
849
          else
850
            {
851
              return force_reg (mode, pic_ref);
852
            }
853
        }
854
      else
855
        {
856
          return pic_ref;
857
        }
858
    }
859
 
860
  else if (GET_CODE (orig) == SYMBOL_REF)
861
    return orig;
862
 
863
  else if (GET_CODE (orig) == PLUS
864
           && (GET_CODE (XEXP (orig, 0)) == MEM
865
               || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
866
               || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
867
           && XEXP (orig, 0) != pic_offset_table_rtx
868
           && GET_CODE (XEXP (orig, 1)) != REG)
869
 
870
    {
871
      rtx base;
872
      int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
873
 
874
      base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
875
      orig = machopic_legitimize_pic_address (XEXP (orig, 1),
876
                                              Pmode, (base == reg ? 0 : reg));
877
      if (GET_CODE (orig) == CONST_INT)
878
        {
879
          pic_ref = plus_constant (base, INTVAL (orig));
880
          is_complex = 1;
881
        }
882
      else
883
        pic_ref = gen_rtx_PLUS (Pmode, base, orig);
884
 
885
      if (reg && is_complex)
886
        {
887
          emit_move_insn (reg, pic_ref);
888
          pic_ref = reg;
889
        }
890
      /* Likewise, should we set special REG_NOTEs here?  */
891
    }
892
 
893
  else if (GET_CODE (orig) == CONST)
894
    {
895
      return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
896
    }
897
 
898
  else if (GET_CODE (orig) == MEM
899
           && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
900
    {
901
      rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
902
      addr = replace_equiv_address (orig, addr);
903
      emit_move_insn (reg, addr);
904
      pic_ref = reg;
905
    }
906
 
907
  return pic_ref;
908
}
909
 
910
/* Output the stub or non-lazy pointer in *SLOT, if it has been used.
911
   DATA is the FILE* for assembly output.  Called from
912
   htab_traverse.  */
913
 
914
static int
915
machopic_output_indirection (void **slot, void *data)
916
{
917
  machopic_indirection *p = *((machopic_indirection **) slot);
918
  FILE *asm_out_file = (FILE *) data;
919
  rtx symbol;
920
  const char *sym_name;
921
  const char *ptr_name;
922
 
923
  if (!p->used)
924
    return 1;
925
 
926
  symbol = p->symbol;
927
  sym_name = XSTR (symbol, 0);
928
  ptr_name = p->ptr_name;
929
 
930
  if (p->stub_p)
931
    {
932
      char *sym;
933
      char *stub;
934
      tree id;
935
 
936
      id = maybe_get_identifier (sym_name);
937
      if (id)
938
        {
939
          tree id_orig = id;
940
 
941
          while (IDENTIFIER_TRANSPARENT_ALIAS (id))
942
            id = TREE_CHAIN (id);
943
          if (id != id_orig)
944
            sym_name = IDENTIFIER_POINTER (id);
945
        }
946
 
947
      sym = XALLOCAVEC (char, strlen (sym_name) + 2);
948
      if (sym_name[0] == '*' || sym_name[0] == '&')
949
        strcpy (sym, sym_name + 1);
950
      else if (sym_name[0] == '-' || sym_name[0] == '+')
951
        strcpy (sym, sym_name);
952
      else
953
        sprintf (sym, "%s%s", user_label_prefix, sym_name);
954
 
955
      stub = XALLOCAVEC (char, strlen (ptr_name) + 2);
956
      if (ptr_name[0] == '*' || ptr_name[0] == '&')
957
        strcpy (stub, ptr_name + 1);
958
      else
959
        sprintf (stub, "%s%s", user_label_prefix, ptr_name);
960
 
961
      machopic_output_stub (asm_out_file, sym, stub);
962
    }
963
  else if (! indirect_data (symbol)
964
           && (machopic_symbol_defined_p (symbol)
965
               || SYMBOL_REF_LOCAL_P (symbol)))
966
    {
967
      switch_to_section (data_section);
968
      assemble_align (GET_MODE_ALIGNMENT (Pmode));
969
      assemble_label (ptr_name);
970
      assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
971
                        GET_MODE_SIZE (Pmode),
972
                        GET_MODE_ALIGNMENT (Pmode), 1);
973
    }
974
  else
975
    {
976
      rtx init = const0_rtx;
977
 
978
      switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
979
 
980
      /* Mach-O symbols are passed around in code through indirect
981
         references and the original symbol_ref hasn't passed through
982
         the generic handling and reference-catching in
983
         output_operand, so we need to manually mark weak references
984
         as such.  */
985
      if (SYMBOL_REF_WEAK (symbol))
986
        {
987
          tree decl = SYMBOL_REF_DECL (symbol);
988
          gcc_assert (DECL_P (decl));
989
 
990
          if (decl != NULL_TREE
991
              && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
992
              /* Handle only actual external-only definitions, not
993
                 e.g. extern inline code or variables for which
994
                 storage has been allocated.  */
995
              && !TREE_STATIC (decl))
996
            {
997
              fputs ("\t.weak_reference ", asm_out_file);
998
              assemble_name (asm_out_file, sym_name);
999
              fputc ('\n', asm_out_file);
1000
            }
1001
        }
1002
 
1003
      assemble_name (asm_out_file, ptr_name);
1004
      fprintf (asm_out_file, ":\n");
1005
 
1006
      fprintf (asm_out_file, "\t.indirect_symbol ");
1007
      assemble_name (asm_out_file, sym_name);
1008
      fprintf (asm_out_file, "\n");
1009
 
1010
      /* Variables that are marked with MACHO_SYMBOL_STATIC need to
1011
         have their symbol name instead of 0 in the second entry of
1012
         the non-lazy symbol pointer data structure when they are
1013
         defined.  This allows the runtime to rebind newer instances
1014
         of the translation unit with the original instance of the
1015
         symbol.  */
1016
 
1017
      if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
1018
          && machopic_symbol_defined_p (symbol))
1019
        init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
1020
 
1021
      assemble_integer (init, GET_MODE_SIZE (Pmode),
1022
                        GET_MODE_ALIGNMENT (Pmode), 1);
1023
    }
1024
 
1025
  return 1;
1026
}
1027
 
1028
void
1029
machopic_finish (FILE *asm_out_file)
1030
{
1031
  if (machopic_indirections)
1032
    htab_traverse_noresize (machopic_indirections,
1033
                            machopic_output_indirection,
1034
                            asm_out_file);
1035
}
1036
 
1037
int
1038
machopic_operand_p (rtx op)
1039
{
1040
  if (MACHOPIC_JUST_INDIRECT)
1041
    return (GET_CODE (op) == SYMBOL_REF
1042
            && machopic_symbol_defined_p (op));
1043
  else
1044
    return (GET_CODE (op) == CONST
1045
            && GET_CODE (XEXP (op, 0)) == UNSPEC
1046
            && XINT (XEXP (op, 0), 1) == UNSPEC_MACHOPIC_OFFSET);
1047
}
1048
 
1049
/* This function records whether a given name corresponds to a defined
1050
   or undefined function or variable, for machopic_classify_ident to
1051
   use later.  */
1052
 
1053
void
1054
darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
1055
{
1056
  rtx sym_ref;
1057
 
1058
  /* Do the standard encoding things first.  */
1059
  default_encode_section_info (decl, rtl, first);
1060
 
1061
  if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
1062
    return;
1063
 
1064
  sym_ref = XEXP (rtl, 0);
1065
  if (TREE_CODE (decl) == VAR_DECL)
1066
    SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
1067
 
1068
  if (!DECL_EXTERNAL (decl)
1069
      && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
1070
      && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1071
      && ((TREE_STATIC (decl)
1072
           && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1073
          || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
1074
              && DECL_INITIAL (decl) != error_mark_node)))
1075
    SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
1076
 
1077
  if (! TREE_PUBLIC (decl))
1078
    SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
1079
}
1080
 
1081
void
1082
darwin_mark_decl_preserved (const char *name)
1083
{
1084
  fprintf (asm_out_file, ".no_dead_strip ");
1085
  assemble_name (asm_out_file, name);
1086
  fputc ('\n', asm_out_file);
1087
}
1088
 
1089
static section *
1090
darwin_text_section (int reloc, int weak)
1091
{
1092
  if (reloc)
1093
    return (weak
1094
            ? darwin_sections[text_unlikely_coal_section]
1095
            : unlikely_text_section ());
1096
  else
1097
    return (weak
1098
            ? darwin_sections[text_coal_section]
1099
            : text_section);
1100
}
1101
 
1102
static section *
1103
darwin_rodata_section (int weak)
1104
{
1105
  return (weak
1106
          ? darwin_sections[const_coal_section]
1107
          : darwin_sections[const_section]);
1108
}
1109
 
1110
static section *
1111
darwin_mergeable_string_section (tree exp,
1112
                                 unsigned HOST_WIDE_INT align)
1113
{
1114
  if (flag_merge_constants
1115
      && TREE_CODE (exp) == STRING_CST
1116
      && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
1117
      && align <= 256
1118
      && (int_size_in_bytes (TREE_TYPE (exp))
1119
          == TREE_STRING_LENGTH (exp))
1120
      && ((size_t) TREE_STRING_LENGTH (exp)
1121
          == strlen (TREE_STRING_POINTER (exp)) + 1))
1122
    return darwin_sections[cstring_section];
1123
 
1124
  return readonly_data_section;
1125
}
1126
 
1127
#ifndef HAVE_GAS_LITERAL16
1128
#define HAVE_GAS_LITERAL16 0
1129
#endif
1130
 
1131
static section *
1132
darwin_mergeable_constant_section (tree exp,
1133
                                   unsigned HOST_WIDE_INT align)
1134
{
1135
  enum machine_mode mode = DECL_MODE (exp);
1136
  unsigned int modesize = GET_MODE_BITSIZE (mode);
1137
 
1138
  if (flag_merge_constants
1139
      && mode != VOIDmode
1140
      && mode != BLKmode
1141
      && modesize <= align
1142
      && align >= 8
1143
      && align <= 256
1144
      && (align & (align -1)) == 0)
1145
    {
1146
      tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1147
 
1148
      if (TREE_CODE (size) == INTEGER_CST
1149
          && TREE_INT_CST_LOW (size) == 4
1150
          && TREE_INT_CST_HIGH (size) == 0)
1151
        return darwin_sections[literal4_section];
1152
      else if (TREE_CODE (size) == INTEGER_CST
1153
               && TREE_INT_CST_LOW (size) == 8
1154
               && TREE_INT_CST_HIGH (size) == 0)
1155
        return darwin_sections[literal8_section];
1156
      else if (HAVE_GAS_LITERAL16
1157
               && TARGET_64BIT
1158
               && TREE_CODE (size) == INTEGER_CST
1159
               && TREE_INT_CST_LOW (size) == 16
1160
               && TREE_INT_CST_HIGH (size) == 0)
1161
        return darwin_sections[literal16_section];
1162
      else
1163
        return readonly_data_section;
1164
    }
1165
 
1166
  return readonly_data_section;
1167
}
1168
 
1169
int
1170
machopic_reloc_rw_mask (void)
1171
{
1172
  return MACHOPIC_INDIRECT ? 3 : 0;
1173
}
1174
 
1175
section *
1176
machopic_select_section (tree decl,
1177
                         int reloc,
1178
                         unsigned HOST_WIDE_INT align)
1179
{
1180
  bool weak = (DECL_P (decl)
1181
               && DECL_WEAK (decl)
1182
               && !lookup_attribute ("weak_import",
1183
                                     DECL_ATTRIBUTES (decl)));
1184
  section *base_section;
1185
 
1186
  switch (categorize_decl_for_section (decl, reloc))
1187
    {
1188
    case SECCAT_TEXT:
1189
      base_section = darwin_text_section (reloc, weak);
1190
      break;
1191
 
1192
    case SECCAT_RODATA:
1193
    case SECCAT_SRODATA:
1194
      base_section = darwin_rodata_section (weak);
1195
      break;
1196
 
1197
    case SECCAT_RODATA_MERGE_STR:
1198
      base_section = darwin_mergeable_string_section (decl, align);
1199
      break;
1200
 
1201
    case SECCAT_RODATA_MERGE_STR_INIT:
1202
      base_section = darwin_mergeable_string_section (DECL_INITIAL (decl), align);
1203
      break;
1204
 
1205
    case SECCAT_RODATA_MERGE_CONST:
1206
      base_section =  darwin_mergeable_constant_section (decl, align);
1207
      break;
1208
 
1209
    case SECCAT_DATA:
1210
    case SECCAT_DATA_REL:
1211
    case SECCAT_DATA_REL_LOCAL:
1212
    case SECCAT_DATA_REL_RO:
1213
    case SECCAT_DATA_REL_RO_LOCAL:
1214
    case SECCAT_SDATA:
1215
    case SECCAT_TDATA:
1216
    case SECCAT_BSS:
1217
    case SECCAT_SBSS:
1218
    case SECCAT_TBSS:
1219
      if (TREE_READONLY (decl) || TREE_CONSTANT (decl))
1220
        base_section = weak ? darwin_sections[const_data_coal_section]
1221
                            : darwin_sections[const_data_section];
1222
      else
1223
        base_section = weak ? darwin_sections[data_coal_section] : data_section;
1224
      break;
1225
 
1226
    default:
1227
      gcc_unreachable ();
1228
    }
1229
 
1230
  /* Darwin weird special cases.  */
1231
  if (TREE_CODE (decl) == CONSTRUCTOR
1232
      && TREE_TYPE (decl)
1233
      && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
1234
      && TYPE_NAME (TREE_TYPE (decl)))
1235
    {
1236
      tree name = TYPE_NAME (TREE_TYPE (decl));
1237
      if (TREE_CODE (name) == TYPE_DECL)
1238
        name = DECL_NAME (name);
1239
 
1240
      if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1241
        {
1242
          if (flag_next_runtime)
1243
            return darwin_sections[objc_constant_string_object_section];
1244
          else
1245
            return darwin_sections[objc_string_object_section];
1246
        }
1247
      else
1248
        return base_section;
1249
    }
1250
  else if (TREE_CODE (decl) == VAR_DECL
1251
           && DECL_NAME (decl)
1252
           && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE
1253
           && IDENTIFIER_POINTER (DECL_NAME (decl))
1254
           && !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "_OBJC_", 6))
1255
    {
1256
      const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
1257
 
1258
      if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1259
        return darwin_sections[objc_cls_meth_section];
1260
      else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1261
        return darwin_sections[objc_inst_meth_section];
1262
      else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1263
        return darwin_sections[objc_cat_cls_meth_section];
1264
      else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1265
        return darwin_sections[objc_cat_inst_meth_section];
1266
      else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1267
        return darwin_sections[objc_class_vars_section];
1268
      else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1269
        return darwin_sections[objc_instance_vars_section];
1270
      else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1271
        return darwin_sections[objc_cat_cls_meth_section];
1272
      else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1273
        return darwin_sections[objc_class_names_section];
1274
      else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1275
        return darwin_sections[objc_meth_var_names_section];
1276
      else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1277
        return darwin_sections[objc_meth_var_types_section];
1278
      else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1279
        return darwin_sections[objc_cls_refs_section];
1280
      else if (!strncmp (name, "_OBJC_CLASS_", 12))
1281
        return darwin_sections[objc_class_section];
1282
      else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1283
        return darwin_sections[objc_meta_class_section];
1284
      else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1285
        return darwin_sections[objc_category_section];
1286
      else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1287
        return darwin_sections[objc_selector_refs_section];
1288
      else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1289
        return darwin_sections[objc_selector_fixup_section];
1290
      else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1291
        return darwin_sections[objc_symbols_section];
1292
      else if (!strncmp (name, "_OBJC_MODULES", 13))
1293
        return darwin_sections[objc_module_info_section];
1294
      else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1295
        return darwin_sections[objc_image_info_section];
1296
      else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1297
        return darwin_sections[objc_cat_inst_meth_section];
1298
      else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1299
        return darwin_sections[objc_cat_cls_meth_section];
1300
      else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1301
        return darwin_sections[objc_cat_cls_meth_section];
1302
      else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1303
        return darwin_sections[objc_protocol_section];
1304
      else
1305
        return base_section;
1306
    }
1307
 
1308
  return base_section;
1309
}
1310
 
1311
/* This can be called with address expressions as "rtx".
1312
   They must go in "const".  */
1313
 
1314
section *
1315
machopic_select_rtx_section (enum machine_mode mode, rtx x,
1316
                             unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1317
{
1318
  if (GET_MODE_SIZE (mode) == 8
1319
      && (GET_CODE (x) == CONST_INT
1320
          || GET_CODE (x) == CONST_DOUBLE))
1321
    return darwin_sections[literal8_section];
1322
  else if (GET_MODE_SIZE (mode) == 4
1323
           && (GET_CODE (x) == CONST_INT
1324
               || GET_CODE (x) == CONST_DOUBLE))
1325
    return darwin_sections[literal4_section];
1326
  else if (HAVE_GAS_LITERAL16
1327
           && TARGET_64BIT
1328
           && GET_MODE_SIZE (mode) == 16
1329
           && (GET_CODE (x) == CONST_INT
1330
               || GET_CODE (x) == CONST_DOUBLE
1331
               || GET_CODE (x) == CONST_VECTOR))
1332
    return darwin_sections[literal16_section];
1333
  else if (MACHOPIC_INDIRECT
1334
           && (GET_CODE (x) == SYMBOL_REF
1335
               || GET_CODE (x) == CONST
1336
               || GET_CODE (x) == LABEL_REF))
1337
    return darwin_sections[const_data_section];
1338
  else
1339
    return darwin_sections[const_section];
1340
}
1341
 
1342
void
1343
machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1344
{
1345
  if (MACHOPIC_INDIRECT)
1346
    switch_to_section (darwin_sections[mod_init_section]);
1347
  else
1348
    switch_to_section (darwin_sections[constructor_section]);
1349
  assemble_align (POINTER_SIZE);
1350
  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1351
 
1352
  if (! MACHOPIC_INDIRECT)
1353
    fprintf (asm_out_file, ".reference .constructors_used\n");
1354
}
1355
 
1356
void
1357
machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1358
{
1359
  if (MACHOPIC_INDIRECT)
1360
    switch_to_section (darwin_sections[mod_term_section]);
1361
  else
1362
    switch_to_section (darwin_sections[destructor_section]);
1363
  assemble_align (POINTER_SIZE);
1364
  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1365
 
1366
  if (! MACHOPIC_INDIRECT)
1367
    fprintf (asm_out_file, ".reference .destructors_used\n");
1368
}
1369
 
1370
void
1371
darwin_globalize_label (FILE *stream, const char *name)
1372
{
1373
  if (!!strncmp (name, "_OBJC_", 6))
1374
    default_globalize_label (stream, name);
1375
}
1376
 
1377
/* This routine returns non-zero if 'name' starts with the special objective-c
1378
   anonymous file-scope static name.  It accommodates c++'s mangling of such
1379
   symbols (in this case the symbols will have form _ZL{d}*_OBJC_* d=digit).  */
1380
 
1381
int
1382
darwin_label_is_anonymous_local_objc_name (const char *name)
1383
{
1384
  const unsigned char *p = (const unsigned char *) name;
1385
  if (*p != '_')
1386
    return 0;
1387
  if (p[1] == 'Z' && p[2] == 'L')
1388
  {
1389
    p += 3;
1390
    while (*p >= '0' && *p <= '9')
1391
      p++;
1392
  }
1393
  return (!strncmp ((const char *)p, "_OBJC_", 6));
1394
}
1395
 
1396
/* LTO support for Mach-O.  */
1397
 
1398
/* Section names for LTO sections.  */
1399
static unsigned int lto_section_names_offset = 0;
1400
 
1401
/* This is the obstack which we use to allocate the many strings.  */
1402
static struct obstack lto_section_names_obstack;
1403
 
1404
/* Segment name for LTO sections.  */
1405
#define LTO_SEGMENT_NAME "__GNU_LTO"
1406
 
1407
/* Section name for LTO section names section.  */
1408
#define LTO_NAMES_SECTION "__section_names"
1409
 
1410
/* File to temporarily store LTO data.  This is appended to asm_out_file
1411
   in darwin_end_file.  */
1412
static FILE *lto_asm_out_file, *saved_asm_out_file;
1413
static char *lto_asm_out_name;
1414
 
1415
/* Prepare asm_out_file for LTO output.  For darwin, this means hiding
1416
   asm_out_file and switching to an alternative output file.  */
1417
void
1418
darwin_asm_lto_start (void)
1419
{
1420
  gcc_assert (! saved_asm_out_file);
1421
  saved_asm_out_file = asm_out_file;
1422
  if (! lto_asm_out_name)
1423
    lto_asm_out_name = make_temp_file (".lto.s");
1424
  lto_asm_out_file = fopen (lto_asm_out_name, "a");
1425
  if (lto_asm_out_file == NULL)
1426
    fatal_error ("failed to open temporary file %s for LTO output",
1427
                 lto_asm_out_name);
1428
  asm_out_file = lto_asm_out_file;
1429
}
1430
 
1431
/* Restore asm_out_file.  */
1432
void
1433
darwin_asm_lto_end (void)
1434
{
1435
  gcc_assert (saved_asm_out_file);
1436
  fclose (lto_asm_out_file);
1437
  asm_out_file = saved_asm_out_file;
1438
  saved_asm_out_file = NULL;
1439
}
1440
 
1441
void
1442
darwin_asm_named_section (const char *name,
1443
                          unsigned int flags,
1444
                          tree decl ATTRIBUTE_UNUSED)
1445
{
1446
  /* LTO sections go in a special segment __GNU_LTO.  We want to replace the
1447
     section name with something we can use to represent arbitrary-length
1448
     names (section names in Mach-O are at most 16 characters long).  */
1449
  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
1450
               strlen (LTO_SECTION_NAME_PREFIX)) == 0)
1451
    {
1452
      /* We expect certain flags to be set...  */
1453
      gcc_assert ((flags & (SECTION_DEBUG | SECTION_NAMED))
1454
                  == (SECTION_DEBUG | SECTION_NAMED));
1455
 
1456
      /* Add the section name to the things to output when we end the
1457
         current assembler output file.
1458
         This is all not very efficient, but that doesn't matter -- this
1459
         shouldn't be a hot path in the compiler...  */
1460
      obstack_1grow (&lto_section_names_obstack, '\t');
1461
      obstack_grow (&lto_section_names_obstack, ".ascii ", 7);
1462
      obstack_1grow (&lto_section_names_obstack, '"');
1463
      obstack_grow (&lto_section_names_obstack, name, strlen (name));
1464
      obstack_grow (&lto_section_names_obstack, "\\0\"\n", 4);
1465
 
1466
      /* Output the dummy section name.  */
1467
      fprintf (asm_out_file, "\t# %s\n", name);
1468
      fprintf (asm_out_file, "\t.section %s,__%08X,regular,debug\n",
1469
               LTO_SEGMENT_NAME, lto_section_names_offset);
1470
 
1471
      /* Update the offset for the next section name.  Make sure we stay
1472
         within reasonable length.  */
1473
      lto_section_names_offset += strlen (name) + 1;
1474
      gcc_assert (lto_section_names_offset > 0
1475
                  && lto_section_names_offset < ((unsigned) 1 << 31));
1476
    }
1477
  else
1478
    fprintf (asm_out_file, "\t.section %s\n", name);
1479
}
1480
 
1481
void
1482
darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1483
{
1484
  /* Darwin does not use unique sections.  */
1485
}
1486
 
1487
/* Handle __attribute__ ((apple_kext_compatibility)).
1488
   This only applies to darwin kexts for 2.95 compatibility -- it shrinks the
1489
   vtable for classes with this attribute (and their descendants) by not
1490
   outputting the new 3.0 nondeleting destructor.  This means that such
1491
   objects CANNOT be allocated on the stack or as globals UNLESS they have
1492
   a completely empty `operator delete'.
1493
   Luckily, this fits in with the Darwin kext model.
1494
 
1495
   This attribute also disables gcc3's potential overlaying of derived
1496
   class data members on the padding at the end of the base class.  */
1497
 
1498
tree
1499
darwin_handle_kext_attribute (tree *node, tree name,
1500
                              tree args ATTRIBUTE_UNUSED,
1501
                              int flags ATTRIBUTE_UNUSED,
1502
                              bool *no_add_attrs)
1503
{
1504
  /* APPLE KEXT stuff -- only applies with pure static C++ code.  */
1505
  if (! TARGET_KEXTABI)
1506
    {
1507
      warning (0, "%qE 2.95 vtable-compatibility attribute applies "
1508
               "only when compiling a kext", name);
1509
 
1510
      *no_add_attrs = true;
1511
    }
1512
  else if (TREE_CODE (*node) != RECORD_TYPE)
1513
    {
1514
      warning (0, "%qE 2.95 vtable-compatibility attribute applies "
1515
               "only to C++ classes", name);
1516
 
1517
      *no_add_attrs = true;
1518
    }
1519
 
1520
  return NULL_TREE;
1521
}
1522
 
1523
/* Handle a "weak_import" attribute; arguments as in
1524
   struct attribute_spec.handler.  */
1525
 
1526
tree
1527
darwin_handle_weak_import_attribute (tree *node, tree name,
1528
                                     tree ARG_UNUSED (args),
1529
                                     int ARG_UNUSED (flags),
1530
                                     bool * no_add_attrs)
1531
{
1532
  if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1533
    {
1534
      warning (OPT_Wattributes, "%qE attribute ignored",
1535
               name);
1536
      *no_add_attrs = true;
1537
    }
1538
  else
1539
    declare_weak (*node);
1540
 
1541
  return NULL_TREE;
1542
}
1543
 
1544
/* Emit a label for an FDE, making it global and/or weak if appropriate.
1545
   The third parameter is nonzero if this is for exception handling.
1546
   The fourth parameter is nonzero if this is just a placeholder for an
1547
   FDE that we are omitting. */
1548
 
1549
void
1550
darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1551
{
1552
  char *lab;
1553
 
1554
  if (! for_eh)
1555
    return;
1556
 
1557
  lab = concat (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), ".eh", NULL);
1558
 
1559
  if (TREE_PUBLIC (decl))
1560
    {
1561
      targetm.asm_out.globalize_label (file, lab);
1562
      if (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN)
1563
        {
1564
          fputs ("\t.private_extern ", file);
1565
          assemble_name (file, lab);
1566
          fputc ('\n', file);
1567
        }
1568
    }
1569
 
1570
  if (DECL_WEAK (decl))
1571
    {
1572
      fputs ("\t.weak_definition ", file);
1573
      assemble_name (file, lab);
1574
      fputc ('\n', file);
1575
    }
1576
 
1577
  assemble_name (file, lab);
1578
  if (empty)
1579
    {
1580
      fputs (" = 0\n", file);
1581
 
1582
      /* Mark the absolute .eh and .eh1 style labels as needed to
1583
         ensure that we don't dead code strip them and keep such
1584
         labels from another instantiation point until we can fix this
1585
         properly with group comdat support.  */
1586
      darwin_mark_decl_preserved (lab);
1587
    }
1588
  else
1589
    fputs (":\n", file);
1590
 
1591
  free (lab);
1592
}
1593
 
1594
static GTY(()) unsigned long except_table_label_num;
1595
 
1596
void
1597
darwin_emit_except_table_label (FILE *file)
1598
{
1599
  char section_start_label[30];
1600
 
1601
  ASM_GENERATE_INTERNAL_LABEL (section_start_label, "GCC_except_table",
1602
                               except_table_label_num++);
1603
  ASM_OUTPUT_LABEL (file, section_start_label);
1604
}
1605
/* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */
1606
 
1607
void
1608
darwin_non_lazy_pcrel (FILE *file, rtx addr)
1609
{
1610
  const char *nlp_name;
1611
 
1612
  gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1613
 
1614
  nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1615
  fputs ("\t.long\t", file);
1616
  ASM_OUTPUT_LABELREF (file, nlp_name);
1617
  fputs ("-.", file);
1618
}
1619
 
1620
/* Emit an assembler directive to set visibility for a symbol.  The
1621
   only supported visibilities are VISIBILITY_DEFAULT and
1622
   VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1623
   extern".  There is no MACH-O equivalent of ELF's
1624
   VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1625
 
1626
void
1627
darwin_assemble_visibility (tree decl, int vis)
1628
{
1629
  if (vis == VISIBILITY_DEFAULT)
1630
    ;
1631
  else if (vis == VISIBILITY_HIDDEN)
1632
    {
1633
      fputs ("\t.private_extern ", asm_out_file);
1634
      assemble_name (asm_out_file,
1635
                     (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1636
      fputs ("\n", asm_out_file);
1637
    }
1638
  else
1639
    warning (OPT_Wattributes, "internal and protected visibility attributes "
1640
             "not supported in this configuration; ignored");
1641
}
1642
 
1643
/* Output a difference of two labels that will be an assembly time
1644
   constant if the two labels are local.  (.long lab1-lab2 will be
1645
   very different if lab1 is at the boundary between two sections; it
1646
   will be relocated according to the second section, not the first,
1647
   so one ends up with a difference between labels in different
1648
   sections, which is bad in the dwarf2 eh context for instance.)  */
1649
 
1650
static int darwin_dwarf_label_counter;
1651
 
1652
void
1653
darwin_asm_output_dwarf_delta (FILE *file, int size,
1654
                               const char *lab1, const char *lab2)
1655
{
1656
  int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1657
                     && lab2[0] == '*' && lab2[1] == 'L');
1658
  const char *directive = (size == 8 ? ".quad" : ".long");
1659
 
1660
  if (islocaldiff)
1661
    fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1662
  else
1663
    fprintf (file, "\t%s\t", directive);
1664
  assemble_name_raw (file, lab1);
1665
  fprintf (file, "-");
1666
  assemble_name_raw (file, lab2);
1667
  if (islocaldiff)
1668
    fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1669
}
1670
 
1671
/* Output labels for the start of the DWARF sections if necessary.
1672
   Initialize the stuff we need for LTO long section names support.  */
1673
void
1674
darwin_file_start (void)
1675
{
1676
  if (write_symbols == DWARF2_DEBUG)
1677
    {
1678
      static const char * const debugnames[] =
1679
        {
1680
          DEBUG_FRAME_SECTION,
1681
          DEBUG_INFO_SECTION,
1682
          DEBUG_ABBREV_SECTION,
1683
          DEBUG_ARANGES_SECTION,
1684
          DEBUG_MACINFO_SECTION,
1685
          DEBUG_LINE_SECTION,
1686
          DEBUG_LOC_SECTION,
1687
          DEBUG_PUBNAMES_SECTION,
1688
          DEBUG_PUBTYPES_SECTION,
1689
          DEBUG_STR_SECTION,
1690
          DEBUG_RANGES_SECTION
1691
        };
1692
      size_t i;
1693
 
1694
      for (i = 0; i < ARRAY_SIZE (debugnames); i++)
1695
        {
1696
          int namelen;
1697
 
1698
          switch_to_section (get_section (debugnames[i], SECTION_DEBUG, NULL));
1699
 
1700
          gcc_assert (strncmp (debugnames[i], "__DWARF,", 8) == 0);
1701
          gcc_assert (strchr (debugnames[i] + 8, ','));
1702
 
1703
          namelen = strchr (debugnames[i] + 8, ',') - (debugnames[i] + 8);
1704
          fprintf (asm_out_file, "Lsection%.*s:\n", namelen, debugnames[i] + 8);
1705
        }
1706
    }
1707
 
1708
  /* We fill this obstack with the complete section text for the lto section
1709
     names to write in darwin_file_end.  */
1710
  obstack_init (&lto_section_names_obstack);
1711
  lto_section_names_offset = 0;
1712
}
1713
 
1714
/* Output an offset in a DWARF section on Darwin.  On Darwin, DWARF section
1715
   offsets are not represented using relocs in .o files; either the
1716
   section never leaves the .o file, or the linker or other tool is
1717
   responsible for parsing the DWARF and updating the offsets.  */
1718
 
1719
void
1720
darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
1721
                                section *base)
1722
{
1723
  char sname[64];
1724
  int namelen;
1725
 
1726
  gcc_assert (base->common.flags & SECTION_NAMED);
1727
  gcc_assert (strncmp (base->named.name, "__DWARF,", 8) == 0);
1728
  gcc_assert (strchr (base->named.name + 8, ','));
1729
 
1730
  namelen = strchr (base->named.name + 8, ',') - (base->named.name + 8);
1731
  sprintf (sname, "*Lsection%.*s", namelen, base->named.name + 8);
1732
  darwin_asm_output_dwarf_delta (file, size, lab, sname);
1733
}
1734
 
1735
void
1736
darwin_file_end (void)
1737
{
1738
  const char *lto_section_names;
1739
 
1740
  machopic_finish (asm_out_file);
1741
  if (strcmp (lang_hooks.name, "GNU C++") == 0)
1742
    {
1743
      switch_to_section (darwin_sections[constructor_section]);
1744
      switch_to_section (darwin_sections[destructor_section]);
1745
      ASM_OUTPUT_ALIGN (asm_out_file, 1);
1746
    }
1747
 
1748
  /* If there was LTO assembler output, append it to asm_out_file.  */
1749
  if (lto_asm_out_name)
1750
    {
1751
      int n;
1752
      char *buf, *lto_asm_txt;
1753
 
1754
      /* Shouldn't be here if we failed to switch back.  */
1755
      gcc_assert (! saved_asm_out_file);
1756
 
1757
      lto_asm_out_file = fopen (lto_asm_out_name, "r");
1758
      if (lto_asm_out_file == NULL)
1759
        fatal_error ("failed to open temporary file %s with LTO output",
1760
                     lto_asm_out_name);
1761
      fseek (lto_asm_out_file, 0, SEEK_END);
1762
      n = ftell (lto_asm_out_file);
1763
      if (n > 0)
1764
        {
1765
          fseek (lto_asm_out_file, 0, SEEK_SET);
1766
          lto_asm_txt = buf = (char *) xmalloc (n + 1);
1767
          while (fgets (lto_asm_txt, n, lto_asm_out_file))
1768
            fputs (lto_asm_txt, asm_out_file);
1769
        }
1770
 
1771
      /* Remove the temporary file.  */
1772
      fclose (lto_asm_out_file);
1773
      unlink_if_ordinary (lto_asm_out_name);
1774
      free (lto_asm_out_name);
1775
    }
1776
 
1777
  /* Finish the LTO section names obstack.  Don't output anything if
1778
     there are no recorded section names.  */
1779
  obstack_1grow (&lto_section_names_obstack, '\0');
1780
  lto_section_names = XOBFINISH (&lto_section_names_obstack, const char *);
1781
  if (strlen (lto_section_names) > 0)
1782
    {
1783
      fprintf (asm_out_file,
1784
               "\t.section %s,%s,regular,debug\n",
1785
               LTO_SEGMENT_NAME, LTO_NAMES_SECTION);
1786
      fprintf (asm_out_file,
1787
               "\t# Section names in %s are offsets into this table\n",
1788
               LTO_SEGMENT_NAME);
1789
      fprintf (asm_out_file, "%s\n", lto_section_names);
1790
    }
1791
  obstack_free (&lto_section_names_obstack, NULL);
1792
 
1793
  fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1794
}
1795
 
1796
/* TODO: Add a language hook for identifying if a decl is a vtable.  */
1797
#define DARWIN_VTABLE_P(DECL) 0
1798
 
1799
/* Cross-module name binding.  Darwin does not support overriding
1800
   functions at dynamic-link time, except for vtables in kexts.  */
1801
 
1802
bool
1803
darwin_binds_local_p (const_tree decl)
1804
{
1805
  return default_binds_local_p_1 (decl,
1806
                                  TARGET_KEXTABI && DARWIN_VTABLE_P (decl));
1807
}
1808
 
1809
#if 0
1810
/* See TARGET_ASM_OUTPUT_ANCHOR for why we can't do this yet.  */
1811
/* The Darwin's implementation of TARGET_ASM_OUTPUT_ANCHOR.  Define the
1812
   anchor relative to ".", the current section position.  We cannot use
1813
   the default one because ASM_OUTPUT_DEF is wrong for Darwin.  */
1814
 
1815
void
1816
darwin_asm_output_anchor (rtx symbol)
1817
{
1818
  fprintf (asm_out_file, "\t.set\t");
1819
  assemble_name (asm_out_file, XSTR (symbol, 0));
1820
  fprintf (asm_out_file, ", . + " HOST_WIDE_INT_PRINT_DEC "\n",
1821
           SYMBOL_REF_BLOCK_OFFSET (symbol));
1822
}
1823
#endif
1824
 
1825
/* Set the darwin specific attributes on TYPE.  */
1826
void
1827
darwin_set_default_type_attributes (tree type)
1828
{
1829
  if (darwin_ms_struct
1830
      && TREE_CODE (type) == RECORD_TYPE)
1831
    TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("ms_struct"),
1832
                                        NULL_TREE,
1833
                                        TYPE_ATTRIBUTES (type));
1834
}
1835
 
1836
/* True, iff we're generating code for loadable kernel extensions.  */
1837
 
1838
bool
1839
darwin_kextabi_p (void) {
1840
  return flag_apple_kext;
1841
}
1842
 
1843
void
1844
darwin_override_options (void)
1845
{
1846
  /* Don't emit DWARF3/4 unless specifically selected.  This is a
1847
     workaround for tool bugs.  */
1848
  if (dwarf_strict < 0)
1849
    dwarf_strict = 1;
1850
 
1851
  /* Disable -freorder-blocks-and-partition for darwin_emit_unwind_label.  */
1852
  if (flag_reorder_blocks_and_partition
1853
      && (targetm.asm_out.unwind_label == darwin_emit_unwind_label))
1854
    {
1855
      inform (input_location,
1856
              "-freorder-blocks-and-partition does not work with exceptions "
1857
              "on this architecture");
1858
      flag_reorder_blocks_and_partition = 0;
1859
      flag_reorder_blocks = 1;
1860
    }
1861
 
1862
  if (flag_mkernel || flag_apple_kext)
1863
    {
1864
      /* -mkernel implies -fapple-kext for C++ */
1865
      if (strcmp (lang_hooks.name, "GNU C++") == 0)
1866
        flag_apple_kext = 1;
1867
 
1868
      flag_no_common = 1;
1869
 
1870
      /* No EH in kexts.  */
1871
      flag_exceptions = 0;
1872
      /* No -fnon-call-exceptions data in kexts.  */
1873
      flag_non_call_exceptions = 0;
1874
    }
1875
  if (flag_var_tracking
1876
      && strverscmp (darwin_macosx_version_min, "10.5") >= 0
1877
      && debug_info_level >= DINFO_LEVEL_NORMAL
1878
      && debug_hooks->var_location != do_nothing_debug_hooks.var_location)
1879
    flag_var_tracking_uninit = 1;
1880
}
1881
 
1882
/* Add $LDBL128 suffix to long double builtins.  */
1883
 
1884
static void
1885
darwin_patch_builtin (int fncode)
1886
{
1887
  tree fn = built_in_decls[fncode];
1888
  tree sym;
1889
  char *newname;
1890
 
1891
  if (!fn)
1892
    return;
1893
 
1894
  sym = DECL_ASSEMBLER_NAME (fn);
1895
  newname = ACONCAT (("_", IDENTIFIER_POINTER (sym), "$LDBL128", NULL));
1896
 
1897
  set_user_assembler_name (fn, newname);
1898
 
1899
  fn = implicit_built_in_decls[fncode];
1900
  if (fn)
1901
    set_user_assembler_name (fn, newname);
1902
}
1903
 
1904
void
1905
darwin_patch_builtins (void)
1906
{
1907
  if (LONG_DOUBLE_TYPE_SIZE != 128)
1908
    return;
1909
 
1910
#define PATCH_BUILTIN(fncode) darwin_patch_builtin (fncode);
1911
#define PATCH_BUILTIN_NO64(fncode)              \
1912
  if (!TARGET_64BIT)                            \
1913
    darwin_patch_builtin (fncode);
1914
#define PATCH_BUILTIN_VARIADIC(fncode)                            \
1915
  if (!TARGET_64BIT                                               \
1916
      && (strverscmp (darwin_macosx_version_min, "10.3.9") >= 0)) \
1917
    darwin_patch_builtin (fncode);
1918
#include "darwin-ppc-ldouble-patch.def"
1919
#undef PATCH_BUILTIN
1920
#undef PATCH_BUILTIN_NO64
1921
#undef PATCH_BUILTIN_VARIADIC
1922
}
1923
 
1924
 
1925
#include "gt-darwin.h"

powered by: WebSVN 2.1.0

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