source: trunk/src/gcc/gcc/config/i386/emx.c@ 612

Last change on this file since 612 was 612, checked in by zap, 22 years ago

* empty log message *

  • Property cvs2svn:cvs-rev set to 1.16
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 12.4 KB
Line 
1/* emx.c: Functions for emx as target system.
2
3Original version by Eberhard Mattes, based on i386.c.
4Heavily modified by Andrew Zabolotny and Knut St. Osmundsen.
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
22
23#include "config.h"
24#include "system.h"
25#include "rtl.h"
26#include "regs.h"
27#include "hard-reg-set.h"
28#include "output.h"
29#include "tree.h"
30#include "toplev.h"
31#include "flags.h"
32
33/* Prototypes */
34static const char *gen_stdcall_suffix (tree);
35
36/* The size of the target's pointer type. */
37#ifndef PTR_SIZE
38#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
39#endif
40
41/** @todo remove debug code */
42#define BIRD_DEBUG
43#ifdef BIRD_DEBUG
44static const char *code(tree node)
45{
46 if (node)
47 {
48 switch (TREE_CODE (node))
49 {
50 case FUNCTION_TYPE: return "FUNCTION_TYPE";
51 case FUNCTION_DECL: return "FUNCTION_DECL";
52 case METHOD_TYPE: return "METHOD_TYPE";
53 case FIELD_DECL: return "FIELD_DECL";
54 case TYPE_DECL: return "TYPE_DECL";
55 case POINTER_TYPE: return "POINTER_TYPE";
56 case VOID_TYPE: return "VOID_TYPE";
57 case INTEGER_TYPE: return "INTEGER_TYPE";
58 case CHAR_TYPE: return "CHAR_TYPE";
59 case SET_TYPE: return "SET_TYPE";
60 case ARRAY_TYPE: return "ARRAY_TYPE";
61 case RECORD_TYPE: return "RECORD_TYPE";
62 case QUAL_UNION_TYPE: return "QUAL_UNION_TYPE";
63 case UNION_TYPE: return "UNION_TYPE";
64 default:
65 break;
66 }
67 }
68 return "";
69}
70
71static void dump (tree node);
72static void dump (tree node)
73{
74 tree type, type2, context, name;
75 if (!node)
76 return;
77
78 type = TREE_TYPE (node);
79 type2 = type ? TREE_TYPE(type) : NULL;
80 context = DECL_P (node) ? DECL_CONTEXT (node) : NULL_TREE;
81 name = DECL_P (node) ? DECL_NAME (node) : NULL_TREE;
82 fprintf(stderr, "dbg: node=%d %s type=%d %s type_type=%d %s context=%d %s name=%s\n",
83 TREE_CODE(node), code(node),
84 type ? (int)TREE_CODE(type) : -1, code(type),
85 type2 ? (int)TREE_CODE(type2) : -1, code(type2),
86 context ? (int)TREE_CODE(context) : -1, code(context),
87 name ? IDENTIFIER_POINTER (name) : "<none>");
88}
89
90#define dfprintf(a) fprintf a
91#define DUMP(node) dump(node)
92#else
93#define dfprintf(a) do {} while (0)
94#define DUMP(node) do {} while (0)
95#endif
96
97
98tree ix86_handle_vacpp_attribute (tree *node, tree name, tree args,
99 int flags, bool *no_add_attrs)
100{
101 tree id, type, context;
102 size_t sl;
103 const char *oldsym;
104 char *newsym;
105
106 DUMP (*node);
107
108 switch (TREE_CODE (*node))
109 {
110 case FUNCTION_DECL:
111 /* This is the core of attribute handling. Every other code is
112 designed so that we end up with a function declaration and
113 an attached attribute (either optlink or system).
114 This is the only part which is changing the mangling. */
115 if (is_attribute_p ("system", name))
116 {
117 /* Here we mangle _System functions as defined by IBM specs.
118 The function always gets its name as-is (unless it is a method,
119 which is a undefined case as VACPP always use _Optlink for methods,
120 at least that's what I have understood from the docs). */
121 /* @todo: verify the class detection here! Does it require use of
122 CLASSTYPE_DECLARED_CLASS (meaning it doesn't apply to plain
123 structs/unions) ? */
124 if ( TREE_CODE (TREE_TYPE (*node)) != METHOD_TYPE
125 && ( !(context = DECL_CONTEXT (*node))
126 || ( TREE_CODE (context) != RECORD_TYPE
127 && TREE_CODE (context) != UNION_TYPE)))
128 {
129 oldsym = IDENTIFIER_POINTER (DECL_NAME (*node));
130 /* Specifying '*' as first symbol character tells gcc (see varasm.c,
131 function assemble_name()) to output the label as-is rather than
132 invoking the ASM_OUTPUT_LABELREF macro (which prepends a underscore) */
133 sl = strlen (oldsym);
134 newsym = xmalloc (sl + 2);
135 newsym [0] = '*';
136 memcpy (newsym + 1, oldsym, sl + 1);
137 SET_DECL_ASSEMBLER_NAME (*node, get_identifier (newsym));
138 dfprintf((stderr, "dbg: system %s -> %s\n", oldsym, newsym));
139 }
140 }
141 else if (is_attribute_p ("optlink", name))
142 {
143 /* At the moment we're only implementing OS/2 VAC linking
144 compatibility for the C language. This means that no leading
145 underscore.
146 For C++ we are not compatible. It doesn't make that much sense
147 either since we're not VFT compatible either. For simplicity
148 and safety we are removing the leading underscore from the
149 default mangled names to catch invalid declarations in the
150 linking. */
151
152 id = DECL_ASSEMBLER_NAME (*node);
153 /* Remove the leading underscore. */
154 oldsym = IDENTIFIER_POINTER (id);
155 sl = strlen (oldsym);
156 newsym = xmalloc (sl + 2);
157 newsym [0] = '*';
158 memcpy (newsym + 1, oldsym, sl + 1);
159 XEXP (DECL_RTL (*node), 0) = gen_rtx (SYMBOL_REF, Pmode,
160 IDENTIFIER_POINTER (get_identifier (newsym)));
161 dfprintf ((stderr, "dbg: optlink %s -> %s\n", oldsym, newsym));
162 }
163 else /* Internal error!!! */
164 {
165 warning ("unexpected attribute `%s' in ix86_handle_vacpp_attribute()",
166 IDENTIFIER_POINTER (name));
167 *no_add_attrs = true;
168 break;
169 }
170
171 /* The attribute should really be attached to our _TYPE
172 rather than to the _DECL. */
173 type = TREE_TYPE (*node);
174 TYPE_ATTRIBUTES (type) = chainon (TYPE_ATTRIBUTES (type),
175 tree_cons (name, args, NULL_TREE));
176 *no_add_attrs = true;
177 break;
178
179 /* Only function declarations needs mangling changes, however other
180 declarations involving function types needs to get the parameter
181 passing right. */
182 case FIELD_DECL:
183 /* Struct, union or class member declaration. Same handling as
184 type declarations. */
185 case TYPE_DECL:
186 /* If this is a type declaration with our attribute, we allow it
187 only if it is a pointer-to-a-function type or a function type. */
188 type = TREE_TYPE (*node);
189 if (TREE_CODE (type) == POINTER_TYPE)
190 type = TREE_TYPE(type);
191 if ( TREE_CODE (type) == FUNCTION_TYPE
192 || TREE_CODE (type) == METHOD_TYPE)
193 {
194 /* Attach the attribute to the (FUNCTION|METHOD)_TYPE node */
195 TYPE_ATTRIBUTES (type) = chainon (TYPE_ATTRIBUTES (type),
196 tree_cons (name, args, NULL_TREE));
197 *no_add_attrs = true;
198 break;
199 }
200 warning ("`%s' attribute only applies to functions and function types (typecode=%d)",
201 IDENTIFIER_POINTER (name), type ? (int)TREE_CODE (type) : -1);
202 *no_add_attrs = true;
203 break;
204
205
206 /* For types involving functions we need to convince decl_attributes
207 (and its callers) to supply a declaration in case the mangling needs
208 to be changed. */
209 case POINTER_TYPE:
210 /* We allow:
211 This being the return type of a function which is coming soon.
212 This being a function pointer which declaration is coming next.
213 Everything else is considered inappropriate use of the attribute. */
214 if ( !(flags & ATTR_FLAG_FUNCTION_NEXT)
215 && ( !(flags & ATTR_FLAG_DECL_NEXT)
216 || !(type = TREE_TYPE (*node))
217 || ( TREE_CODE (type) != FUNCTION_TYPE
218 && TREE_CODE (type) != METHOD_TYPE)))
219 {
220 warning ("`%s' attribute only applies to functions and function types",
221 IDENTIFIER_POINTER (name));
222 *no_add_attrs = true;
223 break;
224 }
225 /* fall thru */
226 case FUNCTION_TYPE:
227 case METHOD_TYPE:
228 /* This branch is taken when a function/method type is encountered.
229 We defer attribute handling until we get the complete declaration */
230 *no_add_attrs = true;
231 return tree_cons (name, args, NULL_TREE);
232
233 default:
234 warning ("`%s' attribute only applies to functions and function types (code=%d)",
235 IDENTIFIER_POINTER (name), TREE_CODE (*node));
236 *no_add_attrs = true;
237 break;
238 }
239
240 return NULL_TREE;
241}