silcbufferstream.c \
silclocalnetstream.c \
silcxml.c \
- silcavltree.c
+ silcavltree.c \
+ silccpuid.c
include_HEADERS = \
$(SILC_DIST_HEADER) \
silclocalnetstream.h \
silcxml.h \
silctree.h \
- silctree_i.h
+ silctree_i.h \
+ silccpuid.h
SILC_EXTRA_DIST =
--- /dev/null
+/*
+
+ silccpuid.c
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 2008 Pekka Riikonen
+
+ 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; version 2 of the License.
+
+ 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.
+
+*/
+
+#include <silcruntime.h>
+
+#if defined(SILC_I486) || defined(SILC_X86_64)
+static void silc_cpuid(SilcUInt32 level, SilcUInt32 *ecx, SilcUInt32 *edx)
+{
+ /* This works on modern CPUs. Probably fails on some ancient CPUs. */
+ asm volatile ("xorl %%ecx, %%ecx \n"
+ "xorl %%edx, %%edx \n"
+ "movl %2, %%eax \n"
+ "cpuid \n"
+ "movl %%edx, %0 \n"
+ "movl %%ecx, %1 \n"
+ : "=m" (*edx), "=m" (*ecx)
+ : "r" (level)
+ : "ebx", "eax", "ecx", "edx");
+
+ SILC_LOG_DEBUG(("CPUID 0x%08x: ecx=0x%08x, edx=0x%08x", level, *ecx, *edx));
+}
+#endif /* SILC_I486 || SILC_X86_64 */
+
+SilcCPUIdFeatures silc_cpuid_features(void)
+{
+ SilcCPUIdFeatures id = SILC_CPUID_UNKNOWN;
+#if defined(SILC_I486) || defined(SILC_X86_64)
+ SilcUInt32 ecx = 0, edx = 0;
+
+ /* Basic level */
+ silc_cpuid(1, &ecx, &edx);
+ if (!edx)
+ return SILC_CPUID_UNKNOWN;
+
+ SILC_LOG_DEBUG(("386"));
+ id = SILC_CPUID_386;
+
+ if (edx & (1 << 23)) {
+ SILC_LOG_DEBUG(("MMX"));
+ id |= SILC_CPUID_MMX;
+ }
+
+ if (edx & (1 << 15)) {
+ SILC_LOG_DEBUG(("CMOV"));
+ id |= SILC_CPUID_CMOV;
+ }
+
+ if (edx & (1 << 25)) {
+ SILC_LOG_DEBUG(("SSE"));
+ id |= SILC_CPUID_SSE;
+ }
+
+ if (edx & (1 << 26)) {
+ SILC_LOG_DEBUG(("SSE2"));
+ id |= SILC_CPUID_SSE2;
+ }
+
+ if (ecx & (1 << 0)) {
+ SILC_LOG_DEBUG(("SSE3"));
+ id |= SILC_CPUID_SSE3;
+ }
+
+ if (ecx & (1 << 9)) {
+ SILC_LOG_DEBUG(("SSSE3"));
+ id |= SILC_CPUID_SSSE3;
+ }
+
+ if (ecx & (1 << 19)) {
+ SILC_LOG_DEBUG(("SSE4.1"));
+ id |= SILC_CPUID_SSE41;
+ }
+
+ if (ecx & (1 << 20)) {
+ SILC_LOG_DEBUG(("SSE4.2"));
+ id |= SILC_CPUID_SSE41;
+ }
+
+ if (ecx & (1 << 28)) {
+ SILC_LOG_DEBUG(("AVX"));
+ id |= SILC_CPUID_AVX;
+ }
+
+ if (ecx & (1 << 25)) {
+ SILC_LOG_DEBUG(("AES"));
+ id |= SILC_CPUID_AES;
+ }
+
+ /* Extended level */
+ ecx = edx = 0;
+ silc_cpuid(0x80000001, &ecx, &edx);
+ if (!ecx)
+ goto out;
+
+ if (ecx & (1 << 6)) {
+ SILC_LOG_DEBUG(("SSE4a"));
+ id |= SILC_CPUID_SSE4A;
+ }
+
+ if (ecx & (1 << 25)) {
+ SILC_LOG_DEBUG(("SSE5"));
+ id |= SILC_CPUID_SSE5;
+ }
+
+ out:
+#endif /* SILC_I486 || SILC_X86_64 */
+ return id;
+}
--- /dev/null
+/*
+
+ silccpuid.h
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 2008 Pekka Riikonen
+
+ 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; version 2 of the License.
+
+ 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.
+
+*/
+
+#ifndef SILCCPUID_H
+#define SILCCPUID_H
+
+/****d* silcutil/SilcCPUIdFeatures
+ *
+ * NAME
+ *
+ * typedef enum { ... } SilcCPUIdFeatures;
+ *
+ * DESCRIPTION
+ *
+ * CPU features. Indicates which instruction sets the CPU supports.
+ *
+ */
+typedef enum {
+ SILC_CPUID_UNKNOWN = 0x00000000, /* 386 only */
+ SILC_CPUID_386 = 0x00000002, /* 386 */
+ SILC_CPUID_MMX = 0x00000004, /* MMX */
+ SILC_CPUID_CMOV = 0x00000008, /* CMOV, FCOMI */
+ SILC_CPUID_SSE = 0x00000010, /* SSE */
+ SILC_CPUID_SSE2 = 0x00000020, /* SSE2 */
+ SILC_CPUID_SSE3 = 0x00000040, /* SSE3 */
+ SILC_CPUID_SSSE3 = 0x00000080, /* SSSE3 */
+ SILC_CPUID_SSE41 = 0x00000100, /* SSE4.1 */
+ SILC_CPUID_SSE42 = 0x00000200, /* SSE4.2 */
+ SILC_CPUID_SSE4A = 0x00000400, /* SSE4a */
+ SILC_CPUID_SSE5 = 0x00000800, /* SSE5 */
+ SILC_CPUID_AVX = 0x00001000, /* AVX */
+ SILC_CPUID_AES = 0x00002000, /* AES */
+} SilcCPUIdFeatures;
+/***/
+
+/****f* silcutil/silc_cpuid_features
+ *
+ * SYNOPSIS
+ *
+ * SilcCPUIdFeatures silc_cpuid_features(void);
+ *
+ * DESCRIPTION
+ *
+ * Returns the CPU instruction set features. The ID can be used to
+ * determine what features the CPU supports. The returned value is a
+ * bitmask of supported features.
+ *
+ * NOTES
+ *
+ * This function should not be called at a code path where speed is
+ * critical. It is recommended to call this once and later use the
+ * returned value to determine features.
+ *
+ * This function works only on x86 or x86-64 CPUs.
+ *
+ ***/
+SilcCPUIdFeatures silc_cpuid_features(void);
+
+#endif /* SILCCPUID_H */
/* SILC Runtime Toolkit includes */
#include <silctypes.h>
+#include <silccpuid.h>
#include <silcerrno.h>
#include <silcbitops.h>
#include <silcmutex.h>
*
* SOURCE
*/
-#if SILC_SIZEOF_LONG == 4
-typedef unsigned long SilcUInt32;
-typedef signed long SilcInt32;
-#else
#if SILC_SIZEOF_INT == 4
typedef unsigned int SilcUInt32;
typedef signed int SilcInt32;
#else
+#if SILC_SIZEOF_LONG == 4
+typedef unsigned long SilcUInt32;
+typedef signed long SilcInt32;
+#else
#if SILC_SIZEOF_LONG_LONG >= 4
#ifndef WIN32
typedef unsigned long long SilcUInt32;
#undef SILC_PREFETCH_ASM
}
+typedef char __check_size1[sizeof(SilcInt8) == 1 ? 1 : -1];
+typedef char __check_size2[sizeof(SilcUInt8) == 1 ? 1 : -1];
+typedef char __check_size3[sizeof(SilcInt16) == 2 ? 1 : -1];
+typedef char __check_size4[sizeof(SilcUInt16) == 2 ? 1 : -1];
+typedef char __check_size5[sizeof(SilcInt32) == 4 ? 1 : -1];
+typedef char __check_size6[sizeof(SilcUInt32) == 4 ? 1 : -1];
+
#endif /* SILCTYPES_H */
test_silcdll test_silcenv test_silctimer test_silcbitops \
test_silcregex test_silcbuffmt test_silcdir test_silcthreadqueue \
test_silcrand test_silcglobal test_silcbufferstream test_silcxml \
- test_silclocalnetstream test_silctree
+ test_silclocalnetstream test_silctree test_silccpuid
TESTS = test_silcstrutil test_silcstringprep test_silchashtable \
test_silclist test_silcfsm test_silcasync test_silcschedule \
test_silcdll test_silcenv test_silctimer test_silcbitops \
test_silcregex test_silcbuffmt test_silcdir test_silcthreadqueue \
test_silcrand test_silcglobal test_silcbufferstream \
- test_silclocalnetstream test_silctree
+ test_silclocalnetstream test_silctree test_silccpuid
LIBS = $(SILC_COMMON_LIBS)
LDADD = -L.. -L../.. -lsrt
--- /dev/null
+/* CPUID tests */
+
+#include "silcruntime.h"
+
+int main(int argc, char **argv)
+{
+ SilcBool success = FALSE;
+ SilcCPUIdFeatures id;
+
+ if (argc > 1 && !strcmp(argv[1], "-d")) {
+ silc_log_debug(TRUE);
+ silc_log_quick(TRUE);
+ silc_log_debug_hexdump(TRUE);
+ silc_log_set_debug_string("*cpu*");
+ }
+
+ id = silc_cpuid_features();
+
+ success = TRUE;
+
+// err:
+ SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
+ fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");
+
+ return !success;
+}
last="$1"
new="$2"
-git tag $new
-git log --no-merges $new ^$last > ChangeLog
+git tag -a -m "Release $new" $new
+git log --no-merges $new ^$last >> ChangeLog
echo "" >> ChangeLog
git diff --stat --summary -M $last $new >> ChangeLog