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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-dev/] [fsf-gcc-snapshot-1-mar-12/] [or1k-gcc/] [gcc/] [config/] [i386/] [winnt.c] - Blame information for rev 847

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
/* Subroutines for insn-output.c for Windows NT.
2
   Contributed by Douglas Rupp (drupp@cs.washington.edu)
3
   Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4
   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "rtl.h"
27
#include "regs.h"
28
#include "hard-reg-set.h"
29
#include "output.h"
30
#include "tree.h"
31
#include "flags.h"
32
#include "tm_p.h"
33
#include "diagnostic-core.h"
34
#include "hashtab.h"
35
#include "langhooks.h"
36
#include "ggc.h"
37
#include "target.h"
38
#include "except.h"
39
#include "lto-streamer.h"
40
 
41
/* i386/PE specific attribute support.
42
 
43
   i386/PE has two new attributes:
44
   dllexport - for exporting a function/variable that will live in a dll
45
   dllimport - for importing a function/variable from a dll
46
 
47
   Microsoft allows multiple declspecs in one __declspec, separating
48
   them with spaces.  We do NOT support this.  Instead, use __declspec
49
   multiple times.
50
*/
51
 
52
/* Handle a "shared" attribute;
53
   arguments as in struct attribute_spec.handler.  */
54
tree
55
ix86_handle_shared_attribute (tree *node, tree name,
56
                              tree args ATTRIBUTE_UNUSED,
57
                              int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
58
{
59
  if (TREE_CODE (*node) != VAR_DECL)
60
    {
61
      warning (OPT_Wattributes, "%qE attribute only applies to variables",
62
               name);
63
      *no_add_attrs = true;
64
    }
65
 
66
  return NULL_TREE;
67
}
68
 
69
/* Handle a "selectany" attribute;
70
   arguments as in struct attribute_spec.handler.  */
71
tree
72
ix86_handle_selectany_attribute (tree *node, tree name,
73
                                 tree args ATTRIBUTE_UNUSED,
74
                                 int flags ATTRIBUTE_UNUSED,
75
                                 bool *no_add_attrs)
76
{
77
  /* The attribute applies only to objects that are initialized and have
78
     external linkage.  However, we may not know about initialization
79
     until the language frontend has processed the decl. We'll check for
80
     initialization later in encode_section_info.  */
81
  if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
82
    {
83
      error ("%qE attribute applies only to initialized variables"
84
             " with external linkage", name);
85
      *no_add_attrs = true;
86
    }
87
 
88
  return NULL_TREE;
89
}
90
 
91
 
92
/* Return the type that we should use to determine if DECL is
93
   imported or exported.  */
94
 
95
static tree
96
associated_type (tree decl)
97
{
98
  return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
99
          ?  DECL_CONTEXT (decl) : NULL_TREE);
100
}
101
 
102
/* Return true if DECL should be a dllexport'd object.  */
103
 
104
static bool
105
i386_pe_determine_dllexport_p (tree decl)
106
{
107
  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
108
    return false;
109
 
110
  /* Don't export local clones of dllexports.  */
111
  if (!TREE_PUBLIC (decl))
112
    return false;
113
 
114
  if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
115
    return true;
116
 
117
  return false;
118
}
119
 
120
/* Return true if DECL should be a dllimport'd object.  */
121
 
122
static bool
123
i386_pe_determine_dllimport_p (tree decl)
124
{
125
  tree assoc;
126
 
127
  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
128
    return false;
129
 
130
  if (DECL_DLLIMPORT_P (decl))
131
    return true;
132
 
133
  /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
134
     by  targetm.cxx.adjust_class_at_definition.  Check again to emit
135
     error message if the class attribute has been overridden by an
136
     out-of-class definition of static data.  */
137
  assoc = associated_type (decl);
138
  if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc))
139
      && TREE_CODE (decl) == VAR_DECL
140
      && TREE_STATIC (decl) && TREE_PUBLIC (decl)
141
      && !DECL_EXTERNAL (decl)
142
      /* vtable's are linkonce constants, so defining a vtable is not
143
         an error as long as we don't try to import it too.  */
144
      && !DECL_VIRTUAL_P (decl))
145
        error ("definition of static data member %q+D of "
146
               "dllimport%'d class", decl);
147
 
148
  return false;
149
}
150
 
151
/* Handle the -mno-fun-dllimport target switch.  */
152
 
153
bool
154
i386_pe_valid_dllimport_attribute_p (const_tree decl)
155
{
156
   if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
157
     return false;
158
   return true;
159
}
160
 
161
/* Return string which is the function name, identified by ID, modified
162
   with a suffix consisting of an atsign (@) followed by the number of
163
   bytes of arguments.  If ID is NULL use the DECL_NAME as base. If
164
   FASTCALL is true, also add the FASTCALL_PREFIX.
165
   Return NULL if no change required.  */
166
 
