#!/bin/sh
#
# This file is part of the coreboot project.
#
# Copyright (C) 2007-2010 coresystems GmbH
# Copyright (C) 2012 Google Inc
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#

TMPFILE=""

die() {
	echo "ERROR: $*" >&2
	exit 1
}

clean_up() {
	if [ -n "$TMPFILE" ]; then
		rm -f "$TMPFILE" "$TMPFILE.c" "$TMPFILE.o"
	fi
}

program_exists() {
	type "$1" >/dev/null 2>&1
}

testcc() {
	local tmp_c="$TMPFILE.c"
	local tmp_o="$TMPFILE.o"
	rm -f "$tmp_c" "$tmp_o"
	echo "void _start(void) {}" >"$tmp_c"
	"$1" -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
}

testas() {
	local gccprefixes="$1"
	local twidth="$2"
	local arch="$3"
	local use_dash_twidth="$4"
	local obj_file="$TMPFILE.o"
	local full_arch="elf$twidth-$arch"

	rm -f "$obj_file"
	[ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth"
	${gccprefixes}as $use_dash_twidth -o "$obj_file" $TMPFILE 2>/dev/null ||
		return 1

	# Check output content type.
	local obj_type="$(${gccprefixes}objdump -p $obj_file)"
	local obj_arch="$(expr "$obj_type" : '.*format \(.[a-z0-9-]*\)')"
	[ "$obj_arch" = "$full_arch" ] || return 1

	# Architecture matched.
	GCCPREFIX="$gccprefixes"

	if [ -z "$use_dash_twidth" ]; then
		ASFLAGS=""
		CFLAGS=""
		LDFLAGS=""
	else
		ASFLAGS="--$twidth"
		CFLAGS="-m$twidth"
		LDFLAGS="-b $full_arch"

	fi

	# Special parameters only available in dash_twidth mode.
	[ -n "$use_dash_twidth" ] && case "$full_arch" in
		"elf32-i386" )
			LDFLAGS="$LDFLAGS -melf_i386"
			CFLAGS="$CFLAGS -Wl,-b,elf32-i386 -Wl,-melf_i386"
			;;
	esac

	return 0
}

detect_special_flags() {
	local architecture="$1"
	# GCC 4.6 is much more picky about unused variables.
	# Turn off it's warnings for now:
	testcc "$CC"   "$CFLAGS -Wno-unused-but-set-variable " &&
		CFLAGS="$CFLAGS -Wno-unused-but-set-variable "

	testcc "$CC"   "$CFLAGS -Wa,--divide" &&
		CFLAGS="$CFLAGS -Wa,--divide"
	testcc "$CC"   "$CFLAGS -fno-stack-protector"&&
		CFLAGS="$CFLAGS -fno-stack-protector"
	testcc "$CC"   "$CFLAGS -Wl,--build-id=none" &&
		CFLAGS="$CFLAGS -Wl,--build-id=none"

	case "$architecture" in
	x86 )
		# Use bfd linker instead of gold if available:
		testcc "$CC"   "$CFLAGS -fuse-ld=bfd" &&
			CFLAGS="$CFLAGS -fuse-ld=bfd" && LINKER_SUFFIX_i386='.bfd'
		# Always build for i686 -- no sse/mmx instructions since SMM
		# modules are compiled using these flags. Note that this
		# doesn't prevent a project using xcompile to explicitly
		# specify -mmsse, etc flags.
		CFLAGS="$CFLAGS  -march=i686"
		;;
	arm )
		testcc "$CC" "$CFLAGS" && CFLAGS="$CFLAGS"
		;;
	mipsel )
		testcc "$CC" "$CFLAGS -mno-abicalls -fno-pic" && \
                  CFLAGS+=" -mno-abicalls -fno-pic"
		;;
	esac
}

