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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [i386/] [netware.c] - Blame information for rev 298

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

Line No. Rev Author Line
1 282 jeremybenn
/* Subroutines for insn-output.c for NetWare.
2
   Contributed by Jan Beulich (jbeulich@novell.com)
3
   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3, or (at your option)
10
any later version.
11
 
12
GCC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
#include "config.h"
22
#include "system.h"
23
#include "coretypes.h"
24
#include "tm.h"
25
#include "rtl.h"
26
#include "regs.h"
27
#include "hard-reg-set.h"
28
#include "output.h"
29
#include "tree.h"
30
#include "flags.h"
31
#include "tm_p.h"
32
#include "toplev.h"
33
#include "langhooks.h"
34
#include "ggc.h"
35
 
36
/* Return string which is the function name, identified by ID, modified
37
   with PREFIX and a suffix consisting of an atsign (@) followed by the
38
   number of bytes of arguments.  If ID is NULL use the DECL_NAME as base.
39
   Return NULL if no change required.  */
40
 
41
static tree
42
gen_stdcall_or_fastcall_decoration (tree decl, tree id, char prefix)
43
{
44
  unsigned HOST_WIDE_INT total = 0;
45
  const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
46
  char *new_str;
47
  tree type = TREE_TYPE (decl);
48
 
49
  if (prototype_p (type))
50
    {
51
      tree arg;
52
      function_args_iterator args_iter;
53
 
54
      /* This attribute is ignored for variadic functions.  */
55
      if (stdarg_p (type))
56
        return NULL_TREE;
57
 
58
      /* Quit if we hit an incomplete type.  Error is reported
59
         by convert_arguments in c-typeck.c or cp/typeck.c.  */
60
      FOREACH_FUNCTION_ARGS(type, arg, args_iter)
61
        {
62
          HOST_WIDE_INT parm_size;
63
          unsigned HOST_WIDE_INT parm_boundary_bytes;
64
 
65
          if (! COMPLETE_TYPE_P (arg))
66
            break;
67
 
68
          parm_size = int_size_in_bytes (arg);
69
          if (parm_size < 0)
70
            break;
71
 
72
          parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
73
 
74
          /* Must round up to include padding.  This is done the same
75
             way as in store_one_arg.  */
76
          total += (parm_size + parm_boundary_bytes - 1)
77
                   / parm_boundary_bytes * parm_boundary_bytes;
78
        }
79
    }
80
 
81
  new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 10 + 1);
82
  sprintf (new_str, "%c%s@" HOST_WIDE_INT_PRINT_UNSIGNED,
83
           prefix, old_str, total);
84
 
85
  return get_identifier (new_str);
86
}
87
 
88
/* Return string which is the function name, identified by ID, modified
89
   with an _n@ prefix (where n represents the number of arguments passed in
90
   registers).  If ID is NULL use the DECL_NAME as base.
91
   Return NULL if no change required.  */
92
 
93
static tree
94
gen_regparm_prefix (tree decl, tree id, unsigned int nregs)
95
{
96
  unsigned HOST_WIDE_INT total = 0;
97
  const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
98
  char *new_str;
99
  tree type = TREE_TYPE (decl);
100
 
101
  if (prototype_p (type))
102
    {
103
      tree arg;
104
      function_args_iterator args_iter;
105
 
106
      /* This attribute is ignored for variadic functions.  */
107
      if (stdarg_p (type))
108
        return NULL_TREE;
109
 
110
      /* Quit if we hit an incomplete type.  Error is reported
111
         by convert_arguments in c-typeck.c or cp/typeck.c.  */
112
      FOREACH_FUNCTION_ARGS(type, arg, args_iter)
113
        {
114
          HOST_WIDE_INT parm_size;
115
          unsigned HOST_WIDE_INT parm_boundary_bytes;
116
 
117
          if (! COMPLETE_TYPE_P (arg))
118
            break;
119
 
120
          parm_size = int_size_in_bytes (arg);
121
          if (parm_size < 0)
122
            break;
123
 
124
          parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
125
 
126
          /* Must round up to include padding.  This is done the same
127
             way as in store_one_arg.  */
128
          total += (parm_size + parm_boundary_bytes - 1)
129
                   / parm_boundary_bytes * parm_boundary_bytes;
130
        }
131
    }
132
 
133
  if (nregs > total / UNITS_PER_WORD)
134
    nregs = total / UNITS_PER_WORD;
135
  gcc_assert (nregs <= 9);
136
  new_str = XALLOCAVEC (char, 3 + strlen (old_str) + 1);
137
  sprintf (new_str, "_%u@%s", nregs, old_str);
138
 
139
  return get_identifier (new_str);
140
}
141
 