167
static tree
168
gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall)
169
{
170
  HOST_WIDE_INT total = 0;
171
  const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
172
  char *new_str, *p;
173
  tree type = TREE_TYPE (DECL_ORIGIN (decl));
174
  tree arg;
175
  function_args_iterator args_iter;
176
 
177
  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
178
 
179
  if (prototype_p (type))
180
    {
181
      /* This attribute is ignored for variadic functions.  */
182
      if (stdarg_p (type))
183
        return NULL_TREE;
184
 
185
      /* Quit if we hit an incomplete type.  Error is reported
186
         by convert_arguments in c-typeck.c or cp/typeck.c.  */
187
      FOREACH_FUNCTION_ARGS(type, arg, args_iter)
188
        {
189
          HOST_WIDE_INT parm_size;
190
          HOST_WIDE_INT parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
191
 
192
          if (! COMPLETE_TYPE_P (arg))
193
            break;
194
 
195
          parm_size = int_size_in_bytes (arg);
196
          if (parm_size < 0)
197
            break;
198
 
199
          /* Must round up to include padding.  This is done the same
200
             way as in store_one_arg.  */
201
          parm_size = ((parm_size + parm_boundary_bytes - 1)
202
                       / parm_boundary_bytes * parm_boundary_bytes);
203
          total += parm_size;
204
        }
205
    }
206
 
207
  /* Assume max of 8 base 10 digits in the suffix.  */
208
  p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1);
209
  if (fastcall)
210
    *p++ = FASTCALL_PREFIX;
211
  sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total);
212
 
213
  return get_identifier (new_str);
214
}
215
 
216
/* Maybe decorate and get a new identifier for the DECL of a stdcall or
217
   fastcall function. The original identifier is supplied in ID. */
218
 
219
static tree
220
i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree id)
221
{
222
  tree new_id = NULL_TREE;
223
 
224
  if (TREE_CODE (decl) == FUNCTION_DECL)
225
    {
226
      unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl));
227
      if ((ccvt & IX86_CALLCVT_STDCALL) != 0)
228
        {
229
          if (TARGET_RTD)
230
            /* If we are using -mrtd emit undecorated symbol and let linker
231
               do the proper resolving.  */
232
            return NULL_TREE;
233
          new_id = gen_stdcall_or_fastcall_suffix (decl, id, false);
234
        }
235
      else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
236
        new_id = gen_stdcall_or_fastcall_suffix (decl, id, true);
237
    }
238
 
239
  return new_id;
240
}
241
 
242
/* Emit an assembler directive to set symbol for DECL visibility to
243
   the visibility type VIS, which must not be VISIBILITY_DEFAULT.
244
   As for PE there is no hidden support in gas, we just warn for
245
   user-specified visibility attributes.  */
246
 
247
void
248
i386_pe_assemble_visibility (tree decl,
249
                             int vis ATTRIBUTE_UNUSED)
250
{
251
  if (!decl
252
      || !lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)))
253
    return;
254
  warning (OPT_Wattributes, "visibility attribute not supported "
255
           "in this configuration; ignored");
256
}
257
 
258
/* This is used as a target hook to modify the DECL_ASSEMBLER_NAME
259
   in the language-independent default hook
260
   langhooks,c:lhd_set_decl_assembler_name ()
261
   and in cp/mangle,c:mangle_decl ().  */
262
tree
263
i386_pe_mangle_decl_assembler_name (tree decl, tree id)
264
{
265
  tree new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, id);
266
 
267
  return (new_id ? new_id : id);
268
}
269
 
270
/* This hook behaves the same as varasm.c/assemble_name(), but
271
   generates the name into memory rather than outputting it to
272
   a file stream.  */
273
 
274
tree
275
i386_pe_mangle_assembler_name (const char *name ATTRIBUTE_UNUSED)
276
{
277
  const char *skipped = name + (*name == '*' ? 1 : 0);
278
  const char *stripped = targetm.strip_name_encoding (skipped);
279
  if (*name != '*' && *user_label_prefix && *stripped != FASTCALL_PREFIX)
280
    stripped = ACONCAT ((user_label_prefix, stripped, NULL));
281
  return get_identifier (stripped);
282
}
283
 
