1 /* Subroutines for insn-output.c for NetWare.
2 Contributed by Jan Beulich (jbeulich@novell.com)
3 Copyright (C) 2004, 2005 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 2, 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 COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
24 #include "coretypes.h"
28 #include "hard-reg-set.h"
37 /* Return string which is the former assembler name modified with an
38 underscore prefix and a suffix consisting of an atsign (@) followed
39 by the number of bytes of arguments */
42 gen_stdcall_or_fastcall_decoration (tree decl
, char prefix
)
45 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
46 of DECL_ASSEMBLER_NAME. */
47 const char *asmname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
49 tree formal_type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
51 if (formal_type
!= NULL_TREE
)
53 /* These attributes are ignored for variadic functions in
54 i386.c:ix86_return_pops_args. For compatibility with MS
55 compiler do not add @0 suffix here. */
56 if (TREE_VALUE (tree_last (formal_type
)) != void_type_node
)
59 /* Quit if we hit an incomplete type. Error is reported
60 by convert_arguments in c-typeck.c or cp/typeck.c. */
61 while (TREE_VALUE (formal_type
) != void_type_node
62 && COMPLETE_TYPE_P (TREE_VALUE (formal_type
)))
65 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type
)));
67 /* Must round up to include padding. This is done the same
68 way as in store_one_arg. */
69 parm_size
= ((parm_size
+ PARM_BOUNDARY
- 1)
70 / PARM_BOUNDARY
* PARM_BOUNDARY
);
72 formal_type
= TREE_CHAIN (formal_type
);
76 newsym
= alloca (1 + strlen (asmname
) + 1 + 10 + 1);
77 return get_identifier_with_length (newsym
,
82 total
/ BITS_PER_UNIT
));
85 /* Return string which is the former assembler name modified with an
86 _n@ prefix where n represents the number of arguments passed in
90 gen_regparm_prefix (tree decl
, unsigned nregs
)
93 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
94 of DECL_ASSEMBLER_NAME. */
95 const char *asmname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
97 tree formal_type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
99 if (formal_type
!= NULL_TREE
)
101 /* This attribute is ignored for variadic functions. */
102 if (TREE_VALUE (tree_last (formal_type
)) != void_type_node
)
105 /* Quit if we hit an incomplete type. Error is reported
106 by convert_arguments in c-typeck.c or cp/typeck.c. */
107 while (TREE_VALUE (formal_type
) != void_type_node
108 && COMPLETE_TYPE_P (TREE_VALUE (formal_type
)))
111 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type
)));
113 /* Must round up to include padding. This is done the same
114 way as in store_one_arg. */
115 parm_size
= ((parm_size
+ PARM_BOUNDARY
- 1)
116 / PARM_BOUNDARY
* PARM_BOUNDARY
);
118 formal_type
= TREE_CHAIN (formal_type
);
122 if (nregs
> total
/ BITS_PER_WORD
)
123 nregs
= total
/ BITS_PER_WORD
;
124 gcc_assert (nregs
<= 9);
125 newsym
= alloca (3 + strlen (asmname
) + 1);
126 return get_identifier_with_length (newsym
,
134 i386_nlm_encode_section_info (tree decl
, rtx rtl
, int first
)
136 default_encode_section_info (decl
, rtl
, first
);
139 && TREE_CODE (decl
) == FUNCTION_DECL
140 && *IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
)) != '*'
141 && !strchr (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
)), '@'))
143 tree type_attributes
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
146 if (lookup_attribute ("stdcall", type_attributes
))
147 newid
= gen_stdcall_or_fastcall_decoration (decl
, '_');
148 else if (lookup_attribute ("fastcall", type_attributes
))
149 newid
= gen_stdcall_or_fastcall_decoration (decl
, FASTCALL_PREFIX
);
150 else if ((newid
= lookup_attribute ("regparm", type_attributes
)) != NULL_TREE
)
151 newid
= gen_regparm_prefix (decl
,
152 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (newid
))));
153 if (newid
!= NULL_TREE
)
155 rtx rtlname
= XEXP (rtl
, 0);
157 if (GET_CODE (rtlname
) == MEM
)
158 rtlname
= XEXP (rtlname
, 0);
159 XSTR (rtlname
, 0) = IDENTIFIER_POINTER (newid
);
160 /* These attributes must be present on first declaration,
161 change_decl_assembler_name will warn if they are added
162 later and the decl has been referenced, but duplicate_decls
163 should catch the mismatch before this is called. */
164 change_decl_assembler_name (decl
, newid
);
169 /* Strip the stdcall/fastcall/regparm pre-/suffix. */
172 i386_nlm_strip_name_encoding (const char *str
)
174 const char *name
= default_strip_name_encoding (str
);
176 if (*str
!= '*' && (*name
== '_' || *name
== '@'))
178 const char *p
= strchr (name
+ 1, '@');
184 name
= ggc_alloc_string (name
, p
- name
);
187 gcc_assert (ISDIGIT (*name
));
189 gcc_assert (name
== p
);