Remove outermost loop parameter.
[official-gcc/graphite-test-results.git] / gcc / config / i386 / netware.c
blobfa9ffbbeac13853538e9cdc94636109df4c7f0f8
1 /* 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.
5 This file is part of GCC.
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.
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.
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/>. */
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"
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. */
41 static tree
42 gen_stdcall_or_fastcall_decoration (tree decl, tree id, char prefix)
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);
49 if (prototype_p (type))
51 tree arg;
52 function_args_iterator args_iter;
54 /* This attribute is ignored for variadic functions. */
55 if (stdarg_p (type))
56 return NULL_TREE;
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)
62 HOST_WIDE_INT parm_size;
63 unsigned HOST_WIDE_INT parm_boundary_bytes;
65 if (! COMPLETE_TYPE_P (arg))
66 break;
68 parm_size = int_size_in_bytes (arg);
69 if (parm_size < 0)
70 break;
72 parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
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;
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);
85 return get_identifier (new_str);
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. */
93 static tree
94 gen_regparm_prefix (tree decl, tree id, unsigned int nregs)
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);
101 if (prototype_p (type))
103 tree arg;
104 function_args_iterator args_iter;
106 /* This attribute is ignored for variadic functions. */
107 if (stdarg_p (type))
108 return NULL_TREE;
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)
114 HOST_WIDE_INT parm_size;
115 unsigned HOST_WIDE_INT parm_boundary_bytes;
117 if (! COMPLETE_TYPE_P (arg))
118 break;
120 parm_size = int_size_in_bytes (arg);
121 if (parm_size < 0)
122 break;
124 parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
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;
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);
139 return get_identifier (new_str);
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. */
145 static tree
146 i386_nlm_maybe_mangle_decl_assembler_name (tree decl, tree id)
148 tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
149 tree new_id;
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;
161 return new_id;
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)
171 tree new_id = TREE_CODE (decl) == FUNCTION_DECL
172 ? i386_nlm_maybe_mangle_decl_assembler_name (decl, id)
173 : NULL_TREE;
175 return (new_id ? new_id : id);
178 void
179 i386_nlm_encode_section_info (tree decl, rtx rtl, int first)
181 default_encode_section_info (decl, rtl, first);
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)
192 rtx symbol = XEXP (rtl, 0);
193 tree new_id;
194 tree old_id = DECL_ASSEMBLER_NAME (decl);
196 gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
198 if ((new_id = i386_nlm_maybe_mangle_decl_assembler_name (decl, old_id)))
199 XSTR (symbol, 0) = IDENTIFIER_POINTER (new_id);
203 /* Strip the stdcall/fastcall/regparm pre-/suffix. */
205 const char *
206 i386_nlm_strip_name_encoding (const char *str)
208 const char *name = default_strip_name_encoding (str);
210 if (*str != '*' && (*name == '_' || *name == '@'))
212 const char *p = strchr (name + 1, '@');
214 if (p)
216 ++name;
217 if (ISDIGIT (p[1]))
218 name = ggc_alloc_string (name, p - name);
219 else
221 gcc_assert (ISDIGIT (*name));
222 name++;
223 gcc_assert (name == p);
227 return name;