284
void
285
i386_pe_encode_section_info (tree decl, rtx rtl, int first)
286
{
287
  rtx symbol;
288
  int flags;
289
 
290
  /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above.  */
291
  default_encode_section_info (decl, rtl, first);
292
 
293
  /* Careful not to prod global register variables.  */
294
  if (!MEM_P (rtl))
295
    return;
296
 
297
  symbol = XEXP (rtl, 0);
298
  gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
299
 
300
  switch (TREE_CODE (decl))
301
    {
302
    case FUNCTION_DECL:
303
      /* FIXME:  Imported stdcall names are not modified by the Ada frontend.
304
         Check and decorate the RTL name now.  */
305
      if  (strcmp (lang_hooks.name, "GNU Ada") == 0)
306
        {
307
          tree new_id;
308
          tree old_id = DECL_ASSEMBLER_NAME (decl);
309
          const char* asm_str = IDENTIFIER_POINTER (old_id);
310
          /* Do not change the identifier if a verbatim asmspec
311
             or if stdcall suffix already added. */
312
          if (!(*asm_str == '*' || strchr (asm_str, '@'))
313
              && (new_id = i386_pe_maybe_mangle_decl_assembler_name (decl,
314
                                                                     old_id)))
315
            XSTR (symbol, 0) = IDENTIFIER_POINTER (new_id);
316
        }
317
      break;
318
 
319
    case VAR_DECL:
320
      if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
321
        {
322
          if (DECL_INITIAL (decl)
323
              /* If an object is initialized with a ctor, the static
324
                 initialization and destruction code for it is present in
325
                 each unit defining the object.  The code that calls the
326
                 ctor is protected by a link-once guard variable, so that
327
                 the object still has link-once semantics,  */
328
              || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
329
            make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
330
          else
331
            error ("%q+D:'selectany' attribute applies only to "
332
                   "initialized objects", decl);
333
        }
334
      break;
335
 
336
    default:
337
      return;
338
    }
339
 
340
  /* Mark the decl so we can tell from the rtl whether the object is
341
     dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
342
     handles dllexport/dllimport override semantics.  */
343
  flags = (SYMBOL_REF_FLAGS (symbol) &
344
           ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT));
345
  if (i386_pe_determine_dllexport_p (decl))
346
    flags |= SYMBOL_FLAG_DLLEXPORT;
347
  else if (i386_pe_determine_dllimport_p (decl))
348
    flags |= SYMBOL_FLAG_DLLIMPORT;
349
 
350
  SYMBOL_REF_FLAGS (symbol) = flags;
351
}
352
 
353
 
354
bool
355
i386_pe_binds_local_p (const_tree exp)
356
{
357
  if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
358
      && DECL_DLLIMPORT_P (exp))
359
    return false;
360
 
361
  /* External public symbols, which aren't weakref-s,
362
     have local-binding for PE targets.  */
363
  if (DECL_P (exp)
364
      && !lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
365
      && TREE_PUBLIC (exp)
366
      && DECL_EXTERNAL (exp))
367
    return true;
368
  return default_binds_local_p_1 (exp, 0);
369
}
370
 
371
/* Also strip the fastcall prefix and stdcall suffix.  */
372
 
373
const char *
374
i386_pe_strip_name_encoding_full (const char *str)
375
{
376
  const char *p;
377
  const char *name = default_strip_name_encoding (str);
378
 
379
  /* Strip leading '@' on fastcall symbols.  */
380
  if (*name == '@')
381
    name++;
382
 
383
  /* Strip trailing "@n".  */
384
  p = strchr (name, '@');
385
  if (p)
386
    return ggc_alloc_string (name, p - name);
387
 
388
  return name;
389
}
390
 
391
void
392
i386_pe_unique_section (tree decl, int reloc)
393
{
394
  int len;
395
  const char *name, *prefix;
396
  char *string;
397
 
398
  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
399
  name = i386_pe_strip_name_encoding_full (name);
400
 
401
  /* The object is put in, for example, section .text$foo.
402
     The linker will then ultimately place them in .text
403
     (everything from the $ on is stripped). Don't put
404
     read-only data in .rdata section to avoid a PE linker
405
     bug when .rdata$* grouped sections are used in code
406
     without a .rdata section.  */
407
  if (TREE_CODE (decl) == FUNCTION_DECL)
408
    prefix = ".text$";
409
  else if (decl_readonly_section (decl, reloc))
410
    prefix = ".rdata$";
411
  else
412
    prefix = ".data$";
413
  len = strlen (name) + strlen (prefix);
414
  string = XALLOCAVEC (char, len + 1);
415
  sprintf (string, "%s%s", prefix, name);
416
 
417
  DECL_SECTION_NAME (decl) = build_string (len, string);
418
}
419
 
420
/* Select a set of attributes for section NAME based on the properties
421
   of DECL and whether or not RELOC indicates that DECL's initializer
422
   might contain runtime relocations.
423
 
424
   We make the section read-only and executable for a function decl,
425
   read-only for a const data decl, and writable for a non-const data decl.
426
 
427
   If the section has already been defined, to not allow it to have
428
   different attributes, as (1) this is ambiguous since we're not seeing
429
   all the declarations up front and (2) some assemblers (e.g. SVR4)
430
   do not recognize section redefinitions.  */
431
/* ??? This differs from the "standard" PE implementation in that we
432
   handle the SHARED variable attribute.  Should this be done for all
433
   PE targets?  */
434
 
435
#define SECTION_PE_SHARED       SECTION_MACH_DEP
436
 
