#!/bin/sh
set -e

cd "$(dirname "$0")"
echo "entering `pwd`"

jplatform64=$(./jplatform64.sh)

if [ "" = "$CFLAGS" ]; then
 # OPTLEVEL will be merged back into CFLAGS, further down
	# OPTLEVEL is probably overly elaborate, but it works
 case "$_DEBUG" in
  3) OPTLEVEL=" -O2 -g " ; DEBUG=1
   NASM_FLAGS="-g";;
  2) OPTLEVEL=" -O0 -ggdb -DOPTMO0 " ; DEBUG=1
   NASM_FLAGS="-g";;
  1) OPTLEVEL=" -O2 -g " ; DEBUG=1
   NASM_FLAGS="-g"
   jplatform64=$(./jplatform64.sh)-debug;;
  *) OPTLEVEL=" -O2 "; DEBUG=0 ;;
 esac
else
 case "$CFLAGS" in *-O0*) OPTLEVEL=" -DOPTMO0 " ; DEBUG=1 ;; *) DEBUG=0 ;; esac
fi
echo "jplatform64=$jplatform64"

USE_LINENOISE="${USE_LINENOISE:=1}"

# gcc 5 vs 4 - killing off linux asm routines (overflow detection)
# new fast code uses builtins not available in gcc 4
# use -DC_NOMULTINTRINSIC to continue to use more standard c in version 4
# too early to move main linux release package to gcc 5

