So, I've been drafting this up in my blog[1], and it is a simple way to 
replace the CPU feature useflags. Let's try to summarise:

Right now we have mmx, 3dnow, 3dnowex, sse, sse2 and so on useflags present in 
the tree, almost never used to get new dependencies, but usually used to 
supply econf switches.

This works as long as the user enable the flags, but for AMD64 the story was, 
until now, that we simply enabled them when they worked, because we had some 
minimum support available. Unfortunately this became a problem with the 
introduction of nocona, because that is an amd64-like system but with no 
3dnow. And there is the problem that sse3 is supported only in later versions 
of Athlon64 and so on.

To try to clean up this mess, and to make it simpler to work in 
cross-compilation, I thought of using the definitions created by the C 
Preprocessor (CPP) by default for the given CFLAGS. Basically when 
using -march=athlon64, the preprocessor will enable a few definitions that 
tells the availability of MMX, 3dNOW, SSE and so on... if we wrap that 
around, we can use it to know if it's the case of enabling something or not.
This is customisable by the user by setting the CFLAGS themselves. If one does 
not want MMX instructions to be generated, but still want the rest of 
Athlon64 optimisations, it's simply the matter of 
using "-march=athlon64 -mno-mmx".

So, rather than the functions proposed in [1], I've sampled today the 
following function:

has_cpuset() {
    local def hasfeat

    while [[ -n $1 ]]; do
        case $1 in
            mmx)
                def="__MMX__" ;;
            3dnow)
                def="__3dNOW__" ;;
            3dnowex)
                def="__3dNOW_A__" ;;
            sse)
                def="__SSE__" ;;
            sse2)
                def="__SSE2__" ;;
            sse3)
                def="__SSE3__" ;;
            altivec)
                def="__ALTIVEC__" ;;
            *)
                ewarn "Instruction set $1 not supported."
                die "Instruction set not supported."
        esac

        echo | $(tc-getCC) ${CFLAGS} -dM -E - 2>/dev/null | grep -q ${def} || 
hasfeat="no"
        shift
    done

    if [[ ${hasfeat} == "no" ]]; then
        return 1
    else
        return 0
    fi
}

that can be tested easily with the following code:

yesno() {
    if "$@"; then
        echo "yes"
    else
        echo "no"
    fi
}

echo "Does it have 3dnow mmx sse2?"
yesno has_cpuset 3dnow mmx sse2
echo "Does it have mmx sse sse3?"
yesno has_cpuset mmx sse sse3
echo "Does it have altivec?"
yesno has_cpuset altivec


Note that you  need to set your CFLAGS corretly or it will, by default, tell 
you that everything is disabled.

Thoughts? Comments?

SPARC team: I'd like to know if VIS does a similar thing, would make simpler 
for instance its handling in xine-lib ebuild.

[1] 
http://farragut.flameeyes.is-a-geek.org/articles/2006/06/24/crazy-idea-an-alternative-to-cpu-features-useflags
-- 
Diego "Flameeyes" Pettenò - http://farragut.flameeyes.is-a-geek.org/
Gentoo/Alt lead, Gentoo/FreeBSD, Video, AMD64, Sound, PAM, KDE

Attachment: pgprX2XeoSak4.pgp
Description: PGP signature

Reply via email to