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

Last change on this file since 9 was 9, checked in by bird, 23 years ago

Applied initial diff from Platon.

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 6.2 KB
Line 
1/* emx.c: Functions for emx as target system.
2
3Written by Eberhard Mattes, based on i386.c.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22#include "config.h"
23#include "system.h"
24#include "rtl.h"
25#include "regs.h"
26#include "hard-reg-set.h"
27#include "output.h"
28#include "tree.h"
29#include "toplev.h"
30#include "flags.h"
31
32/* The size of the target's pointer type. */
33#ifndef PTR_SIZE
34#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
35#endif
36
37extern int ix86_return_pops_args (tree fundecl, tree funtype, int size);
38
39tree ix86_handle_optlink_attribute (tree *node, tree name, tree args,
40 int flags, bool *no_add_attrs)
41{
42 (void)args; (void)flags;
43 if (TREE_CODE (*node) != FUNCTION_TYPE
44 && TREE_CODE (*node) != METHOD_TYPE
45 && TREE_CODE (*node) != FIELD_DECL
46 && TREE_CODE (*node) != TYPE_DECL)
47 {
48 warning ("`%s' attribute only applies to functions",
49 IDENTIFIER_POINTER (name));
50 *no_add_attrs = true;
51 }
52
53 return NULL_TREE;
54}
55
56/* Value is the number of bytes of arguments automatically
57 popped when returning from a subroutine call.
58 FUNDECL is the declaration node of the function (as a tree),
59 FUNTYPE is the data type of the function (as a tree),
60 or for a library call it is an identifier node for the subroutine name.
61 SIZE is the number of bytes of arguments passed on the stack.
62
63 On the 80386, the RTD insn may be used to pop them if the number
64 of args is fixed, but if the number is variable then the caller
65 must pop them all. RTD can't be used for library calls now
66 because the library is compiled with the Unix compiler.
67 Use of RTD is a selectable option, since it is incompatible with
68 standard Unix calling sequences. If the option is not selected,
69 the caller must always pop the args.
70
71 The attribute stdcall is equivalent to RTD on a per module basis. */
72
73int
74emx_return_pops_args (fundecl, funtype, size)
75 tree fundecl;
76 tree funtype;
77 int size;
78{
79 return ix86_return_pops_args (fundecl, funtype, size);
80#if 0
81 int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);
82
83 /* Cdecl functions override -mrtd, and never pop the stack */
84 if (!lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))
85 && !lookup_attribute ("system", TYPE_ATTRIBUTES (funtype)))
86 {
87 /* Stdcall functions will pop the stack if not variable args */
88 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
89 rtd = 1;
90
91 /* `optlink' functions taking a variable number of arguments
92 should also pop the stack, but that's not implemented.
93 We treat `optlink' functions taking a variable number of
94 arguments like `system' functions. */
95 if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (funtype)))
96 rtd = 1;
97
98 if (rtd
99 && (TYPE_ARG_TYPES (funtype) == NULL_TREE
100 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node)))
101 return size;
102 }
103
104 /* Lose any fake structure return argument */
105 /* @@@ This makes the generated code incompatible with that generated
106 * by 2.7.2. I think this belongs in the if (rtd) ... case. Any ideas? */
107 if (aggregate_value_p (TREE_TYPE (funtype)))
108 return GET_MODE_SIZE (Pmode);
109
110 return 0;
111#endif
112}
113
114void
115emx_eh_frame_section ()
116{
117/*
118 tree label = get_file_function_name ('F');
119*/
120 data_section ();
121 ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
122 fprintf (asm_out_file, "\t.stabs\t\"___eh_frame__\",24,0,0,Lframe1\n");
123}
124
125/* Add a __POST$xxx label before epilogue if -mepilogue specified */
126void emx_output_function_begin_epilogue (FILE *f)
127{
128 if (TARGET_EPILOGUE && TREE_PUBLIC (current_function_decl))
129 {
130 const char *func_label = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
131 char *lbl = alloca (strlen (func_label) + 8);
132 strcpy (lbl, "__POST$");
133 strcat (lbl, func_label);
134 ASM_OUTPUT_LABEL (f, lbl);
135 }
136}
137
138/* Return string which is the former assembler name modified with a
139 suffix consisting of an atsign (@) followed by the number of bytes of
140 arguments */
141
142const char *
143gen_stdcall_suffix (decl)
144 tree decl;
145{
146 int total = 0;
147 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
148 of DECL_ASSEMBLER_NAME. */
149 const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
150 char *newsym;
151
152 if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
153 if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
154 == void_type_node)
155 {
156 tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
157
158 while (TREE_VALUE (formal_type) != void_type_node)
159 {
160 int parm_size
161 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
162 /* Must round up to include padding. This is done the same
163 way as in store_one_arg. */
164 parm_size = ((parm_size + PARM_BOUNDARY - 1)
165 / PARM_BOUNDARY * PARM_BOUNDARY);
166 total += parm_size;
167 formal_type = TREE_CHAIN (formal_type);
168 }
169 }
170
171 newsym = xmalloc (strlen (asmname) + 10);
172 sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
173 return IDENTIFIER_POINTER (get_identifier (newsym));
174}
175
176/* Cover function to implement ENCODE_SECTION_INFO. */
177
178void
179emx_encode_section_info (tree decl)
180{
181 /* This bit is copied from i386.h. */
182 if (optimize > 0 && TREE_CONSTANT (decl)
183 && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
184 {
185 rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
186 ? TREE_CST_RTL (decl) : DECL_RTL (decl));
187 SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
188 }
189
190 if (TREE_CODE (decl) == FUNCTION_DECL)
191 if (lookup_attribute ("stdcall",
192 TYPE_ATTRIBUTES (TREE_TYPE (decl))))
193 XEXP (DECL_RTL (decl), 0) =
194 gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
195}
Note: See TracBrowser for help on using the repository browser.