#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/time.h>
#include <openssl/bn.h>

#define SPARCV9_TICK_PRIVILEGED (1<<0)
#define SPARCV9_PREFER_FPU      (1<<1)
#define SPARCV9_VIS1            (1<<2)
#define SPARCV9_VIS2            (1<<3) /* reserved */
#define SPARCV9_FMADD           (1<<4) /* reserved for SPARC64 V */

static int OPENSSL_sparcv9cap_P = SPARCV9_TICK_PRIVILEGED;

int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
                const BN_ULONG *np, const BN_ULONG *n0, int num)
{
    int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
                        const BN_ULONG *np, const BN_ULONG *n0, int num);
    int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
                        const BN_ULONG *np, const BN_ULONG *n0, int num);

    if (num >= 8 && !(num & 1) &&
        (OPENSSL_sparcv9cap_P & (SPARCV9_PREFER_FPU | SPARCV9_VIS1)) ==
        (SPARCV9_PREFER_FPU | SPARCV9_VIS1))
        return bn_mul_mont_fpu(rp, ap, bp, np, n0, num);
    else
        return bn_mul_mont_int(rp, ap, bp, np, n0, num);
}

unsigned long _sparcv9_rdtick(void);
void _sparcv9_vis1_probe(void);
unsigned long _sparcv9_vis1_instrument(void);
void _sparcv9_vis2_probe(void);
void _sparcv9_fmadd_probe(void);

unsigned long OPENSSL_rdtsc(void)
{
    if (OPENSSL_sparcv9cap_P & SPARCV9_TICK_PRIVILEGED)
#if defined(__sun) && defined(__SVR4)
        return gethrtime();
#else
        return 0;
#endif
    else
        return _sparcv9_rdtick();
}

#if 0 && defined(__sun) && defined(__SVR4)
/*
 * This code path is disabled, because of incompatibility of libdevinfo.so.1
 * and libmalloc.so.1 (see below for details)
 */
# include <malloc.h>
# include <dlfcn.h>
# include <libdevinfo.h>
# include <sys/systeminfo.h>

typedef di_node_t(*di_init_t) (const char *, uint_t);
typedef void (*di_fini_t) (di_node_t);
typedef char *(*di_node_name_t) (di_node_t);
typedef int (*di_walk_node_t) (di_node_t, uint_t, di_node_name_t,
                               int (*)(di_node_t, di_node_name_t));

# define DLLINK(h,name) (name=(name##_t)dlsym((h),#name))

static int walk_nodename(di_node_t node, di_node_name_t di_node_name)
{
    char *name = (*di_node_name) (node);

    /* This is expected to catch all UltraSPARC flavors prior T1 */
    if (!strcmp(name, "SUNW,UltraSPARC") ||
        /* covers II,III,IV */
        !strncmp(name, "SUNW,UltraSPARC-I", 17)) {
        OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU | SPARCV9_VIS1;

        /* %tick is privileged only on UltraSPARC-I/II, but not IIe */
        if (name[14] != '\0' && name[17] != '\0' && name[18] != '\0')
            OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;

        return DI_WALK_TERMINATE;
    }
    /* This is expected to catch remaining UltraSPARCs, such as T1 */
    else if (!strncmp(name, "SUNW,UltraSPARC", 15)) {
        OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;

        return DI_WALK_TERMINATE;
    }

    return DI_WALK_CONTINUE;
}

