mirror of https://github.com/gnss-sdr/gnss-sdr
217 lines
6.4 KiB
C
217 lines
6.4 KiB
C
/*
|
|
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
|
* This file is part of GNSS-SDR.
|
|
*
|
|
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
*/
|
|
|
|
// clang-format off
|
|
#include <volk_gnsssdr/volk_gnsssdr_common.h>
|
|
#include "volk_gnsssdr_machines.h"
|
|
#include <volk_gnsssdr/volk_gnsssdr_typedefs.h>
|
|
#include <volk_gnsssdr/volk_gnsssdr_cpu.h>
|
|
#include "volk_gnsssdr_rank_archs.h"
|
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
// clang-format on
|
|
|
|
static size_t __alignment = 0;
|
|
static intptr_t __alignment_mask = 0;
|
|
|
|
struct volk_gnsssdr_machine *get_machine(void)
|
|
{
|
|
extern struct volk_gnsssdr_machine *volk_gnsssdr_machines[];
|
|
extern unsigned int n_volk_gnsssdr_machines;
|
|
static struct volk_gnsssdr_machine *machine = NULL;
|
|
|
|
if (machine != NULL)
|
|
return machine;
|
|
else
|
|
{
|
|
unsigned int max_score = 0;
|
|
unsigned int i;
|
|
struct volk_gnsssdr_machine *max_machine = NULL;
|
|
for (i = 0; i < n_volk_gnsssdr_machines; i++)
|
|
{
|
|
if (!(volk_gnsssdr_machines[i]->caps & (~volk_gnsssdr_get_lvarch())))
|
|
{
|
|
if (volk_gnsssdr_machines[i]->caps > max_score)
|
|
{
|
|
max_score = volk_gnsssdr_machines[i]->caps;
|
|
max_machine = volk_gnsssdr_machines[i];
|
|
}
|
|
}
|
|
}
|
|
machine = max_machine;
|
|
// printf("Using Volk machine: %s\n", machine->name);
|
|
__alignment = machine->alignment;
|
|
__alignment_mask = (intptr_t)(__alignment - 1);
|
|
return machine;
|
|
}
|
|
}
|
|
|
|
void volk_gnsssdr_list_machines(void)
|
|
{
|
|
extern struct volk_gnsssdr_machine *volk_gnsssdr_machines[];
|
|
extern unsigned int n_volk_gnsssdr_machines;
|
|
|
|
unsigned int i;
|
|
for (i = 0; i < n_volk_gnsssdr_machines; i++)
|
|
{
|
|
if (!(volk_gnsssdr_machines[i]->caps & (~volk_gnsssdr_get_lvarch())))
|
|
{
|
|
printf("%s;", volk_gnsssdr_machines[i]->name);
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
const char *volk_gnsssdr_get_machine(void)
|
|
{
|
|
extern struct volk_gnsssdr_machine *volk_gnsssdr_machines[];
|
|
extern unsigned int n_volk_gnsssdr_machines;
|
|
static struct volk_gnsssdr_machine *machine = NULL;
|
|
|
|
if (machine != NULL)
|
|
return machine->name;
|
|
else
|
|
{
|
|
unsigned int max_score = 0;
|
|
unsigned int i;
|
|
struct volk_gnsssdr_machine *max_machine = NULL;
|
|
for (i = 0; i < n_volk_gnsssdr_machines; i++)
|
|
{
|
|
if (!(volk_gnsssdr_machines[i]->caps & (~volk_gnsssdr_get_lvarch())))
|
|
{
|
|
if (volk_gnsssdr_machines[i]->caps > max_score)
|
|
{
|
|
max_score = volk_gnsssdr_machines[i]->caps;
|
|
max_machine = volk_gnsssdr_machines[i];
|
|
}
|
|
}
|
|
}
|
|
machine = max_machine;
|
|
return machine->name;
|
|
}
|
|
}
|
|
|
|
size_t volk_gnsssdr_get_alignment(void)
|
|
{
|
|
get_machine(); // ensures alignment is set
|
|
return __alignment;
|
|
}
|
|
|
|
bool volk_gnsssdr_is_aligned(const void *ptr)
|
|
{
|
|
return ((intptr_t)(ptr)&__alignment_mask) == 0;
|
|
}
|
|
|
|
#define LV_HAVE_GENERIC
|
|
#define LV_HAVE_DISPATCHER
|
|
|
|
// clang-format off
|
|
|
|
%for kern in kernels:
|
|
|
|
%if kern.has_dispatcher:
|
|
#include <volk_gnsssdr/${kern.name}.h> //pulls in the dispatcher
|
|
%endif
|
|
|
|
static inline void __${kern.name}_d(${kern.arglist_full})
|
|
{
|
|
%if kern.has_dispatcher:
|
|
${kern.name}_dispatcher(${kern.arglist_names});
|
|
return;
|
|
%endif
|
|
|
|
if (volk_gnsssdr_is_aligned(<% num_open_parens = 0 %>
|
|
%for arg_type, arg_name in kern.args:
|
|
%if '*' in arg_type:
|
|
VOLK_OR_PTR(${arg_name},<% num_open_parens += 1 %>
|
|
%endif
|
|
%endfor
|
|
0<% end_open_parens = ')'*num_open_parens %>${end_open_parens}
|
|
)){
|
|
${kern.name}_a(${kern.arglist_names});
|
|
}
|
|
else{
|
|
${kern.name}_u(${kern.arglist_names});
|
|
}
|
|
}
|
|
|
|
static inline void __init_${kern.name}(void)
|
|
{
|
|
const char *name = get_machine()->${kern.name}_name;
|
|
const char **impl_names = get_machine()->${kern.name}_impl_names;
|
|
const int *impl_deps = get_machine()->${kern.name}_impl_deps;
|
|
const bool *alignment = get_machine()->${kern.name}_impl_alignment;
|
|
const size_t n_impls = get_machine()->${kern.name}_n_impls;
|
|
const size_t index_a = volk_gnsssdr_rank_archs(name, impl_names, impl_deps, alignment, n_impls, true/*aligned*/);
|
|
const size_t index_u = volk_gnsssdr_rank_archs(name, impl_names, impl_deps, alignment, n_impls, false/*unaligned*/);
|
|
${kern.name}_a = get_machine()->${kern.name}_impls[index_a];
|
|
${kern.name}_u = get_machine()->${kern.name}_impls[index_u];
|
|
|
|
assert(${kern.name}_a);
|
|
assert(${kern.name}_u);
|
|
|
|
${kern.name} = &__${kern.name}_d;
|
|
}
|
|
|
|
static inline void __${kern.name}_a(${kern.arglist_full})
|
|
{
|
|
__init_${kern.name}();
|
|
${kern.name}_a(${kern.arglist_names});
|
|
}
|
|
|
|
static inline void __${kern.name}_u(${kern.arglist_full})
|
|
{
|
|
__init_${kern.name}();
|
|
${kern.name}_u(${kern.arglist_names});
|
|
}
|
|
|
|
static inline void __${kern.name}(${kern.arglist_full})
|
|
{
|
|
__init_${kern.name}();
|
|
${kern.name}(${kern.arglist_names});
|
|
}
|
|
|
|
${kern.pname} ${kern.name}_a = &__${kern.name}_a;
|
|
${kern.pname} ${kern.name}_u = &__${kern.name}_u;
|
|
${kern.pname} ${kern.name} = &__${kern.name};
|
|
|
|
void ${kern.name}_manual(${kern.arglist_full}, const char* impl_name)
|
|
{
|
|
const int index = volk_gnsssdr_get_index(
|
|
get_machine()->${kern.name}_impl_names,
|
|
get_machine()->${kern.name}_n_impls,
|
|
impl_name
|
|
);
|
|
get_machine()->${kern.name}_impls[index](
|
|
${kern.arglist_names}
|
|
);
|
|
}
|
|
|
|
|
|
|
|
volk_gnsssdr_func_desc_t ${kern.name}_get_func_desc(void) {
|
|
const char **impl_names = get_machine()->${kern.name}_impl_names;
|
|
const int *impl_deps = get_machine()->${kern.name}_impl_deps;
|
|
const bool *alignment = get_machine()->${kern.name}_impl_alignment;
|
|
const size_t n_impls = get_machine()->${kern.name}_n_impls;
|
|
volk_gnsssdr_func_desc_t desc = {
|
|
impl_names,
|
|
impl_deps,
|
|
alignment,
|
|
n_impls
|
|
};
|
|
return desc;
|
|
}
|
|
|
|
%endfor
|
|
|
|
// clang-format on
|