142
/* Maybe decorate and get a new identifier for the DECL of a stdcall or
143
   fastcall function. The original identifier is supplied in ID. */
144
 
145
static tree
146
i386_nlm_maybe_mangle_decl_assembler_name (tree decl, tree id)
147
{
148
  tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
149
  tree new_id;
150
 
151
  if (lookup_attribute ("stdcall", type_attributes))
152
    new_id = gen_stdcall_or_fastcall_decoration (decl, id, '_');
153
  else if (lookup_attribute ("fastcall", type_attributes))
154
    new_id = gen_stdcall_or_fastcall_decoration (decl, id, FASTCALL_PREFIX);
155
  else if ((new_id = lookup_attribute ("regparm", type_attributes)))
156
    new_id = gen_regparm_prefix (decl, id,
157
                  TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (new_id))));
158
  else
159
    new_id = NULL_TREE;
160
 
161
  return new_id;
162
}
163
 
164
/* This is used as a target hook to modify the DECL_ASSEMBLER_NAME
165
   in the language-independent default hook
166
   langhooks.c:lhd_set_decl_assembler_name ()
167
   and in cp/mangle.c:mangle_decl ().  */
168
tree
169
i386_nlm_mangle_decl_assembler_name (tree decl, tree id)
170
{
171
  tree new_id = TREE_CODE (decl) == FUNCTION_DECL
172
                ? i386_nlm_maybe_mangle_decl_assembler_name (decl, id)
173
                : NULL_TREE;
174
 
175
  return (new_id ? new_id : id);
176
}
177
 
178
void
179
i386_nlm_encode_section_info (tree decl, rtx rtl, int first)
180
{
181
  default_encode_section_info (decl, rtl, first);
182
 
183
  if (TREE_CODE (decl) == FUNCTION_DECL
184
      /* Do not change the identifier if a verbatim asmspec
185
         or if stdcall suffix already added.  */
186
      && *IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) != '*'
187
      && !strchr (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), '@')
188
      /* FIXME:  Imported stdcall names are not modified by the Ada frontend.
189
         Check and decorate the RTL name now.  */
190
      && strcmp (lang_hooks.name, "GNU Ada") == 0)
191
    {
192
      rtx symbol = XEXP (rtl, 0);
193
      tree new_id;
194
      tree old_id = DECL_ASSEMBLER_NAME (decl);
195
 
196
      gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
197
 
198
      if ((new_id = i386_nlm_maybe_mangle_decl_assembler_name (decl, old_id)))
199
        XSTR (symbol, 0) = IDENTIFIER_POINTER (new_id);
200
    }
201
}
202
 
203
/* Strip the stdcall/fastcall/regparm pre-/suffix.  */
204
 
205
const char *
206
i386_nlm_strip_name_encoding (const char *str)
207
{
208
  const char *name = default_strip_name_encoding (str);
209
 
210
  if (*str != '*' && (*name == '_' || *name == '@'))
211
    {
212
      const char *p = strchr (name + 1, '@');
213
 
214
      if (p)
215
        {
216
          ++name;
217
          if (ISDIGIT (p[1]))
218
            name = ggc_alloc_string (name, p - name);
219
          else
220
            {
221
              gcc_assert (ISDIGIT (*name));
222
              name++;
223
              gcc_assert (name == p);
224
            }
225
        }
226
    }
227
  return name;
228
}

powered by: WebSVN 2.1.0

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