forgot to add files
authorMatthias Braun <matze@braunis.de>
Mon, 15 Feb 2010 15:56:00 +0000 (15:56 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 15 Feb 2010 15:56:00 +0000 (15:56 +0000)
[r27170]

builtins.c [new file with mode: 0644]
builtins.h [new file with mode: 0644]

diff --git a/builtins.c b/builtins.c
new file mode 100644 (file)
index 0000000..1109c25
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * This file is part of cparser.
+ * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include "config.h"
+
+#include "type_t.h"
+#include "types.h"
+#include "entity_t.h"
+#include "ast_t.h"
+#include "parser.h"
+#include "builtins.h"
+#include "lang_features.h"
+
+static entity_t *create_builtin_function(builtin_kind_t kind, const char *name,
+                                         type_t *function_type)
+{
+       symbol_t *symbol = symbol_table_insert(name);
+       entity_t *entity = allocate_entity_zero(ENTITY_FUNCTION);
+       entity->declaration.storage_class          = STORAGE_CLASS_EXTERN;
+       entity->declaration.declared_storage_class = STORAGE_CLASS_EXTERN;
+       entity->declaration.type                   = function_type;
+       entity->declaration.implicit               = true;
+       entity->base.symbol                        = symbol;
+       entity->base.source_position               = builtin_source_position;
+
+       entity->function.btk                       = kind;
+
+       record_entity(entity, /*is_definition=*/false);
+       return entity;
+}
+
+void create_gnu_builtins(void)
+{
+#define GNU_BUILTIN(a, b) create_builtin_function(bk_gnu_builtin_##a, "__builtin_" #a, b)
+
+       GNU_BUILTIN(alloca,         make_function_1_type(type_void_ptr, type_size_t));
+       GNU_BUILTIN(huge_val,       make_function_0_type(type_double));
+       GNU_BUILTIN(huge_valf,      make_function_0_type(type_float));
+       GNU_BUILTIN(huge_vall,      make_function_0_type(type_long_double));
+       GNU_BUILTIN(inf,            make_function_0_type(type_double));
+       GNU_BUILTIN(inff,           make_function_0_type(type_float));
+       GNU_BUILTIN(infl,           make_function_0_type(type_long_double));
+       GNU_BUILTIN(nan,            make_function_1_type(type_double, type_char_ptr));
+       GNU_BUILTIN(nanf,           make_function_1_type(type_float, type_char_ptr));
+       GNU_BUILTIN(nanl,           make_function_1_type(type_long_double, type_char_ptr));
+       GNU_BUILTIN(va_end,         make_function_1_type(type_void, type_valist));
+       GNU_BUILTIN(expect,         make_function_2_type(type_long, type_long, type_long));
+       GNU_BUILTIN(return_address, make_function_1_type(type_void_ptr, type_unsigned_int));
+       GNU_BUILTIN(frame_address,  make_function_1_type(type_void_ptr, type_unsigned_int));
+       GNU_BUILTIN(ffs,            make_function_1_type(type_int, type_unsigned_int));
+       GNU_BUILTIN(clz,            make_function_1_type(type_int, type_unsigned_int));
+       GNU_BUILTIN(ctz,            make_function_1_type(type_int, type_unsigned_int));
+       GNU_BUILTIN(popcount,       make_function_1_type(type_int, type_unsigned_int));
+       GNU_BUILTIN(parity,         make_function_1_type(type_int, type_unsigned_int));
+       GNU_BUILTIN(prefetch,       make_function_1_type_variadic(type_float, type_void_ptr));
+       GNU_BUILTIN(trap,           make_function_type(type_void, 0, NULL, DM_NORETURN));
+       GNU_BUILTIN(object_size,    make_function_2_type(type_size_t, type_void_ptr, type_int));
+       GNU_BUILTIN(abort,          make_function_type(type_void, 0, NULL, DM_NORETURN));
+       GNU_BUILTIN(abs,            make_function_type(type_int, 1, (type_t *[]) { type_int }, DM_CONST));
+       GNU_BUILTIN(labs,           make_function_type(type_long, 1, (type_t *[]) { type_long }, DM_CONST));
+       GNU_BUILTIN(llabs,          make_function_type(type_long_long, 1, (type_t *[]) { type_long_long }, DM_CONST));
+       GNU_BUILTIN(memcpy,         make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr_restrict, type_void_ptr_restrict, type_size_t }, DM_NONE));
+       GNU_BUILTIN(__memcpy_chk,   make_function_type(type_void_ptr, 4, (type_t *[]) { type_void_ptr_restrict, type_void_ptr_restrict, type_size_t, type_size_t}, DM_NONE));
+       GNU_BUILTIN(exit,           make_function_type(type_void, 1, (type_t *[]) { type_int }, DM_NORETURN));
+       GNU_BUILTIN(malloc,         make_function_type(type_void_ptr, 1, (type_t *[]) { type_size_t }, DM_MALLOC));
+       GNU_BUILTIN(memcmp,         make_function_type(type_int, 3, (type_t *[]) { type_const_void_ptr, type_const_void_ptr, type_size_t }, DM_PURE));
+       GNU_BUILTIN(memset,         make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr, type_int, type_size_t }, DM_NONE));
+       GNU_BUILTIN(strlen,         make_function_type(type_size_t, 1, (type_t *[]) { type_const_char_ptr }, DM_PURE));
+       GNU_BUILTIN(strcmp,         make_function_type(type_int, 2, (type_t *[]) { type_const_char_ptr, type_const_char_ptr }, DM_PURE));
+       GNU_BUILTIN(strcpy,         make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
+
+       /* TODO: gcc has a LONG list of builtin functions (nearly everything from
+        * C89-C99 and others. Complete this */
+
+#undef GNU_BUILTIN
+}
+
+static const char *get_builtin_replacement_name(builtin_kind_t kind)
+{
+       switch (kind) {
+       case bk_gnu_builtin_abort:  return "abort";
+       case bk_gnu_builtin_abs:    return "abs";
+       case bk_gnu_builtin_labs:   return "labs";
+       case bk_gnu_builtin_llabs:  return "llabs";
+       case bk_gnu_builtin_exit:   return "exit";
+       case bk_gnu_builtin_malloc: return "malloc";
+       case bk_gnu_builtin_memcmp: return "memcmp";
+       case bk_gnu_builtin_memcpy: return "memcpy";
+       case bk_gnu_builtin_memset: return "memset";
+       case bk_gnu_builtin_strlen: return "strlen";
+       case bk_gnu_builtin_strcmp: return "strcmp";
+       case bk_gnu_builtin_strcpy: return "strcpy";
+
+       default:
+               break;
+       }
+       return NULL;
+}
+
+entity_t *get_builtin_replacement(const entity_t *builtin_entity)
+{
+       builtin_kind_t  kind        = builtin_entity->function.btk;
+       const char     *replacement = get_builtin_replacement_name(kind);
+       if (replacement == NULL)
+               return NULL;
+
+       entity_t *entity = allocate_entity_zero(ENTITY_FUNCTION);
+       entity->base.symbol           = symbol_table_insert(replacement);
+       entity->base.namespc          = NAMESPACE_NORMAL;
+       entity->base.source_position  = builtin_source_position;
+       entity->declaration.storage_class          = STORAGE_CLASS_EXTERN;
+       entity->declaration.declared_storage_class = STORAGE_CLASS_EXTERN;
+       entity->declaration.type      = builtin_entity->declaration.type;
+       entity->declaration.implicit  = true;
+       entity->declaration.modifiers = builtin_entity->declaration.modifiers;
+
+       return entity;
+}
+
+void create_microsoft_intrinsics(void)
+{
+#define MS_BUILTIN(a, b) create_builtin_function(bk_ms##a, #a, b)
+
+       /* intrinsics for all architectures */
+       MS_BUILTIN(_rotl,                  make_function_2_type(type_unsigned_int,   type_unsigned_int, type_int));
+       MS_BUILTIN(_rotr,                  make_function_2_type(type_unsigned_int,   type_unsigned_int, type_int));
+       MS_BUILTIN(_rotl64,                make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
+       MS_BUILTIN(_rotr64,                make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
+       MS_BUILTIN(_byteswap_ushort,       make_function_1_type(type_unsigned_short, type_unsigned_short));
+       MS_BUILTIN(_byteswap_ulong,        make_function_1_type(type_unsigned_long,  type_unsigned_long));
+       MS_BUILTIN(_byteswap_uint64,       make_function_1_type(type_unsigned_int64, type_unsigned_int64));
+
+       MS_BUILTIN(__debugbreak,            make_function_0_type(type_void));
+       MS_BUILTIN(_ReturnAddress,          make_function_0_type(type_void_ptr));
+       MS_BUILTIN(_AddressOfReturnAddress, make_function_0_type(type_void_ptr));
+       MS_BUILTIN(__popcount,              make_function_1_type(type_unsigned_int, type_unsigned_int));
+
+       /* x86/x64 only */
+       MS_BUILTIN(_enable,                make_function_0_type(type_void));
+       MS_BUILTIN(_disable,               make_function_0_type(type_void));
+       MS_BUILTIN(__inbyte,               make_function_1_type(type_unsigned_char, type_unsigned_short));
+       MS_BUILTIN(__inword,               make_function_1_type(type_unsigned_short, type_unsigned_short));
+       MS_BUILTIN(__indword,              make_function_1_type(type_unsigned_long, type_unsigned_short));
+       MS_BUILTIN(__outbyte,              make_function_2_type(type_void, type_unsigned_short, type_unsigned_char));
+       MS_BUILTIN(__outword,              make_function_2_type(type_void, type_unsigned_short, type_unsigned_short));
+       MS_BUILTIN(__outdword,             make_function_2_type(type_void, type_unsigned_short, type_unsigned_long));
+       MS_BUILTIN(__ud2,                  make_function_type(type_void, 0, NULL, DM_NORETURN));
+       MS_BUILTIN(_BitScanForward,        make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
+       MS_BUILTIN(_BitScanReverse,        make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
+       MS_BUILTIN(_InterlockedExchange,   make_function_2_type(type_long, type_long_ptr, type_long));
+       MS_BUILTIN(_InterlockedExchange64, make_function_2_type(type_int64, type_int64_ptr, type_int64));
+
+       if (machine_size <= 32) {
+               MS_BUILTIN(__readeflags,           make_function_0_type(type_unsigned_int));
+               MS_BUILTIN(__writeeflags,          make_function_1_type(type_void, type_unsigned_int));
+       } else {
+               MS_BUILTIN(__readeflags,           make_function_0_type(type_unsigned_int64));
+               MS_BUILTIN(__writeeflags,          make_function_1_type(type_void, type_unsigned_int64));
+       }
+
+#undef MS_BUILTIN
+}
diff --git a/builtins.h b/builtins.h
new file mode 100644 (file)
index 0000000..6170ad5
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * This file is part of cparser.
+ * Copyright (C) 2007-2010 Matthias Braun <matze@braunis.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef BUILTINS_H
+#define BUILTINS_H
+
+/**
+ * GNU builtin or MS intrinsic functions.
+ */
+typedef enum builtin_kind_t {
+       bk_none = 0,
+       bk_gnu_builtin_alloca,
+       bk_gnu_builtin_huge_val,
+       bk_gnu_builtin_huge_valf,
+       bk_gnu_builtin_huge_vall,
+       bk_gnu_builtin_inf,
+       bk_gnu_builtin_inff,
+       bk_gnu_builtin_infl,
+       bk_gnu_builtin_nan,
+       bk_gnu_builtin_nanf,
+       bk_gnu_builtin_nanl,
+       bk_gnu_builtin_va_end,
+       bk_gnu_builtin_expect,
+       bk_gnu_builtin_return_address,
+       bk_gnu_builtin_frame_address,
+       bk_gnu_builtin_ffs,
+       bk_gnu_builtin_clz,
+       bk_gnu_builtin_ctz,
+       bk_gnu_builtin_popcount,
+       bk_gnu_builtin_parity,
+       bk_gnu_builtin_prefetch,
+       bk_gnu_builtin_trap,
+       bk_gnu_builtin_object_size,
+       bk_gnu_builtin_abort,
+       bk_gnu_builtin_abs,
+       bk_gnu_builtin_labs,
+       bk_gnu_builtin_llabs,
+       bk_gnu_builtin_exit,
+       bk_gnu_builtin_malloc,
+       bk_gnu_builtin_memcmp,
+       bk_gnu_builtin_memcpy,
+       bk_gnu_builtin___memcpy_chk,
+       bk_gnu_builtin_memset,
+       bk_gnu_builtin_strlen,
+       bk_gnu_builtin_strcmp,
+       bk_gnu_builtin_strcpy,
+
+       bk_ms_rotl,
+       bk_ms_rotr,
+       bk_ms_rotl64,
+       bk_ms_rotr64,
+       bk_ms_byteswap_ushort,
+       bk_ms_byteswap_ulong,
+       bk_ms_byteswap_uint64,
+
+       bk_ms__debugbreak,
+       bk_ms_ReturnAddress,
+       bk_ms_AddressOfReturnAddress,
+       bk_ms__popcount,
+       bk_ms_enable,
+       bk_ms_disable,
+       bk_ms__inbyte,
+       bk_ms__inword,
+       bk_ms__indword,
+       bk_ms__outbyte,
+       bk_ms__outword,
+       bk_ms__outdword,
+       bk_ms__ud2,
+       bk_ms_BitScanForward,
+       bk_ms_BitScanReverse,
+       bk_ms_InterlockedExchange,
+       bk_ms_InterlockedExchange64,
+       bk_ms__readeflags,
+       bk_ms__writeeflags,
+} builtin_kind_t;
+
+/**
+ * Create predefined gnu builtins.
+ */
+void create_gnu_builtins(void);
+
+/**
+ * Create predefined MS intrinsics.
+ */
+void create_microsoft_intrinsics(void);
+
+/**
+ * Some of the gnu builtins are simply more elaborate declarations of
+ * library functions. Return the library function name so we can simply
+ * replace the builtins with these during code generation
+ */
+entity_t *get_builtin_replacement(const entity_t *builtin_entity);
+
+#endif