case "$jplatform64" in
	darwin/j64iphoneos)
	 USE_OPENMP=0
	 LDTHREAD=" -pthread "
	 CC="$(xcrun --sdk iphoneos --find clang)"
	 AR="$(xcrun --sdk iphoneos --find libtool)"
	 macmin="-isysroot $(xcrun --sdk iphoneos --show-sdk-path) -arch arm64";;
	darwin/j64iphonesimulator)
	 USE_OPENMP=0
	 LDTHREAD=" -pthread "
	 CC="$(xcrun --sdk iphonesimulator --find clang)"
	 AR="$(xcrun --sdk iphonesimulator --find libtool)"
	 macmin="-isysroot $(xcrun --sdk iphonesimulator --show-sdk-path) -arch x86_64";;
	darwin/j64arm)
	 CC="$(xcrun --sdk macosx --find clang)"
	 AR="$(xcrun --sdk macosx --find libtool)"
	 macmin="-isysroot $(xcrun --sdk macosx --show-sdk-path) -arch arm64 -mmacosx-version-min=11";;
	darwin/*)
	 CC="$(xcrun --sdk macosx --find clang)"
	 AR="$(xcrun --sdk macosx --find libtool)"
	 macmin="-isysroot $(xcrun --sdk macosx --show-sdk-path) -arch x86_64 -mmacosx-version-min=10.6";;
	openbsd/*) make=gmake;;
	freebsd/*) make=gmake;;
 wasm*)
	 USE_OPENMP=0
	 LDTHREAD=" -pthread "
	 NO_SHA_ASM=1;USE_OPENMP=0;USE_PYXES=0;;
esac
make="${make:=make}"

CC=${CC-"$(which cc clang gcc 2>/dev/null | head -n1 | xargs basename)"}
compiler="$(readlink -f "$(which $CC)" || which $CC)"
echo "CC=$CC"
echo "compiler=$compiler"

USE_OPENMP="${USE_OPENMP:=0}"
if [ $USE_OPENMP -eq 1 ] ; then
 case $jplatform64 in
  darwin/j64arm*)
   # assume libomp installed at /opt/homebrew/
   OPENMP=" -Xpreprocessor -fopenmp -I/opt/homebrew/include "
   LDOPENMP=" -L/opt/homebrew/lib -Wl,-rpath,/opt/homebrew/lib -lomp "
  ;;
  darwin/*)
   # assume libomp installed at /usr/local/
   OPENMP=" -Xpreprocessor -fopenmp -I/usr/local/include "
   LDOPENMP=" -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lomp "
  ;;
  *)
   OPENMP=" -fopenmp "
   LDOPENMP=" -fopenmp "
   if [ -z "${compiler##*gcc*}" ] || [ -z "${CC##*gcc*}" ]; then
    LDOPENMP32=" -l:libgomp.so.1 " # gcc
   elif [ -f /etc/redhat-release ] ; then
    LDOPENMP32=" -l:libomp.so "    # clang
   else
    LDOPENMP32=" -l:libomp.so.5 "  # clang
   fi
  ;;
 esac
fi

if [ -z "${compiler##*gcc*}" ] || [ -z "${CC##*gcc*}" ]; then
 # gcc
 common="$OPENMP -std=gnu17 -fPIC $OPTLEVEL -falign-functions=4 -fvisibility=hidden -fno-strict-aliasing -fwrapv -fno-stack-protector -flax-vector-conversions \
 -Werror -Wextra -Wno-unknown-warning-option \
 -Wno-attributes \
 -Wno-cast-function-type \
 -Wno-clobbered \
 -Wno-empty-body \
 -Wno-error=stringop-overflow \
 -Wno-format-overflow \
 -Wno-implicit-fallthrough \
 -Wno-incompatible-function-pointer-types \
 -Wno-int-to-pointer-cast \
 -Wno-maybe-uninitialized \
 -Wno-missing-field-initializers \
 -Wno-null-pointer-arithmetic \
 -Wno-null-pointer-subtraction \
 -Wno-overflow \
 -Wno-parentheses \
 -Wno-pointer-sign \
 -Wno-pointer-to-int-cast \
 -Wno-return-local-addr \
 \
 -Wno-shift-negative-value \
 -Wno-sign-compare \
 -Wno-string-plus-int \
 -Wno-type-limits \
 -Wno-uninitialized \
 -Wno-unused-parameter \
 -Wno-unused-value \
 $CFLAGS"

else
 # clang
 common="$OPENMP -fPIC $OPTLEVEL -fvisibility=hidden -fno-strict-aliasing -fwrapv \
 -Werror -Wextra -Wno-unknown-warning-option \
 -Wsign-compare \
 -Wtautological-constant-out-of-range-compare \
 -Wuninitialized \
 -Wno-cast-function-type-mismatch \
 -Wno-char-subscripts \
 -Wno-consumed \
 -Wno-delete-non-abstract-non-virtual-dtor \
 -Wno-deprecated-non-prototype \
 -Wno-empty-body \
 -Wno-gnu-folding-constant \
 -Wno-implicit-float-conversion \
 -Wno-implicit-int-float-conversion \
 -Wno-incompatible-function-pointer-types \
 -Wno-int-conversion \
 -Wno-int-in-bool-context \
 -Wno-missing-braces \
 -Wno-missing-field-initializers \
 -Wno-null-pointer-arithmetic \
 -Wno-null-pointer-subtraction \
 -Wno-parentheses \
 -Wno-pass-failed \
 -Wno-pointer-sign \
 -Wno-pointer-to-int-cast \
 \
 -Wno-sometimes-uninitialized \
 -Wno-string-plus-int \
 -Wno-unknown-pragmas \
 -Wno-unsequenced \
 -Wno-unused-but-set-variable \
 -Wno-unused-function \
 -Wno-unused-parameter \
 -Wno-unused-value \
 -Wno-unused-variable \
 $CFLAGS"

fi

common="$common -DJAMALGAM"

if [ $DEBUG -eq 1 ] ; then
common="$common -DDEBUG"
fi

case "$jplatform64" in
 darwin/*) common="$common -fno-common" ;;  # other platforms already default to this
esac

case "$jplatform64" in
	darwin/j64) # darwin intel 64bit nonavx
  common="$common -msse4.1 -msse4.2 "
  ;;
	*/j64)
  if [ $_SSE4_2 -eq 1 ] ; then
  common="$common -msse4.1 -msse4.2 "
  fi
  ;;
esac

