1 /* Subroutines for insn-output.c for NetWare.
2 Contributed by Jan Beulich (jbeulich@novell.com)
3 Copyright (C) 2004, 2005, 2007 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)
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/>. */
23 #include "coretypes.h"
27 #include "hard-reg-set.h"
36 /* Return string which is the former assembler name modified with an
37 underscore prefix and a suffix consisting of an atsign (@) followed
38 by the number of bytes of arguments */
41 gen_stdcall_or_fastcall_decoration (tree decl, char prefix)
44 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
45 of DECL_ASSEMBLER_NAME. */
46 const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
48 tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
50 if (formal_type != NULL_TREE)
52 /* These attributes are ignored for variadic functions in
53 i386.c:ix86_return_pops_args. For compatibility with MS
54 compiler do not add @0 suffix here. */
55 if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
58 /* Quit if we hit an incomplete type. Error is reported
59 by convert_arguments in c-typeck.c or cp/typeck.c. */
60 while (TREE_VALUE (formal_type) != void_type_node
61 && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
64 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
66 /* Must round up to include padding. This is done the same
67 way as in store_one_arg. */
68 parm_size = ((parm_size + PARM_BOUNDARY - 1)
69 / PARM_BOUNDARY * PARM_BOUNDARY);
71 formal_type = TREE_CHAIN (formal_type);
75 newsym = alloca (1 + strlen (asmname) + 1 + 10 + 1);
76 return get_identifier_with_length (newsym,
81 total / BITS_PER_UNIT));
84 /* Return string which is the former assembler name modified with an
85 _n@ prefix where n represents the number of arguments passed in
89 gen_regparm_prefix (tree decl, unsigned nregs)
92 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
93 of DECL_ASSEMBLER_NAME. */
94 const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
96 tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
98 if (formal_type != NULL_TREE)
100 /* This attribute is ignored for variadic functions. */
101 if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
104 /* Quit if we hit an incomplete type. Error is reported
105 by convert_arguments in c-typeck.c or cp/typeck.c. */
106 while (TREE_VALUE (formal_type) != void_type_node
107 && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
110 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
112 /* Must round up to include padding. This is done the same
113 way as in store_one_arg. */
114 parm_size = ((parm_size + PARM_BOUNDARY - 1)
115 / PARM_BOUNDARY * PARM_BOUNDARY);
117 formal_type = TREE_CHAIN (formal_type);
121 if (nregs > total / BITS_PER_WORD)
122 nregs = total / BITS_PER_WORD;
123 gcc_assert (nregs <= 9);
124 newsym = alloca (3 + strlen (asmname) + 1);
125 return get_identifier_with_length (newsym,
133 i386_nlm_encode_section_info (tree decl, rtx rtl, int first)
135 default_encode_section_info (decl, rtl, first);
138 && TREE_CODE (decl) == FUNCTION_DECL
139 && *IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) != '*'
140 && !strchr (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), '@'))
142 tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
145 if (lookup_attribute ("stdcall", type_attributes))
146 newid = gen_stdcall_or_fastcall_decoration (decl, '_');
147 else if (lookup_attribute ("fastcall", type_attributes))
148 newid = gen_stdcall_or_fastcall_decoration (decl, FASTCALL_PREFIX);
149 else if ((newid = lookup_attribute ("regparm", type_attributes)) != NULL_TREE)
150 newid = gen_regparm_prefix (decl,
151 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (newid))));
152 if (newid != NULL_TREE)
154 rtx rtlname = XEXP (rtl, 0);
156 if (GET_CODE (rtlname) == MEM)
157 rtlname = XEXP (rtlname, 0);
158 XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
159 /* These attributes must be present on first declaration,
160 change_decl_assembler_name will warn if they are added
161 later and the decl has been referenced, but duplicate_decls
162 should catch the mismatch before this is called. */
163 change_decl_assembler_name (decl, newid);
168 /* Strip the stdcall/fastcall/regparm pre-/suffix. */
171 i386_nlm_strip_name_encoding (const char *str)
173 const char *name = default_strip_name_encoding (str);
175 if (*str != '*' && (*name == '_' || *name == '@'))
177 const char *p = strchr (name + 1, '@');
183 name = ggc_alloc_string (name, p - name);
186 gcc_assert (ISDIGIT (*name));
188 gcc_assert (name == p);