report_arch_toolchain() {
	cat <<EOF
# elf${TWIDTH}-${TBFDARCH} toolchain (${GCCPREFIX}gcc)
CC_${TARCH}:=${GCCPREFIX}gcc ${CFLAGS}
AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS}
LD_${TARCH}:=${GCCPREFIX}ld$(eval echo \${LINKER_SUFFIX_${TARCH}}) ${LDFLAGS}
NM_${TARCH}:=${GCCPREFIX}nm
OBJCOPY_${TARCH}:=${GCCPREFIX}objcopy
OBJDUMP_${TARCH}:=${GCCPREFIX}objdump
READELF_${TARCH}:=${GCCPREFIX}readelf
STRIP_${TARCH}:=${GCCPREFIX}strip
AR_${TARCH}:=${GCCPREFIX}ar

EOF
}

# Create temporary file(s).
TMPFILE="$(mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz)"
touch "$TMPFILE"
trap clean_up EXIT

# Architecture definition
SUPPORTED_ARCHITECTURE="x86 arm aarch64 mipsel"

# ARM Architecture
TARCH_arm="arm"
TBFDARCH_arm="littlearm"
TCLIST_arm="armv7a"
TWIDTH_arm="32"

# AARCH64 Architecture
TARCH_aarch64="aarch64"
TBFDARCH_aarch64="littleaarch64"
TCLIST_aarch64="aarch64"
TWIDTH_aarch64="64"

# X86 Architecture
TARCH_x86="i386"
TBFDARCH_x86="i386"
TCLIST_x86="i386 x86_64"
TWIDTH_x86="32"
XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"}

# MIPS Architecture (Little Endian)
TARCH_mipsel="mipsel"
TBFDARCH_mipsel="tradlittlemips littlemips"
TCLIST_mipsel="mipsel"
TWIDTH_mipsel="32"

# This loops over all supported architectures.
for architecture in $SUPPORTED_ARCHITECTURE; do
	GCCPREFIX="invalid"
	TARCH="$(eval echo \$TARCH_$architecture)"
	TBFDARCHS="$(eval echo \$TBFDARCH_$architecture)"
	TCLIST="$(eval echo \$TCLIST_$architecture)"
	TWIDTH="$(eval echo \$TWIDTH_$architecture)"
	[ -z "$TARCH" -o -z "$TCLIST" -o -z "$TWIDTH" ] &&
		die "Missing architecture definition for $architecture."

	# To override toolchain, define CROSS_COMPILE_$arch or CROSS_COMPILE as
	# environment variable.
	# Ex: CROSS_COMPILE_arm="armv7a-cros-linux-gnueabi-"
	#     CROSS_COMPILE_x86="i686-pc-linux-gnu-"
	search="$(eval echo \$CROSS_COMPILE_$architecture 2>/dev/null)"
	search="$search $CROSS_COMPILE"
	for toolchain in $TCLIST; do
		search="$search $XGCCPATH$toolchain-elf-"
		search="$search $toolchain-elf-"
		search="$search $XGCCPATH$toolchain-eabi-"
		search="$search $toolchain-eabi-"
	done
	echo "# $architecture TARCH_SEARCH=$search"

	# Search toolchain by checking assembler capability.
        for TBFDARCH in $TBFDARCHS; do
		for gccprefixes in $search ""; do
			program_exists "${gccprefixes}as" || continue
			testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "" && break
			testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "TRUE" && break
		done
                [ "$GCCPREFIX" = "invalid" ] || break
	done

	if [ "$GCCPREFIX" = "invalid" ]; then
		echo "Warning: no suitable GCC for $architecture." >&2
		continue
	fi
	CC="${GCCPREFIX}"gcc

	detect_special_flags "$architecture"
	report_arch_toolchain
done

if [ "$(${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
	IASL=${XGCCPATH}iasl
else
	IASL=iasl
fi

if program_exists gcc; then
	HOSTCC=gcc
else
	HOSTCC=cc
fi

cat <<EOF
IASL:=${IASL}

# native toolchain
HOSTCC:=${HOSTCC}
EOF