if [ $USE_OPENMP -eq 1 ] ; then
 common="$common -I../../../../openmp/include"
fi

USE_BOXEDSPARSE="${USE_BOXEDSPARSE:=0}"
if [ $USE_BOXEDSPARSE -eq 1 ] ; then
 common="$common -DBOXEDSPARSE"
fi

USE_PYXES="${USE_PYXES:=1}"
if [ $USE_PYXES -eq 1 ] ; then
 common="$common -DPYXES=1"
 LDTHREAD=" -pthread "
else
 common="$common -DPYXES=0"
fi

case "$jplatform64" in 
 */j64) USE_SLEEF=0;USE_SLEEFQUAD=1;;
 raspberry/j32*) USE_SLEEF=0;;
 wasm*) USE_SLEEF=0;;
 *) USE_SLEEF="${USE_SLEEF:=1}";;
esac
USE_SLEEFQUAD="${USE_SLEEFQUAD:=$USE_SLEEF}"
if [ $USE_SLEEF -eq 1 ] ; then
 common="$common -DSLEEF=1"
else
 common="$common -DSLEEF=0"
fi
if [ $USE_SLEEFQUAD -eq 1 ] ; then
 common="$common -DSLEEFQUAD=1"
else
 common="$common -DSLEEFQUAD=0"
fi

if [ "${USE_GMP_H:=1}" -eq 1 ] ; then
 common="$common -I../../../../mpir/include"
fi

if [ "$USE_LINENOISE" -ne "1" ] ; then
common="$common -DREADLINE"
else
common="$common -DREADLINE -DUSE_LINENOISE"
OBJSLN="linenoise.o"
fi

if [ -n "$_MEMAUDIT" ]; then
 common="$common -DMEMAUDIT=$_MEMAUDIT"
fi

if [ -n "$_ASSERT" ]; then
 common="$common -D_ASSERT"
fi

# enforce _ASSERT on file level
if [ -n "$_ASSERT2" ]; then
 common="$common -D_ASSERT2"
fi

if [ -n "$_NAN" ]; then
 common="$common -D_NAN"
fi

if [ -n "$_NAMETRACK" ]; then
 common="$common -DNAMETRACK=$_NAMETRACK"
fi

case "$jplatform64" in
 *32*) USE_EMU_AVX=0;;
 wasm*) USE_EMU_AVX=0;;
  *) USE_EMU_AVX="${USE_EMU_AVX:=1}";;
esac
if [ $USE_EMU_AVX -eq 1 ] ; then
 common="$common -DEMU_AVX2=1"
fi

NO_SHA_ASM="${NO_SHA_ASM:=0}"

if [ $NO_SHA_ASM -ne 0 ] ; then

 common="$common -DNO_SHA_ASM"