void OPENSSL_cpuid_setup(void)
{
    void *h;
    char *e, si[256];
    static int trigger = 0;

    if (trigger)
        return;
    trigger = 1;

    if ((e = getenv("OPENSSL_sparcv9cap"))) {
        OPENSSL_sparcv9cap_P = strtoul(e, NULL, 0);
        return;
    }

    if (sysinfo(SI_MACHINE, si, sizeof(si)) > 0) {
        if (strcmp(si, "sun4v"))
            /* FPU is preferred for all CPUs, but US-T1/2 */
            OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU;
    }

    if (sysinfo(SI_ISALIST, si, sizeof(si)) > 0) {
        if (strstr(si, "+vis"))
            OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
        if (strstr(si, "+vis2")) {
            OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
            OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
            return;
        }
    }
# ifdef M_KEEP
    /*
     * Solaris libdevinfo.so.1 is effectively incomatible with
     * libmalloc.so.1. Specifically, if application is linked with
     * -lmalloc, it crashes upon startup with SIGSEGV in
     * free(3LIBMALLOC) called by di_fini. Prior call to
     * mallopt(M_KEEP,0) somehow helps... But not always...
     */
    if ((h = dlopen(NULL, RTLD_LAZY))) {
        union {
            void *p;
            int (*f) (int, int);
        } sym;
        if ((sym.p = dlsym(h, "mallopt")))
            (*sym.f) (M_KEEP, 0);
        dlclose(h);
    }
# endif
    if ((h = dlopen("libdevinfo.so.1", RTLD_LAZY)))
        do {
            di_init_t di_init;
            di_fini_t di_fini;
            di_walk_node_t di_walk_node;
            di_node_name_t di_node_name;
            di_node_t root_node;

            if (!DLLINK(h, di_init))
                break;
            if (!DLLINK(h, di_fini))
                break;
            if (!DLLINK(h, di_walk_node))
                break;
            if (!DLLINK(h, di_node_name))
                break;

            if ((root_node = (*di_init) ("/", DINFOSUBTREE)) != DI_NODE_NIL) {
                (*di_walk_node) (root_node, DI_WALK_SIBFIRST,
                                 di_node_name, walk_nodename);
                (*di_fini) (root_node);
            }
        } while (0);

    if (h)
        dlclose(h);
}

#else

static sigjmp_buf common_jmp;
static void common_handler(int sig)
{
    siglongjmp(common_jmp, sig);
}

void OPENSSL_cpuid_setup(void)
{
    char *e;
    struct sigaction common_act, ill_oact, bus_oact;
    sigset_t all_masked, oset;
    static int trigger = 0;

    if (trigger)
        return;
    trigger = 1;

    if ((e = getenv("OPENSSL_sparcv9cap"))) {
        OPENSSL_sparcv9cap_P = strtoul(e, NULL, 0);
        return;
    }

    /* Initial value, fits UltraSPARC-I&II... */
    OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED;

    sigfillset(&all_masked);
    sigdelset(&all_masked, SIGILL);
    sigdelset(&all_masked, SIGTRAP);
# ifdef SIGEMT
    sigdelset(&all_masked, SIGEMT);
# endif
    sigdelset(&all_masked, SIGFPE);
    sigdelset(&all_masked, SIGBUS);
    sigdelset(&all_masked, SIGSEGV);
    sigprocmask(SIG_SETMASK, &all_masked, &oset);

    memset(&common_act, 0, sizeof(common_act));
    common_act.sa_handler = common_handler;
    common_act.sa_mask = all_masked;

    sigaction(SIGILL, &common_act, &ill_oact);
    sigaction(SIGBUS, &common_act, &bus_oact); /* T1 fails 16-bit ldda [on
                                                * Linux] */

    if (sigsetjmp(common_jmp, 1) == 0) {
        _sparcv9_rdtick();
        OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
    }

    if (sigsetjmp(common_jmp, 1) == 0) {
        _sparcv9_vis1_probe();
        OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
        /* detect UltraSPARC-Tx, see sparccpud.S for details... */
        if (_sparcv9_vis1_instrument() >= 12)
            OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU);
        else {
            _sparcv9_vis2_probe();
            OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
        }
    }

    if (sigsetjmp(common_jmp, 1) == 0) {
        _sparcv9_fmadd_probe();
        OPENSSL_sparcv9cap_P |= SPARCV9_FMADD;
    }

    sigaction(SIGBUS, &bus_oact, NULL);
    sigaction(SIGILL, &ill_oact, NULL);

    sigprocmask(SIG_SETMASK, &oset, NULL);
}

#endif