437
unsigned int
438
i386_pe_section_type_flags (tree decl, const char *name, int reloc)
439
{
440
  static htab_t htab;
441
  unsigned int flags;
442
  unsigned int **slot;
443
 
444
  /* The names we put in the hashtable will always be the unique
445
     versions given to us by the stringtable, so we can just use
446
     their addresses as the keys.  */
447
  if (!htab)
448
    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
449
 
450
  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
451
    flags = SECTION_CODE;
452
  else if (decl && decl_readonly_section (decl, reloc))
453
    flags = 0;
454
  else
455
    {
456
      flags = SECTION_WRITE;
457
 
458
      if (decl && TREE_CODE (decl) == VAR_DECL
459
          && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
460
        flags |= SECTION_PE_SHARED;
461
    }
462
 
463
  if (decl && DECL_ONE_ONLY (decl))
464
    flags |= SECTION_LINKONCE;
465
 
466
  /* See if we already have an entry for this section.  */
467
  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
468
  if (!*slot)
469
    {
470
      *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
471
      **slot = flags;
472
    }
473
  else
474
    {
475
      if (decl && **slot != flags)
476
        error ("%q+D causes a section type conflict", decl);
477
    }
478
 
479
  return flags;
480
}
481
 
482
void
483
i386_pe_asm_named_section (const char *name, unsigned int flags,
484
                           tree decl)
485
{
486
  char flagchars[8], *f = flagchars;
487
 
488
#if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
489
  if ((flags & SECTION_EXCLUDE) != 0)
490
    *f++ = 'e';
491
#endif
492
 
493
  if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
494
    /* readonly data */
495
    {
496
      *f++ ='d';  /* This is necessary for older versions of gas.  */
497
      *f++ ='r';
498
    }
499
  else
500
    {
501
      if (flags & SECTION_CODE)
502
        *f++ = 'x';
503
      if (flags & SECTION_WRITE)
504
        *f++ = 'w';
505
      if (flags & SECTION_PE_SHARED)
506
        *f++ = 's';
507
#if !defined (HAVE_GAS_SECTION_EXCLUDE) || HAVE_GAS_SECTION_EXCLUDE == 0
508
      /* If attribute "e" isn't supported we mark this section as
509
         never-load.  */
510
      if ((flags & SECTION_EXCLUDE) != 0)
511
        *f++ = 'n';
512
#endif
513
    }
514
 
515
  /* LTO sections need 1-byte alignment to avoid confusing the
516
     zlib decompression algorithm with trailing zero pad bytes.  */
517
  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
518
                        strlen (LTO_SECTION_NAME_PREFIX)) == 0)
519
    *f++ = '0';
520
 
521
  *f = '\0';
522
 
523
  fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
524
 
525
  if (flags & SECTION_LINKONCE)
526
    {
527
      /* Functions may have been compiled at various levels of
528
         optimization so we can't use `same_size' here.
529
         Instead, have the linker pick one, without warning.
530
         If 'selectany' attribute has been specified,  MS compiler
531
         sets 'discard' characteristic, rather than telling linker
532
         to warn of size or content mismatch, so do the same.  */
533
      bool discard = (flags & SECTION_CODE)
534
                      || lookup_attribute ("selectany",
535
                                           DECL_ATTRIBUTES (decl));
536
      fprintf (asm_out_file, "\t.linkonce %s\n",
537
               (discard  ? "discard" : "same_size"));
538
    }
539
}
540
 
541
/* Beware, DECL may be NULL if compile_file() is emitting the LTO marker.  */
542
 
543
void
544
i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
545
                                        const char *name, HOST_WIDE_INT size,
546
                                        HOST_WIDE_INT align ATTRIBUTE_UNUSED)
547
{
548
  HOST_WIDE_INT rounded;
549
 
550
  /* Compute as in assemble_noswitch_variable, since we don't have
551
     support for aligned common on older binutils.  We must also
552
     avoid emitting a common symbol of size zero, as this is the
553
     overloaded representation that indicates an undefined external
554
     symbol in the PE object file format.  */
555
  rounded = size ? size : 1;
556
  rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
557
  rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
558
             * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
559
 
560
  i386_pe_maybe_record_exported_symbol (decl, name, 1);
561
 
562
  fprintf (stream, "\t.comm\t");
563
  assemble_name (stream, name);
564
  if (use_pe_aligned_common)
565
    fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n",
566
           size ? size : (HOST_WIDE_INT) 1,
567
           exact_log2 (align) - exact_log2 (CHAR_BIT));
568
  else
569
    fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
570
           " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size);
571
}
572
 
573
/* The Microsoft linker requires that every function be marked as
574
   DT_FCN.  When using gas on cygwin, we must emit appropriate .type
575
   directives.  */
576
 
577
#include "gsyms.h"
578
 
579
/* Mark a function appropriately.  This should only be called for
580
   functions for which we are not emitting COFF debugging information.
581
   FILE is the assembler output file, NAME is the name of the
582
   function, and PUB is nonzero if the function is globally
583
   visible.  */
584
 
585
void
586
i386_pe_declare_function_type (FILE *file, const char *name, int pub)
587
{
588
  fprintf (file, "\t.def\t");
589
  assemble_name (file, name);
590
  fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
591
           pub ? (int) C_EXT : (int) C_STAT,
592
           (int) DT_FCN << N_BTSHFT);
593
}
594
 
595
/* Keep a list of external functions.  */
596
 