else

 SRC_ASM_LINUXAVX512=" \
 md5-x86_64-elf.o \
 keccak1600-avx512-elf.o \
 sha1-x86_64-elf.o \
 sha256-x86_64-elf.o \
 sha512-x86_64-elf.o \
 viixamd64.o "

 SRC_ASM_LINUXAVX2=" \
 md5-x86_64-elf.o \
 keccak1600-avx2-elf.o \
 sha1-x86_64-elf.o \
 sha256-x86_64-elf.o \
 sha512-x86_64-elf.o \
 viixamd64.o "

 SRC_ASM_LINUX=" \
 md5-x86_64-elf.o \
 keccak1600-x86_64-elf.o \
 sha1-x86_64-elf.o \
 sha256-x86_64-elf.o \
 sha512-x86_64-elf.o "

 SRC_ASM_LINUX32=" \
 md5-586-elf.o \
 keccak1600-mmx-elf.o \
 sha1-586-elf.o \
 sha256-586-elf.o \
 sha512-586-elf.o "

 SRC_ASM_RASPI=" \
 md5-aarch64-elf.o \
 keccak1600-armv8-elf.o \
 sha1-armv8-elf.o \
 sha256-armv8-elf.o \
 sha512-armv8-elf.o "

 SRC_ASM_RASPI32=" \
 keccak1600-armv4-elf.o \
 sha1-armv4-elf.o \
 sha256-armv4-elf.o \
 sha512-armv4-elf.o "

 SRC_ASM_MAC=" \
 md5-x86_64-macho.o \
 keccak1600-x86_64-macho.o \
 sha1-x86_64-macho.o \
 sha256-x86_64-macho.o \
 sha512-x86_64-macho.o "

 SRC_ASM_MAC32=" \
 md5-586-macho.o \
 keccak1600-mmx-macho.o \
 sha1-586-macho.o \
 sha256-586-macho.o \
 sha512-586-macho.o "

 SRC_ASM_IOS=" \
 md5-aarch64-ios.o \
 keccak1600-armv8-ios.o \
 sha1-armv8-ios.o \
 sha256-armv8-ios.o \
 sha512-armv8-ios.o "

 OBJS_ASM_WIN=" \
 ../../../../openssl-asm/md5-x86_64-nasm.o \
 ../../../../openssl-asm/keccak1600-x86_64-nasm.o \
 ../../../../openssl-asm/sha1-x86_64-nasm.o \
 ../../../../openssl-asm/sha256-x86_64-nasm.o \
 ../../../../openssl-asm/sha512-x86_64-nasm.o "

 OBJS_ASM_WIN32=" \
 ../../../../openssl-asm/md5-586-nasm.o \
 ../../../../openssl-asm/keccak1600-mmx-nasm.o \
 ../../../../openssl-asm/sha1-586-nasm.o \
 ../../../../openssl-asm/sha256-586-nasm.o \
 ../../../../openssl-asm/sha512-586-nasm.o "

fi

OBJS_BASE64=" \
  ../../../../base64/lib/arch/avx2/codec-avx2.o \
  ../../../../base64/lib/arch/avx512/codec-avx512.o \
  ../../../../base64/lib/arch/generic/codec-generic.o \
  ../../../../base64/lib/arch/neon32/codec-neon32.o \
  ../../../../base64/lib/arch/neon64/codec-neon64.o \
  ../../../../base64/lib/arch/ssse3/codec-ssse3.o \
  ../../../../base64/lib/arch/sse41/codec-sse41.o \
  ../../../../base64/lib/arch/sse42/codec-sse42.o \
  ../../../../base64/lib/arch/avx/codec-avx.o \
  ../../../../base64/lib/lib.o \
  ../../../../base64/lib/codec_choose.o \
  ../../../../base64/lib/tables/tables.o \
"

