diff options
Diffstat (limited to 'volk/gen/make_cpuid_c.py')
-rw-r--r-- | volk/gen/make_cpuid_c.py | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/volk/gen/make_cpuid_c.py b/volk/gen/make_cpuid_c.py new file mode 100644 index 000000000..eb88dcd7f --- /dev/null +++ b/volk/gen/make_cpuid_c.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python +# +# Copyright 2011 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from xml.dom import minidom + +HEADER_TEMPL = """\ +/*this file is auto_generated by volk_register.py*/ + +#include <volk/volk_cpu.h> +#include <volk/volk_config_fixed.h> + +struct VOLK_CPU volk_cpu; + +#if defined(__i386__) || (__x86_64__) + +//implement get cpuid for gcc compilers using a copy of cpuid.h +#if defined(__GNUC__) +#include <gcc_x86_cpuid.h> +#define cpuid_x86(op, r) __get_cpuid(op, r+0, r+1, r+2, r+3) + +//implement get cpuid for MSVC compilers using __cpuid intrinsic +#elif defined(_MSC_VER) +#include <intrin.h> +#define cpuid(op, r) __cpuid(r, op) + +#else +#error "A get cpuid for volk is not available on this compiler..." +#endif + +static inline unsigned int cpuid_eax(unsigned int op) { + unsigned int regs[4]; + cpuid_x86 (op, regs); + return regs[0]; +} + +static inline unsigned int cpuid_ebx(unsigned int op) { + unsigned int regs[4]; + cpuid_x86 (op, regs); + return regs[1]; +} + +static inline unsigned int cpuid_ecx(unsigned int op) { + unsigned int regs[4]; + cpuid_x86 (op, regs); + return regs[2]; +} + +static inline unsigned int cpuid_edx(unsigned int op) { + unsigned int regs[4]; + cpuid_x86 (op, regs); + return regs[3]; +} +#endif + +""" + +def make_cpuid_c(dom) : + tempstring = HEADER_TEMPL; + + for domarch in dom: + if str(domarch.attributes["type"].value) == "x86": + if "no_test" in domarch.attributes.keys(): + no_test = str(domarch.attributes["no_test"].value); + if no_test == "true": + no_test = True; + else: + no_test = False; + else: + no_test = False; + arch = str(domarch.attributes["name"].value); + op = domarch.getElementsByTagName("op"); + if op: + op = str(op[0].firstChild.data); + reg = domarch.getElementsByTagName("reg"); + if reg: + reg = str(reg[0].firstChild.data); + shift = domarch.getElementsByTagName("shift"); + if shift: + shift = str(shift[0].firstChild.data); + val = domarch.getElementsByTagName("val"); + if val: + val = str(val[0].firstChild.data); + + if no_test: + tempstring = tempstring + """\ +int i_can_has_%s () { +#if defined(__i386__) || (__x86_64__) + return 1; +#else + return 0; +#endif +} + +""" % (arch) + + elif op == "1": + tempstring = tempstring + """\ +int i_can_has_%s () { +#if defined(__i386__) || (__x86_64__) + unsigned int e%sx = cpuid_e%sx (%s); + return ((e%sx >> %s) & 1) == %s; +#else + return 0; +#endif +} + +""" % (arch, reg, reg, op, reg, shift, val) + + elif op == "0x80000001": + tempstring = tempstring + """\ +int i_can_has_%s () { +#if defined(__i386__) || (__x86_64__) + unsigned int extended_fct_count = cpuid_eax(0x80000000); + if (extended_fct_count < 0x80000001) + return %s^1; + unsigned int extended_features = cpuid_e%sx (%s); + return ((extended_features >> %s) & 1) == %s; +#else + return 0; +#endif +} + +""" % (arch, val, reg, op, shift, val) + + elif str(domarch.attributes["type"].value) == "powerpc": + arch = str(domarch.attributes["name"].value); + tempstring = tempstring + """\ +int i_can_has_%s () { +#ifdef __PPC__ + return 1; +#else + return 0; +#endif +} + +""" % (arch) + + elif str(domarch.attributes["type"].value) == "arm": + arch = str(domarch.attributes["name"].value); + tempstring = tempstring + """\ +#if defined(__arm__) && defined(__linux__) +#include <asm/hwcap.h> +#include <linux/auxvec.h> +#include <stdio.h> +#define LOOK_FOR_NEON +#endif + +int i_can_has_%s () { +//it's linux-specific, but if you're compiling libvolk for NEON +//on Windows you have other problems + +#ifdef LOOK_FOR_NEON + FILE *auxvec_f; + unsigned long auxvec[2]; + unsigned int found_neon = 0; + auxvec_f = fopen("/proc/self/auxv", "rb"); + if(!auxvec_f) return 0; + + //so auxv is basically 32b of ID and 32b of value + //so it goes like this + while(!found_neon && auxvec_f) { + fread(auxvec, sizeof(unsigned long), 2, auxvec_f); + if((auxvec[0] == AT_HWCAP) && (auxvec[1] & HWCAP_NEON)) + found_neon = 1; + } + + fclose(auxvec_f); + return found_neon; + +#else + return 0; +#endif +} + +""" % (arch) + + elif str(domarch.attributes["type"].value) == "all": + arch = str(domarch.attributes["name"].value); + tempstring = tempstring + """\ +int i_can_has_%s () { + return 1; +} + +""" % (arch) + else: + arch = str(domarch.attributes["name"].value); + tempstring = tempstring + """\ +int i_can_has_%s () { + return 0; +} + +""" % (arch) + + tempstring = tempstring + "void volk_cpu_init() {\n"; + for domarch in dom: + arch = str(domarch.attributes["name"].value); + tempstring = tempstring + " volk_cpu.has_" + arch + " = &i_can_has_" + arch + ";\n" + tempstring = tempstring + "}\n\n" + + tempstring = tempstring + "unsigned int volk_get_lvarch() {\n"; + tempstring = tempstring + " unsigned int retval = 0;\n" + tempstring = tempstring + " volk_cpu_init();\n" + for domarch in dom: + arch = str(domarch.attributes["name"].value); + tempstring = tempstring + " retval += volk_cpu.has_" + arch + "() << LV_" + arch.swapcase() + ";\n" + tempstring = tempstring + " return retval;\n" + tempstring = tempstring + "}\n\n" + + return tempstring; + + + + + + + |