597
struct GTY(()) extern_list
598
{
599
  struct extern_list *next;
600
  tree decl;
601
  const char *name;
602
};
603
 
604
static GTY(()) struct extern_list *extern_head;
605
 
606
/* Assemble an external function reference.  We need to keep a list of
607
   these, so that we can output the function types at the end of the
608
   assembly.  We can't output the types now, because we might see a
609
   definition of the function later on and emit debugging information
610
   for it then.  */
611
 
612
void
613
i386_pe_record_external_function (tree decl, const char *name)
614
{
615
  struct extern_list *p;
616
 
617
  p = ggc_alloc_extern_list ();
618
  p->next = extern_head;
619
  p->decl = decl;
620
  p->name = name;
621
  extern_head = p;
622
}
623
 
624
/* Keep a list of exported symbols.  */
625
 
626
struct GTY(()) export_list
627
{
628
  struct export_list *next;
629
  const char *name;
630
  int is_data;          /* used to type tag exported symbols.  */
631
};
632
 
633
static GTY(()) struct export_list *export_head;
634
 
635
/* Assemble an export symbol entry.  We need to keep a list of
636
   these, so that we can output the export list at the end of the
637
   assembly.  We used to output these export symbols in each function,
638
   but that causes problems with GNU ld when the sections are
639
   linkonce.  Beware, DECL may be NULL if compile_file() is emitting
640
   the LTO marker.  */
641
 
642
void
643
i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
644
{
645
  rtx symbol;
646
  struct export_list *p;
647
 
648
  if (!decl)
649
    return;
650
 
651
  symbol = XEXP (DECL_RTL (decl), 0);
652
  gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
653
  if (!SYMBOL_REF_DLLEXPORT_P (symbol))
654
    return;
655
 
656
  gcc_assert (TREE_PUBLIC (decl));
657
 
658
  p = ggc_alloc_export_list ();
659
  p->next = export_head;
660
  p->name = name;
661
  p->is_data = is_data;
662
  export_head = p;
663
}
664
 
665
#ifdef CXX_WRAP_SPEC_LIST
666
 
667
/*  Hash table equality helper function.  */
668
 
669
static int
670
wrapper_strcmp (const void *x, const void *y)
671
{
672
  return !strcmp ((const char *) x, (const char *) y);
673
}
674
 
675
/* Search for a function named TARGET in the list of library wrappers
676
   we are using, returning a pointer to it if found or NULL if not.
677
   This function might be called on quite a few symbols, and we only
678
   have the list of names of wrapped functions available to us as a
679
   spec string, so first time round we lazily initialise a hash table
680
   to make things quicker.  */
681
 
682
static const char *
683
i386_find_on_wrapper_list (const char *target)
684
{
685
  static char first_time = 1;
686
  static htab_t wrappers;
687
 
688
  if (first_time)
689
    {
690
      /* Beware that this is not a complicated parser, it assumes
691
         that any sequence of non-whitespace beginning with an
692
         underscore is one of the wrapped symbols.  For now that's
693
         adequate to distinguish symbols from spec substitutions
694
         and command-line options.  */
695
      static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST;
696
      char *bufptr;
697
      /* Breaks up the char array into separated strings
698
         strings and enter them into the hash table.  */
699
      wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
700
        0, xcalloc, free);
701
      for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
702
        {
703
          char *found = NULL;
704
          if (ISSPACE (*bufptr))
705
            continue;
706
          if (*bufptr == '_')
707
            found = bufptr;
708
          while (*bufptr && !ISSPACE (*bufptr))
709
            ++bufptr;
710
          if (*bufptr)
711
            *bufptr = 0;
712
          if (found)
713
            *htab_find_slot (wrappers, found, INSERT) = found;
714
        }
715
      first_time = 0;
716
    }
717
 
718
  return (const char *) htab_find (wrappers, target);
719
}
720
 
721
#endif /* CXX_WRAP_SPEC_LIST */
722
 
723
/* This is called at the end of assembly.  For each external function
724
   which has not been defined, we output a declaration now.  We also
725
   output the .drectve section.  */
726
 