case $jplatform64 in

 linux/j32*) # linux x86
  TARGET=jamalgam
  # faster, but sse2 not available for 32-bit amd cpu
  # sse does not support mfpmath=sse in 32-bit gcc
  CFLAGS="$common -m32 -msse2 -mfpmath=sse "
  # slower, use 387 fpu and truncate extra precision
  # CFLAGS="$common -m32 -ffloat-store "
  LDFLAGS=" -m32 -lm -ldl $LDOPENMP32 $LDTHREAD -Wl,-z,noexecstack "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUX32}"
  GASM_FLAGS="-m32"
  FLAGS_BASE64=""
 ;;

 linux/j64avx512*) # linux intel 64bit avx512
  TARGET=jamalgam
  CFLAGS="$common -DC_AVX2=1 -DC_AVX512=1 "
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP -Wl,-z,noexecstack "
  CFLAGS_SIMD=" -march=skylake-avx512 -mtune=skylake-avx512 -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUXAVX512}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 linux/j64avx2*) # linux intel 64bit avx2
  TARGET=jamalgam
  CFLAGS="$common -DC_AVX2=1 "
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP -Wl,-z,noexecstack "
  CFLAGS_SIMD=" -march=skylake -mtune=skylake -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUXAVX2}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 linux/j64*) # linux intel 64bit nonavx
  TARGET=jamalgam
  CFLAGS="$common -msse3 "
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP -Wl,-z,noexecstack "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUX}"
  GASM_FLAGS=""
  FLAGS_BASE64=""
 ;;

 raspberry/j32*) # linux raspbian arm
  TARGET=jamalgam
  CFLAGS="$common -std=gnu99 -Wno-overflow -marm -march=armv6 -mfloat-abi=hard -mfpu=vfp -DRASPI "
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP"
  SRC_ASM="${SRC_ASM_RASPI32}"
  GASM_FLAGS=""
  FLAGS_BASE64=""
 ;;

 raspberry/j64*) # linux arm64
  TARGET=jamalgam
  CFLAGS="$common -march=armv8-a+crc -DRASPI -DC_CRC32C=1 "    # mno-outline-atomics unavailable on clang-7
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP"
  OBJS_AESARM=" aes-arm.o "
  SRC_ASM="${SRC_ASM_RASPI}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_NEON64=1 "
 ;;

 openbsd/j32*) # openbsd x86
  TARGET=jamalgam
  # faster, but sse2 not available for 32-bit amd cpu
  # sse does not support mfpmath=sse in 32-bit gcc
  CFLAGS="$common -m32 -msse2 -mfpmath=sse "
  # slower, use 387 fpu and truncate extra precision
  # CFLAGS="$common -m32 -ffloat-store "
  LDFLAGS=" -m32 -lm -lkvm $LDOPENMP32 $LDTHREAD"
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUX32}"
  GASM_FLAGS="-m32"
  FLAGS_BASE64=""
 ;;

 openbsd/j64arm) # openbsd arm64
  TARGET=jamalgam
  CFLAGS="$common -march=armv8-a+crc -DC_CRC32C=1 "    # mno-outline-atomics unavailable on clang-7
  LDFLAGS=" -lm -lkvm $LDTHREAD $LDOPENMP"
  OBJS_AESARM=" aes-arm.o "
  SRC_ASM="${SRC_ASM_RASPI}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_NEON64=1 "
 ;;

 openbsd/j64avx512*) # openbsd intel 64bit avx512
  TARGET=jamalgam
  CFLAGS="$common -DC_AVX2=1 -DC_AVX512=1 "
  LDFLAGS=" -lm -lkvm $LDTHREAD $LDOPENMP"
  CFLAGS_SIMD=" -march=skylake-avx512 -mtune=skylake-avx512 -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUXAVX512}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 openbsd/j64avx2*) # openbsd intel 64bit avx2
  TARGET=jamalgam
  CFLAGS="$common -DC_AVX2=1 "
  LDFLAGS=" -lm -lkvm $LDTHREAD $LDOPENMP"
  CFLAGS_SIMD=" -march=skylake -mtune=skylake -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUXAVX2}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 openbsd/j64*) # openbsd intel 64bit nonavx
  TARGET=jamalgam
  CFLAGS="$common -msse3 "
  LDFLAGS=" -lm -lkvm $LDTHREAD $LDOPENMP"
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUX}"
  GASM_FLAGS=""
  FLAGS_BASE64=""
 ;;
 
 freebsd/j32*) # freebsd x86
  TARGET=jamalgam
  # faster, but sse2 not available for 32-bit amd cpu
  # sse does not support mfpmath=sse in 32-bit gcc
  CFLAGS="$common -m32 -msse2 -mfpmath=sse "
  # slower, use 387 fpu and truncate extra precision
  # CFLAGS="$common -m32 -ffloat-store "
  LDFLAGS=" -m32 -lm $LDOPENMP32 $LDTHREAD"
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUX32}"
  GASM_FLAGS="-m32"
  FLAGS_BASE64=""
 ;;

 freebsd/j64arm) # freebsd arm64
  TARGET=jamalgam
  CFLAGS="$common -march=armv8-a+crc -DC_CRC32C=1 "    # mno-outline-atomics unavailable on clang-7
  LDFLAGS=" -lm $LDTHREAD $LDOPENMP"
  OBJS_AESARM=" aes-arm.o "
  SRC_ASM="${SRC_ASM_RASPI}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_NEON64=1 "
 ;;

 freebsd/j64avx512*) # freebsd intel 64bit avx512
  TARGET=jamalgam
  CFLAGS="$common -DC_AVX2=1 -DC_AVX512=1 "
  LDFLAGS=" -lm $LDTHREAD $LDOPENMP"
  CFLAGS_SIMD=" -march=skylake-avx512 -mtune=skylake-avx512 -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUXAVX512}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 freebsd/j64avx2*) # freebsd intel 64bit avx2
  TARGET=jamalgam
  CFLAGS="$common -DC_AVX2=1 "
  LDFLAGS=" -lm $LDTHREAD $LDOPENMP"
  CFLAGS_SIMD=" -march=skylake -mtune=skylake -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUXAVX2}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 freebsd/j64*) # freebsd intel 64bit nonavx
  TARGET=jamalgam
  CFLAGS="$common -msse3 "
  LDFLAGS=" -lm $LDTHREAD $LDOPENMP"
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_LINUX}"
  GASM_FLAGS=""
  FLAGS_BASE64=""
 ;;
 
 darwin/j32*) # darwin x86
  TARGET=jamalgam
  CFLAGS="$common -m32 -msse2 -mfpmath=sse $macmin"
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP -m32 $macmin -framework Accelerate "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_MAC32}"
  GASM_FLAGS="-m32 $macmin"
  FLAGS_BASE64=""
  ;;

 darwin/j64avx512*) # darwin intel 64bit
  TARGET=jamalgam
  CFLAGS="$common $macmin -DC_AVX2=1 -DC_AVX512=1 "
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP $macmin -framework Accelerate "
  CFLAGS_SIMD=" -march=skylake-avx512 -mtune=skylake-avx512 -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_MAC}"
  GASM_FLAGS="$macmin"
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 darwin/j64avx2*) # darwin intel 64bit
  TARGET=jamalgam
  CFLAGS="$common $macmin -DC_AVX2=1 "
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP $macmin -framework Accelerate "
  CFLAGS_SIMD=" -march=skylake -mtune=skylake -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_MAC}"
  GASM_FLAGS="$macmin"
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 darwin/j64arm*) # darwin arm
  TARGET=jamalgam
  CFLAGS="$common $macmin -march=armv8-a+crc -mno-outline-atomics -DC_CRC32C=1 "
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP $macmin -framework Accelerate "
  OBJS_AESARM=" aes-arm.o "
  SRC_ASM="${SRC_ASM_IOS}"
  GASM_FLAGS="$macmin"
  FLAGS_BASE64=" -DHAVE_NEON64=1 "
 ;;

 darwin/j64iphoneos) # iphone
  TARGET=jamalgam
  CFLAGS="$common $macmin -D IMPORTGMPLIB -march=armv8-a+crc -mno-outline-atomics -DC_CRC32C=1 "
  LDFLAGS=" -dynamiclib -install_name libj.dylib -lm $LDTHREAD $LDOPENMP $macmin -framework Accelerate "
  OBJS_AESARM=" aes-arm.o "
  SRC_ASM="${SRC_ASM_IOS}"
  GASM_FLAGS="$macmin"
  FLAGS_BASE64=" -DHAVE_NEON64=1 "
 ;;

 darwin/j64iphonesimulator) # iphone simulator
  TARGET=jamalgam
  CFLAGS="$common $macmin -D IMPORTGMPLIB -DC_CRC32C=1 "
  LDFLAGS=" -dynamiclib -install_name libj.dylib -lm $LDTHREAD $LDOPENMP $macmin -framework Accelerate "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_MAC}"
  GASM_FLAGS="$macmin"
  FLAGS_BASE64=""
 ;;

 darwin/j64*) # darwin intel 64bit nonavx
  TARGET=jamalgam
  CFLAGS="$common $macmin -msse3 "
  LDFLAGS=" -lm -ldl $LDTHREAD $LDOPENMP $macmin -framework Accelerate "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_MAC}"
  GASM_FLAGS="$macmin"
  FLAGS_BASE64=" -DHAVE_SSE42=1 "
 ;;

 windows/j32*) # windows x86
  jolecom="${jolecom:=0}"
  if [ $jolecom -eq 1 ] ; then
   DOLECOM="-DOLECOM"
  fi
  TARGET=jamalgam
  # faster, but sse2 not available for 32-bit amd cpu
  # sse does not support mfpmath=sse in 32-bit gcc
  CFLAGS="$common $DOLECOM -m32 -msse2 -mfpmath=sse -D_FILE_OFFSET_BITS=64 "
  # slower, use 387 fpu and truncate extra precision
  # CFLAGS="$common -m32 -ffloat-store "
  LDFLAGS=" -Wl,--enable-stdcall-fixup -lm -static-libgcc -static-libstdc++ $LDOPENMP32 $LDTHREAD"
  if [ $jolecom -eq 1 ] ; then
   DLLOBJS=" jdll.o jdllcomx.o "
   LIBJDEF=" ../../../../dllsrc/jdll.def "
  else
   DLLOBJS=" jdll.o "
   LIBJDEF=" ../../../../dllsrc/jdll2.def "
  fi
  LIBJRES=" jdllres.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_WIN32}"
  OBJS_ASM="${OBJS_ASM_WIN32}"
  GASM_FLAGS=""
  FLAGS_BASE64=""
 ;;

 windows/j64avx512*) # windows intel 64bit avx512
  jolecom="${jolecom:=0}"
  if [ $jolecom -eq 1 ] ; then
   DOLECOM="-DOLECOM"
  fi
  TARGET=jamalgam
  CFLAGS="$common $DOLECOM -DC_AVX2=1 -DC_AVX512=1 -D_FILE_OFFSET_BITS=64 "
  LDFLAGS=" -Wl,--enable-stdcall-fixup -lm -static-libgcc -static-libstdc++ $LDTHREAD $LDOPENMP"
  CFLAGS_SIMD=" -march=skylake-avx512 -mtune=skylake-avx512 -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  if [ $jolecom -eq 1 ] ; then
   DLLOBJS=" jdll.o jdllcomx.o "
   LIBJDEF=" ../../../../dllsrc/jdll.def "
  else
   DLLOBJS=" jdll.o "
   LIBJDEF=" ../../../../dllsrc/jdll2.def "
  fi
  LIBJRES=" jdllres.o "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_WIN}"
  OBJS_ASM="${OBJS_ASM_WIN}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 windows/j64avx2*) # windows intel 64bit avx2
  jolecom="${jolecom:=0}"
  if [ $jolecom -eq 1 ] ; then
   DOLECOM="-DOLECOM"
  fi
  TARGET=jamalgam
  CFLAGS="$common $DOLECOM -DC_AVX2=1 -D_FILE_OFFSET_BITS=64 "
  LDFLAGS=" -Wl,--enable-stdcall-fixup -lm -static-libgcc -static-libstdc++ $LDTHREAD $LDOPENMP"
  CFLAGS_SIMD=" -march=skylake -mtune=skylake -msse4.1 -msse4.2 -mavx2 -mfma -mbmi -mbmi2 -mlzcnt -mmovbe -mpopcnt -mno-vzeroupper "
  if [ $jolecom -eq 1 ] ; then
   DLLOBJS=" jdll.o jdllcomx.o "
   LIBJDEF=" ../../../../dllsrc/jdll.def "
  else
   DLLOBJS=" jdll.o "
   LIBJDEF=" ../../../../dllsrc/jdll2.def "
  fi
  LIBJRES=" jdllres.o "
  OBJS_FMA=" gemm_int-fma.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_WIN}"
  OBJS_ASM="${OBJS_ASM_WIN}"
  GASM_FLAGS=""
  FLAGS_BASE64=" -DHAVE_AVX2=1 "
 ;;

 windows/j64*) # windows intel 64bit nonavx
  jolecom="${jolecom:=0}"
  if [ $jolecom -eq 1 ] ; then
   DOLECOM="-DOLECOM"
  fi
  TARGET=jamalgam
  CFLAGS="$common -msse3 $DOLECOM -D_FILE_OFFSET_BITS=64 "
  LDFLAGS=" -Wl,--enable-stdcall-fixup -lm -static-libgcc -static-libstdc++ $LDTHREAD $LDOPENMP"
  if [ $jolecom -eq 1 ] ; then
   DLLOBJS=" jdll.o jdllcomx.o "
   LIBJDEF=" ../../../../dllsrc/jdll.def "
  else
   DLLOBJS=" jdll.o "
   LIBJDEF=" ../../../../dllsrc/jdll2.def "
  fi
  LIBJRES=" jdllres.o "
  OBJS_AESNI=" aes-ni.o "
  SRC_ASM="${SRC_ASM_WIN}"
  OBJS_ASM="${OBJS_ASM_WIN}"
  GASM_FLAGS=""
  FLAGS_BASE64=""
 ;;

 wasm/j32) # webassembly
  TARGET=jamalgam.js
