if [ "$SAGE_LOCAL" = "" ]; then
   echo >&2 "SAGE_LOCAL undefined ... exiting"
   echo >&2 "Maybe run 'sage -sh'?"
   exit 1
fi

# Let the environment variable CFLAG64 specify the compiler flag
# to build 64-bit code. It it is not set, set it to -m64
if [ -z $CFLAG64 ] ; then
   CFLAG64=-m64
fi

# If SAGE64 is "yes", build 64-bit.
if [ "x$SAGE64" = xyes ] ; then
   echo "Building SYMPOW 64-bit"
   CFLAGS="$CFLAGS $CFLAG64"
   LDFLAGS="$LDFLAGS $CFLAG64"
   export CFLAGS
   export LDFLAGS
fi


#######################################################################
# Fix FPU precision
#######################################################################
# SYMPOW really needs doubles to have *exactly* 53 bits precision,
# they need to be true IEEE-754 double precision numbers.
# In particular, we need to avoid 80 bits extended precision on i386
# and we need to avoid fused multiply-add instructions (e.g. on ia64).
# We might need to add various flags to CFLAGS to ensure this.
# See Trac tickets #9703, #9734, #9166, #11226, #11920.

# Usage: try_add_CFLAG $FLAG
# Try adding $FLAG to $CFLAGS, compile and run the fpubits program.
# If it compiles and running it doesn't crash it (with an Illegal
# Instruction for example), then we add $FLAG to $CFLAGS.
# Return 0 if we added $FLAG and the FPU correctly used 53 bits,
# return 1 if we added $FLAG but the FPU doesn't use 53 bits,
# return 2 if we did not add $FLAG.
try_add_CFLAG()
{
    # We use -O3 here to really force generation of fused
    # multiply-add instructions and to keep floats as much as
    # possible in registers.
    # We compile in the (already patched!) src/fpu.c which only does
    # something if the macro x86 is defined.
    if $CC -O3 $CFLAGS $FLAG config/fpubits1.c config/fpubits2.c src/fpu.c -o config/fpubits 2>/dev/null; then
        # Compiled successfully, now run it
        config/fpubits >/dev/null 2>/dev/null
        status=$?
        if [ $status -le 1 ]; then
            # The program ran successfully.  For now, we don't need
            # the exit status to be zero (indicating exactly 53 bits),
            # we simply need the program not to crash (which would
            # give an exit status > 128).
            CFLAGS="$CFLAGS $FLAG"
            return $status
        fi
    fi
    return 2
}

# These flags never hurt, so add them if possible
for FLAG in '-fno-fast-math' '-mfpmath=sse' '-Dx86'; do
    try_add_CFLAG $FLAG
done

# Add at most one flag of the following to avoid gcc warnings:
# gcc versions which support -ffp-contract deprecate -mno-fused-madd
for FLAG in '-ffp-contract=on' '-mno-fused-madd'; do
    try_add_CFLAG $FLAG && break
done

# Some flags to try as last resort.  These hurt performance, so only add
# them if needed.
for FLAG in '' '-ffloat-store' '-O0'; do
    # Stop the loop if the FPU precision already is 53 bits
    try_add_CFLAG $FLAG && break
done


# Check the actual FPU precision with our new flags.
$CC -O3 $CFLAGS config/fpubits1.c config/fpubits2.c src/fpu.c -o config/fpubits
if [ $? -ne 0 ]; then
    echo >&2 "Error: the command below failed:"
    echo >&2 "$CC -O3 $CFLAGS config/fpubits1.c config/fpubits2.c src/fpu.c -o config/fpubits"
    exit 1
fi
export CFLAGS

echo "CFLAGS for SYMPOW:$CFLAGS"

config/fpubits
status=$?
if [ $status -eq 1 ]; then
cat >&2 <<EOF
Error: the Quad Double library used by SYMPOW assumes IEEE-754 double
precision numbers with exactly 53 bits in the mantissa (64 bits in
total).  Unfortunately, this is not the case on your system and we
currently have no workaround for your system.  Running SYMPOW will
almost certainly fail on some inputs.

Please report this problem to sage-devel
(http://groups.google.com/group/sage-devel), mentioning in particular
your operating system, processor type and compiler version
(run $CC --version).
EOF
elif [ $status -ne 0 ]; then
cat >&2 <<EOF
Error: something very bad happened while checking the precision of your
FPU.  Please report this problem (mentioning any error messages above)
to sage-devel (http://groups.google.com/group/sage-devel).
Mention in particular your operating system and compiler version
(run $CC --version).
EOF
exit 1
fi

#######################################################################
# Configure
#######################################################################
cd src/
bash ./Configure  # Force bash as shell
if [ $? -ne 0 ]; then
   echo >&2 "Error configuring SYMPOW"
   exit 1
fi


#######################################################################
# Build
#######################################################################
$MAKE
if [ $? -ne 0 ]; then
   echo >&2 "Error building SYMPOW"
   exit 1
fi

#######################################################################
# Install
#######################################################################
TARGET="$SAGE_LOCAL/lib/sympow"

rm -rf "$TARGET"
mkdir "$TARGET"

cp sympow *.gp new_data "$TARGET/"
if [ $? -ne 0 ]; then
   echo >&2 "Error copying SYMPOW files"
   exit 1
fi

# Copy datafiles
mv datafiles "$TARGET/"
if [ ! -d "$TARGET/datafiles" ]; then
   echo >&2 "Error installing SYMPOW datafiles"
   exit 1
fi

# Create binary versions of datafiles
cd "$TARGET/datafiles"
for file in *.txt; do
    NUM=`grep -c AT $file`
    ../sympow -txt2bin "$NUM" <$file ${file/%txt/bin}
    if [ $? -ne 0 ]; then
        echo >&2 "Error running SYMPOW"
        exit 1
    fi
done

# Create sympow script in $SAGE_LOCAL/bin
SCRIPT="$SAGE_LOCAL/bin/sympow"

cat >"$SCRIPT" <<'EOF'
cd "$SAGE_LOCAL/lib/sympow"
exec ./sympow "$@"
EOF

chmod +x "$SCRIPT"
