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

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

See changelog.

  • Property cvs2svn:cvs-rev set to 1.6
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 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/* The size of the target's pointer type. */
34#ifndef PTR_SIZE
35#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
36#endif
37
38static void (*old_lang_set_decl_assembler_name) (tree decl);
39
40static void emx_lang_set_decl_assembler_name (tree decl)
41{
42 tree id;
43
44 if (lookup_attribute ("optlink", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
45 {
46 size_t sl;
47 const char *oldsym;
48 char *newsym;
49
50 old_lang_set_decl_assembler_name (decl);
51 id = DECL_ASSEMBLER_NAME (decl);
52 /* Remove the leading underscore */
53remove_underscore:
54 oldsym = IDENTIFIER_POINTER (id);
55 sl = strlen (oldsym) + 2;
56 newsym = xmalloc (sl);
57 /* Specifying '*' as first symbol character tells gcc (see varasm.c,
58 function assemble_name()) to output the label as-is rather than
59 invoking the ASM_OUTPUT_LABELREF macro (which prepends a underscore) */
60 newsym [0] = '*';
61 memcpy (newsym + 1, oldsym, sl + 1);
62 XEXP (DECL_RTL (decl), 0) = gen_rtx (SYMBOL_REF, Pmode,
63 IDENTIFIER_POINTER (get_identifier (newsym)));
64 }
65 else if (lookup_attribute ("system", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
66 {
67 id = get_identifier (IDENTIFIER_POINTER (DECL_NAME (decl)));
68 SET_DECL_ASSEMBLER_NAME (decl, id);
69 goto remove_underscore;
70 }
71 else
72 old_lang_set_decl_assembler_name (decl);
73}
74
75/* The first time we encounter a _Optlink or _System function we hook the
76 * lang_set_decl_assembler_name function so that instead of calling the
77 * original mangler function our function gets called. Then, if the function
78 * attribute is _System or _Optlink we mangle it according to respective
79 * rules (_System functions always get the name as-is (e.g. no underscore,
80 * no C++ mangling) and _Optlink don't get the leading underscore.
81 */
82static void hook_mangler (void)
83{
84 if (lang_set_decl_assembler_name != emx_lang_set_decl_assembler_name)
85 {
86 old_lang_set_decl_assembler_name = lang_set_decl_assembler_name;
87 lang_set_decl_assembler_name = emx_lang_set_decl_assembler_name;
88 }
89}
90
91tree ix86_handle_system_attribute (tree *node, tree name, tree args,
92 int flags, bool *no_add_attrs)
93{
94 (void)args; (void)flags;
95 if (TREE_CODE (*node) != FUNCTION_TYPE
96 && TREE_CODE (*node) != METHOD_TYPE
97 && TREE_CODE (*node) != FIELD_DECL
98 && TREE_CODE (*node) != TYPE_DECL)
99 {
100 warning ("`%s' attribute only applies to functions",
101 IDENTIFIER_POINTER (name));
102 *no_add_attrs = true;
103 }
104
105 hook_mangler ();
106
107 return NULL_TREE;
108}
109
110tree ix86_handle_optlink_attribute (tree *node, tree name, tree args,
111 int flags, bool *no_add_attrs)
112{
113 (void)args; (void)flags;
114 if (TREE_CODE (*node) != FUNCTION_TYPE
115 && TREE_CODE (*node) != METHOD_TYPE
116 && TREE_CODE (*node) != FIELD_DECL
117 && TREE_CODE (*node) != TYPE_DECL)
118 {
119 warning ("`%s' attribute only applies to functions",
120 IDENTIFIER_POINTER (name));
121 *no_add_attrs = true;
122 }
123
124 hook_mangler ();
125
126 return NULL_TREE;
127}
128
129void
130emx_eh_frame_section ()
131{
132/*
133 tree label = get_file_function_name ('F');
134 The __ehInit undefined external here is to drag __ehInit/__ehInitDLL into
135 the linking so DLLs are initiated correctly. (#577)
136*/
137 data_section ();
138 ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
139 fprintf (asm_out_file,
140 "\t.stabs\t\"___eh_frame__\",24,0,0,Lframe1\n" /* N_SETD */
141 "\t.stabs\t\"___ehInit\",1,0,0,0\n"); /* N_UNDEF | N_EXT */
142}
143
144/* Add a __POST$xxx label before epilogue if -mepilogue specified */
145void emx_output_function_begin_epilogue (FILE *f)
146{
147 if (TARGET_EPILOGUE && TREE_PUBLIC (current_function_decl))
148 {
149 const char *func_label = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
150 char *lbl = alloca (strlen (func_label) + 8);
151 strcpy (lbl, "__POST$");
152 strcat (lbl, func_label);
153 ASM_OUTPUT_LABEL (f, lbl);
154 }
155}
156
157/* Return string which is the former assembler name modified with a
158 suffix consisting of an atsign (@) followed by the number of bytes of
159 arguments */
160
161const char *
162gen_stdcall_suffix (tree decl)
163{
164 int total = 0;
165 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
166 of DECL_ASSEMBLER_NAME. */
167 const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
168 char *newsym;
169
170 if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
171 if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
172 == void_type_node)
173 {
174 tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
175
176 while (TREE_VALUE (formal_type) != void_type_node)
177 {
178 int parm_size
179 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
180 /* Must round up to include padding. This is done the same
181 way as in store_one_arg. */
182 parm_size = ((parm_size + PARM_BOUNDARY - 1)
183 / PARM_BOUNDARY * PARM_BOUNDARY);
184 total += parm_size;
185 formal_type = TREE_CHAIN (formal_type);
186 }
187 }
188
189 newsym = xmalloc (strlen (asmname) + 10);
190 sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
191 return IDENTIFIER_POINTER (get_identifier (newsym));
192}
193
194/* Cover function to implement ENCODE_SECTION_INFO.
195 Note that this could be implemented much better by doing the
196 stdcall mangling like optlink and system, but unfortunately */
197
198void
199emx_encode_section_info (tree decl)
200{
201 /* The default ENCODE_SECTION_INFO from i386.h */
202 if (flag_pic)
203 {
204 rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
205 ? TREE_CST_RTL (decl) : DECL_RTL (decl));
206
207 if (GET_CODE (rtl) == MEM)
208 {
209 if (TARGET_DEBUG_ADDR
210 && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
211 {
212 fprintf (stderr, "Encode %s, public = %d\n",
213 IDENTIFIER_POINTER (DECL_NAME (decl)),
214 TREE_PUBLIC (decl));
215 }
216
217 SYMBOL_REF_FLAG (XEXP (rtl, 0))
218 = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
219 || ! TREE_PUBLIC (decl));
220 }
221 }
222
223 /* If declaring a function, mangle it if it's stdcall */
224 if (TREE_CODE (decl) == FUNCTION_DECL)
225 {
226 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
227 XEXP (DECL_RTL (decl), 0) =
228 gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
229 }
230}
Note: See TracBrowser for help on using the repository browser.