# 948KB stack on v8
  CFLAGS="$common -m32 -D IMPORTGMPLIB -D CSTACKSIZE=1007616 -D CSTACKRESERVE=100000 -Wno-cast-function-type-mismatch -D TESTS "
# these flags do not work on iOS
# -msse2 -msimd128
# EMSCRIPTEN_KEEPALIVE instead of -s LINKABLE=1 -s EXPORT_ALL=1
  LDFLAGS=" -L../../../../mpir/linux/wasm32 -lgmp \
 -s WASM=1 -s ASSERTIONS=1 -s INITIAL_MEMORY=220MB -s TOTAL_MEMORY=600MB -s ALLOW_MEMORY_GROWTH=1 -s STACK_SIZE=984KB \
 -s BINARYEN_EXTRA_PASSES="--pass-arg=max-func-params@80" -s EMULATE_FUNCTION_POINTER_CASTS=1 -s EXIT_RUNTIME=1 \
 -s EXPORTED_FUNCTIONS='[\"_main\"]' \
 -s EXPORTED_RUNTIME_METHODS='[\"cwrap\",\"ccall\", \"UTF8ToString\", \"lengthBytesUTF8\", \"stringToUTF8\"]' \
 --embed-file ../../../../jlibrary/@/home/web_user/j --exclude-file *.dylib --exclude-file *.so --exclude-file *.dll \
 --exclude-file *.exe --exclude-file jconsole* --exclude-file jamalgam* --exclude-file bin32 \
 --embed-file ../../../../test/@/home/web_user/j/test "
  SRC_ASM=""
  GASM_FLAGS=""
  FLAGS_BASE64=""
 ;;

 *)
  echo no case for those parameters
  exit
 ;;
esac

echo "CFLAGS=$CFLAGS"

if [ ! -f ../jsrc/jversion.h ] ; then
  cp ../jsrc/jversion-x.h ../jsrc/jversion.h
fi

mkdir -p ../bin/$jplatform64
mkdir -p obj/$jplatform64/
cp makefile-jamalgam obj/$jplatform64/.
export CFLAGS LDFLAGS TARGET CFLAGS_SIMD GASM_FLAGS NASM_FLAGS FLAGS_BASE64 DLLOBJS LIBJDEF LIBJRES OBJS_BASE64 OBJS_FMA OBJS_AESNI OBJS_AESARM OBJS_ASM SRC_ASM OBJSLN jplatform64
cd obj/$jplatform64/
if [ "x$MAKEFLAGS" = x'' ] ; then
 if [ `uname` = Linux ]; then par=`nproc`; else par=`sysctl -n hw.ncpu`; fi
 $make -j$par -f makefile-jamalgam
else
 $make -f makefile-jamalgam
fi
retval=$?
cd -
exit $retval