727
void
728
i386_pe_file_end (void)
729
{
730
  struct extern_list *p;
731
 
732
  for (p = extern_head; p != NULL; p = p->next)
733
    {
734
      tree decl;
735
 
736
      decl = p->decl;
737
 
738
      /* Positively ensure only one declaration for any given symbol.  */
739
      if (! TREE_ASM_WRITTEN (decl)
740
          && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
741
        {
742
#ifdef CXX_WRAP_SPEC_LIST
743
          /* To ensure the DLL that provides the corresponding real
744
             functions is still loaded at runtime, we must reference
745
             the real function so that an (unused) import is created.  */
746
          const char *realsym = i386_find_on_wrapper_list (p->name);
747
          if (realsym)
748
            i386_pe_declare_function_type (asm_out_file,
749
                concat ("__real_", realsym, NULL), TREE_PUBLIC (decl));
750
#endif /* CXX_WRAP_SPEC_LIST */
751
          TREE_ASM_WRITTEN (decl) = 1;
752
          i386_pe_declare_function_type (asm_out_file, p->name,
753
                                         TREE_PUBLIC (decl));
754
        }
755
    }
756
 
757
  if (export_head)
758
    {
759
      struct export_list *q;
760
      drectve_section ();
761
      for (q = export_head; q != NULL; q = q->next)
762
        {
763
          fprintf (asm_out_file, "\t.ascii \" -export:\\\"%s\\\"%s\"\n",
764
                   default_strip_name_encoding (q->name),
765
                   (q->is_data ? ",data" : ""));
766
        }
767
    }
768
}
769
 
770
 
771
/* x64 Structured Exception Handling unwind info.  */
772
 
773
struct seh_frame_state
774
{
775
  /* SEH records saves relative to the "current" stack pointer, whether
776
     or not there's a frame pointer in place.  This tracks the current
777
     stack pointer offset from the CFA.  */
778
  HOST_WIDE_INT sp_offset;
779
 
780
  /* The CFA is located at CFA_REG + CFA_OFFSET.  */
781
  HOST_WIDE_INT cfa_offset;
782
  rtx cfa_reg;
783
};
784
 
785
/* Set up data structures beginning output for SEH.  */
786
 
787
void
788
i386_pe_seh_init (FILE *f)
789
{
790
  struct seh_frame_state *seh;
791
 
792
  if (!TARGET_SEH)
793
    return;
794
  if (cfun->is_thunk)
795
    return;
796
 
797
  /* We cannot support DRAP with SEH.  We turned off support for it by
798
     re-defining MAX_STACK_ALIGNMENT when SEH is enabled.  */
799
  gcc_assert (!stack_realign_drap);
800
 
801
  seh = XCNEW (struct seh_frame_state);
802
  cfun->machine->seh = seh;
803
 
804
  seh->sp_offset = INCOMING_FRAME_SP_OFFSET;
805
  seh->cfa_offset = INCOMING_FRAME_SP_OFFSET;
806
  seh->cfa_reg = stack_pointer_rtx;
807
 
808
  fputs ("\t.seh_proc\t", f);
809
  assemble_name (f, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (cfun->decl)));
810
  fputc ('\n', f);
811
}
812
 
813
void
814
i386_pe_seh_end_prologue (FILE *f)
815
{
816
  struct seh_frame_state *seh;
817
 
818
  if (!TARGET_SEH)
819
    return;
820
  if (cfun->is_thunk)
821
    return;
822
  seh = cfun->machine->seh;
823
 
824
  /* Emit an assembler directive to set up the frame pointer.  Always do
825
     this last.  The documentation talks about doing this "before" any
826
     other code that uses offsets, but (experimentally) that's after we
827
     emit the codes in reverse order (handled by the assembler).  */
828
  if (seh->cfa_reg != stack_pointer_rtx)
829
    {
830
      HOST_WIDE_INT offset = seh->sp_offset - seh->cfa_offset;
831
 
832
      gcc_assert ((offset & 15) == 0);
833
      gcc_assert (IN_RANGE (offset, 0, 240));
834
 
835
      fputs ("\t.seh_setframe\t", f);
836
      print_reg (seh->cfa_reg, 0, f);
837
      fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset);
838
    }
839
 
840
  XDELETE (seh);
841
  cfun->machine->seh = NULL;
842
 
843
  fputs ("\t.seh_endprologue\n", f);
844
}
845
 
846
static void
847
i386_pe_seh_fini (FILE *f)
848
{
849
  if (!TARGET_SEH)
850
    return;
851
  if (cfun->is_thunk)
852
    return;
853
  fputs ("\t.seh_endproc\n", f);
854
}
855
 
856
/* Emit an assembler directive to save REG via a PUSH.  */
857
 
858
static void
859
seh_emit_push (FILE *f, struct seh_frame_state *seh, rtx reg)
860
{
861
  unsigned int regno = REGNO (reg);
862
 
863
  gcc_checking_assert (GENERAL_REGNO_P (regno));
864
 
865
  seh->sp_offset += UNITS_PER_WORD;
866
  if (seh->cfa_reg == stack_pointer_rtx)
867
    seh->cfa_offset += UNITS_PER_WORD;
868
 
869
  fputs ("\t.seh_pushreg\t", f);
870
  print_reg (reg, 0, f);
871
  fputc ('\n', f);
872
}
873
 
874
/* Emit an assembler directive to save REG at CFA - CFA_OFFSET.  */
875
 
876
static void
877
seh_emit_save (FILE *f, struct seh_frame_state *seh,
878
               rtx reg, HOST_WIDE_INT cfa_offset)
879
{
880
  unsigned int regno = REGNO (reg);
881
  HOST_WIDE_INT offset;
882
 
883
  /* Negative save offsets are of course not supported, since that
884
     would be a store below the stack pointer and thus clobberable.  */
885
  gcc_assert (seh->sp_offset >= cfa_offset);
886
  offset = seh->sp_offset - cfa_offset;
887
 
888
  fputs ((SSE_REGNO_P (regno) ? "\t.seh_savexmm\t"
889
         : GENERAL_REGNO_P (regno) ?  "\t.seh_savereg\t"
890
         : (gcc_unreachable (), "")), f);
891
  print_reg (reg, 0, f);
892
  fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset);
