2 * This file is part of cparser.
3 * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 #include "lang_features.h"
30 static entity_t *create_builtin_function(builtin_kind_t kind, const char *name,
31 type_t *function_type)
33 symbol_t *symbol = symbol_table_insert(name);
34 entity_t *entity = allocate_entity_zero(ENTITY_FUNCTION);
35 entity->declaration.storage_class = STORAGE_CLASS_EXTERN;
36 entity->declaration.declared_storage_class = STORAGE_CLASS_EXTERN;
37 entity->declaration.type = function_type;
38 entity->declaration.implicit = true;
39 entity->base.symbol = symbol;
40 entity->base.source_position = builtin_source_position;
42 entity->function.btk = kind;
44 record_entity(entity, /*is_definition=*/false);
48 void create_gnu_builtins(void)
50 #define GNU_BUILTIN(a, b) create_builtin_function(bk_gnu_builtin_##a, "__builtin_" #a, b)
52 GNU_BUILTIN(alloca, make_function_1_type(type_void_ptr, type_size_t));
53 GNU_BUILTIN(huge_val, make_function_0_type(type_double));
54 GNU_BUILTIN(huge_valf, make_function_0_type(type_float));
55 GNU_BUILTIN(huge_vall, make_function_0_type(type_long_double));
56 GNU_BUILTIN(inf, make_function_0_type(type_double));
57 GNU_BUILTIN(inff, make_function_0_type(type_float));
58 GNU_BUILTIN(infl, make_function_0_type(type_long_double));
59 GNU_BUILTIN(nan, make_function_1_type(type_double, type_char_ptr));
60 GNU_BUILTIN(nanf, make_function_1_type(type_float, type_char_ptr));
61 GNU_BUILTIN(nanl, make_function_1_type(type_long_double, type_char_ptr));
62 GNU_BUILTIN(va_end, make_function_1_type(type_void, type_valist));
63 GNU_BUILTIN(expect, make_function_2_type(type_long, type_long, type_long));
64 GNU_BUILTIN(return_address, make_function_1_type(type_void_ptr, type_unsigned_int));
65 GNU_BUILTIN(frame_address, make_function_1_type(type_void_ptr, type_unsigned_int));
66 GNU_BUILTIN(ffs, make_function_1_type(type_int, type_unsigned_int));
67 GNU_BUILTIN(clz, make_function_1_type(type_int, type_unsigned_int));
68 GNU_BUILTIN(ctz, make_function_1_type(type_int, type_unsigned_int));
69 GNU_BUILTIN(popcount, make_function_1_type(type_int, type_unsigned_int));
70 GNU_BUILTIN(parity, make_function_1_type(type_int, type_unsigned_int));
71 GNU_BUILTIN(prefetch, make_function_1_type_variadic(type_float, type_void_ptr));
72 GNU_BUILTIN(trap, make_function_type(type_void, 0, NULL, DM_NORETURN));
73 GNU_BUILTIN(object_size, make_function_2_type(type_size_t, type_void_ptr, type_int));
74 GNU_BUILTIN(abort, make_function_type(type_void, 0, NULL, DM_NORETURN));
75 GNU_BUILTIN(abs, make_function_type(type_int, 1, (type_t *[]) { type_int }, DM_CONST));
76 GNU_BUILTIN(labs, make_function_type(type_long, 1, (type_t *[]) { type_long }, DM_CONST));
77 GNU_BUILTIN(llabs, make_function_type(type_long_long, 1, (type_t *[]) { type_long_long }, DM_CONST));
78 GNU_BUILTIN(memcpy, make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr_restrict, type_const_void_ptr_restrict, type_size_t }, DM_NONE));
79 GNU_BUILTIN(__memcpy_chk, make_function_type(type_void_ptr, 4, (type_t *[]) { type_void_ptr_restrict, type_const_void_ptr_restrict, type_size_t, type_size_t}, DM_NONE));
80 GNU_BUILTIN(memcmp, make_function_type(type_int, 3, (type_t *[]) { type_const_void_ptr, type_const_void_ptr, type_size_t }, DM_PURE));
81 GNU_BUILTIN(memset, make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr, type_int, type_size_t }, DM_NONE));
82 GNU_BUILTIN(memmove, make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr_restrict, type_const_void_ptr_restrict, type_size_t }, DM_NONE));
83 GNU_BUILTIN(strcat, make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
84 GNU_BUILTIN(strcat, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
85 GNU_BUILTIN(strlen, make_function_type(type_size_t, 1, (type_t *[]) { type_const_char_ptr }, DM_PURE));
86 GNU_BUILTIN(strcmp, make_function_type(type_int, 2, (type_t *[]) { type_const_char_ptr, type_const_char_ptr }, DM_PURE));
87 GNU_BUILTIN(strcpy, make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
88 GNU_BUILTIN(strncpy, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_char_ptr_restrict, type_size_t }, DM_NONE));
89 GNU_BUILTIN(exit, make_function_type(type_void, 1, (type_t *[]) { type_int }, DM_NORETURN));
90 GNU_BUILTIN(malloc, make_function_type(type_void_ptr, 1, (type_t *[]) { type_size_t }, DM_MALLOC));
92 /* TODO: gcc has a LONG list of builtin functions (nearly everything from
93 * C89-C99 and others. Complete this */
98 static const char *get_builtin_replacement_name(builtin_kind_t kind)
101 case bk_gnu_builtin_abort: return "abort";
102 case bk_gnu_builtin_abs: return "abs";
103 case bk_gnu_builtin_labs: return "labs";
104 case bk_gnu_builtin_llabs: return "llabs";
105 case bk_gnu_builtin_exit: return "exit";
106 case bk_gnu_builtin_malloc: return "malloc";
107 case bk_gnu_builtin_memcmp: return "memcmp";
108 case bk_gnu_builtin_memcpy: return "memcpy";
109 case bk_gnu_builtin___memcpy_chk: return "memcpy";
110 case bk_gnu_builtin_memset: return "memset";
111 case bk_gnu_builtin_memmove: return "memmove";
112 case bk_gnu_builtin_strlen: return "strlen";
113 case bk_gnu_builtin_strcmp: return "strcmp";
114 case bk_gnu_builtin_strcpy: return "strcpy";
115 case bk_gnu_builtin_strcat: return "strcat";
116 case bk_gnu_builtin_strncat: return "strncat";
124 int get_builtin_chk_arg_pos(builtin_kind_t kind)
127 case bk_gnu_builtin___memcpy_chk: return 3;
134 entity_t *get_builtin_replacement(const entity_t *builtin_entity)
136 builtin_kind_t kind = builtin_entity->function.btk;
137 const char *replacement = get_builtin_replacement_name(kind);
138 if (replacement == NULL)
141 entity_t *entity = allocate_entity_zero(ENTITY_FUNCTION);
142 entity->base.symbol = symbol_table_insert(replacement);
143 entity->base.namespc = NAMESPACE_NORMAL;
144 entity->base.source_position = builtin_source_position;
145 entity->declaration.storage_class = STORAGE_CLASS_EXTERN;
146 entity->declaration.declared_storage_class = STORAGE_CLASS_EXTERN;
147 entity->declaration.type = builtin_entity->declaration.type;
148 entity->declaration.implicit = true;
149 entity->declaration.modifiers = builtin_entity->declaration.modifiers;
154 void create_microsoft_intrinsics(void)
156 #define MS_BUILTIN(a, b) create_builtin_function(bk_ms##a, #a, b)
158 /* intrinsics for all architectures */
159 MS_BUILTIN(_rotl, make_function_2_type(type_unsigned_int, type_unsigned_int, type_int));
160 MS_BUILTIN(_rotr, make_function_2_type(type_unsigned_int, type_unsigned_int, type_int));
161 MS_BUILTIN(_rotl64, make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
162 MS_BUILTIN(_rotr64, make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
163 MS_BUILTIN(_byteswap_ushort, make_function_1_type(type_unsigned_short, type_unsigned_short));
164 MS_BUILTIN(_byteswap_ulong, make_function_1_type(type_unsigned_long, type_unsigned_long));
165 MS_BUILTIN(_byteswap_uint64, make_function_1_type(type_unsigned_int64, type_unsigned_int64));
167 MS_BUILTIN(__debugbreak, make_function_0_type(type_void));
168 MS_BUILTIN(_ReturnAddress, make_function_0_type(type_void_ptr));
169 MS_BUILTIN(_AddressOfReturnAddress, make_function_0_type(type_void_ptr));
170 MS_BUILTIN(__popcount, make_function_1_type(type_unsigned_int, type_unsigned_int));
173 MS_BUILTIN(_enable, make_function_0_type(type_void));
174 MS_BUILTIN(_disable, make_function_0_type(type_void));
175 MS_BUILTIN(__inbyte, make_function_1_type(type_unsigned_char, type_unsigned_short));
176 MS_BUILTIN(__inword, make_function_1_type(type_unsigned_short, type_unsigned_short));
177 MS_BUILTIN(__indword, make_function_1_type(type_unsigned_long, type_unsigned_short));
178 MS_BUILTIN(__outbyte, make_function_2_type(type_void, type_unsigned_short, type_unsigned_char));
179 MS_BUILTIN(__outword, make_function_2_type(type_void, type_unsigned_short, type_unsigned_short));
180 MS_BUILTIN(__outdword, make_function_2_type(type_void, type_unsigned_short, type_unsigned_long));
181 MS_BUILTIN(__ud2, make_function_type(type_void, 0, NULL, DM_NORETURN));
182 MS_BUILTIN(_BitScanForward, make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
183 MS_BUILTIN(_BitScanReverse, make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
184 MS_BUILTIN(_InterlockedExchange, make_function_2_type(type_long, type_long_ptr, type_long));
185 MS_BUILTIN(_InterlockedExchange64, make_function_2_type(type_int64, type_int64_ptr, type_int64));
187 if (machine_size <= 32) {
188 MS_BUILTIN(__readeflags, make_function_0_type(type_unsigned_int));
189 MS_BUILTIN(__writeeflags, make_function_1_type(type_void, type_unsigned_int));
191 MS_BUILTIN(__readeflags, make_function_0_type(type_unsigned_int64));
192 MS_BUILTIN(__writeeflags, make_function_1_type(type_void, type_unsigned_int64));