893
}
894
 
895
/* Emit an assembler directive to adjust RSP by OFFSET.  */
896
 
897
static void
898
seh_emit_stackalloc (FILE *f, struct seh_frame_state *seh,
899
                     HOST_WIDE_INT offset)
900
{
901
  /* We're only concerned with prologue stack allocations, which all
902
     are subtractions from the stack pointer.  */
903
  gcc_assert (offset < 0);
904
  offset = -offset;
905
 
906
  if (seh->cfa_reg == stack_pointer_rtx)
907
    seh->cfa_offset += offset;
908
  seh->sp_offset += offset;
909
 
910
  fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset);
911
}
912
 
913
/* Process REG_CFA_ADJUST_CFA for SEH.  */
914
 
915
static void
916
seh_cfa_adjust_cfa (FILE *f, struct seh_frame_state *seh, rtx pat)
917
{
918
  rtx dest, src;
919
  HOST_WIDE_INT reg_offset = 0;
920
  unsigned int dest_regno;
921
 
922
  dest = SET_DEST (pat);
923
  src = SET_SRC (pat);
924
 
925
  if (GET_CODE (src) == PLUS)
926
    {
927
      reg_offset = INTVAL (XEXP (src, 1));
928
      src = XEXP (src, 0);
929
    }
930
  else if (GET_CODE (src) == MINUS)
931
    {
932
      reg_offset = -INTVAL (XEXP (src, 1));
933
      src = XEXP (src, 0);
934
    }
935
  gcc_assert (src == stack_pointer_rtx);
936
  gcc_assert (seh->cfa_reg == stack_pointer_rtx);
937
  dest_regno = REGNO (dest);
938
 
939
  if (dest_regno == STACK_POINTER_REGNUM)
940
    seh_emit_stackalloc (f, seh, reg_offset);
941
  else if (dest_regno == HARD_FRAME_POINTER_REGNUM)
942
    {
943
      seh->cfa_reg = dest;
944
      seh->cfa_offset -= reg_offset;
945
    }
946
  else
947
    gcc_unreachable ();
948
}
949
 
950
/* Process REG_CFA_OFFSET for SEH.  */
951
 
952
static void
953
seh_cfa_offset (FILE *f, struct seh_frame_state *seh, rtx pat)
954
{
955
  rtx dest, src;
956
  HOST_WIDE_INT reg_offset;
957
 
958
  dest = SET_DEST (pat);
959
  src = SET_SRC (pat);
960
 
961
  gcc_assert (MEM_P (dest));
962
  dest = XEXP (dest, 0);
963
  if (REG_P (dest))
964
    reg_offset = 0;
965
  else
966
    {
967
      gcc_assert (GET_CODE (dest) == PLUS);
968
      reg_offset = INTVAL (XEXP (dest, 1));
969
      dest = XEXP (dest, 0);
970
    }
971
  gcc_assert (dest == seh->cfa_reg);
972
 
973
  seh_emit_save (f, seh, src, seh->cfa_offset - reg_offset);
974
}
975
 
976
/* Process a FRAME_RELATED_EXPR for SEH.  */
977
 
978
static void
979
seh_frame_related_expr (FILE *f, struct seh_frame_state *seh, rtx pat)
980
{
981
  rtx dest, src;
982
  HOST_WIDE_INT addend;
983
 
984
  /* See the full loop in dwarf2out_frame_debug_expr.  */
985
  if (GET_CODE (pat) == PARALLEL || GET_CODE (pat) == SEQUENCE)
986
    {
987
      int i, n = XVECLEN (pat, 0), pass, npass;
988
 
989
      npass = (GET_CODE (pat) == PARALLEL ? 2 : 1);
990
      for (pass = 0; pass < npass; ++pass)
991
        for (i = 0; i < n; ++i)
992
          {
993
            rtx ele = XVECEXP (pat, 0, i);
994
 
995
            if (GET_CODE (ele) != SET)
996
              continue;
997
            dest = SET_DEST (ele);
998
 
999
            /* Process each member of the PARALLEL independently.  The first
1000
               member is always processed; others only if they are marked.  */
1001
            if (i == 0 || RTX_FRAME_RELATED_P (ele))
1002
              {
1003
                /* Evaluate all register saves in the first pass and all
1004
                   register updates in the second pass.  */
1005
                if ((MEM_P (dest) ^ pass) || npass == 1)
1006
                  seh_frame_related_expr (f, seh, ele);
1007
              }
1008
          }
1009
      return;
1010
    }
1011
 
1012
  dest = SET_DEST (pat);
1013
  src = SET_SRC (pat);
1014
 
1015
  switch (GET_CODE (dest))
1016
    {
1017
    case REG:
1018
      switch (GET_CODE (src))
1019
        {
1020
        case REG:
1021
          /* REG = REG: This should be establishing a frame pointer.  */
1022
          gcc_assert (src == stack_pointer_rtx);
1023
          gcc_assert (dest == hard_frame_pointer_rtx);
1024
          seh_cfa_adjust_cfa (f, seh, pat);
1025
          break;
1026
 
1027
        case PLUS:
1028
          addend = INTVAL (XEXP (src, 1));
1029
          src = XEXP (src, 0);
1030
          if (dest == hard_frame_pointer_rtx)
1031
            seh_cfa_adjust_cfa (f, seh, pat);
1032
          else if (dest == stack_pointer_rtx)
1033
            {
1034
              gcc_assert (src == stack_pointer_rtx);
1035
              seh_emit_stackalloc (f, seh, addend);
1036
            }
1037
          else
1038
            gcc_unreachable ();
1039
          break;
1040
 
1041
        default:
1042
          gcc_unreachable ();
1043
        }
1044
      break;
1045
 
1046
    case MEM:
1047
      /* A save of some kind.  */
1048
      dest = XEXP (dest, 0);
1049
      if (GET_CODE (dest) == PRE_DEC)
1050
        {
1051
          gcc_checking_assert (GET_MODE (src) == Pmode);
1052
          gcc_checking_assert (REG_P (src));
1053
          seh_emit_push (f, seh, src);
1054
        }
1055
      else
1056
        seh_cfa_offset (f, seh, pat);
1057
      break;
1058
 
1059
    default:
1060
      gcc_unreachable ();
1061
    }
1062
}
1063
 
1064
/* This function looks at a single insn and emits any SEH directives
1065
   required for unwind of this insn.  */
1066
 
1067
void
1068
i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx insn)
1069
{
1070
  rtx note, pat;
1071
  bool handled_one = false;
1072
  struct seh_frame_state *seh;
1073
 
1074
  if (!TARGET_SEH)
1075
    return;
1076
 
1077
  /* We free the SEH data once done with the prologue.  Ignore those
1078
     RTX_FRAME_RELATED_P insns that are associated with the epilogue.  */
1079
  seh = cfun->machine->seh;
1080
  if (seh == NULL)
1081
    return;
1082
 
1083
  if (NOTE_P (insn) || !RTX_FRAME_RELATED_P (insn))
1084
    return;
1085
 
1086
  for (note = REG_NOTES (insn); note ; note = XEXP (note, 1))
1087
    {
1088
      pat = XEXP (note, 0);
1089
      switch (REG_NOTE_KIND (note))
1090
        {
1091
        case REG_FRAME_RELATED_EXPR:
1092
          goto found;
1093
 
1094
        case REG_CFA_DEF_CFA:
1095
        case REG_CFA_EXPRESSION:
1096
          /* Only emitted with DRAP, which we disable.  */
1097
          gcc_unreachable ();
1098
          break;
1099
 
1100
        case REG_CFA_REGISTER:
1101
          /* Only emitted in epilogues, which we skip.  */
1102
          gcc_unreachable ();
1103
 
1104
        case REG_CFA_ADJUST_CFA:
1105
          if (pat == NULL)
1106
            {
1107
              pat = PATTERN (insn);
1108
              if (GET_CODE (pat) == PARALLEL)
1109
                pat = XVECEXP (pat, 0, 0);
1110
            }
1111
          seh_cfa_adjust_cfa (asm_out_file, seh, pat);
1112
          handled_one = true;
1113
          break;
1114
 
1115
        case REG_CFA_OFFSET:
1116
          if (pat == NULL)
1117
            pat = single_set (insn);
1118
          seh_cfa_offset (asm_out_file, seh, pat);
1119
          handled_one = true;
1120
          break;
1121
 
1122
        default:
1123
          break;
1124
        }
1125
    }
1126
  if (handled_one)
1127
    return;
1128
  pat = PATTERN (insn);
1129
 found:
1130
  seh_frame_related_expr (asm_out_file, seh, pat);
1131
}
1132
 
1133
void
1134
i386_pe_start_function (FILE *f, const char *name, tree decl)
1135
{
1136
  i386_pe_maybe_record_exported_symbol (decl, name, 0);
1137
  if (write_symbols != SDB_DEBUG)
1138
    i386_pe_declare_function_type (f, name, TREE_PUBLIC (decl));
1139
  /* In case section was altered by debugging output.  */
1140
  if (decl != NULL_TREE)
1141
    switch_to_section (function_section (decl));
1142
  ASM_OUTPUT_FUNCTION_LABEL (f, name, decl);
1143
}
1144
 
1145
void
1146
i386_pe_end_function (FILE *f, const char *name ATTRIBUTE_UNUSED,
1147
                      tree decl ATTRIBUTE_UNUSED)
1148
{
1149
  i386_pe_seh_fini (f);
1150
}
1151
 
1152
 
1153
#include "gt-winnt.h"

powered by: WebSVN 2.1.0

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